diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 663da097..f316631d 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osinacore/__pycache__/consumers.cpython-310.pyc b/osinaweb/osinacore/__pycache__/consumers.cpython-310.pyc index bbb085f3..eae2be93 100644 Binary files a/osinaweb/osinacore/__pycache__/consumers.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/consumers.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc b/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc index cae0b7ee..fe084a9c 100644 Binary files a/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/custom_context.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc index 4ff22a53..0856a296 100644 Binary files a/osinaweb/osinacore/__pycache__/models.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/routing.cpython-310.pyc b/osinaweb/osinacore/__pycache__/routing.cpython-310.pyc index fa5e200b..17c9ec1a 100644 Binary files a/osinaweb/osinacore/__pycache__/routing.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/routing.cpython-310.pyc differ diff --git a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc index a0b99cad..94457723 100644 Binary files a/osinaweb/osinacore/__pycache__/views.cpython-310.pyc and b/osinaweb/osinacore/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/osinacore/consumers.py b/osinaweb/osinacore/consumers.py new file mode 100644 index 00000000..2afe06d8 --- /dev/null +++ b/osinaweb/osinacore/consumers.py @@ -0,0 +1,93 @@ +from channels.generic.websocket import WebsocketConsumer +from .models import * +import json +from django.template.loader import render_to_string +from asgiref.sync import async_to_sync +import threading + +def get_last_seen(user): + connection = Connection.objects.filter(user=user).last() + if not connection.exists(): + return "Not seen yet" + + if connection.online: + return "Online" + last_seen_time = connection.last_seen + now = timezone.now() + time_diff = now - last_seen_time + if time_diff < timedelta(days=1): + if last_seen_time.date() == now.date(): + return f"last seen today at {last_seen_time.strftime('%I:%M %p')}" + else: + return f"last seen yesterday at {last_seen_time.strftime('%I:%M %p')}" + else: + return f"last seen on {last_seen_time.strftime('%b %d at %I:%M %p')}" + + + +class OnlineUserConsumer(WebsocketConsumer): + def connect(self): + self.user = self.scope['user'] + existing_connection = Connection.objects.filter(user=self.user).last() + if existing_connection: + self.connection = existing_connection + self.connection.online = True + self.connection.disconnected = False + self.connection.save() + else: + self.connection = Connection.objects.create(user=self.user, online=True) + + async_to_sync(self.channel_layer.group_add)( + 'online_users', self.channel_name + ) + self.accept() + self.modify_online_user() + + def disconnect(self, close_code): + self.last_seen = datetime.now() + self.connection.disconnected = True + self.connection.save() + timer_thread = threading.Timer(10, self.check_disconnect_status) + timer_thread.start() + + def check_disconnect_status(self): + connection = Connection.objects.filter(user=self.user).last() + if connection.disconnected: + self.connection.last_seen = self.last_seen + self.connection.online = False + self.connection.save() + self.modify_online_user() + + def modify_online_user(self): + connections = Connection.objects.filter(online=True) + online_users_ids = [connection.user.id for connection in connections] + customer_connections = [] + staff_connections = [] + for connection in connections: + if hasattr(connection.user, 'customerprofile'): + customer_connections.append(connection) + elif hasattr(connection.user, 'staffprofile'): + staff_connections.append(connection) + + print(staff_connections) + event = { + 'type': 'online_user_connection_handler', + 'staff_connections': staff_connections, + 'customer_connections': customer_connections, + 'online_users_ids': online_users_ids + } + async_to_sync(self.channel_layer.group_send)( + 'online_users', event + ) + + def online_user_connection_handler(self, event): + context = { + 'staff_connections': event['staff_connections'], + 'customer_connections': event['customer_connections'], + } + html = render_to_string("details_templates/partials/recently-online.html", context=context) + self.send(text_data=json.dumps({ + 'event_type': 'online_user_status', + 'html': html, + 'online_users_ids': event.get('online_users_ids', []) + })) diff --git a/osinaweb/osinacore/custom_context.py b/osinaweb/osinacore/custom_context.py index 8da14f85..342d940e 100644 --- a/osinaweb/osinacore/custom_context.py +++ b/osinaweb/osinacore/custom_context.py @@ -23,15 +23,6 @@ def calculate_time_ago(status): def utilities(request): - latest_connections = Connection.objects.filter(user__staffprofile__isnull=False).values('user').annotate(latest_connection=Max('date')) - online_staff_profiles = [] - for connection in latest_connections: - user_id = connection['user'] - latest_connection = connection['latest_connection'] - last_connection = Connection.objects.filter(user_id=user_id, date=latest_connection).first() - if last_connection.status == 'Online': - online_staff_profiles.append(last_connection.user.staffprofile) - notes = None recent_note = None @@ -45,12 +36,6 @@ def utilities(request): if request.user.is_authenticated and StaffProfile.objects.filter(user=request.user): notes = Note.objects.filter(user=request.user).order_by('-date')[:6] recent_note = Note.objects.filter(user=request.user).last() - last_user_activity = Connection.objects.filter(user=request.user).last() - if last_user_activity and last_user_activity.status == 'Offline': - user_offline = True - else: - user_offline = False - if request.user.is_superuser: open_task_count = Task.objects.filter(status='Open').count() @@ -141,7 +126,6 @@ def utilities(request): 'latest_statuses_time_ago': latest_statuses_time_ago, 'notes' : notes, 'recent_note' : recent_note, - 'online_staff_profiles' : online_staff_profiles, 'user_offline' : user_offline, 'recent_logged_in_staffs' : recent_logged_in_staffs, 'recent_logged_in_customers' : recent_logged_in_customers, diff --git a/osinaweb/osinacore/delete/__pycache__/urls.cpython-310.pyc b/osinaweb/osinacore/delete/__pycache__/urls.cpython-310.pyc index 4550f0b0..4d6ecfc7 100644 Binary files a/osinaweb/osinacore/delete/__pycache__/urls.cpython-310.pyc and b/osinaweb/osinacore/delete/__pycache__/urls.cpython-310.pyc differ diff --git a/osinaweb/osinacore/delete/__pycache__/views.cpython-310.pyc b/osinaweb/osinacore/delete/__pycache__/views.cpython-310.pyc index 28de45ec..ec01aeaa 100644 Binary files a/osinaweb/osinacore/delete/__pycache__/views.cpython-310.pyc and b/osinaweb/osinacore/delete/__pycache__/views.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/0086_remove_connection_status_connection_terminated_at.py b/osinaweb/osinacore/migrations/0086_remove_connection_status_connection_terminated_at.py new file mode 100644 index 00000000..fc0363fe --- /dev/null +++ b/osinaweb/osinacore/migrations/0086_remove_connection_status_connection_terminated_at.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.5 on 2024-07-08 05:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0085_rename_date_staffposition_start_date_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='connection', + name='status', + ), + migrations.AddField( + model_name='connection', + name='terminated_at', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0087_remove_connection_date.py b/osinaweb/osinacore/migrations/0087_remove_connection_date.py new file mode 100644 index 00000000..bcf920cf --- /dev/null +++ b/osinaweb/osinacore/migrations/0087_remove_connection_date.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.5 on 2024-07-08 06:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0086_remove_connection_status_connection_terminated_at'), + ] + + operations = [ + migrations.RemoveField( + model_name='connection', + name='date', + ), + ] diff --git a/osinaweb/osinacore/migrations/0088_connection_date.py b/osinaweb/osinacore/migrations/0088_connection_date.py new file mode 100644 index 00000000..1c49d8e5 --- /dev/null +++ b/osinaweb/osinacore/migrations/0088_connection_date.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-07-08 06:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0087_remove_connection_date'), + ] + + operations = [ + migrations.AddField( + model_name='connection', + name='date', + field=models.DateTimeField(null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0089_connection_connected.py b/osinaweb/osinacore/migrations/0089_connection_connected.py new file mode 100644 index 00000000..5998b4ac --- /dev/null +++ b/osinaweb/osinacore/migrations/0089_connection_connected.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-07-08 08:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0088_connection_date'), + ] + + operations = [ + migrations.AddField( + model_name='connection', + name='connected', + field=models.BooleanField(default=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0090_rename_terminated_at_connection_last_seen.py b/osinaweb/osinacore/migrations/0090_rename_terminated_at_connection_last_seen.py new file mode 100644 index 00000000..524e0168 --- /dev/null +++ b/osinaweb/osinacore/migrations/0090_rename_terminated_at_connection_last_seen.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-07-08 08:55 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0089_connection_connected'), + ] + + operations = [ + migrations.RenameField( + model_name='connection', + old_name='terminated_at', + new_name='last_seen', + ), + ] diff --git a/osinaweb/osinacore/migrations/0091_alter_connection_user.py b/osinaweb/osinacore/migrations/0091_alter_connection_user.py new file mode 100644 index 00000000..f7d3af73 --- /dev/null +++ b/osinaweb/osinacore/migrations/0091_alter_connection_user.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.5 on 2024-07-08 08:55 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('osinacore', '0090_rename_terminated_at_connection_last_seen'), + ] + + operations = [ + migrations.AlterField( + model_name='connection', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/osinaweb/osinacore/migrations/0092_rename_connected_connection_online.py b/osinaweb/osinacore/migrations/0092_rename_connected_connection_online.py new file mode 100644 index 00000000..4b25a33f --- /dev/null +++ b/osinaweb/osinacore/migrations/0092_rename_connected_connection_online.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-07-08 08:57 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0091_alter_connection_user'), + ] + + operations = [ + migrations.RenameField( + model_name='connection', + old_name='connected', + new_name='online', + ), + ] diff --git a/osinaweb/osinacore/migrations/0093_connection_disconnected.py b/osinaweb/osinacore/migrations/0093_connection_disconnected.py new file mode 100644 index 00000000..f2a45deb --- /dev/null +++ b/osinaweb/osinacore/migrations/0093_connection_disconnected.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.5 on 2024-07-08 09:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0092_rename_connected_connection_online'), + ] + + operations = [ + migrations.AddField( + model_name='connection', + name='disconnected', + field=models.BooleanField(default=False), + ), + ] diff --git a/osinaweb/osinacore/migrations/__pycache__/0086_remove_connection_status_connection_terminated_at.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0086_remove_connection_status_connection_terminated_at.cpython-310.pyc new file mode 100644 index 00000000..d52af772 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0086_remove_connection_status_connection_terminated_at.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0087_remove_connection_date.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0087_remove_connection_date.cpython-310.pyc new file mode 100644 index 00000000..2cd31808 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0087_remove_connection_date.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0088_connection_date.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0088_connection_date.cpython-310.pyc new file mode 100644 index 00000000..e707cfd7 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0088_connection_date.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0089_connection_connected.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0089_connection_connected.cpython-310.pyc new file mode 100644 index 00000000..033bfb10 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0089_connection_connected.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0090_rename_terminated_at_connection_last_seen.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0090_rename_terminated_at_connection_last_seen.cpython-310.pyc new file mode 100644 index 00000000..7ee8c542 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0090_rename_terminated_at_connection_last_seen.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0091_alter_connection_user.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0091_alter_connection_user.cpython-310.pyc new file mode 100644 index 00000000..2cae5dd5 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0091_alter_connection_user.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0092_rename_connected_connection_online.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0092_rename_connected_connection_online.cpython-310.pyc new file mode 100644 index 00000000..02a7f25b Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0092_rename_connected_connection_online.cpython-310.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0093_connection_disconnected.cpython-310.pyc b/osinaweb/osinacore/migrations/__pycache__/0093_connection_disconnected.cpython-310.pyc new file mode 100644 index 00000000..15ee9d83 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0093_connection_disconnected.cpython-310.pyc differ diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index 506623d2..9cdf8e40 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -388,12 +388,9 @@ class DailyReport(models.Model): class Connection(models.Model): - STATUS_CHOICES = ( - ('Online', 'Online'), - ('Offline', 'Offline'), - ) - status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True) date = models.DateTimeField(null=True) - user = models.ForeignKey(User, on_delete=models.CASCADE) - + user = models.OneToOneField(User, on_delete=models.CASCADE) + online = models.BooleanField(default=True) + last_seen = models.DateTimeField(null=True, blank=True) + disconnected = models.BooleanField(default=False) diff --git a/osinaweb/osinacore/routing.py b/osinaweb/osinacore/routing.py new file mode 100644 index 00000000..30b01d3f --- /dev/null +++ b/osinaweb/osinacore/routing.py @@ -0,0 +1,8 @@ +from django.urls import path +from .consumers import * + +websocket_urlpatterns = [ + path("ws/online-users/", OnlineUserConsumer.as_asgi()), + + +] \ No newline at end of file diff --git a/osinaweb/osinacore/templates/add-edit-main.html b/osinaweb/osinacore/templates/add-edit-main.html index 0e8babdc..77b5bb4d 100644 --- a/osinaweb/osinacore/templates/add-edit-main.html +++ b/osinaweb/osinacore/templates/add-edit-main.html @@ -944,6 +944,9 @@ + + + diff --git a/osinaweb/osinacore/templates/customer_main.html b/osinaweb/osinacore/templates/customer_main.html index 8d712ccb..b6fe0b79 100644 --- a/osinaweb/osinacore/templates/customer_main.html +++ b/osinaweb/osinacore/templates/customer_main.html @@ -610,6 +610,9 @@ + + + diff --git a/osinaweb/osinacore/templates/recent-activities.html b/osinaweb/osinacore/templates/details_templates/partials/recent-activities.html similarity index 97% rename from osinaweb/osinacore/templates/recent-activities.html rename to osinaweb/osinacore/templates/details_templates/partials/recent-activities.html index 41dc8156..3322d669 100644 --- a/osinaweb/osinacore/templates/recent-activities.html +++ b/osinaweb/osinacore/templates/details_templates/partials/recent-activities.html @@ -126,7 +126,7 @@ {% if latest_statuses_time_ago %} {% for latest in latest_statuses_time_ago %} -
+
- {% if latest.status.staff in online_staff_profiles %} -
- {% else %} -
- {% endif %}
diff --git a/osinaweb/osinacore/templates/details_templates/partials/recently-online.html b/osinaweb/osinacore/templates/details_templates/partials/recently-online.html new file mode 100644 index 00000000..78399cab --- /dev/null +++ b/osinaweb/osinacore/templates/details_templates/partials/recently-online.html @@ -0,0 +1,61 @@ +{% load static %} + +
+
+

Recently Online

+
+ + +
+
+ + +
+
+ {% for staff_connection in staff_connections %} +
+
+
+ +
+
+
+

{{staff_connection.user.first_name}} + {{staff_connection.user.last_name}}

+

Online

+
+
+ {% endfor %} +
+
+ + + +
diff --git a/osinaweb/osinacore/templates/index.html b/osinaweb/osinacore/templates/index.html index fda7d20b..a5821156 100644 --- a/osinaweb/osinacore/templates/index.html +++ b/osinaweb/osinacore/templates/index.html @@ -292,7 +292,9 @@ + + + + @@ -1431,9 +1256,6 @@ - - - diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index 745966f5..84f3af60 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -54,7 +54,6 @@ def signin(request): if user is not None: login(request, user) - Connection.objects.create(status='Online', date=datetime.now(), user=user) if next_page: return redirect(next_page) else: @@ -205,7 +204,7 @@ def home(request, *args, **kwargs): @staff_login_required -def status_mobile_modal (request, *args, **kwargs): +def status_mobile_modal(request, *args, **kwargs): context = { } @@ -733,7 +732,7 @@ def get_updated_last_status(request): 'hours_minutes_ago': hours_minutes_ago, } - recent_status = render_to_string('recent-status.html', response_data) + recent_status = render_to_string('details_templates/partials/recent-status.html', response_data) return HttpResponse(recent_status) @@ -741,31 +740,6 @@ def get_updated_last_status(request): # TO GET USER ACTIVITIES @staff_login_required def get_latest_activities(request): - latest_connections = Connection.objects.filter( - user__staffprofile__isnull=False - ).values('user').annotate( - latest_connection=Max('date') - ) - online_staff_profiles = [] - for connection in latest_connections: - user_id = connection['user'] - latest_connection = connection['latest_connection'] - last_connection = Connection.objects.filter(user_id=user_id, date=latest_connection).first() - if last_connection.status == 'Online': - online_staff_profiles.append(last_connection.user.staffprofile) - if request.user.is_authenticated and request.user.is_superuser: - open_task_count = Task.objects.filter(status='Open').count() - working_on_task_count = Task.objects.filter(status='Working On').count() - elif request.user.is_authenticated: - open_task_count = Task.objects.filter(assigned_to=request.user.staffprofile, status='Open').count() - working_on_task_count = Task.objects.filter(assigned_to=request.user.staffprofile, status='Working On').count() - else: - open_task_count = 0 - working_on_task_count = 0 - - total_tasks = open_task_count + working_on_task_count - - today = datetime.now().date() @@ -776,9 +750,8 @@ def get_latest_activities(request): latest_statuses_time_ago = [{'status': status, 'time_ago': calculate_time_ago(status)} for status in latest_statuses] response_data = { - 'total_tasks': total_tasks, 'latest_statuses_time_ago': latest_statuses_time_ago, - 'online_staff_profiles' : online_staff_profiles, + } recent_activities = render_to_string('recent-activities.html', response_data) diff --git a/osinaweb/osinaweb/__pycache__/asgi.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/asgi.cpython-310.pyc index 9e5097da..918006c0 100644 Binary files a/osinaweb/osinaweb/__pycache__/asgi.cpython-310.pyc and b/osinaweb/osinaweb/__pycache__/asgi.cpython-310.pyc differ diff --git a/osinaweb/osinaweb/__pycache__/routing.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/routing.cpython-310.pyc new file mode 100644 index 00000000..2dfd0b07 Binary files /dev/null and b/osinaweb/osinaweb/__pycache__/routing.cpython-310.pyc differ diff --git a/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc index 4dd1b138..e471f152 100644 Binary files a/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc and b/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc differ diff --git a/osinaweb/osinaweb/asgi.py b/osinaweb/osinaweb/asgi.py index 68029baa..cb95ebcd 100644 --- a/osinaweb/osinaweb/asgi.py +++ b/osinaweb/osinaweb/asgi.py @@ -13,7 +13,7 @@ from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.security.websocket import AllowedHostsOriginValidator from channels.auth import AuthMiddlewareStack -from support import routing +from osinaweb.routing import websocket_urlpatterns os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'osinaweb.settings') @@ -23,7 +23,7 @@ django_asgi_app = get_asgi_application() application = ProtocolTypeRouter({ "http": django_asgi_app, "websocket": AllowedHostsOriginValidator( - AuthMiddlewareStack(URLRouter(routing.websocket_urlpatterns)) + AuthMiddlewareStack(URLRouter(websocket_urlpatterns)) ), }) diff --git a/osinaweb/osinaweb/routing.py b/osinaweb/osinaweb/routing.py new file mode 100644 index 00000000..98055dfd --- /dev/null +++ b/osinaweb/osinaweb/routing.py @@ -0,0 +1,4 @@ +from support.routing import websocket_urlpatterns as support_websocket_urlpatterns +from osinacore.routing import websocket_urlpatterns as osinacore_websocket_urlpatterns + +websocket_urlpatterns = support_websocket_urlpatterns + osinacore_websocket_urlpatterns \ No newline at end of file diff --git a/osinaweb/static/images/uploaded_images/ce11944b98d0742eead2b016a253afd2_XL.jpg b/osinaweb/static/images/uploaded_images/ce11944b98d0742eead2b016a253afd2_XL.jpg new file mode 100644 index 00000000..a6c6d9d4 Binary files /dev/null and b/osinaweb/static/images/uploaded_images/ce11944b98d0742eead2b016a253afd2_XL.jpg differ diff --git a/osinaweb/static/js/online/online-consumer.js b/osinaweb/static/js/online/online-consumer.js new file mode 100644 index 00000000..b0573cd7 --- /dev/null +++ b/osinaweb/static/js/online/online-consumer.js @@ -0,0 +1,67 @@ +document.addEventListener("DOMContentLoaded", function () { + const ws_scheme = window.location.protocol === "https:" ? "wss" : "ws"; + const webSocketUrl = `${ws_scheme}://${window.location.host}/ws/online-users/`; + + const webSocket = new WebSocket(webSocketUrl); + + webSocket.onopen = function (event) { + console.log("WebSocket connection to online established"); + }; + + webSocket.onmessage = function (event) { + const data = JSON.parse(event.data); + if (data.event_type === "online_user_status") { + // Update connected users containers + const connectedUsersContainers = document.querySelectorAll(".connected-users"); + connectedUsersContainers.forEach(container => { + container.innerHTML = data.html; + }); + + // Rebind event listeners to switch between containers + const customerButtons = document.querySelectorAll('.customerButton'); + const staffButtons = document.querySelectorAll('.staffButton'); + const customerContainers = document.querySelectorAll('.recentltLoggedCustomersContainer'); + const staffContainers = document.querySelectorAll('.recentltLoggedStaffsContainer'); + + customerButtons.forEach(button => { + button.addEventListener('click', function () { + customerContainers.forEach(container => container.classList.remove('hidden')); + staffContainers.forEach(container => container.classList.add('hidden')); + }); + }); + + staffButtons.forEach(button => { + button.addEventListener('click', function () { + staffContainers.forEach(container => container.classList.remove('hidden')); + customerContainers.forEach(container => container.classList.add('hidden')); + }); + }); + + const onlineUsersIds = data.online_users_ids || []; + console.log(onlineUsersIds); + + // Update user activity containers based on online status + const userActivityContainers = document.querySelectorAll(".users-activities"); + userActivityContainers.forEach(container => { + const userId = container.getAttribute("data-userId"); + console.log(userId); + + if (onlineUsersIds.map(id => id.toString()).includes(userId)) { + container.querySelector("#connected").classList.remove("hidden"); + container.querySelector("#not-connected").classList.add("hidden"); + } else { + container.querySelector("#connected").classList.add("hidden"); + container.querySelector("#not-connected").classList.remove("hidden"); + } + }); + } + }; + + webSocket.onclose = function (event) { + console.log("WebSocket connection to online closed"); + }; + + webSocket.onerror = function (error) { + console.error("WebSocket error:", error); + }; +}); diff --git a/osinaweb/static/js/recently-logged-in-users.js b/osinaweb/static/js/recently-logged-in-users.js deleted file mode 100644 index 2c827e01..00000000 --- a/osinaweb/static/js/recently-logged-in-users.js +++ /dev/null @@ -1,20 +0,0 @@ -document.addEventListener('DOMContentLoaded', function () { - const customerButtons = document.querySelectorAll('.customerButton'); - const staffButtons = document.querySelectorAll('.staffButton'); - const customerContainers = document.querySelectorAll('.recentltLoggedCustomersContainer'); - const staffContainers = document.querySelectorAll('.recentltLoggedStaffsContainer'); - - customerButtons.forEach(button => { - button.addEventListener('click', function () { - customerContainers.forEach(container => container.classList.remove('hidden')); - staffContainers.forEach(container => container.classList.add('hidden')); - }); - }); - - staffButtons.forEach(button => { - button.addEventListener('click', function () { - staffContainers.forEach(container => container.classList.remove('hidden')); - customerContainers.forEach(container => container.classList.add('hidden')); - }); - }); -});