From 285a3bba6068f60917cdfe0f92485c14a3479c11 Mon Sep 17 00:00:00 2001 From: yeaktas Date: Mon, 15 Apr 2024 18:28:58 +0300 Subject: [PATCH] ws change to wss --- docker-compose.yml | 62 +- docker.dockerfile | 30 +- indianpong/pong/apps.py | 42 +- indianpong/pong/consumer_chat.py | 346 +- indianpong/pong/consumer_pong.py | 1308 ++++---- indianpong/pong/consumer_rps.py | 516 +-- indianpong/pong/consumer_status.py | 146 +- indianpong/pong/langs.py | 2870 ++++++++--------- .../pong/management/commands/populate.py | 132 +- indianpong/pong/rps.py | 248 +- indianpong/pong/templates/_nav.html | 2 +- indianpong/pong/templates/local-game.html | 230 +- .../pong/templates/local-tournament.html | 378 +-- indianpong/pong/templates/play-rps-ai.html | 162 +- indianpong/pong/templates/play-rps.html | 222 +- indianpong/pong/templates/remote-game.html | 152 +- indianpong/pong/templates/room.html | 338 +- .../pong/templates/tournament-create.html | 92 +- .../pong/templates/tournament-room-list.html | 180 +- indianpong/pong/templates/tournament.html | 56 +- .../pong/templatetags/custom_filters.py | 14 +- indianpong/pong/templatetags/status.py | 22 +- indianpong/pong/templatetags/transnav.py | 44 +- indianpong/pong/templatetags/user_info.py | 28 +- indianpong/pong/update.py | 254 +- indianpong/static/assets/intra-42-white.svg | 16 +- indianpong/static/assets/intra42-logo.svg | 16 +- indianpong/static/assets/rps/icon-cheater.svg | 40 +- .../static/assets/rps/icon-godofthings.svg | 80 +- .../static/assets/rps/icon-godthings.svg | 80 +- .../static/assets/rps/icon-likeacheater.svg | 40 +- indianpong/static/css/changepassword.css | 552 ++-- indianpong/static/css/chat.css | 1564 ++++----- indianpong/static/css/local-tournament.css | 500 +-- indianpong/static/css/modal.css | 86 +- indianpong/static/css/navbar.css | 496 +-- indianpong/static/css/ranking.css | 926 +++--- indianpong/static/css/remote-player.css | 366 +-- indianpong/static/css/room-list.css | 336 +- indianpong/static/css/rps.css | 908 +++--- indianpong/static/css/tournament-room.css | 914 +++--- indianpong/static/js/base-chat.js | 68 +- indianpong/static/js/burger.js | 18 +- indianpong/static/js/chat.js | 2 +- indianpong/static/js/create-tournament.js | 82 +- indianpong/static/js/game/local-game.js | 830 ++--- indianpong/static/js/game/localTournament.js | 1088 +++---- indianpong/static/js/game/sockPong.js | 1608 ++++----- indianpong/static/js/inventory.js | 294 +- indianpong/static/js/login.js | 120 +- indianpong/static/js/navigation.js | 440 +-- indianpong/static/js/profile-settings.js | 566 ++-- indianpong/static/js/profile.js | 192 +- indianpong/static/js/rps.js | 698 ++-- indianpong/static/js/search.js | 148 +- indianpong/static/js/signup.js | 282 +- indianpong/static/js/sockRps.js | 774 ++--- indianpong/static/js/store.js | 134 +- indianpong/static/js/tournament-room.js | 286 +- 59 files changed, 11212 insertions(+), 11212 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 43f22f45..6576208c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,31 +1,31 @@ -version: "3.9" - -services: - indianpong: - image: aktas/indianpong:latest - build: - context: ./indianpong - container_name: indianpong - restart: always - ports: - - 8000:8000 -# depends_on: -# - db -# env_file: -# - .env -# networks: -# - indianpongnet - -# db: -# container_name: db -# image: db -# build: -# context: ./ -# dockerfile: docker.dockerfile -# restart: always -# networks: -# - indianpongnet -# -#networks: -# indianpongnet: -# driver: bridge +version: "3.9" + +services: + indianpong: + image: aktas/indianpong:latest + build: + context: ./indianpong + container_name: indianpong + restart: always + ports: + - 8000:8000 +# depends_on: +# - db +# env_file: +# - .env +# networks: +# - indianpongnet + +# db: +# container_name: db +# image: db +# build: +# context: ./ +# dockerfile: docker.dockerfile +# restart: always +# networks: +# - indianpongnet +# +#networks: +# indianpongnet: +# driver: bridge diff --git a/docker.dockerfile b/docker.dockerfile index a0b2c05c..946b66ab 100644 --- a/docker.dockerfile +++ b/docker.dockerfile @@ -1,15 +1,15 @@ -FROM postgres:13 - -# Veritabanı adını ve kullanıcı adını ayarla -ENV POSTGRES_DB=pong -ENV POSTGRES_USER=indianpong -ENV POSTGRES_PASSWORD=indianpong123 -ENV POSTGRES_HOST_AUTH_METHOD=trust - -# Docker imajı oluşturulduğunda çalıştırılacak SQL dosyalarını kopyala - -# PostgreSQL'in varsayılan bağlantı noktası -EXPOSE 5432 - -RUN pg_createcluster 13 main --start -RUN service postgresql start +FROM postgres:13 + +# Veritabanı adını ve kullanıcı adını ayarla +ENV POSTGRES_DB=pong +ENV POSTGRES_USER=indianpong +ENV POSTGRES_PASSWORD=indianpong123 +ENV POSTGRES_HOST_AUTH_METHOD=trust + +# Docker imajı oluşturulduğunda çalıştırılacak SQL dosyalarını kopyala + +# PostgreSQL'in varsayılan bağlantı noktası +EXPOSE 5432 + +RUN pg_createcluster 13 main --start +RUN service postgresql start diff --git a/indianpong/pong/apps.py b/indianpong/pong/apps.py index a46cb47c..d00f2976 100644 --- a/indianpong/pong/apps.py +++ b/indianpong/pong/apps.py @@ -1,21 +1,21 @@ -from django.apps import AppConfig -from django.contrib.auth.signals import user_logged_in, user_logged_out -from django.dispatch import receiver - - -class PongConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'pong' - -""" def ready(self): - - @receiver(user_logged_in) - def user_logged_in_handler(sender, request, **kwargs): - request.user.is_online = True - request.user.save() - - @receiver(user_logged_out) - def user_logged_out_handler(sender, request, **kwargs): - request.user.is_online = False - request.user.save() """ - +from django.apps import AppConfig +from django.contrib.auth.signals import user_logged_in, user_logged_out +from django.dispatch import receiver + + +class PongConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'pong' + +""" def ready(self): + + @receiver(user_logged_in) + def user_logged_in_handler(sender, request, **kwargs): + request.user.is_online = True + request.user.save() + + @receiver(user_logged_out) + def user_logged_out_handler(sender, request, **kwargs): + request.user.is_online = False + request.user.save() """ + diff --git a/indianpong/pong/consumer_chat.py b/indianpong/pong/consumer_chat.py index 0ece607f..6bcc49ff 100644 --- a/indianpong/pong/consumer_chat.py +++ b/indianpong/pong/consumer_chat.py @@ -1,173 +1,173 @@ -import json -from channels.generic.websocket import AsyncWebsocketConsumer - -class ChatConsumer(AsyncWebsocketConsumer): - async def connect(self): - self.room_name = self.scope["url_route"]["kwargs"]["room_name"] - self.room_group_name = "chat_%s" % self.room_name - self.user = self.scope["user"] - - # Join room group - await self.channel_layer.group_add(self.room_group_name, self.channel_name) - - await self.accept() - - async def disconnect(self, close_code): - # Leave room group - await self.channel_layer.group_discard(self.room_group_name, self.channel_name) - await self.close() - - # Receive message from WebSocket - async def receive(self, text_data): - from .models import UserProfile, Message, Game - data = json.loads(text_data) - action = data["action"] - if action == "chat": - message = data["message"] - user = await UserProfile.objects.aget(username=self.user.username) - m = await Message.objects.acreate(content=message, user=user, room_id=self.room_name) #room_id is the room name - # Send message to room group - await self.channel_layer.group_send( - self.room_group_name, - { - "type": "chat.message", - "message": message, - "user": user.username, - "created_date": m.get_short_date(), #? blocking? - } - ) - - elif action == "invite.game": - # Send invite message to room group which have accept button and decline button in it - await self.channel_layer.group_send( - self.room_group_name, - { - "type": "invite.game", - "inviter": self.user.username, - } - ) - - elif action == "accept.game": - # if accept it create game object and send link in form: /remote-game/invite/game_id to both - # send message to room group that user accepted the game make it in client side - accepted = data["accepted"] - group_name = f"{accepted}_{accepter}" - accepted = await UserProfile.objects.aget(username=accepted) - accepter = await UserProfile.objects.aget(username=self.user.username) - # create game object - game = await Game.objects.acreate(group_name=group_name, player1=accepted, player2=accepter) - message = f"/remote-game/invite/{game.id}" #? Maybe do these in client side - m = await Message.objects.acreate(content=message, user=accepted, room_id=self.room_name) #? - await self.channel_layer.group_send( - self.room_group_name, - { - "type": "accept.game", - "message": message, - "user": accepted.username, - "created_date": m.get_short_date(), #? blocking? - } - ) - - elif action == "decline.game": - # if decline it send message to room group that user declined the game - await self.channel_layer.group_send( - self.room_group_name, - { - "type": "decline.game", - "decliner": self.user.username, - } - ) - - elif action == "block": - blocked = data["blocked"] - # add user to block list - me = await UserProfile.objects.aget(username=self.user.username) - blocked = await UserProfile.objects.aget(username=blocked) - await me.blocked_users.aadd(blocked) - await self.channel_layer.group_send( - self.room_group_name, - { - "type": "blocked", - "blocker": self.user.username, - "blocked": blocked.username, - } - ) - - elif action == "unblock": - # remove user from block list - blocked = data["unblocked"] - # add user to block list - me = await UserProfile.objects.aget(username=self.user.username) - blocked = await UserProfile.objects.aget(username=blocked) - await me.blocked_users.aremove(blocked) - await self.channel_layer.group_send( - self.room_group_name, - { - "type": "unblocked", - "unblocker": self.user.username, - "unblocked": blocked.username, - } - ) - - # Receive message from room group - async def chat_message(self, event): - message = event["message"] - user = event["user"] - created_date = event["created_date"] - # Send message to WebSocket - await self.send(text_data=json.dumps({ - "type": "chat.message", - "message": message, - "user": user, - "created_date": created_date, - })) - - async def invite_game(self, event): - inviter = event["inviter"] - # Send message to WebSocket - await self.send(text_data=json.dumps({ - "type": "invite.game", - "inviter": inviter, - })) - - async def accept_game(self, event): - message = event["message"] - user = event["user"] - created_date = event["created_date"] - # Send message to WebSocket - await self.send(text_data=json.dumps({ - "type": "accept.game", - "message": message, - "user": user, - "created_date": created_date, - })) - - async def decline_game(self, event): - decliner = event["decliner"] - # Send message to WebSocket - await self.send(text_data=json.dumps({ - "type": "decline.game", - "decliner": decliner, - })) - - async def blocked(self, event): - # Handle the "blocked" message - blocker = event["blocker"] - blocked = event["blocked"] - - await self.send(text_data=json.dumps({ - "type": "blocked", - "blocker": blocker, - "blocked": blocked, - })) - - async def unblocked(self, event): - # Handle the "unblocked" message - unblocker = event["unblocker"] - unblocked = event["unblocked"] - - await self.send(text_data=json.dumps({ - "type": "unblocked", - "unblocker": unblocker, - "unblocked": unblocked, - })) +import json +from channels.generic.websocket import AsyncWebsocketConsumer + +class ChatConsumer(AsyncWebsocketConsumer): + async def connect(self): + self.room_name = self.scope["url_route"]["kwargs"]["room_name"] + self.room_group_name = "chat_%s" % self.room_name + self.user = self.scope["user"] + + # Join room group + await self.channel_layer.group_add(self.room_group_name, self.channel_name) + + await self.accept() + + async def disconnect(self, close_code): + # Leave room group + await self.channel_layer.group_discard(self.room_group_name, self.channel_name) + await self.close() + + # Receive message from WebSocket + async def receive(self, text_data): + from .models import UserProfile, Message, Game + data = json.loads(text_data) + action = data["action"] + if action == "chat": + message = data["message"] + user = await UserProfile.objects.aget(username=self.user.username) + m = await Message.objects.acreate(content=message, user=user, room_id=self.room_name) #room_id is the room name + # Send message to room group + await self.channel_layer.group_send( + self.room_group_name, + { + "type": "chat.message", + "message": message, + "user": user.username, + "created_date": m.get_short_date(), #? blocking? + } + ) + + elif action == "invite.game": + # Send invite message to room group which have accept button and decline button in it + await self.channel_layer.group_send( + self.room_group_name, + { + "type": "invite.game", + "inviter": self.user.username, + } + ) + + elif action == "accept.game": + # if accept it create game object and send link in form: /remote-game/invite/game_id to both + # send message to room group that user accepted the game make it in client side + accepted = data["accepted"] + group_name = f"{accepted}_{accepter}" + accepted = await UserProfile.objects.aget(username=accepted) + accepter = await UserProfile.objects.aget(username=self.user.username) + # create game object + game = await Game.objects.acreate(group_name=group_name, player1=accepted, player2=accepter) + message = f"/remote-game/invite/{game.id}" #? Maybe do these in client side + m = await Message.objects.acreate(content=message, user=accepted, room_id=self.room_name) #? + await self.channel_layer.group_send( + self.room_group_name, + { + "type": "accept.game", + "message": message, + "user": accepted.username, + "created_date": m.get_short_date(), #? blocking? + } + ) + + elif action == "decline.game": + # if decline it send message to room group that user declined the game + await self.channel_layer.group_send( + self.room_group_name, + { + "type": "decline.game", + "decliner": self.user.username, + } + ) + + elif action == "block": + blocked = data["blocked"] + # add user to block list + me = await UserProfile.objects.aget(username=self.user.username) + blocked = await UserProfile.objects.aget(username=blocked) + await me.blocked_users.aadd(blocked) + await self.channel_layer.group_send( + self.room_group_name, + { + "type": "blocked", + "blocker": self.user.username, + "blocked": blocked.username, + } + ) + + elif action == "unblock": + # remove user from block list + blocked = data["unblocked"] + # add user to block list + me = await UserProfile.objects.aget(username=self.user.username) + blocked = await UserProfile.objects.aget(username=blocked) + await me.blocked_users.aremove(blocked) + await self.channel_layer.group_send( + self.room_group_name, + { + "type": "unblocked", + "unblocker": self.user.username, + "unblocked": blocked.username, + } + ) + + # Receive message from room group + async def chat_message(self, event): + message = event["message"] + user = event["user"] + created_date = event["created_date"] + # Send message to WebSocket + await self.send(text_data=json.dumps({ + "type": "chat.message", + "message": message, + "user": user, + "created_date": created_date, + })) + + async def invite_game(self, event): + inviter = event["inviter"] + # Send message to WebSocket + await self.send(text_data=json.dumps({ + "type": "invite.game", + "inviter": inviter, + })) + + async def accept_game(self, event): + message = event["message"] + user = event["user"] + created_date = event["created_date"] + # Send message to WebSocket + await self.send(text_data=json.dumps({ + "type": "accept.game", + "message": message, + "user": user, + "created_date": created_date, + })) + + async def decline_game(self, event): + decliner = event["decliner"] + # Send message to WebSocket + await self.send(text_data=json.dumps({ + "type": "decline.game", + "decliner": decliner, + })) + + async def blocked(self, event): + # Handle the "blocked" message + blocker = event["blocker"] + blocked = event["blocked"] + + await self.send(text_data=json.dumps({ + "type": "blocked", + "blocker": blocker, + "blocked": blocked, + })) + + async def unblocked(self, event): + # Handle the "unblocked" message + unblocker = event["unblocker"] + unblocked = event["unblocked"] + + await self.send(text_data=json.dumps({ + "type": "unblocked", + "unblocker": unblocker, + "unblocked": unblocked, + })) diff --git a/indianpong/pong/consumer_pong.py b/indianpong/pong/consumer_pong.py index a0b4c31a..a753ea91 100644 --- a/indianpong/pong/consumer_pong.py +++ b/indianpong/pong/consumer_pong.py @@ -1,654 +1,654 @@ -import asyncio -import json -from channels.generic.websocket import AsyncWebsocketConsumer -from channels.db import database_sync_to_async -from asgiref.sync import sync_to_async, async_to_sync -from pong.utils import AsyncLockedDict -from django.core.cache import cache -from .utils import add_to_cache, remove_from_cache -#from .models import Game, Tournament, UserProfile -from pong.game import * -import datetime - -USER_CHANNEL_NAME = AsyncLockedDict() # key: username, value: channel_name -GAMES = AsyncLockedDict() # key: game_id, value: PongGame object -USER_STATUS = AsyncLockedDict() # key: username, value: game_id or lobby - - -class PongConsumer(AsyncWebsocketConsumer): - - async def connect(self): - - self.game_type = self.scope['url_route']['kwargs']['game_type'] # tournament or peer-to-peer or invite - self.game_id = self.scope['url_route']['kwargs']['game_id'] # game_id or new - self.user = self.scope['user'] - - await self.accept() - - # Add the user to the 'lobby' group - await self.channel_layer.group_add("lobby", self.channel_name) - - # Set the user's channel name - await USER_CHANNEL_NAME.set(self.user.username, self.channel_name) - # Add user username to lobby cache - await USER_STATUS.set(self.user.username, "lobby") - # Get the list of online users usernames - lobby_users_usernames = await USER_STATUS.get_keys_with_value('lobby') - lobby_users_usernames.remove(self.user.username) - await self.send(text_data=json.dumps({ - 'type': 'inlobby', - 'user': self.user.username, - 'users': lobby_users_usernames, - })) - await self.channel_layer.group_send("lobby", { - 'type': 'user.inlobby', - 'user': self.user.username, - }) - if self.game_type == 'tournament': - await self.tournament_match_handler() - elif self.game_type == 'invite': - await self.from_chat_handler() - - async def disconnect(self, close_code): - game_id = await USER_STATUS.get(self.user.username) - if game_id != 'lobby': - game = await GAMES.get(game_id) - if game != None: - other_player_channel_name = await USER_CHANNEL_NAME.get(game.otherPlayer(self.user.username)) - await self.record_for_disconnected(game_id, game) - await self.exit_handler(game_id, game) - await self.channel_layer.send(other_player_channel_name, { - 'type': 'game.disconnect', - 'game_id': game_id, - 'disconnected': self.user.username, - }) - - # Remove the user from the 'lobby' group - await self.channel_layer.group_discard("lobby", self.channel_name) - - # Remove the user's channel name - await USER_CHANNEL_NAME.delete(self.user.username) - - # Remove user username from lobby cache - await USER_STATUS.delete(self.user.username) - - # Set the user's status to offline - await self.channel_layer.group_send("lobby", { - 'type': 'user.outlobby', - 'user': self.user.username, - }) - - # Close the websocket connection - await self.close(close_code) - - async def receive(self, text_data): - data = json.loads(text_data) - action = data.get('action') - - if action == 'invite': - matchmaking = data.get('matchmaking') - invitee_username = data.get('invitee_username') - if matchmaking == 'true': - invitee_username = await self.matchmaking_handler() - if invitee_username == None: - await self.send(text_data=json.dumps({ - "error": "No suitable opponent found.", - })) - return - if await self.check_is_user_inlobby(invitee_username): - invitee_channel_name = await USER_CHANNEL_NAME.get(invitee_username) - if invitee_channel_name: - await self.channel_layer.send(invitee_channel_name, { - 'type': 'game.invite', - 'inviter': self.user.username, - 'invitee': invitee_username, - }) - - elif action == 'accept': - inviter_username = data.get('inviter_username') - await self.accept_handler(inviter_username) - - elif action == 'decline': - inviter_username = data.get('inviter_username') - await self.decline_handler(inviter_username) - - - elif action == 'start.request': - opponent_username = data.get('opponent') - game_id = data.get('game_id') - vote = data.get('vote') - await self.start_handler(game_id, opponent_username, vote) - - elif action == 'leave.game': - game_id = data.get('game_id') - left = data.get('left') - opponent = data.get('opponent') - await self.leave_handler(game_id, left, opponent) - - elif action == 'restart': #? not sure is needed or not - invitee_username = data.get('invitee_username') - invitee_channel_name = await USER_CHANNEL_NAME.get(invitee_username) - if invitee_channel_name: - await self.channel_layer.send(invitee_channel_name, { - 'type': 'game.restart', - 'inviter': self.user.username, - }) - elif action == 'exit': - game_id = data.get('game_id') - game = await GAMES.get(game_id) - if await self.check_is_users_ingame(game_id, game): - await self.exit_handler(game_id, game) - - #TODO Maybe remove this - elif action == 'pause.game': - game_id = data.get('game_id') - game = await GAMES.get(game_id) - if (game != None): - game.pauseGame() - await self.channel_layer.group_send( - game.group_name, - { - "type": "game.pause", - "game_id": game_id, - } - ) - - #TODO Maybe remove this - elif action == 'resume.game': - game_id = data.get('game_id') - game = await GAMES.get(game_id) - if (game != None): - game.resumeGame() - await self.channel_layer.group_send( - game.group_name, - { - "type": "game.resume", - "game_id": game_id, - } - ) - - elif action == "ball": #? Needs validation - # Make a move in a game and get the ball coordinates - # we send a message to the clients with the ball coordinates - game_id = data["game_id"] - # Move and Get ball coordinates - game = await GAMES.get(game_id) #? When games status is ended, game_id is deleted from GAMES cache - if (game != None): #? So game becomes None. Is this check enough? or moving delete to end solve without this - if (game.status == Status.PLAYING): - x, y, player1_score, player2_score = game.moveBall() - # Send a message to the game group with the game id, the move coordinates - await self.channel_layer.group_send( - game.group_name, - { - "type": "game.ball", - "game_id": game_id, - "x": x, - "y": y, - "player1_score": player1_score, - "player2_score": player2_score, - } - ) - elif (game.status == Status.ENDED and not game.no_more): - await self.end_handler(game_id, game) - game.no_more = True - - - elif action == "paddle": #? Needs validation - # Make a move in a game - game_id = data["game_id"] - dir = data["direction"] - # Move and Get paddle coordinate - game = await GAMES.get(game_id) #? When games status is ended, game_id is deleted from GAMES cache - if (game != None): #? So game becomes None. Is this check enough? or moving delete to end solve without this - y = game.movePaddle(self.user.username, dir) - # Send a message to the game group with the game id, the paddle coordinate, and the player's username - await self.channel_layer.group_send( - game.group_name, - { - "type": "game.paddle", - "game_id": game_id, - "y": y, - "player": self.user.username, - } - ) - elif action == "ability": - game_id = data["game_id"] - ability = data["abilities"] - game = await GAMES.get(game_id) - if (game != None): - if (game.status == Status.PLAYING): - game.activateAbility(self.user.username, ability) - await self.channel_layer.group_send( - game.group_name, - { - "type": "game.ability", - "game_id": game_id, - "player": self.user.username, - "ability": ability, - } - ) - - ### HANDLERS ### - async def tournament_match_handler(self): - game_id, player1, player2, group_name, tournament_id = await self.match_details() - if await self.check_is_user_inlobby(player1) and await self.check_is_user_inlobby(player2): - player1_channel_name = await USER_CHANNEL_NAME.get(player1) - player2_channel_name = await USER_CHANNEL_NAME.get(player2) - - await self.channel_layer.group_add(group_name, player1_channel_name) - await self.channel_layer.group_add(group_name, player2_channel_name) - - await GAMES.set(game_id, PongGame(player1, player2, tournament_id)) - - await self.channel_layer.group_send(group_name, { - 'type': 'tournament.match', - 'tournament_id': tournament_id, - 'game_id': game_id, - 'player1': player1, - 'player2': player2, - }) - - async def from_chat_handler(self): - game_id, player1, player2, group_name, tournament_id = await self.match_details() - if await self.check_is_user_inlobby(player1) and await self.check_is_user_inlobby(player2): - player1_channel_name = await USER_CHANNEL_NAME.get(player1) - player2_channel_name = await USER_CHANNEL_NAME.get(player2) - - await self.channel_layer.group_add(group_name, player1_channel_name) - await self.channel_layer.group_add(group_name, player2_channel_name) - - await GAMES.set(game_id, PongGame(player1, player2)) - - await self.channel_layer.group_send(group_name, { - 'type': 'chat.game', - 'game_id': game_id, - 'player1': player1, - 'player2': player2, - }) - - async def accept_handler(self, inviter_username): - inviter_channel_name = await USER_CHANNEL_NAME.get(inviter_username) - group_name = f"{inviter_username}-{self.user.username}" - await self.channel_layer.group_add(group_name, self.channel_name) - await self.channel_layer.group_add(group_name, inviter_channel_name) - - # Create a new game instance and save it to the database - game = await self.create_game(group_name, inviter_username, self.user.username) - # Create a new game instance and save it to the cache - await GAMES.set(game.id, PongGame(inviter_username, self.user.username)) - - await self.channel_layer.group_send(group_name, { - 'type': 'game.accept', - 'accepter': self.user.username, - 'accepted': inviter_username, - 'game_id': game.id, - }) - - async def decline_handler(self, inviter_username): - inviter_channel_name = await USER_CHANNEL_NAME.get(inviter_username) - await self.channel_layer.send(inviter_channel_name, { - 'type': 'game.decline', - 'decliner': self.user.username, - 'declined': inviter_username, - }) - - async def start_handler(self, game_id, opponent_username, vote): - # Get the current game status and update it with the vote count - game = await GAMES.get(game_id) - current = game.status.value + int(vote) - await GAMES.set_field_value(game_id, Status(current), "status") - - # Check both players voted to start the game - if Status(current) == Status.PLAYING: # both players voted to start the game - await USER_STATUS.set(self.user.username, game_id) - await USER_STATUS.set(opponent_username, game_id) - cache.set(f"playing_{self.user.username}", True) - cache.set(f"playing_{opponent_username}", True) - - """ # Send message to lobby #? Maybe unnecesary bcs playing_username cache - await self.channel_layer.group_send('lobby', { - 'type': 'users.ingame', - 'game_type': self.game_type, - 'players': [self.user.username, opponent_username], - }) """ - await self.channel_layer.group_send(game.group_name, { - 'type': 'game.start', - 'game_id': game_id, - 'vote': current, - }) - - async def leave_handler(self, game_id, left, opponent): - # Get scores - game = await GAMES.get(game_id) - left_score = game.getScore(left) # blocking? - opponent_score = MAX_SCORE # set max score automaticaly - duration = game.getDuration() - # Record the game - await self.record_stats_elo_wallet(game_id, opponent_score, left_score, opponent, left, duration) - await USER_STATUS.set(game.player1.username, 'lobby') #? - await USER_STATUS.set(game.player2.username, 'lobby') #? - - await self.channel_layer.group_send( - game.group_name, - { - "type": "game.leave", - "game_id": game_id, - "left": self.user.username, - "left_score": left_score, - "opponent_score": opponent_score, - "winner": opponent, - "loser": left, - } - ) - #await self.exit_handler(game_id, game, opponent) #! Invalid channel name error - - async def exit_handler(self, game_id, game): - # Discard both from the game group - opponent = game.otherPlayer(self.user.username) - opponent_channel_name = await USER_CHANNEL_NAME.get(opponent) - await self.channel_layer.group_discard(game.group_name, self.channel_name) - await self.channel_layer.group_discard(game.group_name, opponent_channel_name) - cache.set(f"playing_{self.user.username}", False) - cache.set(f"playing_{opponent}", False) - # delete the game from the cache - await GAMES.delete(game_id) - - async def end_handler(self, game_id, game): - # Get scores - player1_score = game.player1.score - player2_score = game.player2.score - duration = game.getDuration() - winner, loser, winner_score, loser_score = game.getWinnerLoserandScores() - # Set the game winner, scores and save it to the database - await self.record_stats_elo_wallet(game_id, winner_score, loser_score, winner, loser, duration) - await USER_STATUS.set(game.player1.username, 'lobby') #? - await USER_STATUS.set(game.player2.username, 'lobby') #? - - #? Maybe unnecesary - await self.channel_layer.group_send( - game.group_name, - { - "type": "game.end", - "game_id": game_id, - "player1_score": player1_score, - "player2_score": player2_score, - "winner": winner, - "loser": loser, - } - ) - - - ## SENDERS ## - async def user_inlobby(self, event): - user = event['user'] - await self.send(text_data=json.dumps({ - 'type': 'user.inlobby', - 'user': user, - })) - - async def user_outlobby(self, event): - user = event['user'] - await self.send(text_data=json.dumps({ - 'type': 'user.outlobby', - 'user': user, - })) - - async def game_disconnect(self, event): - game_id = event['game_id'] - disconnected = event['disconnected'] - await self.send(text_data=json.dumps({ - 'type': 'game.disconnect', - 'game_id': game_id, - 'disconnected': disconnected, - })) - - async def game_invite(self, event): - inviter = event['inviter'] - invitee = event['invitee'] - await self.send(text_data=json.dumps({ - 'type': 'game.invite', - 'inviter': inviter, - 'invitee': invitee, - })) - - async def tournament_match(self, event): - tournament_id = event['tournament_id'] - game_id = event['game_id'] - player1 = event['player1'] - player2 = event['player2'] - await self.send(text_data=json.dumps({ - 'type': 'tournament.match', - 'tournament_id': tournament_id, - 'game_id': game_id, - 'player1': player1, - 'player2': player2, - })) - - async def chat_game(self, event): - game_id = event['game_id'] - player1 = event['player1'] - player2 = event['player2'] - await self.send(text_data=json.dumps({ - 'type': 'tournament.match', - 'game_id': game_id, - 'player1': player1, - 'player2': player2, - })) - - async def game_accept(self, event): - accepter = event['accepter'] - accepted = event['accepted'] - game_id = event['game_id'] - await self.send(text_data=json.dumps({ - 'type': 'game.accept', - 'accepter': accepter, - 'accepted': accepted, - 'game_id': game_id, - })) - - async def game_decline(self, event): - decliner = event['decliner'] - declined = event['declined'] - await self.send(text_data=json.dumps({ - 'type': 'game.decline', - 'decliner': decliner, - 'declined': declined, - })) - - async def game_start(self, event): - game_id = event['game_id'] - vote = event['vote'] - await self.send(text_data=json.dumps({ - 'type': 'game.start', - 'game_id': game_id, - 'vote': vote, - })) - - #? Maybe unnecesary - async def users_ingame(self, event): - game_type = event['game_type'] - players = event['players'] - await self.send(text_data=json.dumps({ - 'type': 'users.ingame', - 'game_type': game_type, - 'players': players, - })) - - async def game_leave(self, event): - game_id = event['game_id'] - left = event['left'] - left_score = event['left_score'] - opponent_score = event['opponent_score'] - winner = event['winner'] - loser = event['loser'] - await self.send(text_data=json.dumps({ - 'type': 'game.leave', - 'game_id': game_id, - 'left': left, - 'left_score': left_score, - 'opponent_score': opponent_score, - 'winner': winner, - 'loser': loser, - })) - - async def game_end(self, event): - game_id = event['game_id'] - player1_score = event['player1_score'] - player2_score = event['player2_score'] - winner = event['winner'] - loser = event['loser'] - - await self.send(text_data=json.dumps({ - 'type': 'game.end', - 'game_id': game_id, - 'player1_score': player1_score, - 'player2_score': player2_score, - 'winner': winner, - 'loser': loser, - })) - - async def game_restart(self, event): - inviter = event['inviter'] - await self.send(text_data=json.dumps({ - 'type': 'game.restart', - 'inviter': inviter, - })) - - async def game_pause(self, event): - game_id = event['game_id'] - await self.send(text_data=json.dumps({ - 'type': 'game.pause', - 'game_id': game_id, - })) - - async def game_resume(self, event): - game_id = event['game_id'] - await self.send(text_data=json.dumps({ - 'type': 'game.resume', - 'game_id': game_id, - })) - - async def game_ball(self, event): - game_id = event['game_id'] - x = event['x'] - y = event['y'] - player1_score = event['player1_score'] - player2_score = event['player2_score'] - await self.send(text_data=json.dumps({ - 'type': 'game.ball', - 'game_id': game_id, - 'x': x, - 'y': y, - 'player1_score': player1_score, - 'player2_score': player2_score, - })) - - async def game_paddle(self, event): - game_id = event['game_id'] - y = event['y'] - player = event['player'] - await self.send(text_data=json.dumps({ - 'type': 'game.paddle', - 'game_id': game_id, - 'y': y, - 'player': player, - })) - - async def game_ability(self, event): - game_id = event['game_id'] - player = event['player'] - ability = event['ability'] - await self.send(text_data=json.dumps({ - 'type': 'game.ability', - 'game_id': game_id, - 'player': player, - 'ability': ability, - })) - - # Helper methods to interact with the database # - async def create_game(self, group_name, player1, player2): - from .models import Game, UserProfile - # Create a new game instance with the given players and an group_name - accepted = await UserProfile.objects.aget(username=player1) - accepter = await UserProfile.objects.aget(username=player2) - game = await Game.objects.acreate(group_name=group_name, player1=accepted, player2=accepter) - return game - - - @database_sync_to_async - def match_details(self): - from .models import Game - game = Game.objects.get(id=self.game_id) - game_id = game.id - player1 = game.player1.username - player2 = game.player2.username - group_name = game.group_name - tournament_id = game.tournament_id - return game_id, player1, player2, group_name, tournament_id - - @database_sync_to_async - def record_stats_elo_wallet(self, game_id, winner_score, loser_score, winner, loser, game_duration): - from .models import Game, UserProfile - from .update import update_wallet_elo, update_stats_pong, update_tournament - - game = Game.objects.get(id=game_id) - game.winner_score = winner_score - game.loser_score = loser_score - game.winner =UserProfile.objects.get(username=winner) - game.loser = UserProfile.objects.get(username=loser) - game.game_duration = datetime.timedelta(seconds=game_duration) - game.save() - - update_wallet_elo(game.winner, game.loser) - update_stats_pong(game.winner, game.loser, winner_score, loser_score, game_duration, "remote") - - # İf the game is a tournament game - if game.tournament_id: #? Check - update_tournament(game) - - - async def record_for_disconnected(self, game_id, game): - duration = game.getDuration() - if game.player1.username == self.user.username: - await self.record_stats_elo_wallet(game_id, game.player1.score, MAX_SCORE, game.player2.username, game.player1.username, duration) - else: - await self.record_stats_elo_wallet(game_id, MAX_SCORE, game.player2.score, game.player1.username, game.player2.username, duration) - - async def check_is_user_inlobby(self, username): - answer = await USER_STATUS.get(username) == 'lobby' - if not answer: - await self.send(text_data=json.dumps({ - "error": "User is not in the lobby.", - })) - return answer - - async def check_is_users_ingame(self, game_id, game): - answer = await USER_STATUS.get(game.player1.username) == game_id and await USER_STATUS.get(game.player2.username) == game_id - return answer - - async def matchmaking_handler(self): - from .models import UserProfile - # Get the current user's elo_point - current_user = await UserProfile.objects.aget(username=self.user.username) - current_user_elo = current_user.elo_point - # Get a list of online users - lobby_users_usernames = await USER_STATUS.get_keys_with_value('lobby') - lobby_users_usernames.remove(self.user.username) #TODO if user not in lobby - - return await self.get_similar_users(lobby_users_usernames, current_user_elo) - - - - @database_sync_to_async - def get_similar_users(self, lobby_users_usernames, current_user_elo): - from .models import UserProfile - users = UserProfile.objects.filter(username__in=lobby_users_usernames, elo_point__gte=current_user_elo-100, elo_point__lte=current_user_elo+100).all() - similar_users = [user.username for user in users] - if similar_users: - invitee_username = random.choice(similar_users) - else: - invitee_username = random.choice(lobby_users_usernames) if lobby_users_usernames else None - - return invitee_username - - +import asyncio +import json +from channels.generic.websocket import AsyncWebsocketConsumer +from channels.db import database_sync_to_async +from asgiref.sync import sync_to_async, async_to_sync +from pong.utils import AsyncLockedDict +from django.core.cache import cache +from .utils import add_to_cache, remove_from_cache +#from .models import Game, Tournament, UserProfile +from pong.game import * +import datetime + +USER_CHANNEL_NAME = AsyncLockedDict() # key: username, value: channel_name +GAMES = AsyncLockedDict() # key: game_id, value: PongGame object +USER_STATUS = AsyncLockedDict() # key: username, value: game_id or lobby + + +class PongConsumer(AsyncWebsocketConsumer): + + async def connect(self): + + self.game_type = self.scope['url_route']['kwargs']['game_type'] # tournament or peer-to-peer or invite + self.game_id = self.scope['url_route']['kwargs']['game_id'] # game_id or new + self.user = self.scope['user'] + + await self.accept() + + # Add the user to the 'lobby' group + await self.channel_layer.group_add("lobby", self.channel_name) + + # Set the user's channel name + await USER_CHANNEL_NAME.set(self.user.username, self.channel_name) + # Add user username to lobby cache + await USER_STATUS.set(self.user.username, "lobby") + # Get the list of online users usernames + lobby_users_usernames = await USER_STATUS.get_keys_with_value('lobby') + lobby_users_usernames.remove(self.user.username) + await self.send(text_data=json.dumps({ + 'type': 'inlobby', + 'user': self.user.username, + 'users': lobby_users_usernames, + })) + await self.channel_layer.group_send("lobby", { + 'type': 'user.inlobby', + 'user': self.user.username, + }) + if self.game_type == 'tournament': + await self.tournament_match_handler() + elif self.game_type == 'invite': + await self.from_chat_handler() + + async def disconnect(self, close_code): + game_id = await USER_STATUS.get(self.user.username) + if game_id != 'lobby': + game = await GAMES.get(game_id) + if game != None: + other_player_channel_name = await USER_CHANNEL_NAME.get(game.otherPlayer(self.user.username)) + await self.record_for_disconnected(game_id, game) + await self.exit_handler(game_id, game) + await self.channel_layer.send(other_player_channel_name, { + 'type': 'game.disconnect', + 'game_id': game_id, + 'disconnected': self.user.username, + }) + + # Remove the user from the 'lobby' group + await self.channel_layer.group_discard("lobby", self.channel_name) + + # Remove the user's channel name + await USER_CHANNEL_NAME.delete(self.user.username) + + # Remove user username from lobby cache + await USER_STATUS.delete(self.user.username) + + # Set the user's status to offline + await self.channel_layer.group_send("lobby", { + 'type': 'user.outlobby', + 'user': self.user.username, + }) + + # Close the websocket connection + await self.close(close_code) + + async def receive(self, text_data): + data = json.loads(text_data) + action = data.get('action') + + if action == 'invite': + matchmaking = data.get('matchmaking') + invitee_username = data.get('invitee_username') + if matchmaking == 'true': + invitee_username = await self.matchmaking_handler() + if invitee_username == None: + await self.send(text_data=json.dumps({ + "error": "No suitable opponent found.", + })) + return + if await self.check_is_user_inlobby(invitee_username): + invitee_channel_name = await USER_CHANNEL_NAME.get(invitee_username) + if invitee_channel_name: + await self.channel_layer.send(invitee_channel_name, { + 'type': 'game.invite', + 'inviter': self.user.username, + 'invitee': invitee_username, + }) + + elif action == 'accept': + inviter_username = data.get('inviter_username') + await self.accept_handler(inviter_username) + + elif action == 'decline': + inviter_username = data.get('inviter_username') + await self.decline_handler(inviter_username) + + + elif action == 'start.request': + opponent_username = data.get('opponent') + game_id = data.get('game_id') + vote = data.get('vote') + await self.start_handler(game_id, opponent_username, vote) + + elif action == 'leave.game': + game_id = data.get('game_id') + left = data.get('left') + opponent = data.get('opponent') + await self.leave_handler(game_id, left, opponent) + + elif action == 'restart': #? not sure is needed or not + invitee_username = data.get('invitee_username') + invitee_channel_name = await USER_CHANNEL_NAME.get(invitee_username) + if invitee_channel_name: + await self.channel_layer.send(invitee_channel_name, { + 'type': 'game.restart', + 'inviter': self.user.username, + }) + elif action == 'exit': + game_id = data.get('game_id') + game = await GAMES.get(game_id) + if await self.check_is_users_ingame(game_id, game): + await self.exit_handler(game_id, game) + + #TODO Maybe remove this + elif action == 'pause.game': + game_id = data.get('game_id') + game = await GAMES.get(game_id) + if (game != None): + game.pauseGame() + await self.channel_layer.group_send( + game.group_name, + { + "type": "game.pause", + "game_id": game_id, + } + ) + + #TODO Maybe remove this + elif action == 'resume.game': + game_id = data.get('game_id') + game = await GAMES.get(game_id) + if (game != None): + game.resumeGame() + await self.channel_layer.group_send( + game.group_name, + { + "type": "game.resume", + "game_id": game_id, + } + ) + + elif action == "ball": #? Needs validation + # Make a move in a game and get the ball coordinates + # we send a message to the clients with the ball coordinates + game_id = data["game_id"] + # Move and Get ball coordinates + game = await GAMES.get(game_id) #? When games status is ended, game_id is deleted from GAMES cache + if (game != None): #? So game becomes None. Is this check enough? or moving delete to end solve without this + if (game.status == Status.PLAYING): + x, y, player1_score, player2_score = game.moveBall() + # Send a message to the game group with the game id, the move coordinates + await self.channel_layer.group_send( + game.group_name, + { + "type": "game.ball", + "game_id": game_id, + "x": x, + "y": y, + "player1_score": player1_score, + "player2_score": player2_score, + } + ) + elif (game.status == Status.ENDED and not game.no_more): + await self.end_handler(game_id, game) + game.no_more = True + + + elif action == "paddle": #? Needs validation + # Make a move in a game + game_id = data["game_id"] + dir = data["direction"] + # Move and Get paddle coordinate + game = await GAMES.get(game_id) #? When games status is ended, game_id is deleted from GAMES cache + if (game != None): #? So game becomes None. Is this check enough? or moving delete to end solve without this + y = game.movePaddle(self.user.username, dir) + # Send a message to the game group with the game id, the paddle coordinate, and the player's username + await self.channel_layer.group_send( + game.group_name, + { + "type": "game.paddle", + "game_id": game_id, + "y": y, + "player": self.user.username, + } + ) + elif action == "ability": + game_id = data["game_id"] + ability = data["abilities"] + game = await GAMES.get(game_id) + if (game != None): + if (game.status == Status.PLAYING): + game.activateAbility(self.user.username, ability) + await self.channel_layer.group_send( + game.group_name, + { + "type": "game.ability", + "game_id": game_id, + "player": self.user.username, + "ability": ability, + } + ) + + ### HANDLERS ### + async def tournament_match_handler(self): + game_id, player1, player2, group_name, tournament_id = await self.match_details() + if await self.check_is_user_inlobby(player1) and await self.check_is_user_inlobby(player2): + player1_channel_name = await USER_CHANNEL_NAME.get(player1) + player2_channel_name = await USER_CHANNEL_NAME.get(player2) + + await self.channel_layer.group_add(group_name, player1_channel_name) + await self.channel_layer.group_add(group_name, player2_channel_name) + + await GAMES.set(game_id, PongGame(player1, player2, tournament_id)) + + await self.channel_layer.group_send(group_name, { + 'type': 'tournament.match', + 'tournament_id': tournament_id, + 'game_id': game_id, + 'player1': player1, + 'player2': player2, + }) + + async def from_chat_handler(self): + game_id, player1, player2, group_name, tournament_id = await self.match_details() + if await self.check_is_user_inlobby(player1) and await self.check_is_user_inlobby(player2): + player1_channel_name = await USER_CHANNEL_NAME.get(player1) + player2_channel_name = await USER_CHANNEL_NAME.get(player2) + + await self.channel_layer.group_add(group_name, player1_channel_name) + await self.channel_layer.group_add(group_name, player2_channel_name) + + await GAMES.set(game_id, PongGame(player1, player2)) + + await self.channel_layer.group_send(group_name, { + 'type': 'chat.game', + 'game_id': game_id, + 'player1': player1, + 'player2': player2, + }) + + async def accept_handler(self, inviter_username): + inviter_channel_name = await USER_CHANNEL_NAME.get(inviter_username) + group_name = f"{inviter_username}-{self.user.username}" + await self.channel_layer.group_add(group_name, self.channel_name) + await self.channel_layer.group_add(group_name, inviter_channel_name) + + # Create a new game instance and save it to the database + game = await self.create_game(group_name, inviter_username, self.user.username) + # Create a new game instance and save it to the cache + await GAMES.set(game.id, PongGame(inviter_username, self.user.username)) + + await self.channel_layer.group_send(group_name, { + 'type': 'game.accept', + 'accepter': self.user.username, + 'accepted': inviter_username, + 'game_id': game.id, + }) + + async def decline_handler(self, inviter_username): + inviter_channel_name = await USER_CHANNEL_NAME.get(inviter_username) + await self.channel_layer.send(inviter_channel_name, { + 'type': 'game.decline', + 'decliner': self.user.username, + 'declined': inviter_username, + }) + + async def start_handler(self, game_id, opponent_username, vote): + # Get the current game status and update it with the vote count + game = await GAMES.get(game_id) + current = game.status.value + int(vote) + await GAMES.set_field_value(game_id, Status(current), "status") + + # Check both players voted to start the game + if Status(current) == Status.PLAYING: # both players voted to start the game + await USER_STATUS.set(self.user.username, game_id) + await USER_STATUS.set(opponent_username, game_id) + cache.set(f"playing_{self.user.username}", True) + cache.set(f"playing_{opponent_username}", True) + + """ # Send message to lobby #? Maybe unnecesary bcs playing_username cache + await self.channel_layer.group_send('lobby', { + 'type': 'users.ingame', + 'game_type': self.game_type, + 'players': [self.user.username, opponent_username], + }) """ + await self.channel_layer.group_send(game.group_name, { + 'type': 'game.start', + 'game_id': game_id, + 'vote': current, + }) + + async def leave_handler(self, game_id, left, opponent): + # Get scores + game = await GAMES.get(game_id) + left_score = game.getScore(left) # blocking? + opponent_score = MAX_SCORE # set max score automaticaly + duration = game.getDuration() + # Record the game + await self.record_stats_elo_wallet(game_id, opponent_score, left_score, opponent, left, duration) + await USER_STATUS.set(game.player1.username, 'lobby') #? + await USER_STATUS.set(game.player2.username, 'lobby') #? + + await self.channel_layer.group_send( + game.group_name, + { + "type": "game.leave", + "game_id": game_id, + "left": self.user.username, + "left_score": left_score, + "opponent_score": opponent_score, + "winner": opponent, + "loser": left, + } + ) + #await self.exit_handler(game_id, game, opponent) #! Invalid channel name error + + async def exit_handler(self, game_id, game): + # Discard both from the game group + opponent = game.otherPlayer(self.user.username) + opponent_channel_name = await USER_CHANNEL_NAME.get(opponent) + await self.channel_layer.group_discard(game.group_name, self.channel_name) + await self.channel_layer.group_discard(game.group_name, opponent_channel_name) + cache.set(f"playing_{self.user.username}", False) + cache.set(f"playing_{opponent}", False) + # delete the game from the cache + await GAMES.delete(game_id) + + async def end_handler(self, game_id, game): + # Get scores + player1_score = game.player1.score + player2_score = game.player2.score + duration = game.getDuration() + winner, loser, winner_score, loser_score = game.getWinnerLoserandScores() + # Set the game winner, scores and save it to the database + await self.record_stats_elo_wallet(game_id, winner_score, loser_score, winner, loser, duration) + await USER_STATUS.set(game.player1.username, 'lobby') #? + await USER_STATUS.set(game.player2.username, 'lobby') #? + + #? Maybe unnecesary + await self.channel_layer.group_send( + game.group_name, + { + "type": "game.end", + "game_id": game_id, + "player1_score": player1_score, + "player2_score": player2_score, + "winner": winner, + "loser": loser, + } + ) + + + ## SENDERS ## + async def user_inlobby(self, event): + user = event['user'] + await self.send(text_data=json.dumps({ + 'type': 'user.inlobby', + 'user': user, + })) + + async def user_outlobby(self, event): + user = event['user'] + await self.send(text_data=json.dumps({ + 'type': 'user.outlobby', + 'user': user, + })) + + async def game_disconnect(self, event): + game_id = event['game_id'] + disconnected = event['disconnected'] + await self.send(text_data=json.dumps({ + 'type': 'game.disconnect', + 'game_id': game_id, + 'disconnected': disconnected, + })) + + async def game_invite(self, event): + inviter = event['inviter'] + invitee = event['invitee'] + await self.send(text_data=json.dumps({ + 'type': 'game.invite', + 'inviter': inviter, + 'invitee': invitee, + })) + + async def tournament_match(self, event): + tournament_id = event['tournament_id'] + game_id = event['game_id'] + player1 = event['player1'] + player2 = event['player2'] + await self.send(text_data=json.dumps({ + 'type': 'tournament.match', + 'tournament_id': tournament_id, + 'game_id': game_id, + 'player1': player1, + 'player2': player2, + })) + + async def chat_game(self, event): + game_id = event['game_id'] + player1 = event['player1'] + player2 = event['player2'] + await self.send(text_data=json.dumps({ + 'type': 'tournament.match', + 'game_id': game_id, + 'player1': player1, + 'player2': player2, + })) + + async def game_accept(self, event): + accepter = event['accepter'] + accepted = event['accepted'] + game_id = event['game_id'] + await self.send(text_data=json.dumps({ + 'type': 'game.accept', + 'accepter': accepter, + 'accepted': accepted, + 'game_id': game_id, + })) + + async def game_decline(self, event): + decliner = event['decliner'] + declined = event['declined'] + await self.send(text_data=json.dumps({ + 'type': 'game.decline', + 'decliner': decliner, + 'declined': declined, + })) + + async def game_start(self, event): + game_id = event['game_id'] + vote = event['vote'] + await self.send(text_data=json.dumps({ + 'type': 'game.start', + 'game_id': game_id, + 'vote': vote, + })) + + #? Maybe unnecesary + async def users_ingame(self, event): + game_type = event['game_type'] + players = event['players'] + await self.send(text_data=json.dumps({ + 'type': 'users.ingame', + 'game_type': game_type, + 'players': players, + })) + + async def game_leave(self, event): + game_id = event['game_id'] + left = event['left'] + left_score = event['left_score'] + opponent_score = event['opponent_score'] + winner = event['winner'] + loser = event['loser'] + await self.send(text_data=json.dumps({ + 'type': 'game.leave', + 'game_id': game_id, + 'left': left, + 'left_score': left_score, + 'opponent_score': opponent_score, + 'winner': winner, + 'loser': loser, + })) + + async def game_end(self, event): + game_id = event['game_id'] + player1_score = event['player1_score'] + player2_score = event['player2_score'] + winner = event['winner'] + loser = event['loser'] + + await self.send(text_data=json.dumps({ + 'type': 'game.end', + 'game_id': game_id, + 'player1_score': player1_score, + 'player2_score': player2_score, + 'winner': winner, + 'loser': loser, + })) + + async def game_restart(self, event): + inviter = event['inviter'] + await self.send(text_data=json.dumps({ + 'type': 'game.restart', + 'inviter': inviter, + })) + + async def game_pause(self, event): + game_id = event['game_id'] + await self.send(text_data=json.dumps({ + 'type': 'game.pause', + 'game_id': game_id, + })) + + async def game_resume(self, event): + game_id = event['game_id'] + await self.send(text_data=json.dumps({ + 'type': 'game.resume', + 'game_id': game_id, + })) + + async def game_ball(self, event): + game_id = event['game_id'] + x = event['x'] + y = event['y'] + player1_score = event['player1_score'] + player2_score = event['player2_score'] + await self.send(text_data=json.dumps({ + 'type': 'game.ball', + 'game_id': game_id, + 'x': x, + 'y': y, + 'player1_score': player1_score, + 'player2_score': player2_score, + })) + + async def game_paddle(self, event): + game_id = event['game_id'] + y = event['y'] + player = event['player'] + await self.send(text_data=json.dumps({ + 'type': 'game.paddle', + 'game_id': game_id, + 'y': y, + 'player': player, + })) + + async def game_ability(self, event): + game_id = event['game_id'] + player = event['player'] + ability = event['ability'] + await self.send(text_data=json.dumps({ + 'type': 'game.ability', + 'game_id': game_id, + 'player': player, + 'ability': ability, + })) + + # Helper methods to interact with the database # + async def create_game(self, group_name, player1, player2): + from .models import Game, UserProfile + # Create a new game instance with the given players and an group_name + accepted = await UserProfile.objects.aget(username=player1) + accepter = await UserProfile.objects.aget(username=player2) + game = await Game.objects.acreate(group_name=group_name, player1=accepted, player2=accepter) + return game + + + @database_sync_to_async + def match_details(self): + from .models import Game + game = Game.objects.get(id=self.game_id) + game_id = game.id + player1 = game.player1.username + player2 = game.player2.username + group_name = game.group_name + tournament_id = game.tournament_id + return game_id, player1, player2, group_name, tournament_id + + @database_sync_to_async + def record_stats_elo_wallet(self, game_id, winner_score, loser_score, winner, loser, game_duration): + from .models import Game, UserProfile + from .update import update_wallet_elo, update_stats_pong, update_tournament + + game = Game.objects.get(id=game_id) + game.winner_score = winner_score + game.loser_score = loser_score + game.winner =UserProfile.objects.get(username=winner) + game.loser = UserProfile.objects.get(username=loser) + game.game_duration = datetime.timedelta(seconds=game_duration) + game.save() + + update_wallet_elo(game.winner, game.loser) + update_stats_pong(game.winner, game.loser, winner_score, loser_score, game_duration, "remote") + + # İf the game is a tournament game + if game.tournament_id: #? Check + update_tournament(game) + + + async def record_for_disconnected(self, game_id, game): + duration = game.getDuration() + if game.player1.username == self.user.username: + await self.record_stats_elo_wallet(game_id, game.player1.score, MAX_SCORE, game.player2.username, game.player1.username, duration) + else: + await self.record_stats_elo_wallet(game_id, MAX_SCORE, game.player2.score, game.player1.username, game.player2.username, duration) + + async def check_is_user_inlobby(self, username): + answer = await USER_STATUS.get(username) == 'lobby' + if not answer: + await self.send(text_data=json.dumps({ + "error": "User is not in the lobby.", + })) + return answer + + async def check_is_users_ingame(self, game_id, game): + answer = await USER_STATUS.get(game.player1.username) == game_id and await USER_STATUS.get(game.player2.username) == game_id + return answer + + async def matchmaking_handler(self): + from .models import UserProfile + # Get the current user's elo_point + current_user = await UserProfile.objects.aget(username=self.user.username) + current_user_elo = current_user.elo_point + # Get a list of online users + lobby_users_usernames = await USER_STATUS.get_keys_with_value('lobby') + lobby_users_usernames.remove(self.user.username) #TODO if user not in lobby + + return await self.get_similar_users(lobby_users_usernames, current_user_elo) + + + + @database_sync_to_async + def get_similar_users(self, lobby_users_usernames, current_user_elo): + from .models import UserProfile + users = UserProfile.objects.filter(username__in=lobby_users_usernames, elo_point__gte=current_user_elo-100, elo_point__lte=current_user_elo+100).all() + similar_users = [user.username for user in users] + if similar_users: + invitee_username = random.choice(similar_users) + else: + invitee_username = random.choice(lobby_users_usernames) if lobby_users_usernames else None + + return invitee_username + + diff --git a/indianpong/pong/consumer_rps.py b/indianpong/pong/consumer_rps.py index 62c7ab3d..c82f82ba 100644 --- a/indianpong/pong/consumer_rps.py +++ b/indianpong/pong/consumer_rps.py @@ -1,259 +1,259 @@ -import datetime -import json -import random -from channels.db import database_sync_to_async -from django.core.cache import cache -from channels.generic.websocket import AsyncWebsocketConsumer -from .utils import AsyncLockedDict -from .rps import * - -RPS_USER_CHANNEL_NAME = AsyncLockedDict() # key: username, value: channel_name -RPS_GAMES = AsyncLockedDict() # key: game_id, value: RPSGame object -RPS_USER_STATUS = AsyncLockedDict() # key: username, value: game_id or search - - -class RPSConsumer(AsyncWebsocketConsumer): - - async def connect(self): - self.user = self.scope['user'] - - await self.accept() - - # Add the user to the 'lobby' group - await self.channel_layer.group_add("search", self.channel_name) - - # Set the user's channel name - await RPS_USER_CHANNEL_NAME.set(self.user.username, self.channel_name) - # Add user username to lobby cache - await RPS_USER_STATUS.set(self.user.username, "search") - - # Get the number of users in the lobby - lobby_users_usernames = await RPS_USER_STATUS.get_keys_with_value('search') - lobby_users_count = len(lobby_users_usernames) - await self.send(text_data=json.dumps({ - 'type': 'insearch', - 'user': self.user.username, - 'user_count': lobby_users_count, - })) - - #? Maybe unnecessary - await self.channel_layer.group_send("search", { - 'type': 'user.insearch', - 'user': self.user.username, - }) - - async def disconnect(self, close_code): - game_id = await RPS_USER_STATUS.get(self.user.username) - if game_id != 'search': - game = await RPS_GAMES.get(game_id) - if game != None: - other_player_channel_name = await RPS_USER_CHANNEL_NAME.get(game.otherPlayer(self.user.username)) - await self.record_for_disconnected(game_id, game) - await self.exit_handler(game_id, game) - await self.channel_layer.send(other_player_channel_name, { - 'type': 'game.disconnect', - 'game_id': game_id, - 'disconnected': self.user.username, - }) - - # Remove the user from the 'lobby' group - await self.channel_layer.group_discard("search", self.channel_name) - - # Remove the user's channel name - await RPS_USER_CHANNEL_NAME.delete(self.user.username) - - # Remove user username from lobby cache - await RPS_USER_STATUS.delete(self.user.username) - - #? Maybe unnecessary - # Set the user's status to offline - await self.channel_layer.group_send("search", { - 'type': 'user.outsearch', - 'user': self.user.username, - }) - - # Close the websocket connection - await self.close(close_code) - - async def receive(self, text_data): - data = json.loads(text_data) - action = data.get('type') - - if action == 'matchmaking': - opponent = await self.matchmaking_handler() - if opponent == None: - await self.send(text_data=json.dumps({ - "error": "No suitable opponent found.", - })) - return - if opponent: - # Get the channel name of the shaker - opponent_channel_name = await RPS_USER_CHANNEL_NAME.get(opponent) - group_name = f'rps_{self.user.username}_{opponent}' - # Create a new game instance in database - game = await self.create_game(group_name, self.user.username, opponent) - # Add both players to the group - await self.channel_layer.group_add(group_name, self.channel_name) - await self.channel_layer.group_add(group_name, opponent_channel_name) - # Save the game instance in the cache - await RPS_GAMES.set(game.id, RPS(self.user.username, opponent)) - # Set the user's status to playing - await RPS_USER_STATUS.set(self.user.username, game.id) - await RPS_USER_STATUS.set(opponent, game.id) - cache.set(f"playing_{self.user.username}", True) - cache.set(f"playing_{opponent}", True) - - # Send the game id to both players - await self.channel_layer.group_send(group_name, { - 'type': 'start', - 'game_id': game.id, - 'player1': self.user.username, - 'player2': opponent, - }) - else: - await self.send(text_data=json.dumps({ - 'type': 'matchmaking.notfound', - })) - - elif action == 'choice': - game_id = data.get('game_id') - choice = data.get('choice') - game = await RPS_GAMES.get(game_id) - game.play(self.user.username, choice) - if game.both_played(): - player1_choice, player2_choice = game.getChoices() - result = game.round_result() - player1_score, player2_score = game.get_scores() - await self.channel_layer.group_send(game.group_name, { - 'type': 'result', - 'game_id': game_id, - 'result': result, - 'player1_choice': player1_choice, - 'player2_choice': player2_choice, - 'player1_score': player1_score, - 'player2_score': player2_score, - }) - if game.check_is_over(): - winner, loser, winner_score, loser_score = game.getWinnerLoserandScores() - game_duration = game.getDuration() - await self.record_stats_elo_wallet(game_id, winner_score, loser_score, winner, loser, game_duration) - await self.channel_layer.group_send(game.group_name, { - 'type': 'result', - 'game_id': game_id, - 'result': 'OVER', - 'player1_choice': player1_choice, - 'player2_choice': player2_choice, - 'player1_score': player1_score, - 'player2_score': player2_score, - }) - - - ### Handlers ### - async def matchmaking_handler(self): - from .models import UserProfile - # Get the current user's elo_point - current_user = await UserProfile.objects.aget(username=self.user.username) - current_user_elo = current_user.elo_point - # Get a list of online users - lobby_users_usernames = await RPS_USER_STATUS.get_keys_with_value('search') - lobby_users_usernames.remove(self.user.username) #TODO if user not in search - - return await self.get_similar_users(lobby_users_usernames, current_user_elo) - - - @database_sync_to_async - def get_similar_users(self, lobby_users_usernames, current_user_elo): - from .models import UserProfile - users = UserProfile.objects.filter(username__in=lobby_users_usernames, elo_point__gte=current_user_elo-100, elo_point__lte=current_user_elo+100).all() - similar_users = [user.username for user in users] - if similar_users: - invitee_username = random.choice(similar_users) - else: - invitee_username = random.choice(lobby_users_usernames) if lobby_users_usernames else None - - return invitee_username - - async def exit_handler(self, game_id, game): - # Discard both from the game group - opponent = game.otherPlayer(self.user.username) - opponent_channel_name = await RPS_USER_CHANNEL_NAME.get(opponent) - await self.channel_layer.group_discard(game.group_name, self.channel_name) - await self.channel_layer.group_discard(game.group_name, opponent_channel_name) - cache.set(f"playing_{self.user.username}", False) - cache.set(f"playing_{opponent}", False) - # delete the game from the cache - await RPS_GAMES.delete(game_id) - - ## Senders ## - async def user_insearch(self, event): - await self.send(text_data=json.dumps({ - 'type': 'user.insearch', - 'user': event['user'], - })) - - async def user_outsearch(self, event): - await self.send(text_data=json.dumps({ - 'type': 'user.outsearch', - 'user': event['user'], - })) - - async def game_disconnect(self, event): - await self.send(text_data=json.dumps({ - 'type': 'game.disconnect', - 'game_id': event['game_id'], - 'disconnected': event['disconnected'], - })) - - async def result(self, event): - await self.send(text_data=json.dumps({ - 'type': 'result', - 'game_id': event['game_id'], - 'result': event['result'], - 'player1_choice': event['player1_choice'], - 'player2_choice': event['player2_choice'], - 'player1_score': event['player1_score'], - 'player2_score': event['player2_score'], - })) - - - - async def start(self, event): - await self.send(text_data=json.dumps({ - 'type': 'start', - 'game_id': event['game_id'], - 'player1': event['player1'], - 'player2': event['player2'], - })) - - # Helpers # - async def create_game(self,group_name, player1, player2): - from .models import Game, UserProfile - # Create a new game instance with the given players and an group_name - player1 = await UserProfile.objects.aget(username=player1) - player2 = await UserProfile.objects.aget(username=player2) - game = await Game.objects.acreate(game_kind="rps", group_name=group_name, player1=player1, player2=player2) - return game - - @database_sync_to_async - def record_stats_elo_wallet(self, game_id, winner_score, loser_score, winner, loser, game_duration): - from .models import Game, UserProfile - from .update import update_wallet_elo, update_stats_rps - - game = Game.objects.get(id=game_id) - game.game_kind = "rps" - game.winner_score = winner_score - game.loser_score = loser_score - game.winner =UserProfile.objects.get(username=winner) - game.loser = UserProfile.objects.get(username=loser) - game.game_duration = datetime.timedelta(seconds=game_duration) - game.save() - - update_wallet_elo(game.winner, game.loser) - update_stats_rps(game.winner, game.loser, winner_score, loser_score, game_duration, "remote") - - async def record_for_disconnected(self, game_id, game): - duration = game.getDuration() - if game.shaker1.username == self.user.username: - await self.record_stats_elo_wallet(game_id, game.shaker1.score, game.max_score, game.shaker2.username, game.shaker1.username, duration) - else: +import datetime +import json +import random +from channels.db import database_sync_to_async +from django.core.cache import cache +from channels.generic.websocket import AsyncWebsocketConsumer +from .utils import AsyncLockedDict +from .rps import * + +RPS_USER_CHANNEL_NAME = AsyncLockedDict() # key: username, value: channel_name +RPS_GAMES = AsyncLockedDict() # key: game_id, value: RPSGame object +RPS_USER_STATUS = AsyncLockedDict() # key: username, value: game_id or search + + +class RPSConsumer(AsyncWebsocketConsumer): + + async def connect(self): + self.user = self.scope['user'] + + await self.accept() + + # Add the user to the 'lobby' group + await self.channel_layer.group_add("search", self.channel_name) + + # Set the user's channel name + await RPS_USER_CHANNEL_NAME.set(self.user.username, self.channel_name) + # Add user username to lobby cache + await RPS_USER_STATUS.set(self.user.username, "search") + + # Get the number of users in the lobby + lobby_users_usernames = await RPS_USER_STATUS.get_keys_with_value('search') + lobby_users_count = len(lobby_users_usernames) + await self.send(text_data=json.dumps({ + 'type': 'insearch', + 'user': self.user.username, + 'user_count': lobby_users_count, + })) + + #? Maybe unnecessary + await self.channel_layer.group_send("search", { + 'type': 'user.insearch', + 'user': self.user.username, + }) + + async def disconnect(self, close_code): + game_id = await RPS_USER_STATUS.get(self.user.username) + if game_id != 'search': + game = await RPS_GAMES.get(game_id) + if game != None: + other_player_channel_name = await RPS_USER_CHANNEL_NAME.get(game.otherPlayer(self.user.username)) + await self.record_for_disconnected(game_id, game) + await self.exit_handler(game_id, game) + await self.channel_layer.send(other_player_channel_name, { + 'type': 'game.disconnect', + 'game_id': game_id, + 'disconnected': self.user.username, + }) + + # Remove the user from the 'lobby' group + await self.channel_layer.group_discard("search", self.channel_name) + + # Remove the user's channel name + await RPS_USER_CHANNEL_NAME.delete(self.user.username) + + # Remove user username from lobby cache + await RPS_USER_STATUS.delete(self.user.username) + + #? Maybe unnecessary + # Set the user's status to offline + await self.channel_layer.group_send("search", { + 'type': 'user.outsearch', + 'user': self.user.username, + }) + + # Close the websocket connection + await self.close(close_code) + + async def receive(self, text_data): + data = json.loads(text_data) + action = data.get('type') + + if action == 'matchmaking': + opponent = await self.matchmaking_handler() + if opponent == None: + await self.send(text_data=json.dumps({ + "error": "No suitable opponent found.", + })) + return + if opponent: + # Get the channel name of the shaker + opponent_channel_name = await RPS_USER_CHANNEL_NAME.get(opponent) + group_name = f'rps_{self.user.username}_{opponent}' + # Create a new game instance in database + game = await self.create_game(group_name, self.user.username, opponent) + # Add both players to the group + await self.channel_layer.group_add(group_name, self.channel_name) + await self.channel_layer.group_add(group_name, opponent_channel_name) + # Save the game instance in the cache + await RPS_GAMES.set(game.id, RPS(self.user.username, opponent)) + # Set the user's status to playing + await RPS_USER_STATUS.set(self.user.username, game.id) + await RPS_USER_STATUS.set(opponent, game.id) + cache.set(f"playing_{self.user.username}", True) + cache.set(f"playing_{opponent}", True) + + # Send the game id to both players + await self.channel_layer.group_send(group_name, { + 'type': 'start', + 'game_id': game.id, + 'player1': self.user.username, + 'player2': opponent, + }) + else: + await self.send(text_data=json.dumps({ + 'type': 'matchmaking.notfound', + })) + + elif action == 'choice': + game_id = data.get('game_id') + choice = data.get('choice') + game = await RPS_GAMES.get(game_id) + game.play(self.user.username, choice) + if game.both_played(): + player1_choice, player2_choice = game.getChoices() + result = game.round_result() + player1_score, player2_score = game.get_scores() + await self.channel_layer.group_send(game.group_name, { + 'type': 'result', + 'game_id': game_id, + 'result': result, + 'player1_choice': player1_choice, + 'player2_choice': player2_choice, + 'player1_score': player1_score, + 'player2_score': player2_score, + }) + if game.check_is_over(): + winner, loser, winner_score, loser_score = game.getWinnerLoserandScores() + game_duration = game.getDuration() + await self.record_stats_elo_wallet(game_id, winner_score, loser_score, winner, loser, game_duration) + await self.channel_layer.group_send(game.group_name, { + 'type': 'result', + 'game_id': game_id, + 'result': 'OVER', + 'player1_choice': player1_choice, + 'player2_choice': player2_choice, + 'player1_score': player1_score, + 'player2_score': player2_score, + }) + + + ### Handlers ### + async def matchmaking_handler(self): + from .models import UserProfile + # Get the current user's elo_point + current_user = await UserProfile.objects.aget(username=self.user.username) + current_user_elo = current_user.elo_point + # Get a list of online users + lobby_users_usernames = await RPS_USER_STATUS.get_keys_with_value('search') + lobby_users_usernames.remove(self.user.username) #TODO if user not in search + + return await self.get_similar_users(lobby_users_usernames, current_user_elo) + + + @database_sync_to_async + def get_similar_users(self, lobby_users_usernames, current_user_elo): + from .models import UserProfile + users = UserProfile.objects.filter(username__in=lobby_users_usernames, elo_point__gte=current_user_elo-100, elo_point__lte=current_user_elo+100).all() + similar_users = [user.username for user in users] + if similar_users: + invitee_username = random.choice(similar_users) + else: + invitee_username = random.choice(lobby_users_usernames) if lobby_users_usernames else None + + return invitee_username + + async def exit_handler(self, game_id, game): + # Discard both from the game group + opponent = game.otherPlayer(self.user.username) + opponent_channel_name = await RPS_USER_CHANNEL_NAME.get(opponent) + await self.channel_layer.group_discard(game.group_name, self.channel_name) + await self.channel_layer.group_discard(game.group_name, opponent_channel_name) + cache.set(f"playing_{self.user.username}", False) + cache.set(f"playing_{opponent}", False) + # delete the game from the cache + await RPS_GAMES.delete(game_id) + + ## Senders ## + async def user_insearch(self, event): + await self.send(text_data=json.dumps({ + 'type': 'user.insearch', + 'user': event['user'], + })) + + async def user_outsearch(self, event): + await self.send(text_data=json.dumps({ + 'type': 'user.outsearch', + 'user': event['user'], + })) + + async def game_disconnect(self, event): + await self.send(text_data=json.dumps({ + 'type': 'game.disconnect', + 'game_id': event['game_id'], + 'disconnected': event['disconnected'], + })) + + async def result(self, event): + await self.send(text_data=json.dumps({ + 'type': 'result', + 'game_id': event['game_id'], + 'result': event['result'], + 'player1_choice': event['player1_choice'], + 'player2_choice': event['player2_choice'], + 'player1_score': event['player1_score'], + 'player2_score': event['player2_score'], + })) + + + + async def start(self, event): + await self.send(text_data=json.dumps({ + 'type': 'start', + 'game_id': event['game_id'], + 'player1': event['player1'], + 'player2': event['player2'], + })) + + # Helpers # + async def create_game(self,group_name, player1, player2): + from .models import Game, UserProfile + # Create a new game instance with the given players and an group_name + player1 = await UserProfile.objects.aget(username=player1) + player2 = await UserProfile.objects.aget(username=player2) + game = await Game.objects.acreate(game_kind="rps", group_name=group_name, player1=player1, player2=player2) + return game + + @database_sync_to_async + def record_stats_elo_wallet(self, game_id, winner_score, loser_score, winner, loser, game_duration): + from .models import Game, UserProfile + from .update import update_wallet_elo, update_stats_rps + + game = Game.objects.get(id=game_id) + game.game_kind = "rps" + game.winner_score = winner_score + game.loser_score = loser_score + game.winner =UserProfile.objects.get(username=winner) + game.loser = UserProfile.objects.get(username=loser) + game.game_duration = datetime.timedelta(seconds=game_duration) + game.save() + + update_wallet_elo(game.winner, game.loser) + update_stats_rps(game.winner, game.loser, winner_score, loser_score, game_duration, "remote") + + async def record_for_disconnected(self, game_id, game): + duration = game.getDuration() + if game.shaker1.username == self.user.username: + await self.record_stats_elo_wallet(game_id, game.shaker1.score, game.max_score, game.shaker2.username, game.shaker1.username, duration) + else: await self.record_stats_elo_wallet(game_id, game.max_score, game.shaker2.score, game.shaker1.username, game.shaker2.username, duration) \ No newline at end of file diff --git a/indianpong/pong/consumer_status.py b/indianpong/pong/consumer_status.py index 51514686..bf68d55b 100644 --- a/indianpong/pong/consumer_status.py +++ b/indianpong/pong/consumer_status.py @@ -1,74 +1,74 @@ -from channels.generic.websocket import AsyncWebsocketConsumer -from django.core.cache import cache -from .utils import add_to_cache, remove_from_cache -#from .models import UserProfile -import json - -class OnlineStatusConsumer(AsyncWebsocketConsumer): - async def connect(self): - self.user = self.scope['user'] - if self.user.is_anonymous: - return - - """ # get UserProfile object - user_profile = await UserProfile.objects.aget(id=self.user.id) - user_profile.is_online = True - await user_profile.asave() - # Add user ID to online_users list - add_to_cache('online_users', set(), self.user.id) """ - cache.set(f'online_{self.user.username}', True) - cache.set(f'playing_{self.user.username}', False) #TODO spada çalışmıyabilir - # Maybe add playing to the cache - await self.accept() - - await self.send(text_data=json.dumps({ - 'status': 'online', - })) - - - async def disconnect(self, close_code): - if self.user.is_anonymous: - return - - cache.set(f'online_{self.user.username}', False) - # Maybe add playing to the cache - """ user_profile = await UserProfile.objects.aget(id=self.user.id) - user_profile.is_online = False - await user_profile.asave() - # Remove user ID from online_users list - remove_from_cache('online_users', set(), self.user.id) """ - await self.close() - -""" -def is_user_online(user): - return cache.get(f'online_{user.id}') is not None""" - -""" -def get_online_users(): - online_user_ids = cache.get('online_users', set()) - return UserProfile.objects.filter(id__in=online_user_ids)""" - - - -""" # Receive message from WebSocket - async def receive(self, text_data): - text_data_json = json.loads(text_data) - message = text_data_json['message'] - - # Send message to group - await self.channel_layer.group_send( - 'online_status', - { - 'type': 'online_status_message', - 'message': message - } - ) - - # Receive message from group - async def online_status_message(self, event): - message = event['message'] - - # Send message to WebSocket - await self.send(text_data=json.dumps({ - 'message': message +from channels.generic.websocket import AsyncWebsocketConsumer +from django.core.cache import cache +from .utils import add_to_cache, remove_from_cache +#from .models import UserProfile +import json + +class OnlineStatusConsumer(AsyncWebsocketConsumer): + async def connect(self): + self.user = self.scope['user'] + if self.user.is_anonymous: + return + + """ # get UserProfile object + user_profile = await UserProfile.objects.aget(id=self.user.id) + user_profile.is_online = True + await user_profile.asave() + # Add user ID to online_users list + add_to_cache('online_users', set(), self.user.id) """ + cache.set(f'online_{self.user.username}', True) + cache.set(f'playing_{self.user.username}', False) #TODO spada çalışmıyabilir + # Maybe add playing to the cache + await self.accept() + + await self.send(text_data=json.dumps({ + 'status': 'online', + })) + + + async def disconnect(self, close_code): + if self.user.is_anonymous: + return + + cache.set(f'online_{self.user.username}', False) + # Maybe add playing to the cache + """ user_profile = await UserProfile.objects.aget(id=self.user.id) + user_profile.is_online = False + await user_profile.asave() + # Remove user ID from online_users list + remove_from_cache('online_users', set(), self.user.id) """ + await self.close() + +""" +def is_user_online(user): + return cache.get(f'online_{user.id}') is not None""" + +""" +def get_online_users(): + online_user_ids = cache.get('online_users', set()) + return UserProfile.objects.filter(id__in=online_user_ids)""" + + + +""" # Receive message from WebSocket + async def receive(self, text_data): + text_data_json = json.loads(text_data) + message = text_data_json['message'] + + # Send message to group + await self.channel_layer.group_send( + 'online_status', + { + 'type': 'online_status_message', + 'message': message + } + ) + + # Receive message from group + async def online_status_message(self, event): + message = event['message'] + + # Send message to WebSocket + await self.send(text_data=json.dumps({ + 'message': message })) """ \ No newline at end of file diff --git a/indianpong/pong/langs.py b/indianpong/pong/langs.py index 5957e668..7220e5af 100644 --- a/indianpong/pong/langs.py +++ b/indianpong/pong/langs.py @@ -1,1436 +1,1436 @@ -def get_langs(lang): - if lang == "en": - return get_lang_en() - if lang == "hi": - return get_lang_hi() - if lang == "tr": - return get_lang_tr() - if lang == "pt": - return get_lang_pt() - - -def get_lang_en(): - context = { - #index - "basePageTittle": "Indian-Pong", - "baseHeaderText": "Indian-Pong", - "baseSubHeaderText": "Indian-Pong created for 42 school by Indian Dev!", - "basePlayButtonText": "Get Started!", - - "baseInfoHeaderText": "Welcome to Indian-Pong!", - "baseInfoHeaderDescription": "Pong brings the excitement and competition of classic table tennis to the internet. On this platform, you can have fun, showcase your skills, and rise in the rankings to become one of the best.", - "baseInfoSubHeaderText": "Play and Win", - "baseInfoSubHeaderDescription1": "Gain Pong Points with each game you win to climb the ranks.", - "baseInfoSubHeaderDescription2": "Use your earnings to purchase new items, rackets, and tables from the store to enhance your gaming experience.", - "baseInfoSubHeaderText2": "Get Started Now", - "baseInfoSubHeaderDescription3": "Create an account to personalize your profile, track your statistics, and see where you stand in the rankings.", - "baseInfoSubHeaderText3": "More Features", - "baseInfoSubHeaderDescription4": "Participate in tournaments to face off against your opponents.", - "baseInfoSubHeaderDescription5": "Enjoy quality time with your friends by hosting private games.", - "baseInfoSubHeaderDescription6": "Chat with other players, share tactics, and join the Pong community.", - - #Login - "loginPageTittle": "Login", - "loginHeaderText1": "Welcome,", - "loginHeaderText2": "sign in to continue", - "loginInputUsernameText": "Username", - "loginInputPasswordText": "Password", - "loginForgotPasswordText": "Forgot Password?", - "loginButtonLogin": "Let's go", - "loginButtonJoin": "Join Us", - - #404 - "notFoundPageTittle": "404 Not Found", - "notFoundHeaderText": "404 ERROR", - "notFoundSubHeaderText": "Probably you lost in our website!", - "notFoundButtonText": "GO HOME", - - #Signup - "signupPageTittle": "Sign Up", - "signupHeaderText1": "Welcome,", - "signupHeaderText2": "sign up to continue", - "signupInputUsernameText": "Username", - "signupInputDisplayNameText": "Display Name", - "signupInputEmailText": "Email", - "signupInputPasswordText": "Password", - "signupInputConfirmPasswordText": "Password (again)", - "signupImageUploadText": "Upload Image", - "signupGdprText1": "I accept the", - "signupGdprText2": "GDPR Privacy Policy", - "signupButtonSignup": "Let's shine!", - - #ForgotPassword - "forgotPasswordPageTittle": "Forgot Password", - "forgotPasswordHeaderText": "Forgot Password", - "forgotPasswordInputEmailText": "Email", - "forgotPasswordButtonSend": "Send Email", - "forgotPasswordLinkText": "Don't have an account?", - "forgotPasswordLinkButtonText": "Join Us", - - #Password-Reset-Done - "passwordResetDonePageTittle": "Email Send Done", - "passwordResetDoneHeaderText": "EMAIL SEND DONE", - "passwordResetDoneSubHeaderText": "We have emailed your password reset link. Please check your email.", - "passwordResetButtonText": "GO LOGIN", - - #ChangePassword - "changePasswordPageTittle": "Change Password", - "changePasswordHeaderText": "Change Password", - "changePassswordSubHeaderText": "change your password", - - #Dashboard - "dashboardPageTittle": "Dashboard", - "dashboardText1": "Welcome, ", - "dashboardText2": "Indian Pong is a collaborative project developed for the 42 school community, offering a nostalgic gaming experience through the classic Atari game, Ping-Pong. This platform allows users to engage in Ping-Pong matches with each other, fostering a sense of friendly competition. In addition to the gaming aspect, Indian Pong provides a social dimension, featuring chat rooms where users can communicate and connect with one another. The platform also enables users to expand their network by adding friends within the 42 school community. Overall, Indian Pong combines the joy of retro gaming with modern social interaction, creating a vibrant and interactive experience for the 42 school community.", - - "dashboardGamesPlayed": "Games Played", - "dashboardWinCount": "Win Count", - "dashboardWinStreak": "Win Streak", - "dashboardLoseStreak": "Lose Streak", - "dashboardWinRate": "Win Rate", - "dashboardAverageGameDuration": "Average Game Duration", - "dashboardAveragePointsWon": "Average Points Won", - "dashboardAveragePointsLost": "Average Points Lost", - - #Chat - "chatPageTittle": "Chat", - "chatHeaderText": "Chats", - "chatRecentlyText": "Recently", - "chatDMText": "Direct Messages", - "chatContainerSelectText": "Select a chat to start messaging", - "chatTodayText": "Today", - "chatTypeHereText": "Type a message here...", - - - #Pong-Game - "pongGamePageTittle": "Pong Game", - "pongGameHeaderText": "Welcome to Pong Lobby", - "pongGameSubHeaderText": "You can improve yourself by playing with Artificial Intelligence. If you want to play with a real person, consider the other option; if we don't find someone to match with in 5 minutes, the match will be canceled. Good luck before we forget!", - "pongGameAIButtonText": "Play with AI", - "pongGameLocalButtonText": "Local Game", - "pongGameRemoteButtonText": "Remote Player", - "pongGameLocalTournamentButtonText": "Local Tournament", - "pongGameTournamentButtonText": "Tournament", - - #AI-Game - "aiGamePageTittle": "AI Game", - "aiGameReactionDelayText": "Reaction Delay", - "aiGameGetReadyText": "Get Ready", - "aiGameStartButtonText": "Start", - - "aiGameGameOverText": "Game Over", - "aiGameRestartButtonText": "Restart", - "aiGameExitButtonText": "Exit", - - "aiGameInfoHeaderText": "About the Game", - "aiGameInfoSubHeaderText": "How to Play the Game?", - "aiGameInfoSubHeaderDescription1": "In Pong game, players engage in a table tennis match against their opponents. The W-S keys (or up-down arrow keys) are used to control the ball.", - "aiGameInfoSubHeaderText2": "Win and Improve", - "aiGameInfoSubHeaderDescription2": "You earn Pong Points with every game you win. With these points, you can purchase new items, rackets, and tables from the store to enhance your gaming experience.", - "aiGameInfoSubHeaderText3": "Get Started Now", - "aiGameInfoSubHeaderDescription3": "You can create an account to personalize your gaming experience. With an account, you can track your statistics and see your position in the rankings.", - "aiGameInfoSubHeaderText4": "More Features", - "aiGameInfoSubHeaderDescription4": "You can participate in tournaments to face off against your opponents and test your skills. Additionally, you can create private games with your friends and join the Pong community.", - - "aiGameInfoSubHeaderText5": "Controls", - "aiGameInfoSubHeaderDescription5": "Up", - "aiGameInfoSubHeaderDescription6": "Down", - "aiGameInfoSubHeaderText6": "Skills", - "aiGameInfoSubHeaderDescription7": "Like a Cheater", - "aiGameInfoSubHeaderDescription8": "Fast and Furious", - "aiGameInfoSubHeaderDescription9": "Frozen Ball", - - #Local-Game - "localGamePageTittle": "Local Game", - "localGameHeaderText": "1v1 Local Game", - "localGamePlayer1Text": "Player1 Name", - "localGamePlayer2Text": "Player2 Name", - "localGameMaxScoreText": "Max Score", - "localGameGameModeText": "Game Mode", - "localGameChooseModeText1": "Vanilla", - "localGameChooseModeText2": "Abilities", - "localGameButtonStart": "Start", - - #Local-Tournament - "localTournamentPageTittle": "Local Tournament", - "localTournamentGameHeaderText": "Local Tournament", - "localTournamentPlayer1Text": "Player1 Name", - "localTournamentPlayer2Text": "Player2 Name", - "localTournamentPlayer3Text": "Player3 Name", - "localTournamentPlayer4Text": "Player4 Name", - "localTournamentMaxScoreText": "Max Score", - "localTournamentGameModeText": "Game Mode", - "localTournamentChooseModeText1": "Vanilla", - "localTournamentChooseModeText2": "Abilities", - "localTournamentButtonStart": "Start & Bracket", - "localTournamentBracketTitle": "Tournament Bracket", - "localTournamentBracketStartButtonText": "Start Tournament", - "localTournamentTournamentOverText": "Tournament Over", - "localTournamentOverButtonText": "Over", - - "localTournamentNextButtonText": "Next", - - - #Tournament - "tournamentPageTittle": "Tournament", - "tournamentHeaderText": "Welcome to Tournament Lobby for Pong", - "tournamentSubHeaderText": "Here you can join a tournament lobby or create your own tournament lobby. You can invite your friends by sharing the invite code after creating the room. Good luck before I forget!", - "tournamentJoinButtonText": "Join Tournament", - "tournamentCreateButtonText": "Create Tournament", - - #Tournament-Create - "tournamentCreatePageTittle": "Create Tournament", - "tournamentCreateHeaderText": "CREATE TOURNAMENT", - "tournamentCreateSubHeaderText": "To create a tournament I need a tournament name, how many max points each game will have. Good luck before I forget!", - "tournamentCreateNameText": "Tournament Name", - "tournamentCreateMaxPointsText": "Max Score Games", - "tournamentCreateGameModeText": "Game Mode", - "tournamentCreateChooseModeText1": "Vanilla", - "tournamentCreateChooseModeText2": "Abilities", - "tournamentCreateButtonCreate": "Create Tournament", - - #Joined-Tournament-Room - "tournamentroomPageTittle": "Tournament Room", - "tournamentroomHeaderText": "Tournament Room", - "tournamentroomRoomText": "Room", - "tournamentroomLeaveButtonText": "LEAVE TOURNAMENT", - "tournamentroomStartButtonText": "START TOURNAMENT", - "tournamentroomJoinButtonText": "JOIN TOURNAMENT", - "tournamentCheckBracketButtonText": "CHECK BRACKET", - "tournamentOverWinnerGuyText": "the tournament is over and the only person worthy of this throne", - "tournamentOverLosersText": "the tournament is over and these are the losers club", - "tournamentroomTournamentRoomButton": "TOURNAMENT ROOM", - "tournamentroomWaitingText": "Waiting", - "tournamentroomForPlayerText": "for player...", - - #Tournament Room List - "tournamentRoomListPageTittle": "Tournament Rooms", - "tournamentRoomListHeaderText": "Tournament Rooms", - - #Remote Pong Game - "remotePongGamePageTittle": "Remote Pong Game", - "remotePongGameTableName": "Name", - "remotePongGameTableActions": "Actions", - "remotePongGameMatchmakingButtonText": "MATCHMAKING", - "remotePongGameLeaveButtonText": "LEAVE", - "remotePongGameStartText": "Before to start, u can choose game mode!", - "remotePongGameStartButtonText": "START GAME", - "remotePongSelectedMode": "Vanilla", - - - #RPS Game - "rpsGamePageTittle": "Rock Paper Scissors", - "rpsGameText1": "Welcome to RPS Lobby", - "rpsGameText2": "You can improve yourself by playing with Artificial Intelligence. If you want to play with a real person, consider the other option; if we don't find someone to match with in 5 minutes, the match will be canceled. Good luck before we forget!", - "rpsGameAIButtonText": "Play with AI", - "rpsGameLocalButtonText": "Local Game", - "rpsGameSearchOpponentButtonText": "Search Opponent ", - "rpsUserCountText": "number of people looking for a match right now", - - #AI-Game - "rpsGamePageTittle": "RPS Game with Artificial Intelligence", - "rpsGameScoreText": "score", - "rpsGameRockText": "ROCK", - "rpsGamePaperText": "PAPER", - "rpsGameScissorsText": "SCISSORS", - "rpsGamePickedText": "you picked", - "rpsGamePickedText2": "the house picked", - "rpsGameAgainText": "Play again", - "rpsGameGameOverText": "Game Over", - "rpsGameRestartButtonText": "Restart", - "rpsGameExitButtonText": "Exit", - - #Rankings - "rankingsPageTittle": "Rankings", - "rankingsTableRankText": "Rank", - "rankingsTableNameText": "Name", - "rankingsTableUsernameText": "Username", - "rankingsTableWinsText": "Wins", - "rankingsTableLossesText": "Losses", - "rankingsTableWinRateText": "Win Rate", - "rankingsTablePongPointsText": "Pong Point", - - #Store - "storePageTittle": "Store", - "storeText": "Store", - "storeTagText": "All", - "storeWalletText": "Wallet", - "storeWalleinfoText1": "Oyun oynayarak ", - "storeWalleinfoText2": " kazanabilirsin.", - - #Inventory - "inventoryPageTittle": "Inventory", - "inventoryText": "Inventory", - "inventoryTagText": "All", - "inventoryWalletText": "Wallet", - "inventoryWalleinfoText1": " playing games", - "inventoryWalleinfoText2": " can win.", - "inventoryModalHeaderText": "Set Featured Item", - "inventoryModalSaveButton": "Save", - "inventoryModalCloseButton": "Close", - "inventoryItemKeyboardInfoText": "Use the", - "inventoryItemKeyboardInfoText2": "key to use this ability. And remember, you must equip this ability.", - "inventoryItemKeyboardInfoText3": "There is no special keypad for this item, it is used automatically.", - - #Search - "searchPageTittle": "Search", - "searchInputText": "Email or Username or Displayname Search...", - "searchMessageButtonText": "Message", - "searchFollowButtonText": "Follow", - "searchFollowingButtonText": "Unfollow", - "searchNoResultFoundText": "No result found.", - - #Profile - "profilePageTittle": "Profile", - "profileRankAIText": "I'M JUST ROBOT", - "profileRankUserText1": " IN RANKINGS", - "profileRankUserText2": " NO RANKING", - "profileFollowButton": "Follow", - "profileFollowingButton": "Unfollow", - "profileTitleText1": "42 Kocaeli Student", - "profileTitleText2": "Software Developer", - - "profileLinkedinSocialText": "No Linkedin", - "profileGithubSocialText": "No Github", - "profileTwitterSocialText": "No Twitter", - "profileIntra42SocialText": "No Intra42", - - "profileMatchHistoryText1": "Opponent", - "profileMatchHistoryText2": "Result", - "profileMatchHistoryText3": "Score", - "profileMatchHistoryText4": "Duration", - - "profileMatchHistoryWinText": "Win", - "profileMatchHistoryLoseText": "Lose", - - "profileRankText1": "Rank", - "profileStatsText": "Stats", - - "profileGameStats1": "Games Played:", - "profileGameStats2": "Wins:", - "profileGameStats3": "Loses:", - "profileGameStats4": "Win Rate:", - "profileGameStats5": "Win Streak:", - "profileGameStats6": "Average Game Duration:", - - #Friends - "friendsPageTittle": "Friends", - "friendsMessageButtonText": "Message", - "friendsNoResultFoundText": "No result found.", - - #ProfileSettings - "profileSettingsPageTittle": "Profile Settings", - "profileSettingsNavbar1": "Edit Profile", - "profileSettingsNavbar2": "Change Password", - "profileSettingsNavbar3": "Add Socials", - "profileSettingsNavbar4": "Blocked Users", - "profileSettingsNavbar5": "Close Account", - - #Edit-Profile - "editProfileChangeImageText": "Change Image", - "editProfileUsernameText": "Username (how your name will appear to other users on the site)", - "editProfileUsernameTimeText": "You can change your username every 7 days.", - "editProfileEmailText": "Email", - "editProfile42EmailText": "Since you are logged in with 42, your email setting feature is disabled.", - "editProfileDisplayNameText": "Display Name", - "editProfileSaveButtonText": "Save Changes", - - #Change-Passwordg - "changePasswordCurrentPasswordText": "Current Password", - "changePasswordNewPasswordText": "New Password", - "changePasswordNewConfirmPasswordText": "Confirm New Password", - "changePassword42Text": "Since you are logged in with 42, your password setting feature is disabled.", - "changePasswordSaveButtonText": "Save Password", - - #Add-Socials - "addSocialsLinkedinInputText": "Enter your LinkedIn username", - "addSocialsTwitterInputText": "Enter your Twitter username", - "addSocialsGithubInputText": "Enter your Github username", - "addSocialsIntraInputText": "Enter your 42 Intra username", - "addSocialsSaveButtonText": "Save Socials", - - #Blocked-Users - "blockedUsersHeaderText": "Blocked Accounts", - "blockedUsersSubHeaderText": "You can unblock the accounts you have blocked here.", - "blockedStatusText": "Blocked", - - #Close-Account - "closeAccountHeaderText": "Close Account", - "closeAccountInputText": "Email", - "closeAccountSubHeaderText": "You can delete your account here. This action is irreversible.", - "closeAccountButton": "Close Account", - - - } - return context - -def get_lang_tr(): - context = { - #index - "basePageTittle": "Indian-Pong", - "baseHeaderText": "Indian-Pong", - "baseSubHeaderText": "Indian-Pong Hintli geliştiriciler tarafından 42 okulu için geliştirilmiştir!", - "basePlayButtonText": "YOLCULUĞA BAŞLA!", - - "baseInfoHeaderText": "Indian-Pong'a hoş geldiniz!", - "baseInfoHeaderDescription": "Pong, klasik masa tenisi oyununun heyecanını ve rekabetini internet ortamına taşıyor. Bu platformda hem eğlenebilir hem de yeteneğini konuşturabilir, sıralamada yükselip en iyiler arasına girebilirsin.", - "baseInfoSubHeaderText": "Oyna ve Kazan", - "baseInfoSubHeaderDescription1": "Her oyun kazandığında Pong Point kazanarak sıralamada yüksel.", - "baseInfoSubHeaderDescription2": "Kazançlarınla mağazadan yeni eşyalar, raket ve masalar satın alarak oyun deneyimini geliştir.", - "baseInfoSubHeaderText2": "Hemen Başla", - "baseInfoSubHeaderDescription3": "Hesap oluşturarak profilini kişiselleştir, istatistiklerini takip et ve sıralamadaki yerini gör.", - "baseInfoSubHeaderText3": "Daha Fazlası", - "baseInfoSubHeaderDescription4": "Turnuvalara katılarak rakiplerinle yüzleş.", - "baseInfoSubHeaderDescription5": "Arkadaşlarınla özel oyunlar kurarak keyifli vakit geçir.", - "baseInfoSubHeaderDescription6": "Diğer oyuncularla sohbet et, taktikler paylaş ve Pong topluluğuna katıl.", - - #Login - "loginPageTittle": "Giriş Yap", - "loginHeaderText1": "Hoş geldiniz,", - "loginHeaderText2": "devam etmek için giriş yapın", - "loginInputUsernameText": "Kullanıcı Adı", - "loginInputPasswordText": "Şifre", - "loginForgotPasswordText": "Şifremi Unuttum?", - "loginButtonLogin": "Giriş Yap", - "loginButtonJoin": "Üye Ol", - - #404 - "notFoundPageTittle": "Sayfa Bulunamadı", - "notFoundHeaderText": "404 HATA", - "notFoundSubHeaderText": "Muhtemelen sitemizde kayboldunuz!", - "notFoundButtonText": "ANA SAYFA'YA DÖN", - - #Signup - "signupPageTittle": "Kayıt Ol", - "signupHeaderText1": "Hoş geldiniz,", - "signupHeaderText2": "devam etmek için kayıt olun", - "signupInputUsernameText": "Kullanıcı Adı", - "signupInputDisplayNameText": "Görünen Ad", - "signupInputEmailText": "E-posta", - "signupInputPasswordText": "Şifre", - "signupInputConfirmPasswordText": "Şifreyi Onayla", - "signupImageUploadText": "Resim Yükle", - "signupGdprText1": "Kabul ediyorum", - "signupGdprText2": "GDPR Gizlilik Politikası", - "signupButtonSignup": "Kayıt Ol", - - #ForgotPassword - "forgotPasswordPageTittle": "Şifremi Unuttum", - "forgotPasswordHeaderText": "Şifremi Unuttum", - "forgotPasswordInputEmailText": "E-posta", - "forgotPasswordButtonSend": "E-posta Gönder", - "forgotPasswordLinkText": "Hesabınız yok mu?", - "forgotPasswordLinkButtonText": "Kayıt Ol", - - #Password-Reset-Done - "passwordResetDonePageTittle": "E-Posta Gönderildi", - "passwordResetDoneHeaderText": "E-POSTA GÖNDERİLDİ", - "passwordResetDoneSubHeaderText": "Şifre sıfırlama bağlantınızı e-posta ile gönderdik. Lütfen e-postanızı kontrol edin.", - "passwordResetButtonText": "GİRİŞ'E DÖN", - - #ChangePassword - "changePasswordPageTittle": "Şifre Değiştir", - "changePasswordHeaderText": "Şifre Değiştir", - "changePassswordSubHeaderText": "şifreni değiştir", - - #Dashboard - "dashboardPageTittle": "Ana Sayfa", - "dashboardText1": "HOŞ GELDİNİZ, ", - "dashboardText2": "Indian Pong, 42 okulu toplulugu için geliştirilmiş bir takım projesidir ve klasik Atari oyunu Ping-Pong ile nostaljik bir oyun deneyimi sunar. Bu platform, kullanıcıların birbirleriyle Ping-Pong maçlari yapmalarina olanak tanır ve dostane rekabet ortamı oluşturur. Oyun deneyimi dışında, Indian Pong, kullanıcıların birbirleriyle iletişim kurabileceği ve bağlanti kurabilecegi sohbet odalarını içeren bir sosyal boyut sunar. Platform ayrıca, kullanicilarin 42 okulu topluluğunda arkadaş ekleyerek ağlarını genişletmelerine olanak tanır. Genel olarak, Indian Pong, retro oyun keyfini modern sosyal etkileşimle birleştirerek, 42 okulu topluluğu icin canlı ve etkileşimli bir deneyim sunar.", - - "dashboardGamesPlayed": "Oynanan Oyunlar", - "dashboardWinCount": "Kazanma Sayısı", - "dashboardWinStreak": "Kazanma Serisi", - "dashboardLoseStreak": "Kaybetme Serisi", - "dashboardWinRate": "Kazanma Oranı", - "dashboardAverageGameDuration": "Ortalama Oyun Süresi", - "dashboardAveragePointsWon": "Ortalama Kazanılan Puanlar", - "dashboardAveragePointsLost": "Ortalama Kaybedilen Puanlar", - - #Chat - "chatPageTittle": "Sohbet", - "chatHeaderText": "Sohbetler", - "chatRecentlyText": "Son Zamanlar", - "chatDMText": "Direkt Mesajlar", - "chatContainerSelectText": "Mesajlaşmaya başlamak için bir sohbet seçin", - "chatTodayText": "Bugün", - "chatTypeHereText": "Bir mesaj yazın...", - - #Pong-Game - "pongGamePageTittle": "Pong Oyunu", - "pongGameHeaderText": "Pong Lobisine Hoş Geldiniz", - "pongGameSubHeaderText": "Yapay Zeka ile oynayarak kendinizi geliştirebilir. Gerçek bir kişiyle oynamak istiyorsanız, diğer seçeneği düşünün; 5 dakika içinde eşleşecek birini bulamazsak, eşleşme iptal edilecektir. Unutmadan önce iyi şanslar!", - "pongGameAIButtonText": "Yapay Zeka Oyunu", - "pongGameLocalButtonText": "Yerel Oyun", - "pongGameRemoteButtonText": "Uzak Oyuncu", - "pongGameLocalTournamentButtonText": "Yerel Turnuva", - "pongGameTournamentButtonText": "Turnuva", - - #AI-Game - "aiGamePageTittle": "Pong Yapay Zeka Oyunu", - "aiGameReactionDelayText": "Tepki Gecikmesi", - "aiGameGetReadyText": "Hazir Ol", - "aiGameStartButtonText": "Başlat", - - "aiGameGameOverText": "Oyun Bitti", - "aiGameRestartButtonText": "Yeniden", - "aiGameExitButtonText": "Cikis", - - "aiGameInfoHeaderText": "Oyun Hakkında", - "aiGameInfoSubHeaderText": "Oyunu Nasıl Oynarım?", - "aiGameInfoSubHeaderDescription1": "Pong oyununda oyuncular rakiplerine karşı bir masa tenisi maçı yaparlar. W-S tuşları (veya yukarı-aşağı ok tuşları) topu kontrol etmek için kullanılır.", - "aiGameInfoSubHeaderText2": "Kazan ve Geliş", - "aiGameInfoSubHeaderDescription2": "Her oyun kazandığında Pong Puan kazanırsın. Bu puanlarla mağazadan yeni eşyalar, raket ve masalar satın alarak oyun deneyimini geliştirebilirsin.", - "aiGameInfoSubHeaderText3": "Hemen Başla", - "aiGameInfoSubHeaderDescription3": "Hesap oluşturarak oyun deneyimini kişiselleştirebilirsin. Bir hesapla istatistiklerini takip edebilir ve sıralamandaki yerini görebilirsin.", - "aiGameInfoSubHeaderText4": "Daha Fazlası", - "aiGameInfoSubHeaderDescription4": "Rakiplerinle yüzleşmek ve becerilerini test etmek icin turnuvalara katılabilirsin. Ayrıca arkadaşlarınla özel oyunlar oluşturabilir ve Pong topluluğuna katılabilirsin.", - - "aiGameInfoSubHeaderText5": "Kontroller", - "aiGameInfoSubHeaderDescription5": "Yukarı", - "aiGameInfoSubHeaderDescription6": "Aşağı", - "aiGameInfoSubHeaderText6": "Yetenekler", - "aiGameInfoSubHeaderDescription7": "Bir Hilekar Gibi", - "aiGameInfoSubHeaderDescription8": "Hızlı ve Öfkeli", - "aiGameInfoSubHeaderDescription9": "Dondurulmuş Top", - - #Local-Game - "localGamePageTittle": "Yerel Oyun", - "localGameHeaderText": "1v1 Yerel Oyun", - "localGamePlayer1Text": "1. Oyuncu Adı", - "localGamePlayer2Text": "2. Oyuncu Adı", - "localGameMaxScoreText": "Maksimum Skor", - "localGameGameModeText": "Oyun Modu", - "localGameChooseModeText1": "Klasik", - "localGameChooseModeText2": "Yetenekler", - "localGameButtonStart": "Başla", - - #Local-Tournament - "localTournamentPageTittle": "Yerel Turnuva", - "localTournamentGameHeaderText": "Yerel Turnuva", - "localTournamentPlayer1Text": "1. Oyuncu Adı", - "localTournamentPlayer2Text": "2. Oyuncu Adı", - "localTournamentPlayer3Text": "3. Oyuncu Adı", - "localTournamentPlayer4Text": "4. Oyuncu Adı", - "localTournamentMaxScoreText": "Maksimum Skor", - "localTournamentGameModeText": "Oyun Modu", - "localTournamentChooseModeText1": "Klasik", - "localTournamentChooseModeText2": "Yetenekler", - "localTournamentButtonStart": "Başlat & Eşleşme", - "localTournamentBracketTitle": "Turnuva Eşleşmesi", - "localTournamentBracketStartButtonText": "Turnuvayı Başlat", - "localTournamentTournamentOverText": "Turnuva Bitti", - "localTournamentOverButtonText": "Bitti", - - "localTournamentNextButtonText": "Sonraki", - - #Tournament - "tournamentPageTittle": "Turnuva", - "tournamentHeaderText": "Pong için Turnuva Lobisine Hoş Geldiniz", - "tournamentSubHeaderText": "Burada bir turnuva lobisine katılabilir veya kendi turnuva lobinizi oluşturabilirsiniz. Odanızı oluşturduktan sonra davet kodunu paylaşarak arkadaşlarınızı davet edebilirsiniz. Unutmadan önce iyi şanslar!", - "tournamentJoinButtonText": "Turnuvaya Katıl", - "tournamentCreateButtonText": "Turnuva Oluştur", - - #Tournament-Create - "tournamentCreatePageTittle": "Turnuva Oluştur", - "tournamentCreateHeaderText": "TURNUVA OLUŞTUR", - "tournamentCreateSubHeaderText": "Bir turnuva oluşturmak için bir turnuva adına ve her oyunun maksimum kaç puan alacağına ihtiyacım var. Unutmadan önce iyi şanslar!", - "tournamentCreateNameText": "Turnuva Adı", - "tournamentCreateMaxPointsText": "Oyun Başına Maksimum Skor", - "tournamentCreateGameModeText": "Oyun Modu", - "tournamentCreateChooseModeText1": "Klasik", - "tournamentCreateChooseModeText2": "Yetenekler", - "tournamentCreateButtonCreate": "Turnuva Oluştur", - - #Joined-Tournament-Room - "tournamentroomPageTittle": "Turnuva Odası", - "tournamentroomHeaderText": "Turnuva Odası", - "tournamentroomRoomText": "Oda", - "tournamentroomLeaveButtonText": "TURNUVADAN AYRIL", - "tournamentroomStartButtonText": "TURNUVAYI BAŞLAT", - "tournamentroomJoinButtonText": "TURNUVAYA KATIL", - "tournamentCheckBracketButtonText": "BRAKETI GÖRÜNTÜLE", - "tournamentOverWinnerGuyText": "turnuva bitti ve tahtın tek kişilik hakimi", - "tournamentOverLosersText": "turnuva bitti ve işte kaybedenler kulübü", - "tournamentroomTournamentRoomButton": "TURNUVA ODASI", - "tournamentroomWaitingText": "Bekleniyor,", - "tournamentroomForPlayerText": " oyuncu...", - - #Tournament Room List - "tournamentRoomListPageTittle": "Turnuva Odaları", - "tournamentRoomListHeaderText": "Turnuva Odaları", - - #Remote Pong Game - "remotePongGamePageTittle": "Pong Oyunu", - "remotePongGameTableName": "Ad", - "remotePongGameTableActions": "Eylemler", - "remotePongGameMatchmakingButtonText": "EŞLEŞME", - "remotePongGameLeaveButtonText": "AYRIL", - "remotePongGameStartText": "Başlamadan önce, oyun modunu seçebilirsin!", - "remotePongGameStartButtonText": "OYUNU BAŞLAT", - "remotePongSelectedMode": "Vanilya", - - - - #RPS Game - "rpsGamePageTittle": "Taş Kağıt Makas", - "rpsGameText1": "Taş Taş Kağıt Makas Lobisine Hoş Geldiniz", - "rpsGameText2": "Yapay Zeka ile oynayarak kendinizi geliştirebilir. Gerçek bir kişiyle oynamak istiyorsanız, diğer seçeneği düşünün; 5 dakika içinde eşleşecek birini bulamazsak, eşleşme iptal edilecektir. Unutmadan önce iyi şanslar!", - "rpsGameAIButtonText": "Yapay Zeka Oyunu", - "rpsGameLocalButtonText": "Yerel Oyun", - "rpsGameSearchOpponentButtonText": "Rakip Arayın ", - "rpsUserCountText": "şu anda eşleşme arayan kişi sayısı", - - #AI-Game - "rpsGamePageTittle": "RPS Yapay Zeka Oyunu", - "rpsGameScoreText": "skor", - "rpsGameRockText": "TAŞ", - "rpsGamePaperText": "KAĞIT", - "rpsGameScissorsText": "MAKAS", - "rpsGamePickedText": "seçtin", - "rpsGamePickedText2": "rakibin seçti", - "rpsGameAgainText": "tekrar oyna", - "rpsGameGameOverText": "Oyun Bitti", - "rpsGameRestartButtonText": "Yeniden", - "rpsGameExitButtonText": "Çıkış", - - - #Rankings - "rankingsPageTittle": "Sıralamalar", - "rankingsTableRankText": "Sıra", - "rankingsTableNameText": "Ad", - "rankingsTableUsernameText": "Kullanıcı Adı", - "rankingsTableWinsText": "Kazanmalar", - "rankingsTableLossesText": "Kayıplar", - "rankingsTableWinRateText": "Kazanma Yüzdesi", - "rankingsTablePongPointsText": "Pong Puanı", - - #Store - "storePageTittle": "Mağaza", - "storeText": "Mağaza", - "storeTagText": "Tümü", - "storeWalletText": "Cüzdan", - "storeWalleinfoText1": "Oyun oynayarak ", - "storeWalleinfoText2": " kazanabilirsin.", - - #Inventory - "inventoryPageTittle": "Envanter", - "inventoryText": "Envanter", - "inventoryTagText": "Tümü", - "inventoryWalletText": "Cüzdan", - "inventoryWalleinfoText1": "Oyun oynayarak ", - "inventoryWalleinfoText2": " kazanabilirsin.", - "inventoryModalHeaderText": "Öğeyi Ayarla", - "inventoryModalSaveButton": "Kaydet", - "inventoryModalCloseButton": "Kapat", - "inventoryItemKeyboardInfoText": "Yetenek kullanmak için", - "inventoryItemKeyboardInfoText2": "tuşunu kullan. Unutma, bu yeteneği kullanabilmek için kuşanmalısın.", - "inventoryItemKeyboardInfoText3": "Bu öğe için özel bir tuş takımı yok, otomatik olarak kullanılır.", - - - #Search - "searchPageTittle": "Arama", - "searchInputText": "E-posta, kullanıcı adı veya görünen ad ara...", - "searchMessageButtonText": "Mesaj Gönder", - "searchFollowButtonText": "Takip Et", - "searchFollowingButtonText": "Takipten Çık", - - - "searchNoResultFoundText": "Sonuç bulunamadı.", - - #Profile - "profilePageTittle": "Profili", - "profileRankAIText": "SADECE ROBOTUM", - "profileRankUserText1": " SIRALAMADA", - "profileRankUserText2": " SIRALAMA YOK", - "profileFollowButton": "Takip Et", - "profileFollowingButton": "Takipten Çık", - "profileTitleText1": "42 Kocaeli Öğrencisi", - "profileTitleText2": "Yazılım Geliştirici", - - "profileLinkedinSocialText": "LinkedIn Yok", - "profileGithubSocialText": "Github Yok", - "profileTwitterSocialText": "Twitter Yok", - "profileIntra42SocialText": "Intra42 Yok", - - "profileMatchHistoryText1": "Rakip", - "profileMatchHistoryText2": "Sonuç", - "profileMatchHistoryText3": "Puan", - "profileMatchHistoryText4": "Süre", - - "profileMatchHistoryWinText": "Kazandı", - "profileMatchHistoryLoseText": "Kaybetti", - - "profileRankText1": "Sıra", - "profileStatsText": "İstatistikler", - - "profileGameStats1": "Oynanan Oyunlar:", - "profileGameStats2": "Kazanmalar:", - "profileGameStats3": "Kayıplar:", - "profileGameStats4": "Kazanma Oranı:", - "profileGameStats5": "Kazanma Serisi:", - "profileGameStats6": "Ortalama Oyun Süresi:", - - #Friends - "friendsPageTittle": "Arkadaşlar", - "friendsMessageButtonText": "Mesaj Gönder", - "friendsNoResultFoundText": "Sonuç bulunamadı.", - - #ProfileSettings - "profileSettingsPageTittle": "Profil Ayarları", - "profileSettingsNavbar1": "Profili Düzenle", - "profileSettingsNavbar2": "Şifre Değişitr", - "profileSettingsNavbar3": "Sosyal Medya Ekle", - "profileSettingsNavbar4": "Engellenen Kullanıcılar", - "profileSettingsNavbar5": "Hesabı Kapat", - - #Edit-Profile - "editProfileChangeImageText": "Resmi Değiştir", - "editProfileUsernameText": "Kullanıcı Adı (sitenin diğer kullanıcıları tarafından nasıl görüneceği)", - "editProfileUsernameTimeText": "Kullanıcı adınızı her 7 günde bir değiştirebilirsiniz.", - "editProfileEmailText": "E-posta", - "editProfile42EmailText": "42 ile oturum açtığınız için e-posta ayarlama özelliği devre dışı bırakılmıştır.", - "editProfileDisplayNameText": "Görünen Ad", - "editProfileSaveButtonText": "Değişiklikleri Kaydet", - - #Change-Passwordg - "changePasswordCurrentPasswordText": "Mevcut Şifre", - "changePasswordNewPasswordText": "Yeni Şifre", - "changePasswordNewConfirmPasswordText": "Yeni Şifreyi Onayla", - "changePassword42Text": "42 ile oturum açtığınız için şifre ayarlama özelliği devre dışı bırakılmıştır.", - "changePasswordSaveButtonText": "Şifreyi Kaydet", - - #Add-Socials - "addSocialsLinkedinInputText": "LinkedIn kullanıcı adınızı girin", - "addSocialsTwitterInputText": "Twitter kullanıcı adınızı girin", - "addSocialsGithubInputText": "Github kullanıcı adınızı girin", - "addSocialsIntraInputText": "42 Intra kullanıcı adınızı girin", - "addSocialsSaveButtonText": "Sosyal Medyaları Kaydet", - - #Blocked-Users - "blockedUsersHeaderText": "Engellenen Hesaplar", - "blockedUsersSubHeaderText": "Burada engellediğiniz hesapları açabilirsiniz.", - "blockedStatusText": "Engellendi", - - #Close-Account - "closeAccountHeaderText": "Hesabı Kapat", - "closeAccountInputText": "E-posta", - "closeAccountSubHeaderText": "Burada hesabınızı silebilirsiniz. Bu işlem geri alınamaz.", - "closeAccountButton": "Hesabı Kapat", - - - } - return context - - -def get_lang_pt(): - context = { - #index - "basePageTittle": "Indian-Pong", - "baseHeaderText": "Indian-Pong", - "baseSubHeaderText": "A versão indiana do clássico jogo Pong", - "basePlayButtonText": "Vamos Comecar!", - - "baseInfoHeaderText": "Bem-vindo ao Indian-Pong!", - "baseInfoHeaderDescription": "Pong traz a emoção e a competição do tênis de mesa clássico para a internet. Nesta plataforma, você pode se divertir, mostrar suas habilidades e subir no ranking para se tornar um dos melhores.", - "baseInfoSubHeaderText": "Jogue e Ganhe", - "baseInfoSubHeaderDescription1": "Ganhe Pong Points a cada jogo que vencer para subir no ranking.", - "baseInfoSubHeaderDescription2": "Use seus ganhos para comprar novos itens, raquetes e mesas da loja para aprimorar sua experiência de jogo.", - "baseInfoSubHeaderText2": "Comece Agora", - "baseInfoSubHeaderDescription3": "Crie uma conta para personalizar seu perfil, acompanhar suas estatísticas e ver onde você está no ranking.", - "baseInfoSubHeaderText3": "Mais Recursos", - "baseInfoSubHeaderDescription4": "Participe de torneios para enfrentar seus oponentes.", - "baseInfoSubHeaderDescription5": "Divirta-se com seus amigos hospedando jogos privados.", - "baseInfoSubHeaderDescription6": "Converse com outros jogadores, compartilhe táticas e participe da comunidade Pong.", - - #Login - "loginPageTittle": "Iniciar sessão", - "loginHeaderText1": "Bem-vindo,", - "loginHeaderText2": "faca login para continuar", - "loginInputUsernameText": "Nome de Usuário", - "loginInputPasswordText": "Senha", - "loginForgotPasswordText": "Esqueceu a Senha?", - "loginButtonLogin": "Vamos lá", - "loginButtonJoin": "Junte-se", - - #404 - "notFoundPageTittle": "Página não encontrada", - "notFoundHeaderText": "404 ERRO", - "notFoundSubHeaderText": "Você provavelmente se perdeu em nosso site!", - "notFoundButtonText": "VENHA PARA CASA", - - #Signup - "signupPageTittle": "Inscreva-se", - "signupHeaderText1": "Bem-vindo,", - "signupHeaderText2": "inscreva-se para continuar", - "signupInputUsernameText": "Nome de Usuário", - "signupInputDisplayNameText": "Nome de Exibicão", - "signupInputEmailText": "E-mail", - "signupInputPasswordText": "Senha", - "signupInputConfirmPasswordText": "Senha (novamente)", - "signupImageUploadText": "Imagem", - "signupGdprText1": "Concordo ", - "signupGdprText2": "GDPR Política de Privacidade", - "signupButtonSignup": "Vamos!", - - #ForgotPassword - "forgotPasswordPageTittle": "Esqueceu a Senha", - "forgotPasswordHeaderText": "Esqueceu a Senha", - "forgotPasswordInputEmailText": "E-mail", - "forgotPasswordButtonSend": "Enviar E-mail", - "forgotPasswordLinkText": "Não tem uma conta?", - "forgotPasswordLinkButtonText": "Junte-se a Nós", - - #Password-Reset-Done - "passwordResetDonePageTittle": "Email Enviado", - "passwordResetDoneHeaderText": "EMAIL ENVIADO", - "passwordResetDoneSubHeaderText": "Enviamos o link de redefinição de senha para o seu e-mail. Por favor, verifique seu e-mail.", - "passwordResetButtonText": "VOLTAR AO LOGIN", - - #ChangePassword - "changePasswordPageTittle": "Mudar Senha", - "changePasswordHeaderText": "Mudar Senha", - "changePassswordSubHeaderText": "alterar a sua palavra-passe", - - - #Dashboard - "dashboardPageTittle": "Painel", - "dashboardText1": "Bem-vindo, ", - "dashboardText2": "O Indian Pong é um projeto colaborativo desenvolvido para a comunidade da escola 42, oferecendo uma experiência de jogo nostálgica através do clássico jogo Atari, Ping-Pong. Esta plataforma permite que os usuários participem de partidas de Ping-Pong uns com os outros, promovendo uma sensacão de competicão amigável. Além do aspecto de jogo, o Indian Pong oferece uma dimensão social, apresentando salas de bate-papo onde os usuários podem se comunicar e se conectar uns com os outros. A plataforma também permite que os usuários expandam sua rede adicionando amigos dentro da comunidade da escola 42. No geral, o Indian Pong combina a alegria dos jogos retrô com a interacão social moderna, criando uma experiência vibrante e interativa para a comunidade da escola 42.", - - "dashboardGamesPlayed": "Jogos Jogados", - "dashboardWinCount": "Contagem de Vitórias", - "dashboardWinStreak": "Sequência de Vitórias", - "dashboardLoseStreak": "Sequência de Derrotas", - "dashboardWinRate": "Taxa de Vitória", - "dashboardAverageGameDuration": "Duracão Média do Jogo", - "dashboardAveragePointsWon": "Pontos Médios Ganhos", - "dashboardAveragePointsLost": "Pontos Médios Perdidos", - - #Chat - "chatPageTittle": "Bate-papo", - "chatHeaderText": "Bate-papos", - "chatRecentlyText": "Recentemente", - "chatDMText": "Mensagens Diretas", - "chatContainerSelectText": "Selecione um bate-papo para começar a conversar", - "chatTodayText": "Hoje", - "chatTypeHereText": "Digite uma mensagem...", - - - #Pong-Game - "pongGamePageTittle": "Jogo de Pong", - "pongGameHeaderText": "Bem-vindo ao Lobby de Pong", - "pongGameSubHeaderText": "Podes melhorar o teu desempenho jogando com a Inteligência Artificial. Se quiseres jogar com uma pessoa real, considera a outra opção; se não encontrarmos alguém com quem jogar no espaço de 5 minutos, o jogo será cancelado. Boa sorte antes que nos esqueçamos!", - "pongGameAIButtonText": "Jogar com a IA", - "pongGameLocalButtonText": "Jogo Local", - "pongGameRemoteButtonText": "Jogador Remoto", - "pongGameLocalTournamentButtonText": "Locais Torneio", - "pongGameTournamentButtonText": "Torneio", - - #AI-Game - "aiGamePageTittle": "Jogo de Pong com a IA", - "aiGameReactionDelayText": "Atraso na Reacão", - "aiGameGetReadyText": "Prepare-se", - "aiGameStartButtonText":"Começar", - - "aiGameGameOverText": "Fim de Jogo", - "aiGameRestartButtonText": "Reiniciar", - "aiGameExitButtonText": "Sair", - - "aiGameInfoHeaderText": "Sobre o Jogo", - "aiGameInfoSubHeaderText": "Como Jogar o Jogo?", - "aiGameInfoSubHeaderDescription1": "No jogo Pong, os jogadores participam de uma partida de tênis de mesa contra seus oponentes. As teclas W-S (ou as setas cima-baixo) são usadas para controlar a bola.", - "aiGameInfoSubHeaderText2": "Ganhe e Melhore", - "aiGameInfoSubHeaderDescription2": "Você ganha Pong Points a cada jogo que vence. Com esses pontos, você pode comprar novos itens, raquetes e mesas da loja para aprimorar sua experiência de jogo.", - "aiGameInfoSubHeaderText3": "Comece Agora", - "aiGameInfoSubHeaderDescription3": "Você pode criar uma conta para personalizar sua experiência de jogo. Com uma conta, você pode acompanhar suas estatísticas e ver sua posição no ranking.", - "aiGameInfoSubHeaderText4": "Mais Recursos", - "aiGameInfoSubHeaderDescription4": "Você pode participar de torneios para enfrentar seus oponentes e testar suas habilidades. Além disso, você pode criar jogos privados com seus amigos e se juntar à comunidade Pong.", - - "aiGameInfoSubHeaderText5": "Controles", - "aiGameInfoSubHeaderDescription5": "Cima", - "aiGameInfoSubHeaderDescription6": "Baixo", - "aiGameInfoSubHeaderText6": "Habilidades", - "aiGameInfoSubHeaderDescription7": "Como um Trapaceiro", - "aiGameInfoSubHeaderDescription8": "Veloz e Furioso", - "aiGameInfoSubHeaderDescription9": "Bola Congelada", - - #Local-Game - "localGamePageTittle": "Jogo Local", - "localGameHeaderText": "Jogo Local 1v1", - "localGamePlayer1Text": "Nome do Jogador 1", - "localGamePlayer2Text": "Nome do Jogador 2", - "localGameMaxScoreText": "Pontuacão Máxima", - "localGameGameModeText": "Modo de Jogo", - "localGameChooseModeText1": "Vanilla", - "localGameChooseModeText2": "Habilidades", - "localGameButtonStart": "Iniciar", - - #Local-Tournament - "localTournamentPageTittle": "Torneio Local", - "localTournamentGameHeaderText": "Torneio Local", - "localTournamentPlayer1Text": "Nome do Jogador 1", - "localTournamentPlayer2Text": "Nome do Jogador 2", - "localTournamentPlayer3Text": "Nome do Jogador 3", - "localTournamentPlayer4Text": "Nome do Jogador 4", - "localTournamentMaxScoreText": "Pontuacão Máxima", - "localTournamentGameModeText": "Modo de Jogo", - "localTournamentChooseModeText1": "Vanilla", - "localTournamentChooseModeText2": "Habilidades", - "localTournamentButtonStart": "Iniciar & Empar.", - "localTournamentBracketTitle": "Empar. Torneio", - "localTournamentBracketStartButtonText": "Iniciar Torneio", - "localTournamentTournamentOverText": "Torneio Terminado", - "localTournamentOverButtonText": "Terminado", - - "localTournamentNextButtonText": "Próximo", - - #Tournament - "tournamentPageTittle": "Torneio", - "tournamentHeaderText": "Bem-vindo ao Lobby do Torneio de Pong", - "tournamentSubHeaderText": "Aqui você pode entrar em um lobby de torneio ou criar seu próprio lobby de torneio. Você pode convidar seus amigos compartilhando o código de convite após criar a sala. Boa sorte antes que eu esqueca!", - "tournamentJoinButtonText": "Entrar no Torneio", - "tournamentCreateButtonText": "Criar Torneio", - - #Tournament-Create - "tournamentCreatePageTittle": "Criar Torneio", - "tournamentCreateHeaderText": "CRIAR TORNEIO", - "tournamentCreateSubHeaderText": "Para criar um torneio, eu preciso de um nome de torneio, quantos pontos máximos cada jogo terá. Boa sorte antes que eu esqueca!", - "tournamentCreateNameText": "Nome do Torneio", - "tournamentCreateMaxPointsText": "Pontuacão Máxima dos Jogos", - "tournamentCreateGameModeText": "Modo de Jogo", - "tournamentCreateChooseModeText1": "Vanilla", - "tournamentCreateChooseModeText2": "Habilidades", - "tournamentCreateButtonCreate": "Criar Torneio", - - #Joined-Tournament-Room - "tournamentroomPageTittle": "Sala de Torneio", - "tournamentroomHeaderText": "Sala de Torneio", - "tournamentroomRoomText": "Sala", - "tournamentroomLeaveButtonText": "SAIR DO TORNEIO", - "tournamentroomStartButtonText": "INICIAR TORNEIO", - "tournamentroomJoinButtonText": "ENTRAR NO TORNEIO", - "tournamentCheckBracketButtonText": "VER BRACKET", - "tournamentOverWinnerGuyText": "o torneio acabou e o rei da mesa é", - "tournamentOverLosersText": "o torneio acabou e aqui está o clube dos perdedores", - "tournamentroomTournamentRoomButton": "SALA DE TORNEIO", - "tournamentroomWaitingText": "Aguardando,", - "tournamentroomForPlayerText": "jogadores...", - - #Tournament Room List - "tournamentRoomListPageTittle": "Salas de Torneio", - "tournamentRoomListHeaderText": "Salas de Torneio", - - #Remote Pong Game - "remotePongGamePageTittle": "Jogo de Pong", - "remotePongGameTableName": "Nome", - "remotePongGameTableActions": "Ações", - "remotePongGameMatchmakingButtonText": "MATCHMAKING", - "remotePongGameLeaveButtonText": "SAIR", - "remotePongGameStartText": "Antes de começar, você pode escolher o modo de jogo!", - "remotePongGameStartButtonText": "INICIAR JOGO", - "remotePongSelectedMode": "Vanilla", - - #RPS Game - "rpsGamePageTittle": "Pedra, Papel e Tesoura", - "rpsGameText1": "Bem-vindo ao Lobby de Pedra, Papel e Tesoura", - "rpsGameText2": "Podes melhorar o teu desempenho jogando com a Inteligência Artificial. Se quiseres jogar com uma pessoa real, considera a outra opção; se não encontrarmos alguém com quem jogar no espaço de 5 minutos, o jogo será cancelado. Boa sorte antes que nos esqueçamos!", - "rpsGameAIButtonText": "Jogar com a IA", - "rpsGameLocalButtonText": "Jogo Local", - "rpsGameSearchOpponentButtonText": "Buscar Oponente ", - "rpsUserCountText": "Jogadores Online", - - #AI-Game - "rpsGamePageTittle": "Jogo de Pedra, Papel e Tesoura com Inteligência Artificial", - "rpsGameScoreText": "pontuação", - "rpsGameRockText": "PEDRA", - "rpsGamePaperText": "PAPEL", - "rpsGameScissorsText": "TESOURA", - "rpsGamePickedText": "escolheste", - "rpsGamePickedText2": "o adversário escolheu", - "rpsGameAgainText": "jogar novamente", - "rpsGameGameOverText": "Jogo Terminado", - "rpsGameRestartButtonText": "Reiniciar", - "rpsGameExitButtonText": "Sair", - - #Rankings - "rankingsPageTittle": "Classificacão", - "rankingsTableRankText": "Classificacão", - "rankingsTableNameText": "Nome", - "rankingsTableUsernameText": "Nome de Usuário", - "rankingsTableWinsText": "Vitórias", - "rankingsTableLossesText": "Derrotas", - "rankingsTableWinRateText": "Taxa de Vitória", - "rankingsTablePongPointsText": "Pontos Pong", - - #Store - "storePageTittle": "Loja", - "storeText": "Loja", - "storeTagText": "Tudo", - "storeWalletText": "Carteira", - "storeWalleinfoText1": "Você pode ganhar ", - "storeWalleinfoText2": " jogando.", - - #Inventory - "inventoryPageTittle": "Inventário", - "inventoryText": "Inventário", - "inventoryTagText": "Tudo", - "inventoryWalletText": "Carteira", - "inventoryWalleinfoText1": "Você pode ganhar ", - "inventoryWalleinfoText2": " jogando.", - "inventoryModalHeaderText": "Definir Item", - "inventoryModalSaveButton": "Salvar", - "inventoryModalCloseButton": "Fechar", - "inventoryItemKeyboardInfoText": "Use a tecla", - "inventoryItemKeyboardInfoText2": "para usar essa habilidade. E lembre-se, você deve equipar essa habilidade.", - "inventoryItemKeyboardInfoText3": "Este item não tem um teclado personalizado, é usado automaticamente.", - - - #Search - "searchPageTittle": "Procurar", - "searchInputText": "Procurar por e-mail, nome de usuário ou nome de exibicão...", - "searchMessageButtonText": "Mensagem", - "searchFollowButtonText": "Seguir", - "searchFollowingButtonText": "Deixar", - "searchNoResultFoundText": "Nenhum resultado encontrado.", - - #Profile - "profilePageTittle": "Perfil", - "profileRankAIText": "APENAS ROBÔ", - "profileRankUserText1": " RANKING", - "profileRankUserText2": " SEM RANKING", - "profileFollowButton": "Seguir", - "profileFollowingButton": "Deixar", - "profileTitleText1": "Estudante da 42 Kocaeli", - "profileTitleText2": "Desenvolvedor de Software", - - "profileLinkedinSocialText": "Sem LinkedIn", - "profileGithubSocialText": "Sem Github", - "profileTwitterSocialText": "Sem Twitter", - "profileIntra42SocialText": "Sem Intra42", - - "profileMatchHistoryText1": "Oponente", - "profileMatchHistoryText2": "Resultado", - "profileMatchHistoryText3": "Pontos", - "profileMatchHistoryText4": "Tempo", - - "profileMatchHistoryWinText": "Venceu", - "profileMatchHistoryLoseText": "Perdeu", - - "profileRankText1": "Classificacão", - "profileStatsText": "Estatísticas", - - "profileGameStats1": "Jogos Jogados:", - "profileGameStats2": "Vitórias:", - "profileGameStats3": "Derrotas:", - "profileGameStats4": "Taxa de Vitória:", - "profileGameStats5": "Sequência de Vitórias:", - "profileGameStats6": "Duração Média do Jogo:", - - #Friends - "friendsPageTittle": "Amigos", - "friendsMessageButtonText": "Mensagem", - "friendsNoResultFoundText": "Nenhum resultado encontrado.", - - #ProfileSettings - "profileSettingsPageTittle": "Configurações do Perfil", - "profileSettingsNavbar1": "Editar Perfil", - "profileSettingsNavbar2": "Alterar Senha", - "profileSettingsNavbar3": "Adicionar Redes Sociais", - "profileSettingsNavbar4": "Usuários Bloqueados", - "profileSettingsNavbar5": "Fechar Conta", - - #Edit-Profile - "editProfileChangeImageText": "Alterar Imagem", - "editProfileUsernameText": "Nome de usuário (como seu nome aparecerá para outros usuários no site)", - "editProfileUsernameTimeText": "Você pode alterar seu nome de usuário a cada 7 dias.", - "editProfileEmailText": "Email", - "editProfile42EmailText": "Como você está logado com 42, o recurso de configuração de e-mail está desativado.", - "editProfileDisplayNameText": "Nome de Exibição", - "editProfileSaveButtonText": "Salvar Alterações", - - #Change-Password - "changePasswordCurrentPasswordText": "Senha Atual", - "changePasswordNewPasswordText": "Nova Senha", - "changePasswordNewConfirmPasswordText": "Confirmar Nova Senha", - "changePassword42Text": "Como você está logado com 42, o recurso de configuração de senha está desativado.", - "changePasswordSaveButtonText": "Salvar Senha", - - #Add-Socials - "addSocialsLinkedinInputText": "Insira seu nome de usuário do LinkedIn", - "addSocialsTwitterInputText": "Insira seu nome de usuário do Twitter", - "addSocialsGithubInputText": "Insira seu nome de usuário do Github", - "addSocialsIntraInputText": "Insira seu nome de usuário do 42 Intra", - "addSocialsSaveButtonText": "Salvar Redes Sociais", - - #Blocked-Users - "blockedUsersHeaderText": "Contas Bloqueadas", - "blockedUsersSubHeaderText": "Você pode desbloquear as contas que bloqueou aqui.", - "blockedStatusText": "Bloqueado", - - - #Close-Account - "closeAccountHeaderText": "Fechar Conta", - "closeAccountInputText": "E-mail", - "closeAccountSubHeaderText": "Você pode excluir sua conta aqui. Esta ação é irreversível.", - "closeAccountButton": "Fechar Conta", - } - return context - -def get_lang_hi(): - context = { - #index - "basePageTittle": "इंडियन-पॉन्ग", - "baseHeaderText": "इंडियन-पॉन्ग", - "baseSubHeaderText": "प्रसिद्ध खेल पॉन्ग का भारतीय संस्करण", - "basePlayButtonText": "शुरू करें!", - - "baseInfoHeaderText": "इंडियन-पॉन्ग में आपका स्वागत है!", - "baseInfoHeaderDescription": "पॉन्ग इंटरनेट पर क्लासिक टेबल टेनिस खेल के उत्साह और प्रतिस्पर्धा को लाता है। इस प्लेटफ़ॉर्म पर आप मजा कर सकते हैं, अपने कौशल का परिचय दे सकते हैं और शीर्ष में आने के लिए रैंकिंग में चढ़ सकते हैं।", - "baseInfoSubHeaderText": "खेलें और जीतें", - "baseInfoSubHeaderDescription1": "जीतने पर प्रत्येक खेल से पॉन्ग पॉइंट्स कमाकर रैंकिंग में चढ़ें।", - "baseInfoSubHeaderDescription2": "अपनी जीत से नए आइटम, रैकेट और टेबल्स खरीदने के लिए दुकान से खर्च करें।", - "baseInfoSubHeaderText2": "अभी शुरू करें", - "baseInfoSubHeaderDescription3": "प्रोफ़ाइल को व्यक्तिगत बनाने, अपने स्टैटिस्टिक्स को ट्रैक करने और रैंकिंग में अपनी जगह देखने के लिए खाता बनाएं।", - "baseInfoSubHeaderText3": "अधिक सुविधाएं", - "baseInfoSubHeaderDescription4": "अपने प्रतिद्वंद्वियों के साथ टूर्नामेंट में भाग लेने के लिए।", - "baseInfoSubHeaderDescription5": "अपने दोस्तों के साथ निजी खेल खेलकर मजा करें।", - "baseInfoSubHeaderDescription6": "अन्य खिलाड़ियों के साथ चैट करें, रणनीतियाँ साझा करें और पॉन्ग समुदाय में शामिल हों।", - - #Login - "loginPageTittle": "लॉग इन करें", - "loginHeaderText1": "स्वागत है,", - "loginHeaderText2": "जारी रखने के लिए साइन इन करें", - "loginInputUsernameText": "उपयोगकर्ता नाम", - "loginInputPasswordText": "पासवर्ड", - "loginForgotPasswordText": "पासवर्ड भूल गए?", - "loginButtonLogin": "चलो चलते हैं", - "loginButtonJoin": "हमारे साथ", - - #404 - "notFoundPageTittle": "पृष्ठ नहीं मिला", - "notFoundHeaderText": "404 त्रुटि", - "notFoundSubHeaderText": "आप शायद हमारी वेबसाइट में खो गए हैं!", - "notFoundButtonText": "घर वापस जाओ", - - #Signup - "signupPageTittle": "साइन अप करें", - "signupHeaderText1": "स्वागत है,", - "signupHeaderText2": "जारी रखने के लिए साइन अप करें", - "signupInputUsernameText": "उपयोगकर्ता नाम", - "signupInputDisplayNameText": "डिस्प्ले नाम", - "signupInputEmailText": "ईमेल", - "signupInputPasswordText": "पासवर्ड", - "signupInputConfirmPasswordText": "पासवर्ड (फिर से)", - "signupImageUploadText": "छवि अपलोड करें", - "signupGdprText1": "मैं सहमत हूं", - "signupGdprText2": "GDPR गोपनीयता नीति", - "signupButtonSignup": "चमकाओ!", - - #ForgotPassword - "forgotPasswordPageTittle": "पासवर्ड भूल गए", - "forgotPasswordHeaderText": "पासवर्ड भूल गए", - "forgotPasswordInputEmailText": "ईमेल", - "forgotPasswordButtonSend": "ईमेल भेजें", - "forgotPasswordLinkText": "खाता नहीं है?", - "forgotPasswordLinkButtonText": "हमारे साथ शामिल हों", - - #Password-Reset-Done - "passwordResetDonePageTittle": "ईमेल भेजा गया", - "passwordResetDoneHeaderText": "ईमेल भेजा गया", - "passwordResetDoneSubHeaderText": "हमने आपके ईमेल पर पासवर्ड रीसेट लिंक भेज दिया है। कृपया अपने ईमेल की जाँच करें।", - "passwordResetButtonText": "ईमेल भेजा गया", - - #ChangePassword - "changePasswordPageTittle": "पासवर्ड बदलें", - "changePasswordHeaderText": "पासवर्ड बदलें", - "changePassswordSubHeaderText": "अपना पासवर्ड बदलें", - - - #Dashboard - "dashboardPageTittle": "डैशबोर्ड", - "dashboardText1": "स्वागत, ", - "dashboardText2": "इंडियन पॉन्ग एक सहयोगी परियोजना है जो 42 स्कूल समुदाय के लिए विकसित की गई है, जो शास्त्रीय खेल पिंग-पोंग के माध्यम से नोस्टाल्जिक गेमिंग अनुभव प्रदान करता है। यह प्लेटफ़ॉर्म प्रतिद्वंद्वियों के साथ पिंग-पोंग मैच खेलने की अनुमति देता है, जो एक दूसरे के साथ दोस्ताना प्रतिस्पर्धा का मूल्यांकन करता है। खेल के पहले पहल में, इंडियन पॉन्ग को सामाजिक आयाम प्रदान करता है, जिसमें उपयोगकर्ताओं को एक-दूसरे के साथ संवाद करने और जुड़ने का अवसर प्रदान किया जाता है। प्लेटफ़ॉर्म उपयोगकर्ताओं को 42 स्कूल समुदाय के भीतर दोस्तों को जोड़ने की सुविधा भी प्रदान करता है। समग्र रूप में, इंडियन पॉन्ग पुराने गेमिंग का आनंद और आधुनिक सामाजिक आक्रोश जोड़ते हैं, 42 स्कूल समुदाय के लिए एक जीवंत और अंतर्क्रियात्मक अनुभव बनाते हैं।", - - "dashboardGamesPlayed": "खेल खेले गए", - "dashboardWinCount": "जीत की गई बार", - "dashboardWinStreak": "जीत की रेकार्ड", - "dashboardLoseStreak": "हार की रेकार्ड", - "dashboardWinRate": "जीतने की दर", - "dashboardAverageGameDuration": "औसत खेल की अवधि", - "dashboardAveragePointsWon": "औसत अंक जीते", - "dashboardAveragePointsLost": "औसत अंक हारे", - - #Chat - "chatPageTittle": "चैट", - "chatHeaderText": "चैट", - "chatRecentlyText": "हाल ही में", - "chatDMText": "डायरेक्ट मैसेज", - "chatContainerSelectText": "चैट शुरू करने के लिए एक चैट चुनें", - "chatTodayText": "आज", - "chatTypeHereText": "एक संदेश लिखें...", - - - #Pong-Game - "pongGamePageTittle": "पॉन्ग खेल", - "pongGameHeaderText": "पॉन्ग लॉबी में आपका स्वागत है", - "pongGameSubHeaderText": "आप आर्टिफिशियल इंटेलिजेंस के साथ खेलकर खुद को बेहतर बना सकते हैं। यदि आप किसी वास्तविक व्यक्ति के साथ खेलना चाहते हैं, तो दूसरे विकल्प पर विचार करें; यदि हमें 5 मिनट के भीतर मैच के लिए कोई नहीं मिल सका, तो मैच रद्द कर दिया जाएगा। इससे पहले कि मैं भूल जाऊँ, शुभकामनाएँ!", - "pongGameAIButtonText": "ए.आई. के साथ खेलें", - "pongGameLocalButtonText": "स्थानीय खेल", - "pongGameRemoteButtonText": "दूरस्थ खिलाड़ी", - "pongGameLocalTournamentButtonText": "स्थानीय टूर्नामेंट", - "pongGameTournamentButtonText": "टूर्नामेंट", - - #AI-Game - "aiGamePageTittle": "ए.आई. के साथ पॉन्ग खेल", - "aiGameReactionDelayText": "प्रतिक्रिया में देरी", - "aiGameGetReadyText": "तैयार हो जाओ", - "aiGameStartButtonText": "शुरू करें", - - "aiGameGameOverText": "खेल समाप्त हो गया", - "aiGameRestartButtonText": "पुनः आरंभ", - "aiGameExitButtonText": "निकास", - - "aiGameInfoHeaderText": "खेल के बारे में", - "aiGameInfoSubHeaderText": "खेल कैसे खेलें?", - "aiGameInfoSubHeaderDescription1": "पॉन्ग खेल में खिलाड़ी अपने प्रतिद्वंद्वी के खिलाफ एक टेनिस की मैच खेलते हैं। W-S (या ऊपर-नीचे तीर) तीरों को नियंत्रित करने के लिए उपयोग किया जाता है।", - "aiGameInfoSubHeaderText2": "जीतें और सुधारें", - "aiGameInfoSubHeaderDescription2": "आप हर जीते खेल के बाद पॉन्ग पॉइंट्स कमाते हैं। इन पॉइंट्स के साथ आप खेल का अनुभव बेहतर बनाने के लिए दुकान से नए आइटम, रैकेट और टेबल खरीद सकते हैं।", - "aiGameInfoSubHeaderText3": "अभी शुरू करें", - "aiGameInfoSubHeaderDescription3": "आप अपने खेल का अनुभव व्यक्तिगत करने के लिए एक खाता बना सकते हैं। एक खाते के साथ, आप अपने स्टैटिस्टिक्स को ट्रैक कर सकते हैं और रैंकिंग में अपनी जगह देख सकते हैं।", - "aiGameInfoSubHeaderText4": "अधिक सुविधाएं", - "aiGameInfoSubHeaderDescription4": "आप अपने प्रतिद्वंद्वियों के साथ टूर्नामेंट में भाग लेने के लिए और अपने कौशल का परीक्षण करने के लिए टूर्नामेंट में भाग ले सकते हैं। इसके अलावा, आप अपने दोस्तों के साथ निजी खेल बना सकते हैं और पॉन्ग समुदाय में शामिल हो सकते हैं।", - - "aiGameInfoSubHeaderText5": "नियंत्रण", - "aiGameInfoSubHeaderDescription5": "ऊपर", - "aiGameInfoSubHeaderDescription6": "नीचे", - "aiGameInfoSubHeaderText6": "कौशल", - "aiGameInfoSubHeaderDescription7": "जैसे एक धोखेबाज", - "aiGameInfoSubHeaderDescription8": "तेज और उत्तेजित", - "aiGameInfoSubHeaderDescription9": "जमीन गेंद", - - #Local-Game - "localGamePageTittle": "स्थानीय खेल", - "localGameHeaderText": "1v1 स्थानीय खेल", - "localGamePlayer1Text": "प्लेयर1 नाम", - "localGamePlayer2Text": "प्लेयर2 नाम", - "localGameMaxScoreText": "अधिकतम स्कोर", - "localGameGameModeText": "खेल मोड", - "localGameChooseModeText1": "वनिला", - "localGameChooseModeText2": "क्षमताएँ", - "localGameButtonStart": "प्रारंभ करें", - - #Local-Tournament - "localTournamentPageTittle": "स्थानीय टूर्नामेंट", - "localTournamentGameHeaderText": "स्थानीय टूर्नामेंट", - "localTournamentPlayer1Text": "1. खिलाड़ी नाम", - "localTournamentPlayer2Text": "2. खिलाड़ी नाम", - "localTournamentPlayer3Text": "3. खिलाड़ी नाम", - "localTournamentPlayer4Text": "4. खिलाड़ी नाम", - "localTournamentMaxScoreText": "अधिकतम स्कोर", - "localTournamentGameModeText": "खेल मोड", - "localTournamentChooseModeText1": "वनिला", - "localTournamentChooseModeText2": "क्षमताएँ", - "localTournamentButtonStart": "टूर्नामेंट शुरू करें", - "localTournamentBracketTitle": "ब्रैकेट", - "localTournamentBracketStartButtonText": "टूर्नामेंट शुरू करें", - "localTournamentTournamentOverText": "टूर्नामेंट खत्म हो गया", - "localTournamentOverButtonText": "खत्म करें", - - - "localTournamentNextButtonText": "अगला", - - #Tournament - "tournamentPageTittle": "टूर्नामेंट", - "tournamentHeaderText": "पॉन्ग के टूर्नामेंट लॉबी में आपका स्वागत है", - "tournamentSubHeaderText": "यहां आप एक टूर्नामेंट लॉबी में शामिल हो सकते हैं या अपनी खुद की टूर्नामेंट लॉबी बना सकते हैं। आप अपने दोस्तों को रुम बनाने के बाद इनवाइट कोड साझा करके इन्वाइट कर सकते हैं। भूलने से पहले शुभकामनाएं!", - "tournamentJoinButtonText": "टूर्नामेंट में शामिल हों", - "tournamentCreateButtonText": "टूर्नामेंट बनाएं", - - #Tournament-Create - "tournamentCreatePageTittle": "टूर्नामेंट बनाएं", - "tournamentCreateHeaderText": "टूर्नामेंट बनाएं", - "tournamentCreateSubHeaderText": "एक टूर्नामेंट बनाने के लिए मुझे एक टूर्नामेंट का नाम, हर खेल के लिए कितना अधिकतम स्कोर होगा। भूलने से पहले शुभकामनाएं!", - "tournamentCreateNameText": "टूर्नामेंट का नाम", - "tournamentCreateMaxPointsText": "अधिकतम स्कोर खेलें", - "tournamentCreateGameModeText": "खेल मोड", - "tournamentCreateChooseModeText1": "वनिला", - "tournamentCreateChooseModeText2": "क्षमताएँ", - "tournamentCreateButtonCreate": "टूर्नामेंट बनाएं", - - #Joined-Tournament-Room - "tournamentroomPageTittle": "टूर्नामेंट रूम", - "tournamentroomHeaderText": "टूर्नामेंट रूम", - "tournamentroomLeaveButtonText": "छोड़ें", - "tournamentroomRoomText": "रूम", - "tournamentroomStartButtonText": "शुरू करें", - "tournamentroomJoinButtonText": "शामिल हों", - "tournamentCheckBracketButtonText": "ब्रैकेट देखें", - "tournamentOverWinnerGuyText": "विजेता", - "tournamentOverLosersText": "हारने वाले", - "tournamentroomTournamentRoomButton": "टूर्नामेंट रूम", - "tournamentroomWaitingText": "इंतजार कर", - "tournamentroomForPlayerText": "खिलाड़ी ", - - #Tournament Room List - "tournamentRoomListPageTittle": "टूर्नामेंट रूम सूची", - "tournamentRoomListHeaderText": "टूर्नामेंट रूम सूची", - - #Remote Pong Game - "remotePongGamePageTittle": "दूरस्थ पॉन्ग खेल", - "remotePongGameTableName": "नाम", - "remotePongGameTableActions": "कार्रवाई", - "remotePongGameMatchmakingButtonText": "मैचमेकिंग", - "remotePongGameLeaveButtonText": "छोड़ें", - "remotePongGameStartText": "शुरू करें", - "remotePongGameStartButtonText": "शुरू करें", - "remotePongSelectedMode": "चयनित मोड", - - - - #RPS Game - "rpsGamePageTittle": "रॉक-पेपर-सैंड खेल", - "rpsGameText1": "रॉक-पेपर-सैंड लॉबी में आपका स्वागत है", - "rpsGameText2": "आप आर्टिफिशियल इंटेलिजेंस के साथ खेलकर खुद को बेहतर बना सकते हैं। यदि आप किसी वास्तविक व्यक्ति के साथ खेलना चाहते हैं, तो दूसरे विकल्प पर विचार करें; यदि हमें 5 मिनट के भीतर मैच के लिए कोई नहीं मिल सका, तो मैच रद्द कर दिया जाएगा। इससे पहले कि मैं भूल जाऊँ, शुभकामनाएँ!", - "rpsGameAIButtonText": "ए.आई. के साथ खेलें", - "rpsGameLocalButtonText": "स्थानीय खेल", - "rpsGameSearchOpponentButtonText": "विरोधी खोजें ", - "rpsUserCountText": "उपयोगकर्ता", - #AI-Game - "rpsGamePageTittle": "रॉक कागज कैंची आर्टिफिशियल इंटेलिजेंस गेम", - "rpsGameScoreText": "स्कोर", - "rpsGameRockText": "पत्थर", - "rpsGamePaperText": "कागज", - "rpsGameScissorsText": "कैंची", - "rpsGamePickedText": "तुमने चुना", - "rpsGamePickedText2": "विरोधी चुना", - "rpsGameAgainText": "फिर से खेलें", - "rpsGameGameOverText": "खेल समाप्त", - "rpsGameRestartButtonText": "फिर से शुरू करें", - "rpsGameExitButtonText": "बाहर जाएं", - - - #Rankings - "rankingsPageTittle": "रैंकिंग", - "rankingsTableRankText": "रैंक", - "rankingsTableNameText": "नाम", - "rankingsTableUsernameText": "उपयोगकर्ता नाम", - "rankingsTableWinsText": "जीतें", - "rankingsTableLossesText": "हारें", - "rankingsTableWinRateText": "जीतने की दर", - "rankingsTablePongPointsText": "पॉन्ग अंक", - - #Store - "storePageTittle": "दुकान", - "storeText": "दुकान", - "storeTagText": "सभी", - "storeWalletText": "वॉलेट", - "storeWalleinfoText1": "खेल खेलकर ", - "storeWalleinfoText2": " जीत सकते हैं।", - - #Inventory - "inventoryPageTittle": "इन्वेंटरी", - "inventoryText": "इन्वेंटरी", - "inventoryTagText": "सभी", - "inventoryWalletText": "वॉलेट", - "inventoryWalleinfoText1": "खेल खेलकर ", - "inventoryWalleinfoText2": " जीत सकते हैं।", - "inventoryModalHeaderText": "आइटम खरीदें", - "inventoryModalSaveButton": "खरीदें", - "inventoryModalCloseButton": "बंद करें", - "inventoryItemKeyboardInfoText": "उपयोग", - "inventoryItemKeyboardInfoText2": "इस आइटम के लिए कोई विशेष कीपैड नहीं है, यह स्वचालित रूप से उपयोग किया जाता है।", - "inventoryItemKeyboardInfoText3": "इस आइटम के लिए कोई विशेष कीपैड नहीं है, यह स्वचालित रूप से उपयोग किया जाता है।", - - - #Search - "searchPageTittle": "खोजें", - "searchInputText": "ईमेल या उपयोगकर्ता नाम या डिस्प्ले नाम खोजें...", - "searchMessageButtonText": "संदेश", - "searchFollowButtonText": "अनुसरण करना", - "searchFollowingButtonText": "अनफ़ॉलो", - "searchNoResultFoundText": "कोई परिणाम नहीं मिला।", - - #Profile - "profilePageTittle": "प्रोफ़ाइल", - "profileRankAIText": "ए.आई. रैंक", - "profileRankUserText1": " उपयोगकर्ता रैंक", - "profileRankUserText2": " रैंक", - "profileFollowButton": "अनुसरण करना", - "profileFollowingButton": "अनफ़ॉलो", - "profileTitleText1": "42 स्कूल समुदाय", - "profileTitleText2": "पॉन्ग खिलाड़ी", - - "profileLinkedinSocialText": "कोई लिंक्डइन नहीं", - "profileTwitterSocialText": "कोई ट्विटर नहीं", - "profileGithubSocialText": "कोई गिटहब नहीं", - "profileIntra42SocialText": "कोई इंट्रा नहीं", - - "profileMatchHistoryText1": "प्रतिद्वंद्वी", - "profileMatchHistoryText2": "परिणाम", - "profileMatchHistoryText3": "अंक", - "profileMatchHistoryText4": "अवधि", - - "profileMatchHistoryWinText": "जीता", - "profileMatchHistoryLoseText": "हारा", - - "profileRankText1": "रैंक", - "profileStatsText": "आंकड़े", - - "profileGameStats1": "खेल खेले गए:", - "profileGameStats2": "जीतें:", - "profileGameStats3": "हारें:", - "profileGameStats4": "जीतने की दर:", - "profileGameStats5": "औसत अंक जीते:", - "profileGameStats6": "औसत अंक हारे:", - - #Friends - "friendsPageTittle": "मित्र", - "friendsMessageButtonText": "संदेश", - "friendsNoResultFoundText": "कोई परिणाम नहीं मिला।", - - - #ProfileSettings - "profileSettingsPageTittle": "प्रोफ़ाइल सेटिंग्स", - "profileSettingsNavbar1": "प्रोफ़ाइल संपादित करें", - "profileSettingsNavbar2": "पासवर्ड बदलें", - "profileSettingsNavbar3": "सोशल्स जोड़ें", - "profileSettingsNavbar4": "अवरुद्ध उपयोगकर्ता", - "profileSettingsNavbar5": "खाता बंद करें", - - #Edit-Profile - "editProfileChangeImageText": "छवि बदलें", - "editProfileUsernameText": "उपयोगकर्ता नाम (आपका नाम साइट पर अन्य उपयोगकर्ताओं के लिए कैसे दिखाई देगा)", - "editProfileUsernameTimeText": "आप अपना उपयोगकर्ता नाम एक बार बदल सकते हैं।", - "editProfileEmailText": "ईमेल", - "editProfile42EmailText": "चूंकि आप 42 के साथ लॉग इन हैं, आपकी ईमेल सेटिंग सुविधा अक्षम है।", - "editProfileDisplayNameText": "प्रदर्शन नाम", - "editProfileSaveButtonText": "परिवर्तन सहेजें", - - #Change-Password - "changePasswordCurrentPasswordText": "वर्तमान पासवर्ड", - "changePasswordNewPasswordText": "नया पासवर्ड", - "changePasswordNewConfirmPasswordText": "नया पासवर्ड पुष्टि करें", - "changePassword42Text": "चूंकि आप 42 के साथ लॉग इन हैं, आपकी पासवर्ड सेटिंग सुविधा अक्षम है।", - "changePasswordSaveButtonText": "पासवर्ड सहेजें", - - #Add-Socials - "addSocialsLinkedinInputText": "अपना LinkedIn उपयोगकर्ता नाम दर्ज करें", - "addSocialsTwitterInputText": "अपना Twitter उपयोगकर्ता नाम दर्ज करें", - "addSocialsGithubInputText": "अपना Github उपयोगकर्ता नाम दर्ज करें", - "addSocialsIntraInputText": "अपना 42 Intra उपयोगकर्ता नाम दर्ज करें", - "addSocialsSaveButtonText": "सोशल्स सहेजें", - - #Blocked-Users - "blockedUsersHeaderText": "अवरुद्ध खाते", - "blockedUsersSubHeaderText": "आप यहां अपने द्वारा अवरुद्ध किए गए खातों को अनवरोधित कर सकते हैं।", - "blockedStatusText": "अवरुद्ध", - - #Close-Account - "closeAccountHeaderText": "खाता बंद करें", - "closeAccountInputText": "ईमेल", - "closeAccountSubHeaderText": "आप यहां अपना खाता हटा सकते हैं। यह कार्रवाई अपरिवर्तनीय है।", - "closeAccountButton": "खाता बंद करें", - - } +def get_langs(lang): + if lang == "en": + return get_lang_en() + if lang == "hi": + return get_lang_hi() + if lang == "tr": + return get_lang_tr() + if lang == "pt": + return get_lang_pt() + + +def get_lang_en(): + context = { + #index + "basePageTittle": "Indian-Pong", + "baseHeaderText": "Indian-Pong", + "baseSubHeaderText": "Indian-Pong created for 42 school by Indian Dev!", + "basePlayButtonText": "Get Started!", + + "baseInfoHeaderText": "Welcome to Indian-Pong!", + "baseInfoHeaderDescription": "Pong brings the excitement and competition of classic table tennis to the internet. On this platform, you can have fun, showcase your skills, and rise in the rankings to become one of the best.", + "baseInfoSubHeaderText": "Play and Win", + "baseInfoSubHeaderDescription1": "Gain Pong Points with each game you win to climb the ranks.", + "baseInfoSubHeaderDescription2": "Use your earnings to purchase new items, rackets, and tables from the store to enhance your gaming experience.", + "baseInfoSubHeaderText2": "Get Started Now", + "baseInfoSubHeaderDescription3": "Create an account to personalize your profile, track your statistics, and see where you stand in the rankings.", + "baseInfoSubHeaderText3": "More Features", + "baseInfoSubHeaderDescription4": "Participate in tournaments to face off against your opponents.", + "baseInfoSubHeaderDescription5": "Enjoy quality time with your friends by hosting private games.", + "baseInfoSubHeaderDescription6": "Chat with other players, share tactics, and join the Pong community.", + + #Login + "loginPageTittle": "Login", + "loginHeaderText1": "Welcome,", + "loginHeaderText2": "sign in to continue", + "loginInputUsernameText": "Username", + "loginInputPasswordText": "Password", + "loginForgotPasswordText": "Forgot Password?", + "loginButtonLogin": "Let's go", + "loginButtonJoin": "Join Us", + + #404 + "notFoundPageTittle": "404 Not Found", + "notFoundHeaderText": "404 ERROR", + "notFoundSubHeaderText": "Probably you lost in our website!", + "notFoundButtonText": "GO HOME", + + #Signup + "signupPageTittle": "Sign Up", + "signupHeaderText1": "Welcome,", + "signupHeaderText2": "sign up to continue", + "signupInputUsernameText": "Username", + "signupInputDisplayNameText": "Display Name", + "signupInputEmailText": "Email", + "signupInputPasswordText": "Password", + "signupInputConfirmPasswordText": "Password (again)", + "signupImageUploadText": "Upload Image", + "signupGdprText1": "I accept the", + "signupGdprText2": "GDPR Privacy Policy", + "signupButtonSignup": "Let's shine!", + + #ForgotPassword + "forgotPasswordPageTittle": "Forgot Password", + "forgotPasswordHeaderText": "Forgot Password", + "forgotPasswordInputEmailText": "Email", + "forgotPasswordButtonSend": "Send Email", + "forgotPasswordLinkText": "Don't have an account?", + "forgotPasswordLinkButtonText": "Join Us", + + #Password-Reset-Done + "passwordResetDonePageTittle": "Email Send Done", + "passwordResetDoneHeaderText": "EMAIL SEND DONE", + "passwordResetDoneSubHeaderText": "We have emailed your password reset link. Please check your email.", + "passwordResetButtonText": "GO LOGIN", + + #ChangePassword + "changePasswordPageTittle": "Change Password", + "changePasswordHeaderText": "Change Password", + "changePassswordSubHeaderText": "change your password", + + #Dashboard + "dashboardPageTittle": "Dashboard", + "dashboardText1": "Welcome, ", + "dashboardText2": "Indian Pong is a collaborative project developed for the 42 school community, offering a nostalgic gaming experience through the classic Atari game, Ping-Pong. This platform allows users to engage in Ping-Pong matches with each other, fostering a sense of friendly competition. In addition to the gaming aspect, Indian Pong provides a social dimension, featuring chat rooms where users can communicate and connect with one another. The platform also enables users to expand their network by adding friends within the 42 school community. Overall, Indian Pong combines the joy of retro gaming with modern social interaction, creating a vibrant and interactive experience for the 42 school community.", + + "dashboardGamesPlayed": "Games Played", + "dashboardWinCount": "Win Count", + "dashboardWinStreak": "Win Streak", + "dashboardLoseStreak": "Lose Streak", + "dashboardWinRate": "Win Rate", + "dashboardAverageGameDuration": "Average Game Duration", + "dashboardAveragePointsWon": "Average Points Won", + "dashboardAveragePointsLost": "Average Points Lost", + + #Chat + "chatPageTittle": "Chat", + "chatHeaderText": "Chats", + "chatRecentlyText": "Recently", + "chatDMText": "Direct Messages", + "chatContainerSelectText": "Select a chat to start messaging", + "chatTodayText": "Today", + "chatTypeHereText": "Type a message here...", + + + #Pong-Game + "pongGamePageTittle": "Pong Game", + "pongGameHeaderText": "Welcome to Pong Lobby", + "pongGameSubHeaderText": "You can improve yourself by playing with Artificial Intelligence. If you want to play with a real person, consider the other option; if we don't find someone to match with in 5 minutes, the match will be canceled. Good luck before we forget!", + "pongGameAIButtonText": "Play with AI", + "pongGameLocalButtonText": "Local Game", + "pongGameRemoteButtonText": "Remote Player", + "pongGameLocalTournamentButtonText": "Local Tournament", + "pongGameTournamentButtonText": "Tournament", + + #AI-Game + "aiGamePageTittle": "AI Game", + "aiGameReactionDelayText": "Reaction Delay", + "aiGameGetReadyText": "Get Ready", + "aiGameStartButtonText": "Start", + + "aiGameGameOverText": "Game Over", + "aiGameRestartButtonText": "Restart", + "aiGameExitButtonText": "Exit", + + "aiGameInfoHeaderText": "About the Game", + "aiGameInfoSubHeaderText": "How to Play the Game?", + "aiGameInfoSubHeaderDescription1": "In Pong game, players engage in a table tennis match against their opponents. The W-S keys (or up-down arrow keys) are used to control the ball.", + "aiGameInfoSubHeaderText2": "Win and Improve", + "aiGameInfoSubHeaderDescription2": "You earn Pong Points with every game you win. With these points, you can purchase new items, rackets, and tables from the store to enhance your gaming experience.", + "aiGameInfoSubHeaderText3": "Get Started Now", + "aiGameInfoSubHeaderDescription3": "You can create an account to personalize your gaming experience. With an account, you can track your statistics and see your position in the rankings.", + "aiGameInfoSubHeaderText4": "More Features", + "aiGameInfoSubHeaderDescription4": "You can participate in tournaments to face off against your opponents and test your skills. Additionally, you can create private games with your friends and join the Pong community.", + + "aiGameInfoSubHeaderText5": "Controls", + "aiGameInfoSubHeaderDescription5": "Up", + "aiGameInfoSubHeaderDescription6": "Down", + "aiGameInfoSubHeaderText6": "Skills", + "aiGameInfoSubHeaderDescription7": "Like a Cheater", + "aiGameInfoSubHeaderDescription8": "Fast and Furious", + "aiGameInfoSubHeaderDescription9": "Frozen Ball", + + #Local-Game + "localGamePageTittle": "Local Game", + "localGameHeaderText": "1v1 Local Game", + "localGamePlayer1Text": "Player1 Name", + "localGamePlayer2Text": "Player2 Name", + "localGameMaxScoreText": "Max Score", + "localGameGameModeText": "Game Mode", + "localGameChooseModeText1": "Vanilla", + "localGameChooseModeText2": "Abilities", + "localGameButtonStart": "Start", + + #Local-Tournament + "localTournamentPageTittle": "Local Tournament", + "localTournamentGameHeaderText": "Local Tournament", + "localTournamentPlayer1Text": "Player1 Name", + "localTournamentPlayer2Text": "Player2 Name", + "localTournamentPlayer3Text": "Player3 Name", + "localTournamentPlayer4Text": "Player4 Name", + "localTournamentMaxScoreText": "Max Score", + "localTournamentGameModeText": "Game Mode", + "localTournamentChooseModeText1": "Vanilla", + "localTournamentChooseModeText2": "Abilities", + "localTournamentButtonStart": "Start & Bracket", + "localTournamentBracketTitle": "Tournament Bracket", + "localTournamentBracketStartButtonText": "Start Tournament", + "localTournamentTournamentOverText": "Tournament Over", + "localTournamentOverButtonText": "Over", + + "localTournamentNextButtonText": "Next", + + + #Tournament + "tournamentPageTittle": "Tournament", + "tournamentHeaderText": "Welcome to Tournament Lobby for Pong", + "tournamentSubHeaderText": "Here you can join a tournament lobby or create your own tournament lobby. You can invite your friends by sharing the invite code after creating the room. Good luck before I forget!", + "tournamentJoinButtonText": "Join Tournament", + "tournamentCreateButtonText": "Create Tournament", + + #Tournament-Create + "tournamentCreatePageTittle": "Create Tournament", + "tournamentCreateHeaderText": "CREATE TOURNAMENT", + "tournamentCreateSubHeaderText": "To create a tournament I need a tournament name, how many max points each game will have. Good luck before I forget!", + "tournamentCreateNameText": "Tournament Name", + "tournamentCreateMaxPointsText": "Max Score Games", + "tournamentCreateGameModeText": "Game Mode", + "tournamentCreateChooseModeText1": "Vanilla", + "tournamentCreateChooseModeText2": "Abilities", + "tournamentCreateButtonCreate": "Create Tournament", + + #Joined-Tournament-Room + "tournamentroomPageTittle": "Tournament Room", + "tournamentroomHeaderText": "Tournament Room", + "tournamentroomRoomText": "Room", + "tournamentroomLeaveButtonText": "LEAVE TOURNAMENT", + "tournamentroomStartButtonText": "START TOURNAMENT", + "tournamentroomJoinButtonText": "JOIN TOURNAMENT", + "tournamentCheckBracketButtonText": "CHECK BRACKET", + "tournamentOverWinnerGuyText": "the tournament is over and the only person worthy of this throne", + "tournamentOverLosersText": "the tournament is over and these are the losers club", + "tournamentroomTournamentRoomButton": "TOURNAMENT ROOM", + "tournamentroomWaitingText": "Waiting", + "tournamentroomForPlayerText": "for player...", + + #Tournament Room List + "tournamentRoomListPageTittle": "Tournament Rooms", + "tournamentRoomListHeaderText": "Tournament Rooms", + + #Remote Pong Game + "remotePongGamePageTittle": "Remote Pong Game", + "remotePongGameTableName": "Name", + "remotePongGameTableActions": "Actions", + "remotePongGameMatchmakingButtonText": "MATCHMAKING", + "remotePongGameLeaveButtonText": "LEAVE", + "remotePongGameStartText": "Before to start, u can choose game mode!", + "remotePongGameStartButtonText": "START GAME", + "remotePongSelectedMode": "Vanilla", + + + #RPS Game + "rpsGamePageTittle": "Rock Paper Scissors", + "rpsGameText1": "Welcome to RPS Lobby", + "rpsGameText2": "You can improve yourself by playing with Artificial Intelligence. If you want to play with a real person, consider the other option; if we don't find someone to match with in 5 minutes, the match will be canceled. Good luck before we forget!", + "rpsGameAIButtonText": "Play with AI", + "rpsGameLocalButtonText": "Local Game", + "rpsGameSearchOpponentButtonText": "Search Opponent ", + "rpsUserCountText": "number of people looking for a match right now", + + #AI-Game + "rpsGamePageTittle": "RPS Game with Artificial Intelligence", + "rpsGameScoreText": "score", + "rpsGameRockText": "ROCK", + "rpsGamePaperText": "PAPER", + "rpsGameScissorsText": "SCISSORS", + "rpsGamePickedText": "you picked", + "rpsGamePickedText2": "the house picked", + "rpsGameAgainText": "Play again", + "rpsGameGameOverText": "Game Over", + "rpsGameRestartButtonText": "Restart", + "rpsGameExitButtonText": "Exit", + + #Rankings + "rankingsPageTittle": "Rankings", + "rankingsTableRankText": "Rank", + "rankingsTableNameText": "Name", + "rankingsTableUsernameText": "Username", + "rankingsTableWinsText": "Wins", + "rankingsTableLossesText": "Losses", + "rankingsTableWinRateText": "Win Rate", + "rankingsTablePongPointsText": "Pong Point", + + #Store + "storePageTittle": "Store", + "storeText": "Store", + "storeTagText": "All", + "storeWalletText": "Wallet", + "storeWalleinfoText1": "Oyun oynayarak ", + "storeWalleinfoText2": " kazanabilirsin.", + + #Inventory + "inventoryPageTittle": "Inventory", + "inventoryText": "Inventory", + "inventoryTagText": "All", + "inventoryWalletText": "Wallet", + "inventoryWalleinfoText1": " playing games", + "inventoryWalleinfoText2": " can win.", + "inventoryModalHeaderText": "Set Featured Item", + "inventoryModalSaveButton": "Save", + "inventoryModalCloseButton": "Close", + "inventoryItemKeyboardInfoText": "Use the", + "inventoryItemKeyboardInfoText2": "key to use this ability. And remember, you must equip this ability.", + "inventoryItemKeyboardInfoText3": "There is no special keypad for this item, it is used automatically.", + + #Search + "searchPageTittle": "Search", + "searchInputText": "Email or Username or Displayname Search...", + "searchMessageButtonText": "Message", + "searchFollowButtonText": "Follow", + "searchFollowingButtonText": "Unfollow", + "searchNoResultFoundText": "No result found.", + + #Profile + "profilePageTittle": "Profile", + "profileRankAIText": "I'M JUST ROBOT", + "profileRankUserText1": " IN RANKINGS", + "profileRankUserText2": " NO RANKING", + "profileFollowButton": "Follow", + "profileFollowingButton": "Unfollow", + "profileTitleText1": "42 Kocaeli Student", + "profileTitleText2": "Software Developer", + + "profileLinkedinSocialText": "No Linkedin", + "profileGithubSocialText": "No Github", + "profileTwitterSocialText": "No Twitter", + "profileIntra42SocialText": "No Intra42", + + "profileMatchHistoryText1": "Opponent", + "profileMatchHistoryText2": "Result", + "profileMatchHistoryText3": "Score", + "profileMatchHistoryText4": "Duration", + + "profileMatchHistoryWinText": "Win", + "profileMatchHistoryLoseText": "Lose", + + "profileRankText1": "Rank", + "profileStatsText": "Stats", + + "profileGameStats1": "Games Played:", + "profileGameStats2": "Wins:", + "profileGameStats3": "Loses:", + "profileGameStats4": "Win Rate:", + "profileGameStats5": "Win Streak:", + "profileGameStats6": "Average Game Duration:", + + #Friends + "friendsPageTittle": "Friends", + "friendsMessageButtonText": "Message", + "friendsNoResultFoundText": "No result found.", + + #ProfileSettings + "profileSettingsPageTittle": "Profile Settings", + "profileSettingsNavbar1": "Edit Profile", + "profileSettingsNavbar2": "Change Password", + "profileSettingsNavbar3": "Add Socials", + "profileSettingsNavbar4": "Blocked Users", + "profileSettingsNavbar5": "Close Account", + + #Edit-Profile + "editProfileChangeImageText": "Change Image", + "editProfileUsernameText": "Username (how your name will appear to other users on the site)", + "editProfileUsernameTimeText": "You can change your username every 7 days.", + "editProfileEmailText": "Email", + "editProfile42EmailText": "Since you are logged in with 42, your email setting feature is disabled.", + "editProfileDisplayNameText": "Display Name", + "editProfileSaveButtonText": "Save Changes", + + #Change-Passwordg + "changePasswordCurrentPasswordText": "Current Password", + "changePasswordNewPasswordText": "New Password", + "changePasswordNewConfirmPasswordText": "Confirm New Password", + "changePassword42Text": "Since you are logged in with 42, your password setting feature is disabled.", + "changePasswordSaveButtonText": "Save Password", + + #Add-Socials + "addSocialsLinkedinInputText": "Enter your LinkedIn username", + "addSocialsTwitterInputText": "Enter your Twitter username", + "addSocialsGithubInputText": "Enter your Github username", + "addSocialsIntraInputText": "Enter your 42 Intra username", + "addSocialsSaveButtonText": "Save Socials", + + #Blocked-Users + "blockedUsersHeaderText": "Blocked Accounts", + "blockedUsersSubHeaderText": "You can unblock the accounts you have blocked here.", + "blockedStatusText": "Blocked", + + #Close-Account + "closeAccountHeaderText": "Close Account", + "closeAccountInputText": "Email", + "closeAccountSubHeaderText": "You can delete your account here. This action is irreversible.", + "closeAccountButton": "Close Account", + + + } + return context + +def get_lang_tr(): + context = { + #index + "basePageTittle": "Indian-Pong", + "baseHeaderText": "Indian-Pong", + "baseSubHeaderText": "Indian-Pong Hintli geliştiriciler tarafından 42 okulu için geliştirilmiştir!", + "basePlayButtonText": "YOLCULUĞA BAŞLA!", + + "baseInfoHeaderText": "Indian-Pong'a hoş geldiniz!", + "baseInfoHeaderDescription": "Pong, klasik masa tenisi oyununun heyecanını ve rekabetini internet ortamına taşıyor. Bu platformda hem eğlenebilir hem de yeteneğini konuşturabilir, sıralamada yükselip en iyiler arasına girebilirsin.", + "baseInfoSubHeaderText": "Oyna ve Kazan", + "baseInfoSubHeaderDescription1": "Her oyun kazandığında Pong Point kazanarak sıralamada yüksel.", + "baseInfoSubHeaderDescription2": "Kazançlarınla mağazadan yeni eşyalar, raket ve masalar satın alarak oyun deneyimini geliştir.", + "baseInfoSubHeaderText2": "Hemen Başla", + "baseInfoSubHeaderDescription3": "Hesap oluşturarak profilini kişiselleştir, istatistiklerini takip et ve sıralamadaki yerini gör.", + "baseInfoSubHeaderText3": "Daha Fazlası", + "baseInfoSubHeaderDescription4": "Turnuvalara katılarak rakiplerinle yüzleş.", + "baseInfoSubHeaderDescription5": "Arkadaşlarınla özel oyunlar kurarak keyifli vakit geçir.", + "baseInfoSubHeaderDescription6": "Diğer oyuncularla sohbet et, taktikler paylaş ve Pong topluluğuna katıl.", + + #Login + "loginPageTittle": "Giriş Yap", + "loginHeaderText1": "Hoş geldiniz,", + "loginHeaderText2": "devam etmek için giriş yapın", + "loginInputUsernameText": "Kullanıcı Adı", + "loginInputPasswordText": "Şifre", + "loginForgotPasswordText": "Şifremi Unuttum?", + "loginButtonLogin": "Giriş Yap", + "loginButtonJoin": "Üye Ol", + + #404 + "notFoundPageTittle": "Sayfa Bulunamadı", + "notFoundHeaderText": "404 HATA", + "notFoundSubHeaderText": "Muhtemelen sitemizde kayboldunuz!", + "notFoundButtonText": "ANA SAYFA'YA DÖN", + + #Signup + "signupPageTittle": "Kayıt Ol", + "signupHeaderText1": "Hoş geldiniz,", + "signupHeaderText2": "devam etmek için kayıt olun", + "signupInputUsernameText": "Kullanıcı Adı", + "signupInputDisplayNameText": "Görünen Ad", + "signupInputEmailText": "E-posta", + "signupInputPasswordText": "Şifre", + "signupInputConfirmPasswordText": "Şifreyi Onayla", + "signupImageUploadText": "Resim Yükle", + "signupGdprText1": "Kabul ediyorum", + "signupGdprText2": "GDPR Gizlilik Politikası", + "signupButtonSignup": "Kayıt Ol", + + #ForgotPassword + "forgotPasswordPageTittle": "Şifremi Unuttum", + "forgotPasswordHeaderText": "Şifremi Unuttum", + "forgotPasswordInputEmailText": "E-posta", + "forgotPasswordButtonSend": "E-posta Gönder", + "forgotPasswordLinkText": "Hesabınız yok mu?", + "forgotPasswordLinkButtonText": "Kayıt Ol", + + #Password-Reset-Done + "passwordResetDonePageTittle": "E-Posta Gönderildi", + "passwordResetDoneHeaderText": "E-POSTA GÖNDERİLDİ", + "passwordResetDoneSubHeaderText": "Şifre sıfırlama bağlantınızı e-posta ile gönderdik. Lütfen e-postanızı kontrol edin.", + "passwordResetButtonText": "GİRİŞ'E DÖN", + + #ChangePassword + "changePasswordPageTittle": "Şifre Değiştir", + "changePasswordHeaderText": "Şifre Değiştir", + "changePassswordSubHeaderText": "şifreni değiştir", + + #Dashboard + "dashboardPageTittle": "Ana Sayfa", + "dashboardText1": "HOŞ GELDİNİZ, ", + "dashboardText2": "Indian Pong, 42 okulu toplulugu için geliştirilmiş bir takım projesidir ve klasik Atari oyunu Ping-Pong ile nostaljik bir oyun deneyimi sunar. Bu platform, kullanıcıların birbirleriyle Ping-Pong maçlari yapmalarina olanak tanır ve dostane rekabet ortamı oluşturur. Oyun deneyimi dışında, Indian Pong, kullanıcıların birbirleriyle iletişim kurabileceği ve bağlanti kurabilecegi sohbet odalarını içeren bir sosyal boyut sunar. Platform ayrıca, kullanicilarin 42 okulu topluluğunda arkadaş ekleyerek ağlarını genişletmelerine olanak tanır. Genel olarak, Indian Pong, retro oyun keyfini modern sosyal etkileşimle birleştirerek, 42 okulu topluluğu icin canlı ve etkileşimli bir deneyim sunar.", + + "dashboardGamesPlayed": "Oynanan Oyunlar", + "dashboardWinCount": "Kazanma Sayısı", + "dashboardWinStreak": "Kazanma Serisi", + "dashboardLoseStreak": "Kaybetme Serisi", + "dashboardWinRate": "Kazanma Oranı", + "dashboardAverageGameDuration": "Ortalama Oyun Süresi", + "dashboardAveragePointsWon": "Ortalama Kazanılan Puanlar", + "dashboardAveragePointsLost": "Ortalama Kaybedilen Puanlar", + + #Chat + "chatPageTittle": "Sohbet", + "chatHeaderText": "Sohbetler", + "chatRecentlyText": "Son Zamanlar", + "chatDMText": "Direkt Mesajlar", + "chatContainerSelectText": "Mesajlaşmaya başlamak için bir sohbet seçin", + "chatTodayText": "Bugün", + "chatTypeHereText": "Bir mesaj yazın...", + + #Pong-Game + "pongGamePageTittle": "Pong Oyunu", + "pongGameHeaderText": "Pong Lobisine Hoş Geldiniz", + "pongGameSubHeaderText": "Yapay Zeka ile oynayarak kendinizi geliştirebilir. Gerçek bir kişiyle oynamak istiyorsanız, diğer seçeneği düşünün; 5 dakika içinde eşleşecek birini bulamazsak, eşleşme iptal edilecektir. Unutmadan önce iyi şanslar!", + "pongGameAIButtonText": "Yapay Zeka Oyunu", + "pongGameLocalButtonText": "Yerel Oyun", + "pongGameRemoteButtonText": "Uzak Oyuncu", + "pongGameLocalTournamentButtonText": "Yerel Turnuva", + "pongGameTournamentButtonText": "Turnuva", + + #AI-Game + "aiGamePageTittle": "Pong Yapay Zeka Oyunu", + "aiGameReactionDelayText": "Tepki Gecikmesi", + "aiGameGetReadyText": "Hazir Ol", + "aiGameStartButtonText": "Başlat", + + "aiGameGameOverText": "Oyun Bitti", + "aiGameRestartButtonText": "Yeniden", + "aiGameExitButtonText": "Cikis", + + "aiGameInfoHeaderText": "Oyun Hakkında", + "aiGameInfoSubHeaderText": "Oyunu Nasıl Oynarım?", + "aiGameInfoSubHeaderDescription1": "Pong oyununda oyuncular rakiplerine karşı bir masa tenisi maçı yaparlar. W-S tuşları (veya yukarı-aşağı ok tuşları) topu kontrol etmek için kullanılır.", + "aiGameInfoSubHeaderText2": "Kazan ve Geliş", + "aiGameInfoSubHeaderDescription2": "Her oyun kazandığında Pong Puan kazanırsın. Bu puanlarla mağazadan yeni eşyalar, raket ve masalar satın alarak oyun deneyimini geliştirebilirsin.", + "aiGameInfoSubHeaderText3": "Hemen Başla", + "aiGameInfoSubHeaderDescription3": "Hesap oluşturarak oyun deneyimini kişiselleştirebilirsin. Bir hesapla istatistiklerini takip edebilir ve sıralamandaki yerini görebilirsin.", + "aiGameInfoSubHeaderText4": "Daha Fazlası", + "aiGameInfoSubHeaderDescription4": "Rakiplerinle yüzleşmek ve becerilerini test etmek icin turnuvalara katılabilirsin. Ayrıca arkadaşlarınla özel oyunlar oluşturabilir ve Pong topluluğuna katılabilirsin.", + + "aiGameInfoSubHeaderText5": "Kontroller", + "aiGameInfoSubHeaderDescription5": "Yukarı", + "aiGameInfoSubHeaderDescription6": "Aşağı", + "aiGameInfoSubHeaderText6": "Yetenekler", + "aiGameInfoSubHeaderDescription7": "Bir Hilekar Gibi", + "aiGameInfoSubHeaderDescription8": "Hızlı ve Öfkeli", + "aiGameInfoSubHeaderDescription9": "Dondurulmuş Top", + + #Local-Game + "localGamePageTittle": "Yerel Oyun", + "localGameHeaderText": "1v1 Yerel Oyun", + "localGamePlayer1Text": "1. Oyuncu Adı", + "localGamePlayer2Text": "2. Oyuncu Adı", + "localGameMaxScoreText": "Maksimum Skor", + "localGameGameModeText": "Oyun Modu", + "localGameChooseModeText1": "Klasik", + "localGameChooseModeText2": "Yetenekler", + "localGameButtonStart": "Başla", + + #Local-Tournament + "localTournamentPageTittle": "Yerel Turnuva", + "localTournamentGameHeaderText": "Yerel Turnuva", + "localTournamentPlayer1Text": "1. Oyuncu Adı", + "localTournamentPlayer2Text": "2. Oyuncu Adı", + "localTournamentPlayer3Text": "3. Oyuncu Adı", + "localTournamentPlayer4Text": "4. Oyuncu Adı", + "localTournamentMaxScoreText": "Maksimum Skor", + "localTournamentGameModeText": "Oyun Modu", + "localTournamentChooseModeText1": "Klasik", + "localTournamentChooseModeText2": "Yetenekler", + "localTournamentButtonStart": "Başlat & Eşleşme", + "localTournamentBracketTitle": "Turnuva Eşleşmesi", + "localTournamentBracketStartButtonText": "Turnuvayı Başlat", + "localTournamentTournamentOverText": "Turnuva Bitti", + "localTournamentOverButtonText": "Bitti", + + "localTournamentNextButtonText": "Sonraki", + + #Tournament + "tournamentPageTittle": "Turnuva", + "tournamentHeaderText": "Pong için Turnuva Lobisine Hoş Geldiniz", + "tournamentSubHeaderText": "Burada bir turnuva lobisine katılabilir veya kendi turnuva lobinizi oluşturabilirsiniz. Odanızı oluşturduktan sonra davet kodunu paylaşarak arkadaşlarınızı davet edebilirsiniz. Unutmadan önce iyi şanslar!", + "tournamentJoinButtonText": "Turnuvaya Katıl", + "tournamentCreateButtonText": "Turnuva Oluştur", + + #Tournament-Create + "tournamentCreatePageTittle": "Turnuva Oluştur", + "tournamentCreateHeaderText": "TURNUVA OLUŞTUR", + "tournamentCreateSubHeaderText": "Bir turnuva oluşturmak için bir turnuva adına ve her oyunun maksimum kaç puan alacağına ihtiyacım var. Unutmadan önce iyi şanslar!", + "tournamentCreateNameText": "Turnuva Adı", + "tournamentCreateMaxPointsText": "Oyun Başına Maksimum Skor", + "tournamentCreateGameModeText": "Oyun Modu", + "tournamentCreateChooseModeText1": "Klasik", + "tournamentCreateChooseModeText2": "Yetenekler", + "tournamentCreateButtonCreate": "Turnuva Oluştur", + + #Joined-Tournament-Room + "tournamentroomPageTittle": "Turnuva Odası", + "tournamentroomHeaderText": "Turnuva Odası", + "tournamentroomRoomText": "Oda", + "tournamentroomLeaveButtonText": "TURNUVADAN AYRIL", + "tournamentroomStartButtonText": "TURNUVAYI BAŞLAT", + "tournamentroomJoinButtonText": "TURNUVAYA KATIL", + "tournamentCheckBracketButtonText": "BRAKETI GÖRÜNTÜLE", + "tournamentOverWinnerGuyText": "turnuva bitti ve tahtın tek kişilik hakimi", + "tournamentOverLosersText": "turnuva bitti ve işte kaybedenler kulübü", + "tournamentroomTournamentRoomButton": "TURNUVA ODASI", + "tournamentroomWaitingText": "Bekleniyor,", + "tournamentroomForPlayerText": " oyuncu...", + + #Tournament Room List + "tournamentRoomListPageTittle": "Turnuva Odaları", + "tournamentRoomListHeaderText": "Turnuva Odaları", + + #Remote Pong Game + "remotePongGamePageTittle": "Pong Oyunu", + "remotePongGameTableName": "Ad", + "remotePongGameTableActions": "Eylemler", + "remotePongGameMatchmakingButtonText": "EŞLEŞME", + "remotePongGameLeaveButtonText": "AYRIL", + "remotePongGameStartText": "Başlamadan önce, oyun modunu seçebilirsin!", + "remotePongGameStartButtonText": "OYUNU BAŞLAT", + "remotePongSelectedMode": "Vanilya", + + + + #RPS Game + "rpsGamePageTittle": "Taş Kağıt Makas", + "rpsGameText1": "Taş Taş Kağıt Makas Lobisine Hoş Geldiniz", + "rpsGameText2": "Yapay Zeka ile oynayarak kendinizi geliştirebilir. Gerçek bir kişiyle oynamak istiyorsanız, diğer seçeneği düşünün; 5 dakika içinde eşleşecek birini bulamazsak, eşleşme iptal edilecektir. Unutmadan önce iyi şanslar!", + "rpsGameAIButtonText": "Yapay Zeka Oyunu", + "rpsGameLocalButtonText": "Yerel Oyun", + "rpsGameSearchOpponentButtonText": "Rakip Arayın ", + "rpsUserCountText": "şu anda eşleşme arayan kişi sayısı", + + #AI-Game + "rpsGamePageTittle": "RPS Yapay Zeka Oyunu", + "rpsGameScoreText": "skor", + "rpsGameRockText": "TAŞ", + "rpsGamePaperText": "KAĞIT", + "rpsGameScissorsText": "MAKAS", + "rpsGamePickedText": "seçtin", + "rpsGamePickedText2": "rakibin seçti", + "rpsGameAgainText": "tekrar oyna", + "rpsGameGameOverText": "Oyun Bitti", + "rpsGameRestartButtonText": "Yeniden", + "rpsGameExitButtonText": "Çıkış", + + + #Rankings + "rankingsPageTittle": "Sıralamalar", + "rankingsTableRankText": "Sıra", + "rankingsTableNameText": "Ad", + "rankingsTableUsernameText": "Kullanıcı Adı", + "rankingsTableWinsText": "Kazanmalar", + "rankingsTableLossesText": "Kayıplar", + "rankingsTableWinRateText": "Kazanma Yüzdesi", + "rankingsTablePongPointsText": "Pong Puanı", + + #Store + "storePageTittle": "Mağaza", + "storeText": "Mağaza", + "storeTagText": "Tümü", + "storeWalletText": "Cüzdan", + "storeWalleinfoText1": "Oyun oynayarak ", + "storeWalleinfoText2": " kazanabilirsin.", + + #Inventory + "inventoryPageTittle": "Envanter", + "inventoryText": "Envanter", + "inventoryTagText": "Tümü", + "inventoryWalletText": "Cüzdan", + "inventoryWalleinfoText1": "Oyun oynayarak ", + "inventoryWalleinfoText2": " kazanabilirsin.", + "inventoryModalHeaderText": "Öğeyi Ayarla", + "inventoryModalSaveButton": "Kaydet", + "inventoryModalCloseButton": "Kapat", + "inventoryItemKeyboardInfoText": "Yetenek kullanmak için", + "inventoryItemKeyboardInfoText2": "tuşunu kullan. Unutma, bu yeteneği kullanabilmek için kuşanmalısın.", + "inventoryItemKeyboardInfoText3": "Bu öğe için özel bir tuş takımı yok, otomatik olarak kullanılır.", + + + #Search + "searchPageTittle": "Arama", + "searchInputText": "E-posta, kullanıcı adı veya görünen ad ara...", + "searchMessageButtonText": "Mesaj Gönder", + "searchFollowButtonText": "Takip Et", + "searchFollowingButtonText": "Takipten Çık", + + + "searchNoResultFoundText": "Sonuç bulunamadı.", + + #Profile + "profilePageTittle": "Profili", + "profileRankAIText": "SADECE ROBOTUM", + "profileRankUserText1": " SIRALAMADA", + "profileRankUserText2": " SIRALAMA YOK", + "profileFollowButton": "Takip Et", + "profileFollowingButton": "Takipten Çık", + "profileTitleText1": "42 Kocaeli Öğrencisi", + "profileTitleText2": "Yazılım Geliştirici", + + "profileLinkedinSocialText": "LinkedIn Yok", + "profileGithubSocialText": "Github Yok", + "profileTwitterSocialText": "Twitter Yok", + "profileIntra42SocialText": "Intra42 Yok", + + "profileMatchHistoryText1": "Rakip", + "profileMatchHistoryText2": "Sonuç", + "profileMatchHistoryText3": "Puan", + "profileMatchHistoryText4": "Süre", + + "profileMatchHistoryWinText": "Kazandı", + "profileMatchHistoryLoseText": "Kaybetti", + + "profileRankText1": "Sıra", + "profileStatsText": "İstatistikler", + + "profileGameStats1": "Oynanan Oyunlar:", + "profileGameStats2": "Kazanmalar:", + "profileGameStats3": "Kayıplar:", + "profileGameStats4": "Kazanma Oranı:", + "profileGameStats5": "Kazanma Serisi:", + "profileGameStats6": "Ortalama Oyun Süresi:", + + #Friends + "friendsPageTittle": "Arkadaşlar", + "friendsMessageButtonText": "Mesaj Gönder", + "friendsNoResultFoundText": "Sonuç bulunamadı.", + + #ProfileSettings + "profileSettingsPageTittle": "Profil Ayarları", + "profileSettingsNavbar1": "Profili Düzenle", + "profileSettingsNavbar2": "Şifre Değişitr", + "profileSettingsNavbar3": "Sosyal Medya Ekle", + "profileSettingsNavbar4": "Engellenen Kullanıcılar", + "profileSettingsNavbar5": "Hesabı Kapat", + + #Edit-Profile + "editProfileChangeImageText": "Resmi Değiştir", + "editProfileUsernameText": "Kullanıcı Adı (sitenin diğer kullanıcıları tarafından nasıl görüneceği)", + "editProfileUsernameTimeText": "Kullanıcı adınızı her 7 günde bir değiştirebilirsiniz.", + "editProfileEmailText": "E-posta", + "editProfile42EmailText": "42 ile oturum açtığınız için e-posta ayarlama özelliği devre dışı bırakılmıştır.", + "editProfileDisplayNameText": "Görünen Ad", + "editProfileSaveButtonText": "Değişiklikleri Kaydet", + + #Change-Passwordg + "changePasswordCurrentPasswordText": "Mevcut Şifre", + "changePasswordNewPasswordText": "Yeni Şifre", + "changePasswordNewConfirmPasswordText": "Yeni Şifreyi Onayla", + "changePassword42Text": "42 ile oturum açtığınız için şifre ayarlama özelliği devre dışı bırakılmıştır.", + "changePasswordSaveButtonText": "Şifreyi Kaydet", + + #Add-Socials + "addSocialsLinkedinInputText": "LinkedIn kullanıcı adınızı girin", + "addSocialsTwitterInputText": "Twitter kullanıcı adınızı girin", + "addSocialsGithubInputText": "Github kullanıcı adınızı girin", + "addSocialsIntraInputText": "42 Intra kullanıcı adınızı girin", + "addSocialsSaveButtonText": "Sosyal Medyaları Kaydet", + + #Blocked-Users + "blockedUsersHeaderText": "Engellenen Hesaplar", + "blockedUsersSubHeaderText": "Burada engellediğiniz hesapları açabilirsiniz.", + "blockedStatusText": "Engellendi", + + #Close-Account + "closeAccountHeaderText": "Hesabı Kapat", + "closeAccountInputText": "E-posta", + "closeAccountSubHeaderText": "Burada hesabınızı silebilirsiniz. Bu işlem geri alınamaz.", + "closeAccountButton": "Hesabı Kapat", + + + } + return context + + +def get_lang_pt(): + context = { + #index + "basePageTittle": "Indian-Pong", + "baseHeaderText": "Indian-Pong", + "baseSubHeaderText": "A versão indiana do clássico jogo Pong", + "basePlayButtonText": "Vamos Comecar!", + + "baseInfoHeaderText": "Bem-vindo ao Indian-Pong!", + "baseInfoHeaderDescription": "Pong traz a emoção e a competição do tênis de mesa clássico para a internet. Nesta plataforma, você pode se divertir, mostrar suas habilidades e subir no ranking para se tornar um dos melhores.", + "baseInfoSubHeaderText": "Jogue e Ganhe", + "baseInfoSubHeaderDescription1": "Ganhe Pong Points a cada jogo que vencer para subir no ranking.", + "baseInfoSubHeaderDescription2": "Use seus ganhos para comprar novos itens, raquetes e mesas da loja para aprimorar sua experiência de jogo.", + "baseInfoSubHeaderText2": "Comece Agora", + "baseInfoSubHeaderDescription3": "Crie uma conta para personalizar seu perfil, acompanhar suas estatísticas e ver onde você está no ranking.", + "baseInfoSubHeaderText3": "Mais Recursos", + "baseInfoSubHeaderDescription4": "Participe de torneios para enfrentar seus oponentes.", + "baseInfoSubHeaderDescription5": "Divirta-se com seus amigos hospedando jogos privados.", + "baseInfoSubHeaderDescription6": "Converse com outros jogadores, compartilhe táticas e participe da comunidade Pong.", + + #Login + "loginPageTittle": "Iniciar sessão", + "loginHeaderText1": "Bem-vindo,", + "loginHeaderText2": "faca login para continuar", + "loginInputUsernameText": "Nome de Usuário", + "loginInputPasswordText": "Senha", + "loginForgotPasswordText": "Esqueceu a Senha?", + "loginButtonLogin": "Vamos lá", + "loginButtonJoin": "Junte-se", + + #404 + "notFoundPageTittle": "Página não encontrada", + "notFoundHeaderText": "404 ERRO", + "notFoundSubHeaderText": "Você provavelmente se perdeu em nosso site!", + "notFoundButtonText": "VENHA PARA CASA", + + #Signup + "signupPageTittle": "Inscreva-se", + "signupHeaderText1": "Bem-vindo,", + "signupHeaderText2": "inscreva-se para continuar", + "signupInputUsernameText": "Nome de Usuário", + "signupInputDisplayNameText": "Nome de Exibicão", + "signupInputEmailText": "E-mail", + "signupInputPasswordText": "Senha", + "signupInputConfirmPasswordText": "Senha (novamente)", + "signupImageUploadText": "Imagem", + "signupGdprText1": "Concordo ", + "signupGdprText2": "GDPR Política de Privacidade", + "signupButtonSignup": "Vamos!", + + #ForgotPassword + "forgotPasswordPageTittle": "Esqueceu a Senha", + "forgotPasswordHeaderText": "Esqueceu a Senha", + "forgotPasswordInputEmailText": "E-mail", + "forgotPasswordButtonSend": "Enviar E-mail", + "forgotPasswordLinkText": "Não tem uma conta?", + "forgotPasswordLinkButtonText": "Junte-se a Nós", + + #Password-Reset-Done + "passwordResetDonePageTittle": "Email Enviado", + "passwordResetDoneHeaderText": "EMAIL ENVIADO", + "passwordResetDoneSubHeaderText": "Enviamos o link de redefinição de senha para o seu e-mail. Por favor, verifique seu e-mail.", + "passwordResetButtonText": "VOLTAR AO LOGIN", + + #ChangePassword + "changePasswordPageTittle": "Mudar Senha", + "changePasswordHeaderText": "Mudar Senha", + "changePassswordSubHeaderText": "alterar a sua palavra-passe", + + + #Dashboard + "dashboardPageTittle": "Painel", + "dashboardText1": "Bem-vindo, ", + "dashboardText2": "O Indian Pong é um projeto colaborativo desenvolvido para a comunidade da escola 42, oferecendo uma experiência de jogo nostálgica através do clássico jogo Atari, Ping-Pong. Esta plataforma permite que os usuários participem de partidas de Ping-Pong uns com os outros, promovendo uma sensacão de competicão amigável. Além do aspecto de jogo, o Indian Pong oferece uma dimensão social, apresentando salas de bate-papo onde os usuários podem se comunicar e se conectar uns com os outros. A plataforma também permite que os usuários expandam sua rede adicionando amigos dentro da comunidade da escola 42. No geral, o Indian Pong combina a alegria dos jogos retrô com a interacão social moderna, criando uma experiência vibrante e interativa para a comunidade da escola 42.", + + "dashboardGamesPlayed": "Jogos Jogados", + "dashboardWinCount": "Contagem de Vitórias", + "dashboardWinStreak": "Sequência de Vitórias", + "dashboardLoseStreak": "Sequência de Derrotas", + "dashboardWinRate": "Taxa de Vitória", + "dashboardAverageGameDuration": "Duracão Média do Jogo", + "dashboardAveragePointsWon": "Pontos Médios Ganhos", + "dashboardAveragePointsLost": "Pontos Médios Perdidos", + + #Chat + "chatPageTittle": "Bate-papo", + "chatHeaderText": "Bate-papos", + "chatRecentlyText": "Recentemente", + "chatDMText": "Mensagens Diretas", + "chatContainerSelectText": "Selecione um bate-papo para começar a conversar", + "chatTodayText": "Hoje", + "chatTypeHereText": "Digite uma mensagem...", + + + #Pong-Game + "pongGamePageTittle": "Jogo de Pong", + "pongGameHeaderText": "Bem-vindo ao Lobby de Pong", + "pongGameSubHeaderText": "Podes melhorar o teu desempenho jogando com a Inteligência Artificial. Se quiseres jogar com uma pessoa real, considera a outra opção; se não encontrarmos alguém com quem jogar no espaço de 5 minutos, o jogo será cancelado. Boa sorte antes que nos esqueçamos!", + "pongGameAIButtonText": "Jogar com a IA", + "pongGameLocalButtonText": "Jogo Local", + "pongGameRemoteButtonText": "Jogador Remoto", + "pongGameLocalTournamentButtonText": "Locais Torneio", + "pongGameTournamentButtonText": "Torneio", + + #AI-Game + "aiGamePageTittle": "Jogo de Pong com a IA", + "aiGameReactionDelayText": "Atraso na Reacão", + "aiGameGetReadyText": "Prepare-se", + "aiGameStartButtonText":"Começar", + + "aiGameGameOverText": "Fim de Jogo", + "aiGameRestartButtonText": "Reiniciar", + "aiGameExitButtonText": "Sair", + + "aiGameInfoHeaderText": "Sobre o Jogo", + "aiGameInfoSubHeaderText": "Como Jogar o Jogo?", + "aiGameInfoSubHeaderDescription1": "No jogo Pong, os jogadores participam de uma partida de tênis de mesa contra seus oponentes. As teclas W-S (ou as setas cima-baixo) são usadas para controlar a bola.", + "aiGameInfoSubHeaderText2": "Ganhe e Melhore", + "aiGameInfoSubHeaderDescription2": "Você ganha Pong Points a cada jogo que vence. Com esses pontos, você pode comprar novos itens, raquetes e mesas da loja para aprimorar sua experiência de jogo.", + "aiGameInfoSubHeaderText3": "Comece Agora", + "aiGameInfoSubHeaderDescription3": "Você pode criar uma conta para personalizar sua experiência de jogo. Com uma conta, você pode acompanhar suas estatísticas e ver sua posição no ranking.", + "aiGameInfoSubHeaderText4": "Mais Recursos", + "aiGameInfoSubHeaderDescription4": "Você pode participar de torneios para enfrentar seus oponentes e testar suas habilidades. Além disso, você pode criar jogos privados com seus amigos e se juntar à comunidade Pong.", + + "aiGameInfoSubHeaderText5": "Controles", + "aiGameInfoSubHeaderDescription5": "Cima", + "aiGameInfoSubHeaderDescription6": "Baixo", + "aiGameInfoSubHeaderText6": "Habilidades", + "aiGameInfoSubHeaderDescription7": "Como um Trapaceiro", + "aiGameInfoSubHeaderDescription8": "Veloz e Furioso", + "aiGameInfoSubHeaderDescription9": "Bola Congelada", + + #Local-Game + "localGamePageTittle": "Jogo Local", + "localGameHeaderText": "Jogo Local 1v1", + "localGamePlayer1Text": "Nome do Jogador 1", + "localGamePlayer2Text": "Nome do Jogador 2", + "localGameMaxScoreText": "Pontuacão Máxima", + "localGameGameModeText": "Modo de Jogo", + "localGameChooseModeText1": "Vanilla", + "localGameChooseModeText2": "Habilidades", + "localGameButtonStart": "Iniciar", + + #Local-Tournament + "localTournamentPageTittle": "Torneio Local", + "localTournamentGameHeaderText": "Torneio Local", + "localTournamentPlayer1Text": "Nome do Jogador 1", + "localTournamentPlayer2Text": "Nome do Jogador 2", + "localTournamentPlayer3Text": "Nome do Jogador 3", + "localTournamentPlayer4Text": "Nome do Jogador 4", + "localTournamentMaxScoreText": "Pontuacão Máxima", + "localTournamentGameModeText": "Modo de Jogo", + "localTournamentChooseModeText1": "Vanilla", + "localTournamentChooseModeText2": "Habilidades", + "localTournamentButtonStart": "Iniciar & Empar.", + "localTournamentBracketTitle": "Empar. Torneio", + "localTournamentBracketStartButtonText": "Iniciar Torneio", + "localTournamentTournamentOverText": "Torneio Terminado", + "localTournamentOverButtonText": "Terminado", + + "localTournamentNextButtonText": "Próximo", + + #Tournament + "tournamentPageTittle": "Torneio", + "tournamentHeaderText": "Bem-vindo ao Lobby do Torneio de Pong", + "tournamentSubHeaderText": "Aqui você pode entrar em um lobby de torneio ou criar seu próprio lobby de torneio. Você pode convidar seus amigos compartilhando o código de convite após criar a sala. Boa sorte antes que eu esqueca!", + "tournamentJoinButtonText": "Entrar no Torneio", + "tournamentCreateButtonText": "Criar Torneio", + + #Tournament-Create + "tournamentCreatePageTittle": "Criar Torneio", + "tournamentCreateHeaderText": "CRIAR TORNEIO", + "tournamentCreateSubHeaderText": "Para criar um torneio, eu preciso de um nome de torneio, quantos pontos máximos cada jogo terá. Boa sorte antes que eu esqueca!", + "tournamentCreateNameText": "Nome do Torneio", + "tournamentCreateMaxPointsText": "Pontuacão Máxima dos Jogos", + "tournamentCreateGameModeText": "Modo de Jogo", + "tournamentCreateChooseModeText1": "Vanilla", + "tournamentCreateChooseModeText2": "Habilidades", + "tournamentCreateButtonCreate": "Criar Torneio", + + #Joined-Tournament-Room + "tournamentroomPageTittle": "Sala de Torneio", + "tournamentroomHeaderText": "Sala de Torneio", + "tournamentroomRoomText": "Sala", + "tournamentroomLeaveButtonText": "SAIR DO TORNEIO", + "tournamentroomStartButtonText": "INICIAR TORNEIO", + "tournamentroomJoinButtonText": "ENTRAR NO TORNEIO", + "tournamentCheckBracketButtonText": "VER BRACKET", + "tournamentOverWinnerGuyText": "o torneio acabou e o rei da mesa é", + "tournamentOverLosersText": "o torneio acabou e aqui está o clube dos perdedores", + "tournamentroomTournamentRoomButton": "SALA DE TORNEIO", + "tournamentroomWaitingText": "Aguardando,", + "tournamentroomForPlayerText": "jogadores...", + + #Tournament Room List + "tournamentRoomListPageTittle": "Salas de Torneio", + "tournamentRoomListHeaderText": "Salas de Torneio", + + #Remote Pong Game + "remotePongGamePageTittle": "Jogo de Pong", + "remotePongGameTableName": "Nome", + "remotePongGameTableActions": "Ações", + "remotePongGameMatchmakingButtonText": "MATCHMAKING", + "remotePongGameLeaveButtonText": "SAIR", + "remotePongGameStartText": "Antes de começar, você pode escolher o modo de jogo!", + "remotePongGameStartButtonText": "INICIAR JOGO", + "remotePongSelectedMode": "Vanilla", + + #RPS Game + "rpsGamePageTittle": "Pedra, Papel e Tesoura", + "rpsGameText1": "Bem-vindo ao Lobby de Pedra, Papel e Tesoura", + "rpsGameText2": "Podes melhorar o teu desempenho jogando com a Inteligência Artificial. Se quiseres jogar com uma pessoa real, considera a outra opção; se não encontrarmos alguém com quem jogar no espaço de 5 minutos, o jogo será cancelado. Boa sorte antes que nos esqueçamos!", + "rpsGameAIButtonText": "Jogar com a IA", + "rpsGameLocalButtonText": "Jogo Local", + "rpsGameSearchOpponentButtonText": "Buscar Oponente ", + "rpsUserCountText": "Jogadores Online", + + #AI-Game + "rpsGamePageTittle": "Jogo de Pedra, Papel e Tesoura com Inteligência Artificial", + "rpsGameScoreText": "pontuação", + "rpsGameRockText": "PEDRA", + "rpsGamePaperText": "PAPEL", + "rpsGameScissorsText": "TESOURA", + "rpsGamePickedText": "escolheste", + "rpsGamePickedText2": "o adversário escolheu", + "rpsGameAgainText": "jogar novamente", + "rpsGameGameOverText": "Jogo Terminado", + "rpsGameRestartButtonText": "Reiniciar", + "rpsGameExitButtonText": "Sair", + + #Rankings + "rankingsPageTittle": "Classificacão", + "rankingsTableRankText": "Classificacão", + "rankingsTableNameText": "Nome", + "rankingsTableUsernameText": "Nome de Usuário", + "rankingsTableWinsText": "Vitórias", + "rankingsTableLossesText": "Derrotas", + "rankingsTableWinRateText": "Taxa de Vitória", + "rankingsTablePongPointsText": "Pontos Pong", + + #Store + "storePageTittle": "Loja", + "storeText": "Loja", + "storeTagText": "Tudo", + "storeWalletText": "Carteira", + "storeWalleinfoText1": "Você pode ganhar ", + "storeWalleinfoText2": " jogando.", + + #Inventory + "inventoryPageTittle": "Inventário", + "inventoryText": "Inventário", + "inventoryTagText": "Tudo", + "inventoryWalletText": "Carteira", + "inventoryWalleinfoText1": "Você pode ganhar ", + "inventoryWalleinfoText2": " jogando.", + "inventoryModalHeaderText": "Definir Item", + "inventoryModalSaveButton": "Salvar", + "inventoryModalCloseButton": "Fechar", + "inventoryItemKeyboardInfoText": "Use a tecla", + "inventoryItemKeyboardInfoText2": "para usar essa habilidade. E lembre-se, você deve equipar essa habilidade.", + "inventoryItemKeyboardInfoText3": "Este item não tem um teclado personalizado, é usado automaticamente.", + + + #Search + "searchPageTittle": "Procurar", + "searchInputText": "Procurar por e-mail, nome de usuário ou nome de exibicão...", + "searchMessageButtonText": "Mensagem", + "searchFollowButtonText": "Seguir", + "searchFollowingButtonText": "Deixar", + "searchNoResultFoundText": "Nenhum resultado encontrado.", + + #Profile + "profilePageTittle": "Perfil", + "profileRankAIText": "APENAS ROBÔ", + "profileRankUserText1": " RANKING", + "profileRankUserText2": " SEM RANKING", + "profileFollowButton": "Seguir", + "profileFollowingButton": "Deixar", + "profileTitleText1": "Estudante da 42 Kocaeli", + "profileTitleText2": "Desenvolvedor de Software", + + "profileLinkedinSocialText": "Sem LinkedIn", + "profileGithubSocialText": "Sem Github", + "profileTwitterSocialText": "Sem Twitter", + "profileIntra42SocialText": "Sem Intra42", + + "profileMatchHistoryText1": "Oponente", + "profileMatchHistoryText2": "Resultado", + "profileMatchHistoryText3": "Pontos", + "profileMatchHistoryText4": "Tempo", + + "profileMatchHistoryWinText": "Venceu", + "profileMatchHistoryLoseText": "Perdeu", + + "profileRankText1": "Classificacão", + "profileStatsText": "Estatísticas", + + "profileGameStats1": "Jogos Jogados:", + "profileGameStats2": "Vitórias:", + "profileGameStats3": "Derrotas:", + "profileGameStats4": "Taxa de Vitória:", + "profileGameStats5": "Sequência de Vitórias:", + "profileGameStats6": "Duração Média do Jogo:", + + #Friends + "friendsPageTittle": "Amigos", + "friendsMessageButtonText": "Mensagem", + "friendsNoResultFoundText": "Nenhum resultado encontrado.", + + #ProfileSettings + "profileSettingsPageTittle": "Configurações do Perfil", + "profileSettingsNavbar1": "Editar Perfil", + "profileSettingsNavbar2": "Alterar Senha", + "profileSettingsNavbar3": "Adicionar Redes Sociais", + "profileSettingsNavbar4": "Usuários Bloqueados", + "profileSettingsNavbar5": "Fechar Conta", + + #Edit-Profile + "editProfileChangeImageText": "Alterar Imagem", + "editProfileUsernameText": "Nome de usuário (como seu nome aparecerá para outros usuários no site)", + "editProfileUsernameTimeText": "Você pode alterar seu nome de usuário a cada 7 dias.", + "editProfileEmailText": "Email", + "editProfile42EmailText": "Como você está logado com 42, o recurso de configuração de e-mail está desativado.", + "editProfileDisplayNameText": "Nome de Exibição", + "editProfileSaveButtonText": "Salvar Alterações", + + #Change-Password + "changePasswordCurrentPasswordText": "Senha Atual", + "changePasswordNewPasswordText": "Nova Senha", + "changePasswordNewConfirmPasswordText": "Confirmar Nova Senha", + "changePassword42Text": "Como você está logado com 42, o recurso de configuração de senha está desativado.", + "changePasswordSaveButtonText": "Salvar Senha", + + #Add-Socials + "addSocialsLinkedinInputText": "Insira seu nome de usuário do LinkedIn", + "addSocialsTwitterInputText": "Insira seu nome de usuário do Twitter", + "addSocialsGithubInputText": "Insira seu nome de usuário do Github", + "addSocialsIntraInputText": "Insira seu nome de usuário do 42 Intra", + "addSocialsSaveButtonText": "Salvar Redes Sociais", + + #Blocked-Users + "blockedUsersHeaderText": "Contas Bloqueadas", + "blockedUsersSubHeaderText": "Você pode desbloquear as contas que bloqueou aqui.", + "blockedStatusText": "Bloqueado", + + + #Close-Account + "closeAccountHeaderText": "Fechar Conta", + "closeAccountInputText": "E-mail", + "closeAccountSubHeaderText": "Você pode excluir sua conta aqui. Esta ação é irreversível.", + "closeAccountButton": "Fechar Conta", + } + return context + +def get_lang_hi(): + context = { + #index + "basePageTittle": "इंडियन-पॉन्ग", + "baseHeaderText": "इंडियन-पॉन्ग", + "baseSubHeaderText": "प्रसिद्ध खेल पॉन्ग का भारतीय संस्करण", + "basePlayButtonText": "शुरू करें!", + + "baseInfoHeaderText": "इंडियन-पॉन्ग में आपका स्वागत है!", + "baseInfoHeaderDescription": "पॉन्ग इंटरनेट पर क्लासिक टेबल टेनिस खेल के उत्साह और प्रतिस्पर्धा को लाता है। इस प्लेटफ़ॉर्म पर आप मजा कर सकते हैं, अपने कौशल का परिचय दे सकते हैं और शीर्ष में आने के लिए रैंकिंग में चढ़ सकते हैं।", + "baseInfoSubHeaderText": "खेलें और जीतें", + "baseInfoSubHeaderDescription1": "जीतने पर प्रत्येक खेल से पॉन्ग पॉइंट्स कमाकर रैंकिंग में चढ़ें।", + "baseInfoSubHeaderDescription2": "अपनी जीत से नए आइटम, रैकेट और टेबल्स खरीदने के लिए दुकान से खर्च करें।", + "baseInfoSubHeaderText2": "अभी शुरू करें", + "baseInfoSubHeaderDescription3": "प्रोफ़ाइल को व्यक्तिगत बनाने, अपने स्टैटिस्टिक्स को ट्रैक करने और रैंकिंग में अपनी जगह देखने के लिए खाता बनाएं।", + "baseInfoSubHeaderText3": "अधिक सुविधाएं", + "baseInfoSubHeaderDescription4": "अपने प्रतिद्वंद्वियों के साथ टूर्नामेंट में भाग लेने के लिए।", + "baseInfoSubHeaderDescription5": "अपने दोस्तों के साथ निजी खेल खेलकर मजा करें।", + "baseInfoSubHeaderDescription6": "अन्य खिलाड़ियों के साथ चैट करें, रणनीतियाँ साझा करें और पॉन्ग समुदाय में शामिल हों।", + + #Login + "loginPageTittle": "लॉग इन करें", + "loginHeaderText1": "स्वागत है,", + "loginHeaderText2": "जारी रखने के लिए साइन इन करें", + "loginInputUsernameText": "उपयोगकर्ता नाम", + "loginInputPasswordText": "पासवर्ड", + "loginForgotPasswordText": "पासवर्ड भूल गए?", + "loginButtonLogin": "चलो चलते हैं", + "loginButtonJoin": "हमारे साथ", + + #404 + "notFoundPageTittle": "पृष्ठ नहीं मिला", + "notFoundHeaderText": "404 त्रुटि", + "notFoundSubHeaderText": "आप शायद हमारी वेबसाइट में खो गए हैं!", + "notFoundButtonText": "घर वापस जाओ", + + #Signup + "signupPageTittle": "साइन अप करें", + "signupHeaderText1": "स्वागत है,", + "signupHeaderText2": "जारी रखने के लिए साइन अप करें", + "signupInputUsernameText": "उपयोगकर्ता नाम", + "signupInputDisplayNameText": "डिस्प्ले नाम", + "signupInputEmailText": "ईमेल", + "signupInputPasswordText": "पासवर्ड", + "signupInputConfirmPasswordText": "पासवर्ड (फिर से)", + "signupImageUploadText": "छवि अपलोड करें", + "signupGdprText1": "मैं सहमत हूं", + "signupGdprText2": "GDPR गोपनीयता नीति", + "signupButtonSignup": "चमकाओ!", + + #ForgotPassword + "forgotPasswordPageTittle": "पासवर्ड भूल गए", + "forgotPasswordHeaderText": "पासवर्ड भूल गए", + "forgotPasswordInputEmailText": "ईमेल", + "forgotPasswordButtonSend": "ईमेल भेजें", + "forgotPasswordLinkText": "खाता नहीं है?", + "forgotPasswordLinkButtonText": "हमारे साथ शामिल हों", + + #Password-Reset-Done + "passwordResetDonePageTittle": "ईमेल भेजा गया", + "passwordResetDoneHeaderText": "ईमेल भेजा गया", + "passwordResetDoneSubHeaderText": "हमने आपके ईमेल पर पासवर्ड रीसेट लिंक भेज दिया है। कृपया अपने ईमेल की जाँच करें।", + "passwordResetButtonText": "ईमेल भेजा गया", + + #ChangePassword + "changePasswordPageTittle": "पासवर्ड बदलें", + "changePasswordHeaderText": "पासवर्ड बदलें", + "changePassswordSubHeaderText": "अपना पासवर्ड बदलें", + + + #Dashboard + "dashboardPageTittle": "डैशबोर्ड", + "dashboardText1": "स्वागत, ", + "dashboardText2": "इंडियन पॉन्ग एक सहयोगी परियोजना है जो 42 स्कूल समुदाय के लिए विकसित की गई है, जो शास्त्रीय खेल पिंग-पोंग के माध्यम से नोस्टाल्जिक गेमिंग अनुभव प्रदान करता है। यह प्लेटफ़ॉर्म प्रतिद्वंद्वियों के साथ पिंग-पोंग मैच खेलने की अनुमति देता है, जो एक दूसरे के साथ दोस्ताना प्रतिस्पर्धा का मूल्यांकन करता है। खेल के पहले पहल में, इंडियन पॉन्ग को सामाजिक आयाम प्रदान करता है, जिसमें उपयोगकर्ताओं को एक-दूसरे के साथ संवाद करने और जुड़ने का अवसर प्रदान किया जाता है। प्लेटफ़ॉर्म उपयोगकर्ताओं को 42 स्कूल समुदाय के भीतर दोस्तों को जोड़ने की सुविधा भी प्रदान करता है। समग्र रूप में, इंडियन पॉन्ग पुराने गेमिंग का आनंद और आधुनिक सामाजिक आक्रोश जोड़ते हैं, 42 स्कूल समुदाय के लिए एक जीवंत और अंतर्क्रियात्मक अनुभव बनाते हैं।", + + "dashboardGamesPlayed": "खेल खेले गए", + "dashboardWinCount": "जीत की गई बार", + "dashboardWinStreak": "जीत की रेकार्ड", + "dashboardLoseStreak": "हार की रेकार्ड", + "dashboardWinRate": "जीतने की दर", + "dashboardAverageGameDuration": "औसत खेल की अवधि", + "dashboardAveragePointsWon": "औसत अंक जीते", + "dashboardAveragePointsLost": "औसत अंक हारे", + + #Chat + "chatPageTittle": "चैट", + "chatHeaderText": "चैट", + "chatRecentlyText": "हाल ही में", + "chatDMText": "डायरेक्ट मैसेज", + "chatContainerSelectText": "चैट शुरू करने के लिए एक चैट चुनें", + "chatTodayText": "आज", + "chatTypeHereText": "एक संदेश लिखें...", + + + #Pong-Game + "pongGamePageTittle": "पॉन्ग खेल", + "pongGameHeaderText": "पॉन्ग लॉबी में आपका स्वागत है", + "pongGameSubHeaderText": "आप आर्टिफिशियल इंटेलिजेंस के साथ खेलकर खुद को बेहतर बना सकते हैं। यदि आप किसी वास्तविक व्यक्ति के साथ खेलना चाहते हैं, तो दूसरे विकल्प पर विचार करें; यदि हमें 5 मिनट के भीतर मैच के लिए कोई नहीं मिल सका, तो मैच रद्द कर दिया जाएगा। इससे पहले कि मैं भूल जाऊँ, शुभकामनाएँ!", + "pongGameAIButtonText": "ए.आई. के साथ खेलें", + "pongGameLocalButtonText": "स्थानीय खेल", + "pongGameRemoteButtonText": "दूरस्थ खिलाड़ी", + "pongGameLocalTournamentButtonText": "स्थानीय टूर्नामेंट", + "pongGameTournamentButtonText": "टूर्नामेंट", + + #AI-Game + "aiGamePageTittle": "ए.आई. के साथ पॉन्ग खेल", + "aiGameReactionDelayText": "प्रतिक्रिया में देरी", + "aiGameGetReadyText": "तैयार हो जाओ", + "aiGameStartButtonText": "शुरू करें", + + "aiGameGameOverText": "खेल समाप्त हो गया", + "aiGameRestartButtonText": "पुनः आरंभ", + "aiGameExitButtonText": "निकास", + + "aiGameInfoHeaderText": "खेल के बारे में", + "aiGameInfoSubHeaderText": "खेल कैसे खेलें?", + "aiGameInfoSubHeaderDescription1": "पॉन्ग खेल में खिलाड़ी अपने प्रतिद्वंद्वी के खिलाफ एक टेनिस की मैच खेलते हैं। W-S (या ऊपर-नीचे तीर) तीरों को नियंत्रित करने के लिए उपयोग किया जाता है।", + "aiGameInfoSubHeaderText2": "जीतें और सुधारें", + "aiGameInfoSubHeaderDescription2": "आप हर जीते खेल के बाद पॉन्ग पॉइंट्स कमाते हैं। इन पॉइंट्स के साथ आप खेल का अनुभव बेहतर बनाने के लिए दुकान से नए आइटम, रैकेट और टेबल खरीद सकते हैं।", + "aiGameInfoSubHeaderText3": "अभी शुरू करें", + "aiGameInfoSubHeaderDescription3": "आप अपने खेल का अनुभव व्यक्तिगत करने के लिए एक खाता बना सकते हैं। एक खाते के साथ, आप अपने स्टैटिस्टिक्स को ट्रैक कर सकते हैं और रैंकिंग में अपनी जगह देख सकते हैं।", + "aiGameInfoSubHeaderText4": "अधिक सुविधाएं", + "aiGameInfoSubHeaderDescription4": "आप अपने प्रतिद्वंद्वियों के साथ टूर्नामेंट में भाग लेने के लिए और अपने कौशल का परीक्षण करने के लिए टूर्नामेंट में भाग ले सकते हैं। इसके अलावा, आप अपने दोस्तों के साथ निजी खेल बना सकते हैं और पॉन्ग समुदाय में शामिल हो सकते हैं।", + + "aiGameInfoSubHeaderText5": "नियंत्रण", + "aiGameInfoSubHeaderDescription5": "ऊपर", + "aiGameInfoSubHeaderDescription6": "नीचे", + "aiGameInfoSubHeaderText6": "कौशल", + "aiGameInfoSubHeaderDescription7": "जैसे एक धोखेबाज", + "aiGameInfoSubHeaderDescription8": "तेज और उत्तेजित", + "aiGameInfoSubHeaderDescription9": "जमीन गेंद", + + #Local-Game + "localGamePageTittle": "स्थानीय खेल", + "localGameHeaderText": "1v1 स्थानीय खेल", + "localGamePlayer1Text": "प्लेयर1 नाम", + "localGamePlayer2Text": "प्लेयर2 नाम", + "localGameMaxScoreText": "अधिकतम स्कोर", + "localGameGameModeText": "खेल मोड", + "localGameChooseModeText1": "वनिला", + "localGameChooseModeText2": "क्षमताएँ", + "localGameButtonStart": "प्रारंभ करें", + + #Local-Tournament + "localTournamentPageTittle": "स्थानीय टूर्नामेंट", + "localTournamentGameHeaderText": "स्थानीय टूर्नामेंट", + "localTournamentPlayer1Text": "1. खिलाड़ी नाम", + "localTournamentPlayer2Text": "2. खिलाड़ी नाम", + "localTournamentPlayer3Text": "3. खिलाड़ी नाम", + "localTournamentPlayer4Text": "4. खिलाड़ी नाम", + "localTournamentMaxScoreText": "अधिकतम स्कोर", + "localTournamentGameModeText": "खेल मोड", + "localTournamentChooseModeText1": "वनिला", + "localTournamentChooseModeText2": "क्षमताएँ", + "localTournamentButtonStart": "टूर्नामेंट शुरू करें", + "localTournamentBracketTitle": "ब्रैकेट", + "localTournamentBracketStartButtonText": "टूर्नामेंट शुरू करें", + "localTournamentTournamentOverText": "टूर्नामेंट खत्म हो गया", + "localTournamentOverButtonText": "खत्म करें", + + + "localTournamentNextButtonText": "अगला", + + #Tournament + "tournamentPageTittle": "टूर्नामेंट", + "tournamentHeaderText": "पॉन्ग के टूर्नामेंट लॉबी में आपका स्वागत है", + "tournamentSubHeaderText": "यहां आप एक टूर्नामेंट लॉबी में शामिल हो सकते हैं या अपनी खुद की टूर्नामेंट लॉबी बना सकते हैं। आप अपने दोस्तों को रुम बनाने के बाद इनवाइट कोड साझा करके इन्वाइट कर सकते हैं। भूलने से पहले शुभकामनाएं!", + "tournamentJoinButtonText": "टूर्नामेंट में शामिल हों", + "tournamentCreateButtonText": "टूर्नामेंट बनाएं", + + #Tournament-Create + "tournamentCreatePageTittle": "टूर्नामेंट बनाएं", + "tournamentCreateHeaderText": "टूर्नामेंट बनाएं", + "tournamentCreateSubHeaderText": "एक टूर्नामेंट बनाने के लिए मुझे एक टूर्नामेंट का नाम, हर खेल के लिए कितना अधिकतम स्कोर होगा। भूलने से पहले शुभकामनाएं!", + "tournamentCreateNameText": "टूर्नामेंट का नाम", + "tournamentCreateMaxPointsText": "अधिकतम स्कोर खेलें", + "tournamentCreateGameModeText": "खेल मोड", + "tournamentCreateChooseModeText1": "वनिला", + "tournamentCreateChooseModeText2": "क्षमताएँ", + "tournamentCreateButtonCreate": "टूर्नामेंट बनाएं", + + #Joined-Tournament-Room + "tournamentroomPageTittle": "टूर्नामेंट रूम", + "tournamentroomHeaderText": "टूर्नामेंट रूम", + "tournamentroomLeaveButtonText": "छोड़ें", + "tournamentroomRoomText": "रूम", + "tournamentroomStartButtonText": "शुरू करें", + "tournamentroomJoinButtonText": "शामिल हों", + "tournamentCheckBracketButtonText": "ब्रैकेट देखें", + "tournamentOverWinnerGuyText": "विजेता", + "tournamentOverLosersText": "हारने वाले", + "tournamentroomTournamentRoomButton": "टूर्नामेंट रूम", + "tournamentroomWaitingText": "इंतजार कर", + "tournamentroomForPlayerText": "खिलाड़ी ", + + #Tournament Room List + "tournamentRoomListPageTittle": "टूर्नामेंट रूम सूची", + "tournamentRoomListHeaderText": "टूर्नामेंट रूम सूची", + + #Remote Pong Game + "remotePongGamePageTittle": "दूरस्थ पॉन्ग खेल", + "remotePongGameTableName": "नाम", + "remotePongGameTableActions": "कार्रवाई", + "remotePongGameMatchmakingButtonText": "मैचमेकिंग", + "remotePongGameLeaveButtonText": "छोड़ें", + "remotePongGameStartText": "शुरू करें", + "remotePongGameStartButtonText": "शुरू करें", + "remotePongSelectedMode": "चयनित मोड", + + + + #RPS Game + "rpsGamePageTittle": "रॉक-पेपर-सैंड खेल", + "rpsGameText1": "रॉक-पेपर-सैंड लॉबी में आपका स्वागत है", + "rpsGameText2": "आप आर्टिफिशियल इंटेलिजेंस के साथ खेलकर खुद को बेहतर बना सकते हैं। यदि आप किसी वास्तविक व्यक्ति के साथ खेलना चाहते हैं, तो दूसरे विकल्प पर विचार करें; यदि हमें 5 मिनट के भीतर मैच के लिए कोई नहीं मिल सका, तो मैच रद्द कर दिया जाएगा। इससे पहले कि मैं भूल जाऊँ, शुभकामनाएँ!", + "rpsGameAIButtonText": "ए.आई. के साथ खेलें", + "rpsGameLocalButtonText": "स्थानीय खेल", + "rpsGameSearchOpponentButtonText": "विरोधी खोजें ", + "rpsUserCountText": "उपयोगकर्ता", + #AI-Game + "rpsGamePageTittle": "रॉक कागज कैंची आर्टिफिशियल इंटेलिजेंस गेम", + "rpsGameScoreText": "स्कोर", + "rpsGameRockText": "पत्थर", + "rpsGamePaperText": "कागज", + "rpsGameScissorsText": "कैंची", + "rpsGamePickedText": "तुमने चुना", + "rpsGamePickedText2": "विरोधी चुना", + "rpsGameAgainText": "फिर से खेलें", + "rpsGameGameOverText": "खेल समाप्त", + "rpsGameRestartButtonText": "फिर से शुरू करें", + "rpsGameExitButtonText": "बाहर जाएं", + + + #Rankings + "rankingsPageTittle": "रैंकिंग", + "rankingsTableRankText": "रैंक", + "rankingsTableNameText": "नाम", + "rankingsTableUsernameText": "उपयोगकर्ता नाम", + "rankingsTableWinsText": "जीतें", + "rankingsTableLossesText": "हारें", + "rankingsTableWinRateText": "जीतने की दर", + "rankingsTablePongPointsText": "पॉन्ग अंक", + + #Store + "storePageTittle": "दुकान", + "storeText": "दुकान", + "storeTagText": "सभी", + "storeWalletText": "वॉलेट", + "storeWalleinfoText1": "खेल खेलकर ", + "storeWalleinfoText2": " जीत सकते हैं।", + + #Inventory + "inventoryPageTittle": "इन्वेंटरी", + "inventoryText": "इन्वेंटरी", + "inventoryTagText": "सभी", + "inventoryWalletText": "वॉलेट", + "inventoryWalleinfoText1": "खेल खेलकर ", + "inventoryWalleinfoText2": " जीत सकते हैं।", + "inventoryModalHeaderText": "आइटम खरीदें", + "inventoryModalSaveButton": "खरीदें", + "inventoryModalCloseButton": "बंद करें", + "inventoryItemKeyboardInfoText": "उपयोग", + "inventoryItemKeyboardInfoText2": "इस आइटम के लिए कोई विशेष कीपैड नहीं है, यह स्वचालित रूप से उपयोग किया जाता है।", + "inventoryItemKeyboardInfoText3": "इस आइटम के लिए कोई विशेष कीपैड नहीं है, यह स्वचालित रूप से उपयोग किया जाता है।", + + + #Search + "searchPageTittle": "खोजें", + "searchInputText": "ईमेल या उपयोगकर्ता नाम या डिस्प्ले नाम खोजें...", + "searchMessageButtonText": "संदेश", + "searchFollowButtonText": "अनुसरण करना", + "searchFollowingButtonText": "अनफ़ॉलो", + "searchNoResultFoundText": "कोई परिणाम नहीं मिला।", + + #Profile + "profilePageTittle": "प्रोफ़ाइल", + "profileRankAIText": "ए.आई. रैंक", + "profileRankUserText1": " उपयोगकर्ता रैंक", + "profileRankUserText2": " रैंक", + "profileFollowButton": "अनुसरण करना", + "profileFollowingButton": "अनफ़ॉलो", + "profileTitleText1": "42 स्कूल समुदाय", + "profileTitleText2": "पॉन्ग खिलाड़ी", + + "profileLinkedinSocialText": "कोई लिंक्डइन नहीं", + "profileTwitterSocialText": "कोई ट्विटर नहीं", + "profileGithubSocialText": "कोई गिटहब नहीं", + "profileIntra42SocialText": "कोई इंट्रा नहीं", + + "profileMatchHistoryText1": "प्रतिद्वंद्वी", + "profileMatchHistoryText2": "परिणाम", + "profileMatchHistoryText3": "अंक", + "profileMatchHistoryText4": "अवधि", + + "profileMatchHistoryWinText": "जीता", + "profileMatchHistoryLoseText": "हारा", + + "profileRankText1": "रैंक", + "profileStatsText": "आंकड़े", + + "profileGameStats1": "खेल खेले गए:", + "profileGameStats2": "जीतें:", + "profileGameStats3": "हारें:", + "profileGameStats4": "जीतने की दर:", + "profileGameStats5": "औसत अंक जीते:", + "profileGameStats6": "औसत अंक हारे:", + + #Friends + "friendsPageTittle": "मित्र", + "friendsMessageButtonText": "संदेश", + "friendsNoResultFoundText": "कोई परिणाम नहीं मिला।", + + + #ProfileSettings + "profileSettingsPageTittle": "प्रोफ़ाइल सेटिंग्स", + "profileSettingsNavbar1": "प्रोफ़ाइल संपादित करें", + "profileSettingsNavbar2": "पासवर्ड बदलें", + "profileSettingsNavbar3": "सोशल्स जोड़ें", + "profileSettingsNavbar4": "अवरुद्ध उपयोगकर्ता", + "profileSettingsNavbar5": "खाता बंद करें", + + #Edit-Profile + "editProfileChangeImageText": "छवि बदलें", + "editProfileUsernameText": "उपयोगकर्ता नाम (आपका नाम साइट पर अन्य उपयोगकर्ताओं के लिए कैसे दिखाई देगा)", + "editProfileUsernameTimeText": "आप अपना उपयोगकर्ता नाम एक बार बदल सकते हैं।", + "editProfileEmailText": "ईमेल", + "editProfile42EmailText": "चूंकि आप 42 के साथ लॉग इन हैं, आपकी ईमेल सेटिंग सुविधा अक्षम है।", + "editProfileDisplayNameText": "प्रदर्शन नाम", + "editProfileSaveButtonText": "परिवर्तन सहेजें", + + #Change-Password + "changePasswordCurrentPasswordText": "वर्तमान पासवर्ड", + "changePasswordNewPasswordText": "नया पासवर्ड", + "changePasswordNewConfirmPasswordText": "नया पासवर्ड पुष्टि करें", + "changePassword42Text": "चूंकि आप 42 के साथ लॉग इन हैं, आपकी पासवर्ड सेटिंग सुविधा अक्षम है।", + "changePasswordSaveButtonText": "पासवर्ड सहेजें", + + #Add-Socials + "addSocialsLinkedinInputText": "अपना LinkedIn उपयोगकर्ता नाम दर्ज करें", + "addSocialsTwitterInputText": "अपना Twitter उपयोगकर्ता नाम दर्ज करें", + "addSocialsGithubInputText": "अपना Github उपयोगकर्ता नाम दर्ज करें", + "addSocialsIntraInputText": "अपना 42 Intra उपयोगकर्ता नाम दर्ज करें", + "addSocialsSaveButtonText": "सोशल्स सहेजें", + + #Blocked-Users + "blockedUsersHeaderText": "अवरुद्ध खाते", + "blockedUsersSubHeaderText": "आप यहां अपने द्वारा अवरुद्ध किए गए खातों को अनवरोधित कर सकते हैं।", + "blockedStatusText": "अवरुद्ध", + + #Close-Account + "closeAccountHeaderText": "खाता बंद करें", + "closeAccountInputText": "ईमेल", + "closeAccountSubHeaderText": "आप यहां अपना खाता हटा सकते हैं। यह कार्रवाई अपरिवर्तनीय है।", + "closeAccountButton": "खाता बंद करें", + + } return context \ No newline at end of file diff --git a/indianpong/pong/management/commands/populate.py b/indianpong/pong/management/commands/populate.py index badca14f..f151eb43 100644 --- a/indianpong/pong/management/commands/populate.py +++ b/indianpong/pong/management/commands/populate.py @@ -1,67 +1,67 @@ -from django.contrib.auth.hashers import make_password -from pong.models import UserProfile, UserGameStat, Social -from random import randint, choice -from django.core.management.base import BaseCommand -from datetime import timedelta - -class Command(BaseCommand): - help = 'Populates the database with users' - - def add_arguments(self, parser): - parser.add_argument('num_users', type=int, help='Number of users to create') - - def handle(self, *args, **options): - num_users = options['num_users'] - user_game_stats_pong = [] - socials = [] - user_profiles = [] - password = make_password('123456a.') - - for i in range(num_users): - username = "Indian" + str(i) - displayname = "Original Indian" + str(i) - email = username + '@indian.com' - - # Prepare UserGameStat instance - game_stat = UserGameStat( - total_games_pong=randint(0, 100), - total_win_pong=randint(0, 100), - total_lose_pong=randint(0, 100), - total_win_streak_pong=randint(0, 100), - total_lose_streak_pong=randint(0, 100), - total_win_rate_pong=randint(0, 100) / 100.0, - total_avg_game_duration_pong=timedelta(seconds=randint(0, 3600)), - total_avg_points_won_pong=randint(0, 100), - total_avg_points_lost_pong=randint(0, 100) - ) - user_game_stats_pong.append(game_stat) - - # Prepare Social instance - social = Social( - intra42 = username, - linkedin = username, - github = username, - twitter= username, - ) - socials.append(social) - - # Prepare UserProfile instance - user_profile = UserProfile( - username=username, - email=email, - displayname=displayname, - password=password, - game_stats_pong=game_stat, - social=social - ) - user_profiles.append(user_profile) - - # Create instances in database - UserGameStat.objects.bulk_create(user_game_stats_pong) - Social.objects.bulk_create(socials) - #UserProfile.objects.bulk_create(user_profiles) - # Create UserProfile instances individually to trigger save method - for user_profile in user_profiles: - user_profile.save() - +from django.contrib.auth.hashers import make_password +from pong.models import UserProfile, UserGameStat, Social +from random import randint, choice +from django.core.management.base import BaseCommand +from datetime import timedelta + +class Command(BaseCommand): + help = 'Populates the database with users' + + def add_arguments(self, parser): + parser.add_argument('num_users', type=int, help='Number of users to create') + + def handle(self, *args, **options): + num_users = options['num_users'] + user_game_stats_pong = [] + socials = [] + user_profiles = [] + password = make_password('123456a.') + + for i in range(num_users): + username = "Indian" + str(i) + displayname = "Original Indian" + str(i) + email = username + '@indian.com' + + # Prepare UserGameStat instance + game_stat = UserGameStat( + total_games_pong=randint(0, 100), + total_win_pong=randint(0, 100), + total_lose_pong=randint(0, 100), + total_win_streak_pong=randint(0, 100), + total_lose_streak_pong=randint(0, 100), + total_win_rate_pong=randint(0, 100) / 100.0, + total_avg_game_duration_pong=timedelta(seconds=randint(0, 3600)), + total_avg_points_won_pong=randint(0, 100), + total_avg_points_lost_pong=randint(0, 100) + ) + user_game_stats_pong.append(game_stat) + + # Prepare Social instance + social = Social( + intra42 = username, + linkedin = username, + github = username, + twitter= username, + ) + socials.append(social) + + # Prepare UserProfile instance + user_profile = UserProfile( + username=username, + email=email, + displayname=displayname, + password=password, + game_stats_pong=game_stat, + social=social + ) + user_profiles.append(user_profile) + + # Create instances in database + UserGameStat.objects.bulk_create(user_game_stats_pong) + Social.objects.bulk_create(socials) + #UserProfile.objects.bulk_create(user_profiles) + # Create UserProfile instances individually to trigger save method + for user_profile in user_profiles: + user_profile.save() + self.stdout.write(self.style.SUCCESS(f'Successfully populated the database with {num_users} users.')) \ No newline at end of file diff --git a/indianpong/pong/rps.py b/indianpong/pong/rps.py index a1d99970..1b0ea88d 100644 --- a/indianpong/pong/rps.py +++ b/indianpong/pong/rps.py @@ -1,124 +1,124 @@ -from enum import Enum -import time - -class Choices(Enum): - ROCK = 0 - PAPER = 1 - SCISSORS = 2 - -class Abilities(Enum): - LIKEACHEATER = 3, - GODOFTHINGS = 4 - -class RoundResult(Enum): - DRAW = 0 - PLAYER1_WIN = 1 - PLAYER2_WIN = 2 - -KV_CHOICES = {'rock': Choices.ROCK, 'paper': Choices.PAPER, 'scissors': Choices.SCISSORS, 'godthings': Abilities.GODOFTHINGS, 'cheater': Abilities.LIKEACHEATER} - -class Shaker: - def __init__(self, username): - self.username = username - self.score = 0 - self.choices = [] - -class RPS: - def __init__(self, player1, player2): - self.shaker1 = Shaker(player1) - self.shaker2 = Shaker(player2) - self.max_score = 3 - self.group_name = f'rps_{player1}_{player2}' - self.start_time = 0 - self.end_time = 0 - - def play(self, username, choice): - if (self.start_time == 0): - self.start_time = time.time() - if username == self.shaker1.username: - self.shaker1.choices.append(KV_CHOICES[choice]) - elif username == self.shaker2.username: - self.shaker2.choices.append(KV_CHOICES[choice]) - - def ability_result(self, choice1, choice2): - ab1 = choice1 == Abilities.LIKEACHEATER or choice1 == Abilities.GODOFTHINGS - ab2 = choice2 == Abilities.LIKEACHEATER or choice2 == Abilities.GODOFTHINGS - if ab1 and ab2: #both played this it's draw - return 0 - elif ab1 and choice1 == Abilities.LIKEACHEATER: #stole opponent score if greater than 0 - if self.shaker2.score > 0: - self.shaker2.score -= 1 - self.shaker1.score += 1 - return 1 - elif ab2 and choice2 == Abilities.LIKEACHEATER: #won round instantly - if self.shaker1.score > 0: - self.shaker1.score -= 1 - self.shaker2.score += 1 - return 2 - elif ab1 and choice1 == Abilities.GODOFTHINGS: - self.shaker1.score += 1 - return 1 - elif ab2 and choice2 == Abilities.GODOFTHINGS: - self.shaker2.score += 1 - return 2 - else: - return 3 - - - def round_result(self): - shaker1_choice = self.shaker1.choices.pop() - shaker2_choice = self.shaker2.choices.pop() - result = self.ability_result(shaker1_choice, shaker2_choice) - if result == 0: - return RoundResult.DRAW.name - elif result == 1: - return RoundResult.PLAYER1_WIN.name - elif result == 2: - return RoundResult.PLAYER2_WIN.name - result = (shaker1_choice.value - shaker2_choice.value) % 3 - if result == 0: - return RoundResult.DRAW.name - elif result == 1: - self.shaker1.score += 1 - return RoundResult.PLAYER1_WIN.name - else: - self.shaker2.score += 1 - return RoundResult.PLAYER2_WIN.name - - def check_is_over(self): - if self.shaker1.score == self.max_score or self.shaker2.score == self.max_score: - self.end_time = time.time() - return True - return False - - def get_winner_loser(self): - if self.shaker1.score > self.shaker2.score: - return self.shaker1.username, self.shaker2.username - else: - return self.shaker2.username, self.shaker1.username - - def otherPlayer(self, username): - if username == self.shaker1.username: - return self.shaker2.username - else: - return self.shaker1.username - - def get_scores(self): - return self.shaker1.score, self.shaker2.score - - def getDuration(self): - if self.end_time == 0: - self.end_time = time.time() - return self.end_time - self.start_time - - def getWinnerLoserandScores(self): - if self.shaker1.score > self.shaker2.score: - return self.shaker1.username, self.shaker2.username, self.shaker1.score, self.shaker2.score - else: - return self.shaker2.username, self.shaker1.username, self.shaker2.score, self.shaker1.score - - def both_played(self): - return len(self.shaker1.choices) == len(self.shaker2.choices) == 1 - - def getChoices(self): - return self.shaker1.choices[0].name, self.shaker2.choices[0].name +from enum import Enum +import time + +class Choices(Enum): + ROCK = 0 + PAPER = 1 + SCISSORS = 2 + +class Abilities(Enum): + LIKEACHEATER = 3, + GODOFTHINGS = 4 + +class RoundResult(Enum): + DRAW = 0 + PLAYER1_WIN = 1 + PLAYER2_WIN = 2 + +KV_CHOICES = {'rock': Choices.ROCK, 'paper': Choices.PAPER, 'scissors': Choices.SCISSORS, 'godthings': Abilities.GODOFTHINGS, 'cheater': Abilities.LIKEACHEATER} + +class Shaker: + def __init__(self, username): + self.username = username + self.score = 0 + self.choices = [] + +class RPS: + def __init__(self, player1, player2): + self.shaker1 = Shaker(player1) + self.shaker2 = Shaker(player2) + self.max_score = 3 + self.group_name = f'rps_{player1}_{player2}' + self.start_time = 0 + self.end_time = 0 + + def play(self, username, choice): + if (self.start_time == 0): + self.start_time = time.time() + if username == self.shaker1.username: + self.shaker1.choices.append(KV_CHOICES[choice]) + elif username == self.shaker2.username: + self.shaker2.choices.append(KV_CHOICES[choice]) + + def ability_result(self, choice1, choice2): + ab1 = choice1 == Abilities.LIKEACHEATER or choice1 == Abilities.GODOFTHINGS + ab2 = choice2 == Abilities.LIKEACHEATER or choice2 == Abilities.GODOFTHINGS + if ab1 and ab2: #both played this it's draw + return 0 + elif ab1 and choice1 == Abilities.LIKEACHEATER: #stole opponent score if greater than 0 + if self.shaker2.score > 0: + self.shaker2.score -= 1 + self.shaker1.score += 1 + return 1 + elif ab2 and choice2 == Abilities.LIKEACHEATER: #won round instantly + if self.shaker1.score > 0: + self.shaker1.score -= 1 + self.shaker2.score += 1 + return 2 + elif ab1 and choice1 == Abilities.GODOFTHINGS: + self.shaker1.score += 1 + return 1 + elif ab2 and choice2 == Abilities.GODOFTHINGS: + self.shaker2.score += 1 + return 2 + else: + return 3 + + + def round_result(self): + shaker1_choice = self.shaker1.choices.pop() + shaker2_choice = self.shaker2.choices.pop() + result = self.ability_result(shaker1_choice, shaker2_choice) + if result == 0: + return RoundResult.DRAW.name + elif result == 1: + return RoundResult.PLAYER1_WIN.name + elif result == 2: + return RoundResult.PLAYER2_WIN.name + result = (shaker1_choice.value - shaker2_choice.value) % 3 + if result == 0: + return RoundResult.DRAW.name + elif result == 1: + self.shaker1.score += 1 + return RoundResult.PLAYER1_WIN.name + else: + self.shaker2.score += 1 + return RoundResult.PLAYER2_WIN.name + + def check_is_over(self): + if self.shaker1.score == self.max_score or self.shaker2.score == self.max_score: + self.end_time = time.time() + return True + return False + + def get_winner_loser(self): + if self.shaker1.score > self.shaker2.score: + return self.shaker1.username, self.shaker2.username + else: + return self.shaker2.username, self.shaker1.username + + def otherPlayer(self, username): + if username == self.shaker1.username: + return self.shaker2.username + else: + return self.shaker1.username + + def get_scores(self): + return self.shaker1.score, self.shaker2.score + + def getDuration(self): + if self.end_time == 0: + self.end_time = time.time() + return self.end_time - self.start_time + + def getWinnerLoserandScores(self): + if self.shaker1.score > self.shaker2.score: + return self.shaker1.username, self.shaker2.username, self.shaker1.score, self.shaker2.score + else: + return self.shaker2.username, self.shaker1.username, self.shaker2.score, self.shaker1.score + + def both_played(self): + return len(self.shaker1.choices) == len(self.shaker2.choices) == 1 + + def getChoices(self): + return self.shaker1.choices[0].name, self.shaker2.choices[0].name diff --git a/indianpong/pong/templates/_nav.html b/indianpong/pong/templates/_nav.html index dbda8096..f51ab4f5 100644 --- a/indianpong/pong/templates/_nav.html +++ b/indianpong/pong/templates/_nav.html @@ -69,7 +69,7 @@ initializeBurger(); } - var socket = new WebSocket('ws://' + window.location.host + '/ws/online_status/'); + var socket = new WebSocket('wss://' + window.location.host + '/ws/online_status/'); socket.onopen = function(e) { console.log('User is connected'); diff --git a/indianpong/pong/templates/local-game.html b/indianpong/pong/templates/local-game.html index af7bb964..d5041256 100644 --- a/indianpong/pong/templates/local-game.html +++ b/indianpong/pong/templates/local-game.html @@ -1,116 +1,116 @@ -{% extends "base.html" %} - -{% load static %} - -{% block title %}{{context.localGamePageTittle}}{% endblock title %} - -{% block stylesheet %}{% endblock %} - -{% block app %} - -
-
- -
-
-
- -
-
-

{{context.localGameHeaderText}}

-
- - - - - - -
- - -
- -
- - -
-
- - - -
- -
-

-

{{context.aiGameGameOverText}}

- - -
-
-
- - +{% extends "base.html" %} + +{% load static %} + +{% block title %}{{context.localGamePageTittle}}{% endblock title %} + +{% block stylesheet %}{% endblock %} + +{% block app %} + +
+
+ +
+
+
+ +
+
+

{{context.localGameHeaderText}}

+
+ + + + + + +
+ + +
+ +
+ + +
+
+ + + +
+ +
+

+

{{context.aiGameGameOverText}}

+ + +
+
+
+ + {% endblock %} \ No newline at end of file diff --git a/indianpong/pong/templates/local-tournament.html b/indianpong/pong/templates/local-tournament.html index e14c8061..584b21d8 100644 --- a/indianpong/pong/templates/local-tournament.html +++ b/indianpong/pong/templates/local-tournament.html @@ -1,190 +1,190 @@ -{% extends "base.html" %} - -{% load static %} - -{% block title %}{{context.localTournamentPageTittle}}{% endblock title %} - - -{% block app %} - -
-
- -
-
-
- -
-
-

{{context.localTournamentGameHeaderText}}

-
- - - - - - - - - - - - -
- - -
- -
- - -
-
- -
-
-

{{context.localTournamentBracketTitle}}

-
-
-
-
-
-
- 1 - -
-
- 2 - -
-
-
-
-
-
-
-
-
-
-
- 3 - -
-
- 4 - -
-
-
-
-
-
-
-
-
-
-
-
-
- 5 - -
-
- 6 - -
-
-
-
-
-
-
-
-
-
-
-
-
- - -
- - -
-

-

{{context.aiGameGameOverText}}

- -
- -
-

-

{{context.localTournamentTournamentOverText}}

- -
-
-
- +{% extends "base.html" %} + +{% load static %} + +{% block title %}{{context.localTournamentPageTittle}}{% endblock title %} + + +{% block app %} + +
+
+ +
+
+
+ +
+
+

{{context.localTournamentGameHeaderText}}

+
+ + + + + + + + + + + + +
+ + +
+ +
+ + +
+
+ +
+
+

{{context.localTournamentBracketTitle}}

+
+
+
+
+
+
+ 1 + +
+
+ 2 + +
+
+
+
+
+
+
+
+
+
+
+ 3 + +
+
+ 4 + +
+
+
+
+
+
+
+
+
+
+
+
+
+ 5 + +
+
+ 6 + +
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+ + +
+

+

{{context.aiGameGameOverText}}

+ +
+ +
+

+

{{context.localTournamentTournamentOverText}}

+ +
+
+
+ {% endblock %} \ No newline at end of file diff --git a/indianpong/pong/templates/play-rps-ai.html b/indianpong/pong/templates/play-rps-ai.html index 5bdcd017..b39d180f 100644 --- a/indianpong/pong/templates/play-rps-ai.html +++ b/indianpong/pong/templates/play-rps-ai.html @@ -1,81 +1,81 @@ -{% extends 'base.html' %} - -{% load static %} - -{% block title %} - {{context.rpsGamePageTittle}} -{% endblock %} - -{% block stylesheet %}{% endblock %} - -{% block app %} -
-
-
-
-
{{request.user.username}}
-
{{context.rpsGameScoreText}}
-
0
-
-

{{context.rpsGameRockText}}
{{context.rpsGamePaperText}}
{{context.rpsGameScissorsText}}

-
-
{% if not ainametag %} IndianAI {% else %} {{ainametag}} {% endif %}
-
{{context.rpsGameScoreText}}
-
0
-
-
-
-
- {% if cheater_rps == "true" %} - - {% endif %} - {% if godthings_rps == "true" %} - - {% endif %} - - - -
-
- - - -
-

-

{{context.rpsGameGameOverText}}

- - -
- - - {% csrf_token %} -{% endblock %} +{% extends 'base.html' %} + +{% load static %} + +{% block title %} + {{context.rpsGamePageTittle}} +{% endblock %} + +{% block stylesheet %}{% endblock %} + +{% block app %} +
+
+
+
+
{{request.user.username}}
+
{{context.rpsGameScoreText}}
+
0
+
+

{{context.rpsGameRockText}}
{{context.rpsGamePaperText}}
{{context.rpsGameScissorsText}}

+
+
{% if not ainametag %} IndianAI {% else %} {{ainametag}} {% endif %}
+
{{context.rpsGameScoreText}}
+
0
+
+
+
+
+ {% if cheater_rps == "true" %} + + {% endif %} + {% if godthings_rps == "true" %} + + {% endif %} + + + +
+
+ + + +
+

+

{{context.rpsGameGameOverText}}

+ + +
+ + + {% csrf_token %} +{% endblock %} diff --git a/indianpong/pong/templates/play-rps.html b/indianpong/pong/templates/play-rps.html index 64352485..c068fffe 100644 --- a/indianpong/pong/templates/play-rps.html +++ b/indianpong/pong/templates/play-rps.html @@ -1,111 +1,111 @@ -{% extends 'base.html' %} - -{% load static %} - -{% block title %} - Remote RPS -{% endblock %} - -{% block stylesheet %} - -{% endblock %} - -{% block app %} - -
-

{{context.rpsUserCountText}}:

-
0
-
- -
-
- -
-
- -
-
- {{context.rpsGameSearchOpponentButtonText}} -
-
- - - - - -
-

-

{{context.rpsGameGameOverText}}

- -
- -
- -
- - -{% endblock %} +{% extends 'base.html' %} + +{% load static %} + +{% block title %} + Remote RPS +{% endblock %} + +{% block stylesheet %} + +{% endblock %} + +{% block app %} + +
+

{{context.rpsUserCountText}}:

+
0
+
+ +
+
+ +
+
+ +
+
+ {{context.rpsGameSearchOpponentButtonText}} +
+
+ + + + + +
+

+

{{context.rpsGameGameOverText}}

+ +
+ +
+ +
+ + +{% endblock %} diff --git a/indianpong/pong/templates/remote-game.html b/indianpong/pong/templates/remote-game.html index a731b872..93328ad7 100644 --- a/indianpong/pong/templates/remote-game.html +++ b/indianpong/pong/templates/remote-game.html @@ -1,77 +1,77 @@ - {% extends 'base.html' %} -{% load static %} - -{% block title %} - {{context.remotePongGamePageTittle}} -{% endblock %} - -{% block stylesheet %} - - -{% endblock %} - -{% block app %} - -
-
- - - - - - - - - - - -
{{context.remotePongGameTableName}}{{context.remotePongGameTableActions}}
- -
- -
-
- -
-
- -
- -
- - - {% comment %} - - {% endcomment %} -
-
-
- - -
-

-

-

{{context.aiGameGameOverText}}

- -
-
- -
- - -{% csrf_token %} + {% extends 'base.html' %} +{% load static %} + +{% block title %} + {{context.remotePongGamePageTittle}} +{% endblock %} + +{% block stylesheet %} + + +{% endblock %} + +{% block app %} + +
+
+ + + + + + + + + + + +
{{context.remotePongGameTableName}}{{context.remotePongGameTableActions}}
+ +
+ +
+
+ +
+
+ +
+ +
+ + + {% comment %} + + {% endcomment %} +
+
+
+ + +
+

+

+

{{context.aiGameGameOverText}}

+ +
+
+ +
+ + +{% csrf_token %} {% endblock %} \ No newline at end of file diff --git a/indianpong/pong/templates/room.html b/indianpong/pong/templates/room.html index 03613c3b..58adbc6d 100644 --- a/indianpong/pong/templates/room.html +++ b/indianpong/pong/templates/room.html @@ -1,170 +1,170 @@ -{% extends 'base.html' %} - -{% load static %} -{% load status %} - -{% block title %} -{{context.chatPageTittle}} -{% endblock %} - -{% block stylesheet %}{% endblock %} -{% block app %} - -{% load custom_filters %} - -
-
-
-
- - - - -
- - -
-
- -
- {% if room.first_user == request.user %} - - -
- {{ room.second_user }} -
- {% else %} - - -
- {{ room.first_user }} -
- {% endif %} -
-
- - - - {% if not user_friends_status|get_item:room.second_user.username %} - - - {% else %} - - - {% endif %} - {% if user_blocked_status|get_item:room.second_user.username or user_blocked_status|get_item:room.first_user.username %} - - - {% else %} - - - {% endif %} - - -
-
- -
- -
- - - -
-
-
-
- -
- {{ room_name|json_script:"room-name" }} - {{ request.user.username|json_script:"user" }} - - -
-
-
- -
-
- {% csrf_token %} +{% extends 'base.html' %} + +{% load static %} +{% load status %} + +{% block title %} +{{context.chatPageTittle}} +{% endblock %} + +{% block stylesheet %}{% endblock %} +{% block app %} + +{% load custom_filters %} + +
+
+
+
+ + + + +
+ + +
+
+ +
+ {% if room.first_user == request.user %} + + +
+ {{ room.second_user }} +
+ {% else %} + + +
+ {{ room.first_user }} +
+ {% endif %} +
+
+ + + + {% if not user_friends_status|get_item:room.second_user.username %} + + + {% else %} + + + {% endif %} + {% if user_blocked_status|get_item:room.second_user.username or user_blocked_status|get_item:room.first_user.username %} + + + {% else %} + + + {% endif %} + + +
+
+ +
+ +
+ + + +
+
+
+
+ +
+ {{ room_name|json_script:"room-name" }} + {{ request.user.username|json_script:"user" }} + + +
+
+
+ +
+
+ {% csrf_token %} {% endblock %} \ No newline at end of file diff --git a/indianpong/pong/templates/tournament-create.html b/indianpong/pong/templates/tournament-create.html index c71dad5c..d516630a 100644 --- a/indianpong/pong/templates/tournament-create.html +++ b/indianpong/pong/templates/tournament-create.html @@ -1,47 +1,47 @@ -{% extends 'base.html' %} -{% load static %} - -{% block title %}{{context.tournamentCreatePageTittle}}{% endblock title %} -{% block stylesheet %}{% endblock stylesheet %} - -{% block app %} -
-
-
-

{{context.tournamentCreateHeaderText}}

-
- {{context.tournamentCreateSubHeaderText}} -
-
-
- {% csrf_token %} -
-
- - - - {% if form.name.errors %} -
{{ form.name.errors }}
- {% endif %} -
-
- - -
-
- -
-
-
-
-
-
- - - +{% extends 'base.html' %} +{% load static %} + +{% block title %}{{context.tournamentCreatePageTittle}}{% endblock title %} +{% block stylesheet %}{% endblock stylesheet %} + +{% block app %} +
+
+
+

{{context.tournamentCreateHeaderText}}

+
+ {{context.tournamentCreateSubHeaderText}} +
+
+
+ {% csrf_token %} +
+
+ + + + {% if form.name.errors %} +
{{ form.name.errors }}
+ {% endif %} +
+
+ + +
+
+ +
+
+
+
+
+
+ + + {% endblock %} \ No newline at end of file diff --git a/indianpong/pong/templates/tournament-room-list.html b/indianpong/pong/templates/tournament-room-list.html index 43b9daf4..5226e886 100644 --- a/indianpong/pong/templates/tournament-room-list.html +++ b/indianpong/pong/templates/tournament-room-list.html @@ -1,90 +1,90 @@ -{% extends "base.html" %} -{% load static %} - -{% block stylesheet %} - -{% endblock stylesheet %} - -{% block title %} {{context.tournamentRoomListPageTittle}} {% endblock title %} - -{% block app %} - -
-
-

{{context.tournamentRoomListHeaderText}}

- -
- -
- -
-
- -
-
-{% endblock %} - +{% extends "base.html" %} +{% load static %} + +{% block stylesheet %} + +{% endblock stylesheet %} + +{% block title %} {{context.tournamentRoomListPageTittle}} {% endblock title %} + +{% block app %} + +
+
+

{{context.tournamentRoomListHeaderText}}

+ +
+ +
+ +
+
+ +
+
+{% endblock %} + diff --git a/indianpong/pong/templates/tournament.html b/indianpong/pong/templates/tournament.html index 09435140..2bc800cd 100644 --- a/indianpong/pong/templates/tournament.html +++ b/indianpong/pong/templates/tournament.html @@ -1,28 +1,28 @@ -{% extends 'base.html' %} -{% load static %} - -{% block title %}{{context.tournamentPageTittle}}{% endblock title %} -{% block stylesheet %}{% endblock stylesheet %} - -{% block app %} -
-
-

{{context.tournamentHeaderText}}

-
- {{context.tournamentSubHeaderText}} -
- - -
-
- -{% endblock %} +{% extends 'base.html' %} +{% load static %} + +{% block title %}{{context.tournamentPageTittle}}{% endblock title %} +{% block stylesheet %}{% endblock stylesheet %} + +{% block app %} +
+
+

{{context.tournamentHeaderText}}

+
+ {{context.tournamentSubHeaderText}} +
+ + +
+
+ +{% endblock %} diff --git a/indianpong/pong/templatetags/custom_filters.py b/indianpong/pong/templatetags/custom_filters.py index a5316d0a..b7852914 100644 --- a/indianpong/pong/templatetags/custom_filters.py +++ b/indianpong/pong/templatetags/custom_filters.py @@ -1,7 +1,7 @@ -from django import template - -register = template.Library() - -@register.filter -def get_item(dictionary, key): - return dictionary.get(key, False) +from django import template + +register = template.Library() + +@register.filter +def get_item(dictionary, key): + return dictionary.get(key, False) diff --git a/indianpong/pong/templatetags/status.py b/indianpong/pong/templatetags/status.py index a0deb53f..d72983dc 100644 --- a/indianpong/pong/templatetags/status.py +++ b/indianpong/pong/templatetags/status.py @@ -1,12 +1,12 @@ -from django import template -from django.core.cache import cache - -register = template.Library() - -@register.simple_tag -def is_user_online(user_username): - return cache.get(f'online_{user_username}', default=False) - -@register.simple_tag -def is_user_playing(user_username): +from django import template +from django.core.cache import cache + +register = template.Library() + +@register.simple_tag +def is_user_online(user_username): + return cache.get(f'online_{user_username}', default=False) + +@register.simple_tag +def is_user_playing(user_username): return cache.get(f'playing_{user_username}', default=False) \ No newline at end of file diff --git a/indianpong/pong/templatetags/transnav.py b/indianpong/pong/templatetags/transnav.py index a7f928c7..a25c0328 100644 --- a/indianpong/pong/templatetags/transnav.py +++ b/indianpong/pong/templatetags/transnav.py @@ -1,22 +1,22 @@ -from django import template - - -register = template.Library() - -@register.simple_tag(takes_context=True) -def transnav(context): - request = context['request'] - lang = request.COOKIES.get('selectedLanguage', 'en') - d = {'tr': "Ana Sayfa", 'en': "Dashboard", 'hi': "डैशबोर्ड", 'pt': "Página Inicial"} - c = {'tr': "Sohbet", 'en': "Chat", 'hi': "चैट", 'pt': "Bate-papo"} - p = {'tr': "Pong Oyunu", 'en': "Pong Game", 'hi': "पोंग खेल", 'pt': "Jogo de Pong"} - t = {'tr': "TKM Oyunu", 'en': "RPS Game", 'hi': "पत्थर-कागज-कैंची", 'pt': "PPT Jogo"} - r = {'tr': "Sıralama", 'en': "Ranking", 'hi': "रैंकिंग", 'pt': "Classificação"} - s = {'tr': "Mağaza", 'en': "Store", 'hi': "स्टोर", 'pt': "Loja"} - a = {'tr': "Arama", 'en': "Search", 'hi': "खोज", 'pt': "Pesquisa"} - h = {'tr': "Hakkımızda", 'en': "About Us", 'hi': "हमारे बारे में", 'pt': "Sobre nós"} - f = {'tr': "Profil", 'en': "Profile", 'hi': "प्रोफाइल", 'pt': "Perfil"} - k = {'tr': "Arkadaşlar", 'en': "Friends", 'hi': "मित्र", 'pt': "Amigos"} - g = {'tr': "Profil Ayarları", 'en': "Profile Settings", 'hi': "प्रोफाइल सेटिंग्स", 'pt': "Configurações do Perfil"} - o = {'tr': "Çıkış", 'en': "Logout", 'hi': "लॉग आउट", 'pt': "Sair"} - return d[lang], c[lang], p[lang], t[lang], r[lang], s[lang], a[lang], h[lang], f[lang], k[lang], g[lang], o[lang] +from django import template + + +register = template.Library() + +@register.simple_tag(takes_context=True) +def transnav(context): + request = context['request'] + lang = request.COOKIES.get('selectedLanguage', 'en') + d = {'tr': "Ana Sayfa", 'en': "Dashboard", 'hi': "डैशबोर्ड", 'pt': "Página Inicial"} + c = {'tr': "Sohbet", 'en': "Chat", 'hi': "चैट", 'pt': "Bate-papo"} + p = {'tr': "Pong Oyunu", 'en': "Pong Game", 'hi': "पोंग खेल", 'pt': "Jogo de Pong"} + t = {'tr': "TKM Oyunu", 'en': "RPS Game", 'hi': "पत्थर-कागज-कैंची", 'pt': "PPT Jogo"} + r = {'tr': "Sıralama", 'en': "Ranking", 'hi': "रैंकिंग", 'pt': "Classificação"} + s = {'tr': "Mağaza", 'en': "Store", 'hi': "स्टोर", 'pt': "Loja"} + a = {'tr': "Arama", 'en': "Search", 'hi': "खोज", 'pt': "Pesquisa"} + h = {'tr': "Hakkımızda", 'en': "About Us", 'hi': "हमारे बारे में", 'pt': "Sobre nós"} + f = {'tr': "Profil", 'en': "Profile", 'hi': "प्रोफाइल", 'pt': "Perfil"} + k = {'tr': "Arkadaşlar", 'en': "Friends", 'hi': "मित्र", 'pt': "Amigos"} + g = {'tr': "Profil Ayarları", 'en': "Profile Settings", 'hi': "प्रोफाइल सेटिंग्स", 'pt': "Configurações do Perfil"} + o = {'tr': "Çıkış", 'en': "Logout", 'hi': "लॉग आउट", 'pt': "Sair"} + return d[lang], c[lang], p[lang], t[lang], r[lang], s[lang], a[lang], h[lang], f[lang], k[lang], g[lang], o[lang] diff --git a/indianpong/pong/templatetags/user_info.py b/indianpong/pong/templatetags/user_info.py index 5331751d..19959a2d 100644 --- a/indianpong/pong/templatetags/user_info.py +++ b/indianpong/pong/templatetags/user_info.py @@ -1,15 +1,15 @@ -from django import template -from django.shortcuts import get_object_or_404 -from django.core.cache import cache -from pong.models import UserProfile - -register = template.Library() - -@register.simple_tag(takes_context=True) -def user_info(context): - request = context['request'] - - profile = get_object_or_404(UserProfile, username=request.user.username) - is_online = cache.get(f'online_{profile.username}', default=False) - is_playing = cache.get(f'playing_{profile.username}', default=False) +from django import template +from django.shortcuts import get_object_or_404 +from django.core.cache import cache +from pong.models import UserProfile + +register = template.Library() + +@register.simple_tag(takes_context=True) +def user_info(context): + request = context['request'] + + profile = get_object_or_404(UserProfile, username=request.user.username) + is_online = cache.get(f'online_{profile.username}', default=False) + is_playing = cache.get(f'playing_{profile.username}', default=False) return {'username': profile.username, 'avatar': profile.avatar.url, 'is_online': is_online, 'is_playing': is_playing} \ No newline at end of file diff --git a/indianpong/pong/update.py b/indianpong/pong/update.py index ce7006d2..e9ede4d7 100644 --- a/indianpong/pong/update.py +++ b/indianpong/pong/update.py @@ -1,128 +1,128 @@ - -from datetime import timedelta -import random - -def update_tournament(game): - from .models import Tournament - - tournament = Tournament.objects.get(id=game.tournament_id) - tournament.played_games_count += 1 - if tournament.played_games_count == 2: - tournament.create_final_round_matches() - elif tournament.played_games_count == 3: - tournament.status = "ended" - tournament.winner = game.winner - #? Maybe save end_date - tournament.save() - - -def update_wallet_elo(winner, loser): - winner.indian_wallet += random.randint(300, 500) - winner.elo_point += random.randint(20, 30) - - loser.indian_wallet += random.randint(20, 30) - lose_elo = random.randint(10, 20) - if lose_elo < loser.elo_point: - loser.elo_point -= lose_elo - winner.save() - loser.save() - - -def update_stats_pong(winner, loser, winnerscore, loserscore, game_duration, game_type): - # Update total games count - winner.game_stats_pong.total_games_pong += 1 - loser.game_stats_pong.total_games_pong += 1 - - - # Update stats for winner - winner.game_stats_pong.total_win_pong += 1 - winner.game_stats_pong.total_win_streak_pong += 1 - winner.game_stats_pong.total_lose_streak_pong = 0 - - # Update average points won and lost for winner - winner.game_stats_pong.total_avg_points_won_pong = ((winner.game_stats_pong.total_avg_points_won_pong * (winner.game_stats_pong.total_win_pong - 1)) + winnerscore) / winner.game_stats_pong.total_win_pong - winner.game_stats_pong.total_avg_points_lost_pong = ((winner.game_stats_pong.total_avg_points_lost_pong * (winner.game_stats_pong.total_win_pong - 1)) + loserscore) / winner.game_stats_pong.total_win_pong - - # Update stats for loser - loser.game_stats_pong.total_lose_pong += 1 - loser.game_stats_pong.total_win_rate_pong = (loser.game_stats_pong.total_win_pong / loser.game_stats_pong.total_games_pong) - loser.game_stats_pong.total_win_streak_pong = 0 - loser.game_stats_pong.total_lose_streak_pong += 1 - - # Update average points won and lost for loser - loser.game_stats_pong.total_avg_points_won_pong = ((loser.game_stats_pong.total_avg_points_won_pong * (loser.game_stats_pong.total_lose_pong - 1)) + loserscore) / loser.game_stats_pong.total_lose_pong - loser.game_stats_pong.total_avg_points_lost_pong = ((loser.game_stats_pong.total_avg_points_lost_pong * (loser.game_stats_pong.total_lose_pong - 1)) + winnerscore) / loser.game_stats_pong.total_lose_pong - - # Update total win rate - winner.game_stats_pong.total_win_rate_pong = (winner.game_stats_pong.total_win_pong / winner.game_stats_pong.total_games_pong) - loser.game_stats_pong.total_win_rate_pong = (loser.game_stats_pong.total_win_pong / loser.game_stats_pong.total_games_pong) - - # Update total average game duration for both winner and loser - winner_total_game_duration_seconds = winner.game_stats_pong.total_avg_game_duration_pong.total_seconds() * (winner.game_stats_pong.total_games_pong - 1) - loser_total_game_duration_seconds = loser.game_stats_pong.total_avg_game_duration_pong.total_seconds() * (loser.game_stats_pong.total_games_pong - 1) - - if game_type != "not_remote": - winner_total_game_duration_seconds += game_duration - loser_total_game_duration_seconds += game_duration - else: - winner_total_game_duration_seconds += game_duration.total_seconds() - loser_total_game_duration_seconds += game_duration.total_seconds() - - winner_avg_game_duration_seconds = winner_total_game_duration_seconds / winner.game_stats_pong.total_games_pong - winner.game_stats_pong.total_avg_game_duration_pong = timedelta(seconds=winner_avg_game_duration_seconds) - loser_avg_game_duration_seconds = loser_total_game_duration_seconds / loser.game_stats_pong.total_games_pong - loser.game_stats_pong.total_avg_game_duration_pong = timedelta(seconds=loser_avg_game_duration_seconds) - - # Save updated stats - winner.game_stats_pong.save() - loser.game_stats_pong.save() - - -def update_stats_rps(winner, loser, winnerscore, loserscore, game_duration, game_type): - # Update total games count - winner.game_stats_rps.total_games_rps += 1 - loser.game_stats_rps.total_games_rps += 1 - - # Update stats for winner - winner.game_stats_rps.total_win_rps += 1 - winner.game_stats_rps.total_win_streak_rps += 1 - winner.game_stats_rps.total_lose_streak_rps = 0 - - # Update average points won and lost for winner - winner.game_stats_rps.total_avg_points_won_rps = ((winner.game_stats_rps.total_avg_points_won_rps * (winner.game_stats_rps.total_win_rps - 1)) + winnerscore) / winner.game_stats_rps.total_win_rps - winner.game_stats_rps.total_avg_points_lost_rps = ((winner.game_stats_rps.total_avg_points_lost_rps * (winner.game_stats_rps.total_win_rps - 1)) + loserscore) / winner.game_stats_rps.total_win_rps - - - # Update stats for loser - loser.game_stats_rps.total_lose_rps += 1 - loser.game_stats_rps.total_win_rate_rps = (loser.game_stats_rps.total_win_rps / loser.game_stats_rps.total_games_rps) - loser.game_stats_rps.total_win_streak_rps = 0 - loser.game_stats_rps.total_lose_streak_rps += 1 - - # Update average points won and lost for loser - loser.game_stats_rps.total_avg_points_won_rps = ((loser.game_stats_rps.total_avg_points_won_rps * (loser.game_stats_rps.total_lose_rps - 1)) + loserscore) / loser.game_stats_rps.total_lose_rps - loser.game_stats_rps.total_avg_points_lost_rps = ((loser.game_stats_rps.total_avg_points_lost_rps * (loser.game_stats_rps.total_lose_rps - 1)) + winnerscore) / loser.game_stats_rps.total_lose_rps - - # Update total win rate - winner.game_stats_rps.total_win_rate_rps = (winner.game_stats_rps.total_win_rps / winner.game_stats_rps.total_games_rps) - loser.game_stats_rps.total_win_rate_rps = (loser.game_stats_rps.total_win_rps / loser.game_stats_rps.total_games_rps) - - winner_total_game_duration_seconds = winner.game_stats_rps.total_avg_game_duration_rps.total_seconds() * (winner.game_stats_rps.total_games_rps - 1) - loser_total_game_duration_seconds = loser.game_stats_rps.total_avg_game_duration_rps.total_seconds() * (loser.game_stats_rps.total_games_rps - 1) - # Update total average game duration for winner - if game_type != "not_remote": - winner_total_game_duration_seconds += game_duration - loser_total_game_duration_seconds += game_duration - else: - winner_total_game_duration_seconds += game_duration.total_seconds() - loser_total_game_duration_seconds += game_duration.total_seconds() - - - winner_avg_game_duration_seconds = winner_total_game_duration_seconds / winner.game_stats_rps.total_games_rps - winner.game_stats_rps.total_avg_game_duration_rps = timedelta(seconds=winner_avg_game_duration_seconds) - loser_avg_game_duration_seconds = loser_total_game_duration_seconds / loser.game_stats_rps.total_games_rps - loser.game_stats_rps.total_avg_game_duration_rps = timedelta(seconds=loser_avg_game_duration_seconds) - - # Save updated stats - winner.game_stats_rps.save() + +from datetime import timedelta +import random + +def update_tournament(game): + from .models import Tournament + + tournament = Tournament.objects.get(id=game.tournament_id) + tournament.played_games_count += 1 + if tournament.played_games_count == 2: + tournament.create_final_round_matches() + elif tournament.played_games_count == 3: + tournament.status = "ended" + tournament.winner = game.winner + #? Maybe save end_date + tournament.save() + + +def update_wallet_elo(winner, loser): + winner.indian_wallet += random.randint(300, 500) + winner.elo_point += random.randint(20, 30) + + loser.indian_wallet += random.randint(20, 30) + lose_elo = random.randint(10, 20) + if lose_elo < loser.elo_point: + loser.elo_point -= lose_elo + winner.save() + loser.save() + + +def update_stats_pong(winner, loser, winnerscore, loserscore, game_duration, game_type): + # Update total games count + winner.game_stats_pong.total_games_pong += 1 + loser.game_stats_pong.total_games_pong += 1 + + + # Update stats for winner + winner.game_stats_pong.total_win_pong += 1 + winner.game_stats_pong.total_win_streak_pong += 1 + winner.game_stats_pong.total_lose_streak_pong = 0 + + # Update average points won and lost for winner + winner.game_stats_pong.total_avg_points_won_pong = ((winner.game_stats_pong.total_avg_points_won_pong * (winner.game_stats_pong.total_win_pong - 1)) + winnerscore) / winner.game_stats_pong.total_win_pong + winner.game_stats_pong.total_avg_points_lost_pong = ((winner.game_stats_pong.total_avg_points_lost_pong * (winner.game_stats_pong.total_win_pong - 1)) + loserscore) / winner.game_stats_pong.total_win_pong + + # Update stats for loser + loser.game_stats_pong.total_lose_pong += 1 + loser.game_stats_pong.total_win_rate_pong = (loser.game_stats_pong.total_win_pong / loser.game_stats_pong.total_games_pong) + loser.game_stats_pong.total_win_streak_pong = 0 + loser.game_stats_pong.total_lose_streak_pong += 1 + + # Update average points won and lost for loser + loser.game_stats_pong.total_avg_points_won_pong = ((loser.game_stats_pong.total_avg_points_won_pong * (loser.game_stats_pong.total_lose_pong - 1)) + loserscore) / loser.game_stats_pong.total_lose_pong + loser.game_stats_pong.total_avg_points_lost_pong = ((loser.game_stats_pong.total_avg_points_lost_pong * (loser.game_stats_pong.total_lose_pong - 1)) + winnerscore) / loser.game_stats_pong.total_lose_pong + + # Update total win rate + winner.game_stats_pong.total_win_rate_pong = (winner.game_stats_pong.total_win_pong / winner.game_stats_pong.total_games_pong) + loser.game_stats_pong.total_win_rate_pong = (loser.game_stats_pong.total_win_pong / loser.game_stats_pong.total_games_pong) + + # Update total average game duration for both winner and loser + winner_total_game_duration_seconds = winner.game_stats_pong.total_avg_game_duration_pong.total_seconds() * (winner.game_stats_pong.total_games_pong - 1) + loser_total_game_duration_seconds = loser.game_stats_pong.total_avg_game_duration_pong.total_seconds() * (loser.game_stats_pong.total_games_pong - 1) + + if game_type != "not_remote": + winner_total_game_duration_seconds += game_duration + loser_total_game_duration_seconds += game_duration + else: + winner_total_game_duration_seconds += game_duration.total_seconds() + loser_total_game_duration_seconds += game_duration.total_seconds() + + winner_avg_game_duration_seconds = winner_total_game_duration_seconds / winner.game_stats_pong.total_games_pong + winner.game_stats_pong.total_avg_game_duration_pong = timedelta(seconds=winner_avg_game_duration_seconds) + loser_avg_game_duration_seconds = loser_total_game_duration_seconds / loser.game_stats_pong.total_games_pong + loser.game_stats_pong.total_avg_game_duration_pong = timedelta(seconds=loser_avg_game_duration_seconds) + + # Save updated stats + winner.game_stats_pong.save() + loser.game_stats_pong.save() + + +def update_stats_rps(winner, loser, winnerscore, loserscore, game_duration, game_type): + # Update total games count + winner.game_stats_rps.total_games_rps += 1 + loser.game_stats_rps.total_games_rps += 1 + + # Update stats for winner + winner.game_stats_rps.total_win_rps += 1 + winner.game_stats_rps.total_win_streak_rps += 1 + winner.game_stats_rps.total_lose_streak_rps = 0 + + # Update average points won and lost for winner + winner.game_stats_rps.total_avg_points_won_rps = ((winner.game_stats_rps.total_avg_points_won_rps * (winner.game_stats_rps.total_win_rps - 1)) + winnerscore) / winner.game_stats_rps.total_win_rps + winner.game_stats_rps.total_avg_points_lost_rps = ((winner.game_stats_rps.total_avg_points_lost_rps * (winner.game_stats_rps.total_win_rps - 1)) + loserscore) / winner.game_stats_rps.total_win_rps + + + # Update stats for loser + loser.game_stats_rps.total_lose_rps += 1 + loser.game_stats_rps.total_win_rate_rps = (loser.game_stats_rps.total_win_rps / loser.game_stats_rps.total_games_rps) + loser.game_stats_rps.total_win_streak_rps = 0 + loser.game_stats_rps.total_lose_streak_rps += 1 + + # Update average points won and lost for loser + loser.game_stats_rps.total_avg_points_won_rps = ((loser.game_stats_rps.total_avg_points_won_rps * (loser.game_stats_rps.total_lose_rps - 1)) + loserscore) / loser.game_stats_rps.total_lose_rps + loser.game_stats_rps.total_avg_points_lost_rps = ((loser.game_stats_rps.total_avg_points_lost_rps * (loser.game_stats_rps.total_lose_rps - 1)) + winnerscore) / loser.game_stats_rps.total_lose_rps + + # Update total win rate + winner.game_stats_rps.total_win_rate_rps = (winner.game_stats_rps.total_win_rps / winner.game_stats_rps.total_games_rps) + loser.game_stats_rps.total_win_rate_rps = (loser.game_stats_rps.total_win_rps / loser.game_stats_rps.total_games_rps) + + winner_total_game_duration_seconds = winner.game_stats_rps.total_avg_game_duration_rps.total_seconds() * (winner.game_stats_rps.total_games_rps - 1) + loser_total_game_duration_seconds = loser.game_stats_rps.total_avg_game_duration_rps.total_seconds() * (loser.game_stats_rps.total_games_rps - 1) + # Update total average game duration for winner + if game_type != "not_remote": + winner_total_game_duration_seconds += game_duration + loser_total_game_duration_seconds += game_duration + else: + winner_total_game_duration_seconds += game_duration.total_seconds() + loser_total_game_duration_seconds += game_duration.total_seconds() + + + winner_avg_game_duration_seconds = winner_total_game_duration_seconds / winner.game_stats_rps.total_games_rps + winner.game_stats_rps.total_avg_game_duration_rps = timedelta(seconds=winner_avg_game_duration_seconds) + loser_avg_game_duration_seconds = loser_total_game_duration_seconds / loser.game_stats_rps.total_games_rps + loser.game_stats_rps.total_avg_game_duration_rps = timedelta(seconds=loser_avg_game_duration_seconds) + + # Save updated stats + winner.game_stats_rps.save() loser.game_stats_rps.save() \ No newline at end of file diff --git a/indianpong/static/assets/intra-42-white.svg b/indianpong/static/assets/intra-42-white.svg index 767d8bfd..9f71c8c2 100644 --- a/indianpong/static/assets/intra-42-white.svg +++ b/indianpong/static/assets/intra-42-white.svg @@ -1,9 +1,9 @@ - - 42_Logo - - - - - + + 42_Logo + + + + + \ No newline at end of file diff --git a/indianpong/static/assets/intra42-logo.svg b/indianpong/static/assets/intra42-logo.svg index 25015ef1..60a1b8b4 100644 --- a/indianpong/static/assets/intra42-logo.svg +++ b/indianpong/static/assets/intra42-logo.svg @@ -1,9 +1,9 @@ - - 42_Logo - - - - - + + 42_Logo + + + + + \ No newline at end of file diff --git a/indianpong/static/assets/rps/icon-cheater.svg b/indianpong/static/assets/rps/icon-cheater.svg index fed936f8..2befc8c4 100644 --- a/indianpong/static/assets/rps/icon-cheater.svg +++ b/indianpong/static/assets/rps/icon-cheater.svg @@ -1,20 +1,20 @@ - - - - - - - - + + + + + + + + diff --git a/indianpong/static/assets/rps/icon-godofthings.svg b/indianpong/static/assets/rps/icon-godofthings.svg index 6a612946..47ef411d 100644 --- a/indianpong/static/assets/rps/icon-godofthings.svg +++ b/indianpong/static/assets/rps/icon-godofthings.svg @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/indianpong/static/assets/rps/icon-godthings.svg b/indianpong/static/assets/rps/icon-godthings.svg index 6a612946..47ef411d 100644 --- a/indianpong/static/assets/rps/icon-godthings.svg +++ b/indianpong/static/assets/rps/icon-godthings.svg @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/indianpong/static/assets/rps/icon-likeacheater.svg b/indianpong/static/assets/rps/icon-likeacheater.svg index fed936f8..2befc8c4 100644 --- a/indianpong/static/assets/rps/icon-likeacheater.svg +++ b/indianpong/static/assets/rps/icon-likeacheater.svg @@ -1,20 +1,20 @@ - - - - - - - - + + + + + + + + diff --git a/indianpong/static/css/changepassword.css b/indianpong/static/css/changepassword.css index d44faec6..971f38e1 100644 --- a/indianpong/static/css/changepassword.css +++ b/indianpong/static/css/changepassword.css @@ -1,277 +1,277 @@ - -/* Change Password */ - -.ChangePasswordArea { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - } - - - /* Forgot Password */ - - .ForgotPasswordArea { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - } - - .link { - color: #1778f2; - text-decoration: none; - } - - .signup-link { - color: #000000; - font-family: inherit; - font-size: 14px; - margin-top: 20px; - align-self: center; - } - - .signup-link .link { - color: #2260ff; - font-family: inherit; - text-decoration: none; - font-weight: 500; - font-size: 16px; - } - - .signup-link .link:hover { - text-decoration: underline; - } - - - .button-send-email { - width: auto; - height: 40px; - border-radius: 5px; - border: 2px solid var(--main-color); - background-color: var(--bg-color); - box-shadow: 4px 4px var(--main-color); - font-size: 17px; - font-weight: 600; - color: var(--font-color); - margin-bottom: -10px; - cursor: url('../assets/scrool/crossedsword.png'), auto; - } - - .button-send-email:hover { - transform: translate(-0.05em, -0.05em); - box-shadow: 0.15em 0.15em; - } - - -.form { - --input-focus: #f0302d; - --font-color: #323232; - --font-color-sub: #666; - --bg-color: beige; - --main-color: black; - padding: 20px; - background: #f5f2ee; - display: flex; - flex-direction: column; - justify-content: center; - gap: 20px; - border-radius: 5px; - border: 2px solid var(--main-color); - box-shadow: 4px 4px var(--main-color); -} - -.title { - color: var(--font-color); - font-weight: 900; - font-size: 20px; - -} - -.titlebottom { - color: var(--font-color-sub); - font-weight: 600; - font-size: 17px; -} - -label { - display: inline-block; - width: 90px; /* Adjust this value according to your needs */ - text-align: start; - margin-right: 10px; /* Space between the label and the input field */ - font-size: 16px; - font-weight: 600; - color: var(--font-color-sub); - opacity: 0.8; -} - -.input { - width: 250px; - height: 40px; - margin-left: auto; - margin-right: auto; - border-radius: 5px; - border: 2px solid var(--main-color); - background-color: var(--bg-color); - box-shadow: 4px 4px var(--main-color); - font-size: 15px; - font-weight: 600; - color: var(--font-color); - padding: 5px 10px; - outline: none; -} - -.input::placeholder { - color: var(--font-color-sub); - opacity: 0.8; -} - -.input:focus { - border: 2px solid var(--input-focus); -} - -.login-with { - display: flex; - gap: 10px; - justify-content: center; /* İçeriği yatayda ortala */ - align-items: center; -} - -.button-log { - cursor: pointer; - width: 40px; - height: 40px; - border-radius: 100%; - border: 2px solid var(--main-color); - background-color: var(--bg-color); - box-shadow: 4px 4px var(--main-color); - color: var(--font-color); - font-size: 25px; - display: flex; - justify-content: center; - align-items: center; -} - -.icon { - width: 24px; - height: 24px; - fill: var(--main-color); -} - -.button-log:active, .button-confirm:active { - box-shadow: 0px 0px var(--main-color); - transform: translate(3px, 3px); -} - -.button-confirm { - margin: 5px auto 0 auto; - width: 120px; - height: 40px; - border-radius: 5px; - border: 2px solid var(--main-color); - background-color: var(--bg-color); - box-shadow: 4px 4px var(--main-color); - font-size: 17px; - font-weight: 600; - color: var(--font-color); - cursor: url('../assets/scrool/crossedsword.png'), auto; -} - -.button-confirm:hover { - transform: translate(-0.05em, -0.05em); - box-shadow: 0.15em 0.15em; -} - - -.registerbtn { - margin: 5px auto 0 auto; - width: 120px; - height: 40px; - background: #FBCA1F; - font-family: inherit; - font-weight: 600; - font-size: 17px; - border: 3px solid black; - border-radius: 0.4em; - box-shadow: 0.1em 0.1em; -} - -.registerbtn:hover { - transform: translate(-0.05em, -0.05em); - box-shadow: 0.15em 0.15em; -} - -.registerbtn:active { - transform: translate(0.05em, 0.05em); - box-shadow: 0.05em 0.05em; -} - -.play { - transition: all .5s ease; - transition-delay: 300ms; -} - -.registerbtn:hover svg { - transform: scale(3) translate(50%); -} - -.now { - position: absolute; - left: 0; - transform: translateX(-100%); - transition: all .5s ease; - z-index: 2; -} - -.registerbtn:hover .now { - transform: translateX(10px); - transition-delay: 300ms; -} - -.registerbtn:hover .play { - transform: translateX(200%); - transition-delay: 300ms; -} - -.backbtn { - display: flex; - width: 50px; - height: 50px; - align-items: center; - justify-content: center; - border-radius: 3px; - letter-spacing: 1px; - transition: all 0.2s linear; - border: none; - cursor: pointer; - background: #F4F2ED; - } - - .backbtn > svg { - margin-right: 5px; - margin-left: 5px; - font-size: 30px; - transition: all 0.4s ease-in; - } - - .backbtn:hover > svg { - font-size: 1.2em; - transform: translateX(-5px); - } - - .backbtn:hover { - box-shadow: 9px 9px 33px #d1d1d1, -9px -9px 33px #ffffff; - transform: translateY(-2px); - } - - .error-message { - color: red; - font-size: 14px; - text-align: left; -} - -.no-underline { - text-decoration: none; + +/* Change Password */ + +.ChangePasswordArea { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + } + + + /* Forgot Password */ + + .ForgotPasswordArea { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + } + + .link { + color: #1778f2; + text-decoration: none; + } + + .signup-link { + color: #000000; + font-family: inherit; + font-size: 14px; + margin-top: 20px; + align-self: center; + } + + .signup-link .link { + color: #2260ff; + font-family: inherit; + text-decoration: none; + font-weight: 500; + font-size: 16px; + } + + .signup-link .link:hover { + text-decoration: underline; + } + + + .button-send-email { + width: auto; + height: 40px; + border-radius: 5px; + border: 2px solid var(--main-color); + background-color: var(--bg-color); + box-shadow: 4px 4px var(--main-color); + font-size: 17px; + font-weight: 600; + color: var(--font-color); + margin-bottom: -10px; + cursor: url('../assets/scrool/crossedsword.png'), auto; + } + + .button-send-email:hover { + transform: translate(-0.05em, -0.05em); + box-shadow: 0.15em 0.15em; + } + + +.form { + --input-focus: #f0302d; + --font-color: #323232; + --font-color-sub: #666; + --bg-color: beige; + --main-color: black; + padding: 20px; + background: #f5f2ee; + display: flex; + flex-direction: column; + justify-content: center; + gap: 20px; + border-radius: 5px; + border: 2px solid var(--main-color); + box-shadow: 4px 4px var(--main-color); +} + +.title { + color: var(--font-color); + font-weight: 900; + font-size: 20px; + +} + +.titlebottom { + color: var(--font-color-sub); + font-weight: 600; + font-size: 17px; +} + +label { + display: inline-block; + width: 90px; /* Adjust this value according to your needs */ + text-align: start; + margin-right: 10px; /* Space between the label and the input field */ + font-size: 16px; + font-weight: 600; + color: var(--font-color-sub); + opacity: 0.8; +} + +.input { + width: 250px; + height: 40px; + margin-left: auto; + margin-right: auto; + border-radius: 5px; + border: 2px solid var(--main-color); + background-color: var(--bg-color); + box-shadow: 4px 4px var(--main-color); + font-size: 15px; + font-weight: 600; + color: var(--font-color); + padding: 5px 10px; + outline: none; +} + +.input::placeholder { + color: var(--font-color-sub); + opacity: 0.8; +} + +.input:focus { + border: 2px solid var(--input-focus); +} + +.login-with { + display: flex; + gap: 10px; + justify-content: center; /* İçeriği yatayda ortala */ + align-items: center; +} + +.button-log { + cursor: pointer; + width: 40px; + height: 40px; + border-radius: 100%; + border: 2px solid var(--main-color); + background-color: var(--bg-color); + box-shadow: 4px 4px var(--main-color); + color: var(--font-color); + font-size: 25px; + display: flex; + justify-content: center; + align-items: center; +} + +.icon { + width: 24px; + height: 24px; + fill: var(--main-color); +} + +.button-log:active, .button-confirm:active { + box-shadow: 0px 0px var(--main-color); + transform: translate(3px, 3px); +} + +.button-confirm { + margin: 5px auto 0 auto; + width: 120px; + height: 40px; + border-radius: 5px; + border: 2px solid var(--main-color); + background-color: var(--bg-color); + box-shadow: 4px 4px var(--main-color); + font-size: 17px; + font-weight: 600; + color: var(--font-color); + cursor: url('../assets/scrool/crossedsword.png'), auto; +} + +.button-confirm:hover { + transform: translate(-0.05em, -0.05em); + box-shadow: 0.15em 0.15em; +} + + +.registerbtn { + margin: 5px auto 0 auto; + width: 120px; + height: 40px; + background: #FBCA1F; + font-family: inherit; + font-weight: 600; + font-size: 17px; + border: 3px solid black; + border-radius: 0.4em; + box-shadow: 0.1em 0.1em; +} + +.registerbtn:hover { + transform: translate(-0.05em, -0.05em); + box-shadow: 0.15em 0.15em; +} + +.registerbtn:active { + transform: translate(0.05em, 0.05em); + box-shadow: 0.05em 0.05em; +} + +.play { + transition: all .5s ease; + transition-delay: 300ms; +} + +.registerbtn:hover svg { + transform: scale(3) translate(50%); +} + +.now { + position: absolute; + left: 0; + transform: translateX(-100%); + transition: all .5s ease; + z-index: 2; +} + +.registerbtn:hover .now { + transform: translateX(10px); + transition-delay: 300ms; +} + +.registerbtn:hover .play { + transform: translateX(200%); + transition-delay: 300ms; +} + +.backbtn { + display: flex; + width: 50px; + height: 50px; + align-items: center; + justify-content: center; + border-radius: 3px; + letter-spacing: 1px; + transition: all 0.2s linear; + border: none; + cursor: pointer; + background: #F4F2ED; + } + + .backbtn > svg { + margin-right: 5px; + margin-left: 5px; + font-size: 30px; + transition: all 0.4s ease-in; + } + + .backbtn:hover > svg { + font-size: 1.2em; + transform: translateX(-5px); + } + + .backbtn:hover { + box-shadow: 9px 9px 33px #d1d1d1, -9px -9px 33px #ffffff; + transform: translateY(-2px); + } + + .error-message { + color: red; + font-size: 14px; + text-align: left; +} + +.no-underline { + text-decoration: none; } \ No newline at end of file diff --git a/indianpong/static/css/chat.css b/indianpong/static/css/chat.css index 929fc2b8..1960db27 100644 --- a/indianpong/static/css/chat.css +++ b/indianpong/static/css/chat.css @@ -1,783 +1,783 @@ -/* Chat Menu css */ - -.chat-section { - font-family: 'Inter', sans-serif; - box-shadow: inset 0 160px 0 0 #10b981; - display: flex; - align-items: center; - justify-content: center; - max-height: 720px; - background-color: #f1f5f9; -} - -.chat-container { - max-width: 1360px; - width: 100%; - height: 720px; - box-shadow: 0 8px 24px -4px rgba(0, 0, 0, .1); - background-color: white; - position: relative; -} - -#follow { - color: #e31b23 !important; -} - -#unfollow { - color:#515151 !important; -} - -#invite { - color:#0d8d45 !important; -} -/* end: Chat */ - -#unblock { - color:#515151 !important; -} - -#block { - color: #e31b23 !important; -} - -.room-profile-click { - cursor: pointer !important; -} - -/* start: Sidebar */ -.chat-sidebar { - width: 64px; - background-color: #f1f5f9; - height: 100%; - display: flex; - flex-direction: column; - position: absolute; - left: 0; - top: 0; - z-index: 50; -} -.chat-sidebar-logo { - font-size: 28px; - color: #059669; - display: block; - text-align: center; - padding: 12px 8px; - text-decoration: none; -} -.chat-sidebar-menu { - list-style-type: none; - display: flex; - flex-direction: column; - height: 100%; - padding: 16px 0; -} -.chat-sidebar-menu > * > a { - display: block; - text-align: center; - padding: 12px 8px; - font-size: 24px; - text-decoration: none; - color: #94a3b8; - position: relative; - transition: color .15s ease-in-out; -} -.chat-sidebar-menu > * > a:hover { - color: #475569; -} -.chat-sidebar-menu > .active > a { - box-shadow: inset 4px 0 0 0 #10b981; - color: #059669; - background-color: #d1fae5; -} -.chat-sidebar-menu > * > a::before { - content: attr(data-title); - position: absolute; - top: 50%; - left: calc(100% - 16px); - border-radius: 4px; - transform: translateY(-50%); - font-size: 13px; - padding: 6px 12px; - background-color: rgba(0, 0, 0, .6); - color: white; - opacity: 0; - visibility: hidden; - backdrop-filter: blur(10px); /* İstediğiniz blur miktarını ayarlayabilirsiniz */ - transition: all .15s ease-in-out; -} -.chat-sidebar-menu > * > a:hover::before { - left: calc(100% - 8px); - opacity: 1; - visibility: visible; -} -.chat-sidebar-profile { - margin-top: auto; - position: relative; -} -.chat-sidebar-profile-toggle { - background-color: transparent; - border: none; - outline: transparent; - width: 40px; - height: 40px; - margin: 0 auto; - display: block; - cursor: pointer; -} -.chat-sidebar-profile-toggle > img { - object-fit: cover; - width: 200%; - height: 100%; - border-radius: 10%; - border: 2px solid #059669; -} -.chat-sidebar-profile-dropdown { - position: absolute; - bottom: 100%; - left: 16px; - background-color: white; - box-shadow: 0 2px 8px rgba(0, 0, 0, .1); - list-style-type: none; - border-radius: 4px; - padding: 4px 0; - opacity: 0; - visibility: hidden; - transform: scale(.9); - transform-origin: left bottom; - transition: all .15s ease-in-out; -} -.chat-sidebar-profile.active .chat-sidebar-profile-dropdown { - opacity: 1; - visibility: visible; - transform: scale(1); -} -.chat-sidebar-profile-dropdown a { - display: flex; - align-items: center; - padding: 8px 12px; - text-decoration: none; - color: #94a3b8; - font-size: 14px; -} -.chat-sidebar-profile-dropdown a:hover { - background-color: #f1f5f9; - color: #475569; -} -.chat-sidebar-profile-dropdown a:active { - background-color: #e2e8f0; -} -.chat-sidebar-profile-dropdown a i { - margin-right: 12px; - font-size: 17px; -} -/* end: Sidebar */ - - - -/* start: Content side */ -.chat-content { - padding-left: 64px; - height: 100%; - position: relative; -} -.content-sidebar { - width: 256px; - background-color: white; - display: flex; - flex-direction: column; - height: 100%; - position: absolute; - top: 0; - left: 64px; -} -.content-sidebar-title { - font-size: 20px; - font-weight: 600; - padding: 16px; -} -.content-sidebar-form { - position: relative; - padding: 0 16px; -} -.content-sidebar-input { - padding: 8px 16px; - background-color: #f1f5f9; - border: 1px solid #cbd5e1; - outline: none; - width: 100%; - border-radius: 4px; - padding-right: 32px; - font-size: 14px; -} -.content-sidebar-input:focus { - border-color: #94a3b8; -} -.content-sidebar-submit { - position: absolute; - top: 50%; - transform: translateY(-50%); - right: 32px; - color: #94a3b8; - background-color: transparent; - outline: transparent; - border: none; - cursor: pointer; - transition: color .15s ease-in-out; -} -.content-sidebar-submit:hover { - color: #475569; -} -.content-messages { - overflow-y: auto; - height: 100%; - margin-top: 16px; -} -.content-messages-list { - list-style-type: none; - padding: 8px 0; -} -.content-messages-list > * > a { - display: flex; - align-items: center; - text-decoration: none; - color: #334155; - padding: 6px 16px; -} -.content-messages-list > * > a:hover { - background-color: #f8fafc; -} -.content-messages-list > .active > a { - background-color: #f8fafc; -} -.content-message-title { - margin-left: 16px; - margin-right: 16px; - color: #94a3b8; - font-size: 13px; - font-weight: 500; - margin-bottom: 2px; - position: relative; -} -.content-message-title > * { - position: relative; - z-index: 1; - padding: 0 4px 0 0; - background-color: white; -} -.content-message-title::before { - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%); - left: 0; - width: 100%; - height: 0; - border-bottom: 1px solid #cbd5e1; - z-index: 0; -} -.content-message-image { - width: 50px; - height: 50px; - border-radius: 50%; - object-fit: cover; - flex-shrink: 0; - margin-right: 12px; -} -.content-message-info { - display: grid; - margin-right: 12px; - width: 100%; -} -.content-message-name { - display: block; - font-size: 14px; - font-weight: 500; - margin-bottom: 2px; -} -.content-message-text { - font-size: 13px; - color: #94a3b8; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} -.content-message-more { - text-align: right; -} -.content-message-unread { - font-size: 12px; - font-weight: 500; - color: white; - background-color: #10b981; - padding: 2px 4px; - border-radius: 4px; -} -.content-message-time { - font-size: 12px; - color: #94a3b8; - font-weight: 500; -} -/* end: Content side */ - - - -/* start: Conversation */ -.conversation { - background-color: #f8fafc; - height: 100%; - padding-left: 256px; - display: flex; - -} -.conversation.active { - display: flex; - flex-direction: column; -} -.conversation-top { - padding: 8px 16px; - background-color: --white; - display: flex; - align-items: center; -} -.conversation-back { - background-color: transparent; - border: none; - outline: none; - width: 32px; - height: 32px; - align-items: center; - justify-content: center; - font-size: 20px; - cursor: pointer; - color: #94a3b8; - margin-right: 12px; - display: none; -} -.conversation-back:hover { - background-color: #f8fafc; - border-radius: 50%; - color: #475569; -} -.conversation-back:active { - background-color: #e2e8f0; -} -.conversation-user { - display: flex; - align-items: center; -} -.conversation-user-image { - width: 40px; - height: 40px; - border-radius: 50%; - object-fit: cover; - margin-right: 8px; -} -.conversation-user-name { - font-weight: 500; - font-size: 17px; -} -.conversation-user-status { - color: #94a3b8; - font-size: 13px; -} -.conversation-user-status::before { - content: ''; - width: 10px; - height: 10px; - background-color: #cbd5e1; - border-radius: 50%; - vertical-align: middle; - display: inline-block; - margin-right: 4px; -} -.conversation-user-status.online::before { - background-color: #10b981; -} -.conversation-buttons { - display: flex; - align-items: center; - margin-left: auto; -} -.conversation-buttons > * { - width: 36px; - height: 36px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 4px; - font-size: 20px; - background-color: transparent; - border: none; - outline: transparent; - cursor: pointer; - color: #475569; - margin-left: 4px; -} -.conversation-buttons > :hover { - background-color: #f8fafc; - color: #334155; -} -.conversation-buttons > :active { - background-color: #e2e8f0; -} - -.conversation-main { - overflow-y: auto; - overflow-x: hidden; - height: 100%; - padding: 16px; -} -.conversation-wrapper { - list-style-type: none; -} -.conversation-item { - display: flex; - align-items: flex-end; - flex-direction: row-reverse; - margin-bottom: 16px; -} -.conversation-item.me { - flex-direction: row; -} -.conversation-item-side { - margin-left: 8px; -} -.conversation-item.me .conversation-item-side { - margin-right: 8px; -} -.conversation-item-image { - width: 24px; - height: 24px; - border-radius: 50%; - object-fit: cover; - display: block; -} -.conversation-item-content { - width: 100%; -} -.conversation-item-wrapper:not(:last-child) { - margin-bottom: 8px; -} -.conversation-item-box { - max-width: 720px; - position: relative; - margin-left: unset; -} -.conversation-item.me .conversation-item-box { - - margin-left: auto; -} -.conversation-item-text { - padding: 12px 16px 8px; - background-color: white; - box-shadow: 0 2px 12px -2px rgba(0, 0, 0, .1); - font-size: 14px; - border-radius: 6px; - line-height: 1.5; - margin-left: 32px; -} -.conversation-item.me .conversation-item-text { - margin-left: unset; - margin-right: 32px; -} -.conversation-item.me .conversation-item-text { - background-color: #10b981; - box-shadow: 0 2px 12px -2px #10b981; - color: rgba(255, 255, 255, .8); -} -.conversation-item-time { - font-size: 10px; - color: #94a3b8; - display: block; - text-align: right; - margin-top: 4px; - line-height: 1; -} -.conversation-item.me .conversation-item-time { - color: rgba(255, 255, 255, .7); -} -.conversation-item-dropdown { - position: absolute; - top: 0; - left: 0; - opacity: 0; - visibility: hidden; - transition: all .15s ease-in-out; -} -.conversation-item.me .conversation-item-dropdown { - left: unset; - right: 0; -} -.conversation-item-wrapper:hover .conversation-item-dropdown { - opacity: 1; - visibility: visible; -} -.conversation-item-dropdown-toggle { - width: 24px; - height: 24px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 4px; - background-color: white; - outline: transparent; - border: 1px solid #e2e8f0; - cursor: pointer; - transition: all .15s ease-in-out; -} -.conversation-item-dropdown-toggle:hover { - background-color: #10b981; - color: white; - box-shadow: 0 2px 12px -2px #10b981; -} -.conversation-item-dropdown-toggle:active { - background-color: #059669; -} -.conversation-item-dropdown-list { - position: absolute; - top: 100%; - left: 0; - background-color: white; - z-index: 10; - box-shadow: 0 2px 8px rgba(0, 0, 0, .1); - border-radius: 4px; - padding: 4px 0; - list-style-type: none; - opacity: 0; - visibility: hidden; - transform: scale(.9); - transform-origin: left top; - transition: all .15s ease-in-out; -} -.conversation-item.me .conversation-item-dropdown-list { - left: unset; - right: 0; -} -.conversation-item-dropdown.active .conversation-item-dropdown-list { - opacity: 1; - visibility: visible; - transform: scale(1); -} -.conversation-item-dropdown-list a { - display: flex; - align-items: center; - text-decoration: none; - color: #94a3b8; - font-size: 13px; - padding: 6px 12px; -} -.conversation-item-dropdown-list a:hover { - background-color: #f8fafc; - color: #475569; -} -.conversation-item-dropdown-list a:active { - background-color: #e2e8f0; -} -.conversation-item-dropdown-list a i { - font-size: 16px; - margin-right: 8px; -} -.coversation-divider { - text-align: center; - font-size: 13px; - color: #94a3b8; - margin-bottom: 16px; - position: relative; -} -.coversation-divider::before { - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%); - left: 0; - width: 100%; - height: 0; - border-bottom: 1px solid #cbd5e1; -} -.coversation-divider span { - display: inline-block; - padding: 0 8px; - background-color: #f8fafc; - position: relative; - z-index: 1; -} - -.conversation-form { - padding: 8px 16px; - background-color: white; - display: flex; - align-items: flex-end; -} -.conversation-form-group { - width: 100%; - position: relative; - margin-left: 16px; - margin-right: 16px; -} -.conversation-form-input { - background-color: #f8fafc; - border: 1px solid #cbd5e1; - border-radius: 4px; - outline: transparent; - padding: 10px 32px 10px 16px; - font: inherit; - font-size: 14px; - resize: none; - width: 100%; - display: block; - line-height: 1.5; - max-height: calc(20px + ((14px * 2) * 6)); -} -.conversation-form-input:focus { - border-color: #94a3b8; -} -.conversation-form-record { - position: absolute; - bottom: 8px; - right: 16px; - font-size: 20px; - color: #94a3b8; - background-color: transparent; - border: none; - outline: transparent; - cursor: pointer; -} -.conversation-form-record:hover { - color: #475569; -} -.conversation-form-button { - width: 40px; - height: 40px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 4px; - border: none; - background-color: transparent; - outline: transparent; - font-size: 20px; - color: #94a3b8; - cursor: pointer; - flex-shrink: 0; -} -.conversation-form-button:hover { - background-color: #f8fafc; - color: #475569; -} -.conversation-form-button:active { - background-color: #e2e8f0; - color: #475569; -} -.conversation-form-submit { - background-color: #10b981; - box-shadow: 0 2px 8px -2px #10b981; - color: white; -} -.conversation-form-submit:hover { - background-color: #059669; - color: white; -} -.conversation-form-submit:active { - background-color: #047857; - color: white; -} -.conversation-default { - align-items: center; - justify-content: center; - padding: 16px; - padding-left: calc(256px + 16px); - color: #94a3b8; -} -.conversation-default i { - font-size: 32px; -} -.conversation-default p { - margin-top: 16px; -} -/* end: Conversation */ - - - -/* start: Breakpoints */ -@media screen and (max-width: 1600px) { - .chat-container { - max-width: unset; - height: 100vh; - } -} - -@media screen and (max-width: 767px) { - .chat-sidebar { - top: unset; - bottom: 0; - width: 100%; - height: 48px; - } - .chat-sidebar-logo { - display: none; - } - .chat-sidebar-menu { - flex-direction: row; - padding: 0; - } - .chat-sidebar-menu > *, - .chat-sidebar-menu > * > a { - width: 100%; - height: 100%; - } - .chat-sidebar-menu > * > a { - padding: 8px; - } - .chat-sidebar-menu > .active > a { - box-shadow: inset 0 4px 0 0 #10b981; - } - .chat-sidebar-profile { - margin-top: 0; - display: flex; - align-items: center; - } - .chat-sidebar-profile-toggle { - width: 32px; - height: 32px; - } - .chat-sidebar-profile-dropdown { - left: unset; - right: 16px; - } - - .conversation, - .chat-content { - padding-left: unset; - } - .content-sidebar { - left: unset; - z-index: 10; - width: 100%; - } - .chat-sidebar-menu > * > a::before { - left: 50%; - transform: translateX(-50%); - bottom: 100%; - top: unset; - } - .chat-sidebar-menu > * > a:hover::before { - bottom: calc(100% + 8px); - left: 50%; - } - - .chat-content { - position: relative; - height: calc(100% - 48px); - } - .conversation.active { - position: relative; - z-index: 20; - } - .conversation-back { - display: flex; - } - .conversation-default.active { - display: none; - padding: 16px; - } +/* Chat Menu css */ + +.chat-section { + font-family: 'Inter', sans-serif; + box-shadow: inset 0 160px 0 0 #10b981; + display: flex; + align-items: center; + justify-content: center; + max-height: 720px; + background-color: #f1f5f9; +} + +.chat-container { + max-width: 1360px; + width: 100%; + height: 720px; + box-shadow: 0 8px 24px -4px rgba(0, 0, 0, .1); + background-color: white; + position: relative; +} + +#follow { + color: #e31b23 !important; +} + +#unfollow { + color:#515151 !important; +} + +#invite { + color:#0d8d45 !important; +} +/* end: Chat */ + +#unblock { + color:#515151 !important; +} + +#block { + color: #e31b23 !important; +} + +.room-profile-click { + cursor: pointer !important; +} + +/* start: Sidebar */ +.chat-sidebar { + width: 64px; + background-color: #f1f5f9; + height: 100%; + display: flex; + flex-direction: column; + position: absolute; + left: 0; + top: 0; + z-index: 50; +} +.chat-sidebar-logo { + font-size: 28px; + color: #059669; + display: block; + text-align: center; + padding: 12px 8px; + text-decoration: none; +} +.chat-sidebar-menu { + list-style-type: none; + display: flex; + flex-direction: column; + height: 100%; + padding: 16px 0; +} +.chat-sidebar-menu > * > a { + display: block; + text-align: center; + padding: 12px 8px; + font-size: 24px; + text-decoration: none; + color: #94a3b8; + position: relative; + transition: color .15s ease-in-out; +} +.chat-sidebar-menu > * > a:hover { + color: #475569; +} +.chat-sidebar-menu > .active > a { + box-shadow: inset 4px 0 0 0 #10b981; + color: #059669; + background-color: #d1fae5; +} +.chat-sidebar-menu > * > a::before { + content: attr(data-title); + position: absolute; + top: 50%; + left: calc(100% - 16px); + border-radius: 4px; + transform: translateY(-50%); + font-size: 13px; + padding: 6px 12px; + background-color: rgba(0, 0, 0, .6); + color: white; + opacity: 0; + visibility: hidden; + backdrop-filter: blur(10px); /* İstediğiniz blur miktarını ayarlayabilirsiniz */ + transition: all .15s ease-in-out; +} +.chat-sidebar-menu > * > a:hover::before { + left: calc(100% - 8px); + opacity: 1; + visibility: visible; +} +.chat-sidebar-profile { + margin-top: auto; + position: relative; +} +.chat-sidebar-profile-toggle { + background-color: transparent; + border: none; + outline: transparent; + width: 40px; + height: 40px; + margin: 0 auto; + display: block; + cursor: pointer; +} +.chat-sidebar-profile-toggle > img { + object-fit: cover; + width: 200%; + height: 100%; + border-radius: 10%; + border: 2px solid #059669; +} +.chat-sidebar-profile-dropdown { + position: absolute; + bottom: 100%; + left: 16px; + background-color: white; + box-shadow: 0 2px 8px rgba(0, 0, 0, .1); + list-style-type: none; + border-radius: 4px; + padding: 4px 0; + opacity: 0; + visibility: hidden; + transform: scale(.9); + transform-origin: left bottom; + transition: all .15s ease-in-out; +} +.chat-sidebar-profile.active .chat-sidebar-profile-dropdown { + opacity: 1; + visibility: visible; + transform: scale(1); +} +.chat-sidebar-profile-dropdown a { + display: flex; + align-items: center; + padding: 8px 12px; + text-decoration: none; + color: #94a3b8; + font-size: 14px; +} +.chat-sidebar-profile-dropdown a:hover { + background-color: #f1f5f9; + color: #475569; +} +.chat-sidebar-profile-dropdown a:active { + background-color: #e2e8f0; +} +.chat-sidebar-profile-dropdown a i { + margin-right: 12px; + font-size: 17px; +} +/* end: Sidebar */ + + + +/* start: Content side */ +.chat-content { + padding-left: 64px; + height: 100%; + position: relative; +} +.content-sidebar { + width: 256px; + background-color: white; + display: flex; + flex-direction: column; + height: 100%; + position: absolute; + top: 0; + left: 64px; +} +.content-sidebar-title { + font-size: 20px; + font-weight: 600; + padding: 16px; +} +.content-sidebar-form { + position: relative; + padding: 0 16px; +} +.content-sidebar-input { + padding: 8px 16px; + background-color: #f1f5f9; + border: 1px solid #cbd5e1; + outline: none; + width: 100%; + border-radius: 4px; + padding-right: 32px; + font-size: 14px; +} +.content-sidebar-input:focus { + border-color: #94a3b8; +} +.content-sidebar-submit { + position: absolute; + top: 50%; + transform: translateY(-50%); + right: 32px; + color: #94a3b8; + background-color: transparent; + outline: transparent; + border: none; + cursor: pointer; + transition: color .15s ease-in-out; +} +.content-sidebar-submit:hover { + color: #475569; +} +.content-messages { + overflow-y: auto; + height: 100%; + margin-top: 16px; +} +.content-messages-list { + list-style-type: none; + padding: 8px 0; +} +.content-messages-list > * > a { + display: flex; + align-items: center; + text-decoration: none; + color: #334155; + padding: 6px 16px; +} +.content-messages-list > * > a:hover { + background-color: #f8fafc; +} +.content-messages-list > .active > a { + background-color: #f8fafc; +} +.content-message-title { + margin-left: 16px; + margin-right: 16px; + color: #94a3b8; + font-size: 13px; + font-weight: 500; + margin-bottom: 2px; + position: relative; +} +.content-message-title > * { + position: relative; + z-index: 1; + padding: 0 4px 0 0; + background-color: white; +} +.content-message-title::before { + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 0; + width: 100%; + height: 0; + border-bottom: 1px solid #cbd5e1; + z-index: 0; +} +.content-message-image { + width: 50px; + height: 50px; + border-radius: 50%; + object-fit: cover; + flex-shrink: 0; + margin-right: 12px; +} +.content-message-info { + display: grid; + margin-right: 12px; + width: 100%; +} +.content-message-name { + display: block; + font-size: 14px; + font-weight: 500; + margin-bottom: 2px; +} +.content-message-text { + font-size: 13px; + color: #94a3b8; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} +.content-message-more { + text-align: right; +} +.content-message-unread { + font-size: 12px; + font-weight: 500; + color: white; + background-color: #10b981; + padding: 2px 4px; + border-radius: 4px; +} +.content-message-time { + font-size: 12px; + color: #94a3b8; + font-weight: 500; +} +/* end: Content side */ + + + +/* start: Conversation */ +.conversation { + background-color: #f8fafc; + height: 100%; + padding-left: 256px; + display: flex; + +} +.conversation.active { + display: flex; + flex-direction: column; +} +.conversation-top { + padding: 8px 16px; + background-color: --white; + display: flex; + align-items: center; +} +.conversation-back { + background-color: transparent; + border: none; + outline: none; + width: 32px; + height: 32px; + align-items: center; + justify-content: center; + font-size: 20px; + cursor: pointer; + color: #94a3b8; + margin-right: 12px; + display: none; +} +.conversation-back:hover { + background-color: #f8fafc; + border-radius: 50%; + color: #475569; +} +.conversation-back:active { + background-color: #e2e8f0; +} +.conversation-user { + display: flex; + align-items: center; +} +.conversation-user-image { + width: 40px; + height: 40px; + border-radius: 50%; + object-fit: cover; + margin-right: 8px; +} +.conversation-user-name { + font-weight: 500; + font-size: 17px; +} +.conversation-user-status { + color: #94a3b8; + font-size: 13px; +} +.conversation-user-status::before { + content: ''; + width: 10px; + height: 10px; + background-color: #cbd5e1; + border-radius: 50%; + vertical-align: middle; + display: inline-block; + margin-right: 4px; +} +.conversation-user-status.online::before { + background-color: #10b981; +} +.conversation-buttons { + display: flex; + align-items: center; + margin-left: auto; +} +.conversation-buttons > * { + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + font-size: 20px; + background-color: transparent; + border: none; + outline: transparent; + cursor: pointer; + color: #475569; + margin-left: 4px; +} +.conversation-buttons > :hover { + background-color: #f8fafc; + color: #334155; +} +.conversation-buttons > :active { + background-color: #e2e8f0; +} + +.conversation-main { + overflow-y: auto; + overflow-x: hidden; + height: 100%; + padding: 16px; +} +.conversation-wrapper { + list-style-type: none; +} +.conversation-item { + display: flex; + align-items: flex-end; + flex-direction: row-reverse; + margin-bottom: 16px; +} +.conversation-item.me { + flex-direction: row; +} +.conversation-item-side { + margin-left: 8px; +} +.conversation-item.me .conversation-item-side { + margin-right: 8px; +} +.conversation-item-image { + width: 24px; + height: 24px; + border-radius: 50%; + object-fit: cover; + display: block; +} +.conversation-item-content { + width: 100%; +} +.conversation-item-wrapper:not(:last-child) { + margin-bottom: 8px; +} +.conversation-item-box { + max-width: 720px; + position: relative; + margin-left: unset; +} +.conversation-item.me .conversation-item-box { + + margin-left: auto; +} +.conversation-item-text { + padding: 12px 16px 8px; + background-color: white; + box-shadow: 0 2px 12px -2px rgba(0, 0, 0, .1); + font-size: 14px; + border-radius: 6px; + line-height: 1.5; + margin-left: 32px; +} +.conversation-item.me .conversation-item-text { + margin-left: unset; + margin-right: 32px; +} +.conversation-item.me .conversation-item-text { + background-color: #10b981; + box-shadow: 0 2px 12px -2px #10b981; + color: rgba(255, 255, 255, .8); +} +.conversation-item-time { + font-size: 10px; + color: #94a3b8; + display: block; + text-align: right; + margin-top: 4px; + line-height: 1; +} +.conversation-item.me .conversation-item-time { + color: rgba(255, 255, 255, .7); +} +.conversation-item-dropdown { + position: absolute; + top: 0; + left: 0; + opacity: 0; + visibility: hidden; + transition: all .15s ease-in-out; +} +.conversation-item.me .conversation-item-dropdown { + left: unset; + right: 0; +} +.conversation-item-wrapper:hover .conversation-item-dropdown { + opacity: 1; + visibility: visible; +} +.conversation-item-dropdown-toggle { + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + background-color: white; + outline: transparent; + border: 1px solid #e2e8f0; + cursor: pointer; + transition: all .15s ease-in-out; +} +.conversation-item-dropdown-toggle:hover { + background-color: #10b981; + color: white; + box-shadow: 0 2px 12px -2px #10b981; +} +.conversation-item-dropdown-toggle:active { + background-color: #059669; +} +.conversation-item-dropdown-list { + position: absolute; + top: 100%; + left: 0; + background-color: white; + z-index: 10; + box-shadow: 0 2px 8px rgba(0, 0, 0, .1); + border-radius: 4px; + padding: 4px 0; + list-style-type: none; + opacity: 0; + visibility: hidden; + transform: scale(.9); + transform-origin: left top; + transition: all .15s ease-in-out; +} +.conversation-item.me .conversation-item-dropdown-list { + left: unset; + right: 0; +} +.conversation-item-dropdown.active .conversation-item-dropdown-list { + opacity: 1; + visibility: visible; + transform: scale(1); +} +.conversation-item-dropdown-list a { + display: flex; + align-items: center; + text-decoration: none; + color: #94a3b8; + font-size: 13px; + padding: 6px 12px; +} +.conversation-item-dropdown-list a:hover { + background-color: #f8fafc; + color: #475569; +} +.conversation-item-dropdown-list a:active { + background-color: #e2e8f0; +} +.conversation-item-dropdown-list a i { + font-size: 16px; + margin-right: 8px; +} +.coversation-divider { + text-align: center; + font-size: 13px; + color: #94a3b8; + margin-bottom: 16px; + position: relative; +} +.coversation-divider::before { + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 0; + width: 100%; + height: 0; + border-bottom: 1px solid #cbd5e1; +} +.coversation-divider span { + display: inline-block; + padding: 0 8px; + background-color: #f8fafc; + position: relative; + z-index: 1; +} + +.conversation-form { + padding: 8px 16px; + background-color: white; + display: flex; + align-items: flex-end; +} +.conversation-form-group { + width: 100%; + position: relative; + margin-left: 16px; + margin-right: 16px; +} +.conversation-form-input { + background-color: #f8fafc; + border: 1px solid #cbd5e1; + border-radius: 4px; + outline: transparent; + padding: 10px 32px 10px 16px; + font: inherit; + font-size: 14px; + resize: none; + width: 100%; + display: block; + line-height: 1.5; + max-height: calc(20px + ((14px * 2) * 6)); +} +.conversation-form-input:focus { + border-color: #94a3b8; +} +.conversation-form-record { + position: absolute; + bottom: 8px; + right: 16px; + font-size: 20px; + color: #94a3b8; + background-color: transparent; + border: none; + outline: transparent; + cursor: pointer; +} +.conversation-form-record:hover { + color: #475569; +} +.conversation-form-button { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + border: none; + background-color: transparent; + outline: transparent; + font-size: 20px; + color: #94a3b8; + cursor: pointer; + flex-shrink: 0; +} +.conversation-form-button:hover { + background-color: #f8fafc; + color: #475569; +} +.conversation-form-button:active { + background-color: #e2e8f0; + color: #475569; +} +.conversation-form-submit { + background-color: #10b981; + box-shadow: 0 2px 8px -2px #10b981; + color: white; +} +.conversation-form-submit:hover { + background-color: #059669; + color: white; +} +.conversation-form-submit:active { + background-color: #047857; + color: white; +} +.conversation-default { + align-items: center; + justify-content: center; + padding: 16px; + padding-left: calc(256px + 16px); + color: #94a3b8; +} +.conversation-default i { + font-size: 32px; +} +.conversation-default p { + margin-top: 16px; +} +/* end: Conversation */ + + + +/* start: Breakpoints */ +@media screen and (max-width: 1600px) { + .chat-container { + max-width: unset; + height: 100vh; + } +} + +@media screen and (max-width: 767px) { + .chat-sidebar { + top: unset; + bottom: 0; + width: 100%; + height: 48px; + } + .chat-sidebar-logo { + display: none; + } + .chat-sidebar-menu { + flex-direction: row; + padding: 0; + } + .chat-sidebar-menu > *, + .chat-sidebar-menu > * > a { + width: 100%; + height: 100%; + } + .chat-sidebar-menu > * > a { + padding: 8px; + } + .chat-sidebar-menu > .active > a { + box-shadow: inset 0 4px 0 0 #10b981; + } + .chat-sidebar-profile { + margin-top: 0; + display: flex; + align-items: center; + } + .chat-sidebar-profile-toggle { + width: 32px; + height: 32px; + } + .chat-sidebar-profile-dropdown { + left: unset; + right: 16px; + } + + .conversation, + .chat-content { + padding-left: unset; + } + .content-sidebar { + left: unset; + z-index: 10; + width: 100%; + } + .chat-sidebar-menu > * > a::before { + left: 50%; + transform: translateX(-50%); + bottom: 100%; + top: unset; + } + .chat-sidebar-menu > * > a:hover::before { + bottom: calc(100% + 8px); + left: 50%; + } + + .chat-content { + position: relative; + height: calc(100% - 48px); + } + .conversation.active { + position: relative; + z-index: 20; + } + .conversation-back { + display: flex; + } + .conversation-default.active { + display: none; + padding: 16px; + } } \ No newline at end of file diff --git a/indianpong/static/css/local-tournament.css b/indianpong/static/css/local-tournament.css index 873c8b26..22980a3f 100644 --- a/indianpong/static/css/local-tournament.css +++ b/indianpong/static/css/local-tournament.css @@ -1,251 +1,251 @@ - -.tournament-start-info { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - padding: 20px; - margin-top: 3em; - background-color: rgba(0, 0, 0, 0.5); - width: 700px; - height: 650px; - border-radius: 10px; -} - -.tournamentLocalGameText { - color: greenyellow; - font-size: 30px; - margin: 0 0 20px; -} - -.game-info-menu-tournament { - position: absolute; - top: 0; - right: 0; -} - -.game-info-menu-local { - position: absolute; - top: 0; - right: 0; -} - -.tournamentLocalGamePlayerText { - color: greenyellow; - font-size: 16px; - font-weight: bold; - margin-bottom: 5px; - margin-top: 10px; -} - -.input-style { - padding: 10px; - border: 2px solid #ccc; - width: 70%; - border-radius: 5px; - font-size: 10px; - color: #555; - outline: none; -} - -.input-style:focus { - border-color: #007bff; - background-color: rgba(0, 0, 0, 0.5); -} - -.form-select { - width: 462px !important; -} - -.btn { - margin-top: 2em; - width: 300px; -} - -#show-bracket { - display: none; - margin-top: 5em; - margin-right: 2em; - width: 800px; - text-align: center; - height: 400px; - padding: 10px; - background-color: rgba(0, 0, 0, 0.393); -} - - -.tournament-bracket-title { -text-align: center; -font-size: 2rem; -font-weight: 900; -margin-bottom: 0.5em; -font-family: 'Roboto', sans-serif; -color: #fff; -} - -.game-chart-middle { -text-align: center; -} - -.game-chart-middle h1, -.game-chart-middle h2 { -font-size: 2rem; -font-weight: 900; -margin-bottom: 0.5em;; -font-family: 'Roboto', sans-serif; -} - -.game-bracket-area { -margin-left: 6em; -width: 50%; -margin-top: 1em; -} - -.theme { -height: 100%; -width: 100%; -position: absolute; -} -.bracket { -margin-right: 30px !important; - -} -.bracket { -display: flex; -flex-direction: row; -position: relative; -} -.column { -display: flex; -flex-direction: column; -min-height: 100%; -justify-content: space-around; -align-content: center; -} -.match { -position: relative; -display: flex; -flex-direction: column; -min-width: 240px; -max-width: 240px; -height: 62px; -margin: 12px 24px 12px 0; -} -.match-bottom team { - /* diğer stil özellikleri */ - pointer-events: auto; /* Eğer pointer-events: none; olarak atanmışsa, bu satırı ekleyin veya bu özelliği kaldırın */ - z-index: 1; /* Eğer bu elementin diğer elementlerin üzerinde olmasını istiyorsanız, z-index değerini artırabilirsiniz */ -} -.match .match-top { -border-radius: 2px 2px 0 0; -} -.match .match-bottom { -border-radius: 0 0 2px 2px; -} -.match .team { -display: flex; -align-items: center; -width: 100%; -height: 100%; -border: 1px solid rgb(255, 255, 255); -position: relative; -} -.match .team span { -padding-left: 8px; -color: #ffffff; -font-weight: bold; -} -.match .team span:last-child { -padding-right: 8px; -} -.match .team .score { -margin-left: auto; -} -.match .team:first-child { -margin-bottom: -1px; -} -.match-lines { -display: block; -position: absolute; -top: 50%; -bottom: 0; -margin-top: 0px; -right: -1px; -} -.match-lines .line { -background: red; -position: absolute; -} -.match-lines .line.one { -height: 1px; -width: 12px; -} -.match-lines .line.two { -height: 44px; -width: 1px; -left: 11px; -} -.match-lines.alt { -left: -12px; -} -.match:nth-child(even) .match-lines .line.two { -transform: translate(0, -100%); -} -.column:first-child .match-lines.alt { -display: none; -} -.column:last-child .match-lines { -display: none; -} -.column:last-child .match-lines.alt { -display: block; -} -.column:nth-child(2) .match-lines .line.two { -height: 88px; -} -.column:nth-child(3) .match-lines .line.two { -height: 175px; -} -.column:nth-child(4) .match-lines .line.two { -height: 262px; -} -.column:nth-child(5) .match-lines .line.two { -height: 349px; -} - - - -.disable-image .image, -.disable-seed .seed, -.disable-name .name, -.disable-score .score { -display: none !important; - -} -.disable-borders { -border-width: 0px !important; -} -.disable-borders .team { -border-width: 0px !important; -} -.disable-seperator .match-top { -border-bottom: 0px !important; -} -.disable-seperator .match-bottom { -border-top: 0px !important; -} -.disable-seperator .team:first-child { -margin-bottom: 0px; -} - -#gameInfosMenu { - display: none; -} - -.modal-backdrop { - display: none !important; /* Overlay'i kaldırır */ -} -.modal { - background-color: rgba(0,0,0,0.5); /* Modal arka planını yarı şeffaf yapar */ + +.tournament-start-info { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + padding: 20px; + margin-top: 3em; + background-color: rgba(0, 0, 0, 0.5); + width: 700px; + height: 650px; + border-radius: 10px; +} + +.tournamentLocalGameText { + color: greenyellow; + font-size: 30px; + margin: 0 0 20px; +} + +.game-info-menu-tournament { + position: absolute; + top: 0; + right: 0; +} + +.game-info-menu-local { + position: absolute; + top: 0; + right: 0; +} + +.tournamentLocalGamePlayerText { + color: greenyellow; + font-size: 16px; + font-weight: bold; + margin-bottom: 5px; + margin-top: 10px; +} + +.input-style { + padding: 10px; + border: 2px solid #ccc; + width: 70%; + border-radius: 5px; + font-size: 10px; + color: #555; + outline: none; +} + +.input-style:focus { + border-color: #007bff; + background-color: rgba(0, 0, 0, 0.5); +} + +.form-select { + width: 462px !important; +} + +.btn { + margin-top: 2em; + width: 300px; +} + +#show-bracket { + display: none; + margin-top: 5em; + margin-right: 2em; + width: 800px; + text-align: center; + height: 400px; + padding: 10px; + background-color: rgba(0, 0, 0, 0.393); +} + + +.tournament-bracket-title { +text-align: center; +font-size: 2rem; +font-weight: 900; +margin-bottom: 0.5em; +font-family: 'Roboto', sans-serif; +color: #fff; +} + +.game-chart-middle { +text-align: center; +} + +.game-chart-middle h1, +.game-chart-middle h2 { +font-size: 2rem; +font-weight: 900; +margin-bottom: 0.5em;; +font-family: 'Roboto', sans-serif; +} + +.game-bracket-area { +margin-left: 6em; +width: 50%; +margin-top: 1em; +} + +.theme { +height: 100%; +width: 100%; +position: absolute; +} +.bracket { +margin-right: 30px !important; + +} +.bracket { +display: flex; +flex-direction: row; +position: relative; +} +.column { +display: flex; +flex-direction: column; +min-height: 100%; +justify-content: space-around; +align-content: center; +} +.match { +position: relative; +display: flex; +flex-direction: column; +min-width: 240px; +max-width: 240px; +height: 62px; +margin: 12px 24px 12px 0; +} +.match-bottom team { + /* diğer stil özellikleri */ + pointer-events: auto; /* Eğer pointer-events: none; olarak atanmışsa, bu satırı ekleyin veya bu özelliği kaldırın */ + z-index: 1; /* Eğer bu elementin diğer elementlerin üzerinde olmasını istiyorsanız, z-index değerini artırabilirsiniz */ +} +.match .match-top { +border-radius: 2px 2px 0 0; +} +.match .match-bottom { +border-radius: 0 0 2px 2px; +} +.match .team { +display: flex; +align-items: center; +width: 100%; +height: 100%; +border: 1px solid rgb(255, 255, 255); +position: relative; +} +.match .team span { +padding-left: 8px; +color: #ffffff; +font-weight: bold; +} +.match .team span:last-child { +padding-right: 8px; +} +.match .team .score { +margin-left: auto; +} +.match .team:first-child { +margin-bottom: -1px; +} +.match-lines { +display: block; +position: absolute; +top: 50%; +bottom: 0; +margin-top: 0px; +right: -1px; +} +.match-lines .line { +background: red; +position: absolute; +} +.match-lines .line.one { +height: 1px; +width: 12px; +} +.match-lines .line.two { +height: 44px; +width: 1px; +left: 11px; +} +.match-lines.alt { +left: -12px; +} +.match:nth-child(even) .match-lines .line.two { +transform: translate(0, -100%); +} +.column:first-child .match-lines.alt { +display: none; +} +.column:last-child .match-lines { +display: none; +} +.column:last-child .match-lines.alt { +display: block; +} +.column:nth-child(2) .match-lines .line.two { +height: 88px; +} +.column:nth-child(3) .match-lines .line.two { +height: 175px; +} +.column:nth-child(4) .match-lines .line.two { +height: 262px; +} +.column:nth-child(5) .match-lines .line.two { +height: 349px; +} + + + +.disable-image .image, +.disable-seed .seed, +.disable-name .name, +.disable-score .score { +display: none !important; + +} +.disable-borders { +border-width: 0px !important; +} +.disable-borders .team { +border-width: 0px !important; +} +.disable-seperator .match-top { +border-bottom: 0px !important; +} +.disable-seperator .match-bottom { +border-top: 0px !important; +} +.disable-seperator .team:first-child { +margin-bottom: 0px; +} + +#gameInfosMenu { + display: none; +} + +.modal-backdrop { + display: none !important; /* Overlay'i kaldırır */ +} +.modal { + background-color: rgba(0,0,0,0.5); /* Modal arka planını yarı şeffaf yapar */ } \ No newline at end of file diff --git a/indianpong/static/css/modal.css b/indianpong/static/css/modal.css index bf5e4985..30649eeb 100644 --- a/indianpong/static/css/modal.css +++ b/indianpong/static/css/modal.css @@ -1,43 +1,43 @@ -@font-face { - font-family: 'PixelifySans'; - src: url('fonts/PixelifySans-VariableFont_wght.ttf'); -} - -.modal { - font-family: 'PixelifySans'; -} - -.modal.show .modal-dialog { - max-width: 30%; -} - -.modal-header { - padding-bottom: 0; -} - -.modal-body { - padding-top: 0; -} - -.modal-body h3 { - border-bottom: 1px solid; - font-size: 1.5rem; -} - -.modal-controls { - padding: 1rem 0px; - display: flex; - justify-content: space-between; -} - -.modal-controls .col:first-child { - font-weight: bold; -} - -.modal-keys{ - - padding: 0.1em 0.5em; - background-color: rgb(75, 73, 73); - border: 3px solid rgb(49, 49, 49); - color: rgb(224, 224, 224); -} +@font-face { + font-family: 'PixelifySans'; + src: url('fonts/PixelifySans-VariableFont_wght.ttf'); +} + +.modal { + font-family: 'PixelifySans'; +} + +.modal.show .modal-dialog { + max-width: 30%; +} + +.modal-header { + padding-bottom: 0; +} + +.modal-body { + padding-top: 0; +} + +.modal-body h3 { + border-bottom: 1px solid; + font-size: 1.5rem; +} + +.modal-controls { + padding: 1rem 0px; + display: flex; + justify-content: space-between; +} + +.modal-controls .col:first-child { + font-weight: bold; +} + +.modal-keys{ + + padding: 0.1em 0.5em; + background-color: rgb(75, 73, 73); + border: 3px solid rgb(49, 49, 49); + color: rgb(224, 224, 224); +} diff --git a/indianpong/static/css/navbar.css b/indianpong/static/css/navbar.css index e6d5054c..41d44d14 100644 --- a/indianpong/static/css/navbar.css +++ b/indianpong/static/css/navbar.css @@ -1,249 +1,249 @@ -/* NavBar */ - -.navbar { - background-color: rgba(51, 51, 51, 0); /* R: 51, G: 51, B: 51, Alfa: 0.7 (70% saydamlık) */ - padding: 5px; - display: flex; - justify-content: space-between; - align-items: center; - color: greenyellow; - } - - .nav-links li { - cursor:pointer; - font-family: 'Pixeboy-z8XGD'; - } - - .nav-links li a i { - margin-right: 5px; /* İkon ile metin arasındaki boşluğu ayarlar */ - font-size: 0.8em; - color: white; - } - - .nav-links li a { - cursor:pointer; - font-size: 1.2em; - color: greenyellow; - position: relative; - } - - .nav-links li a::after { - content: ""; - position: absolute; - left: 0; - right: 0; - bottom: 0; - height: 2px; /* Çizgi kalınlığını ayarlayabilirsiniz */ - background-color: red; /* Çizgi rengini ayarlayabilirsiniz */ - visibility: hidden; - transform: scaleX(0); - transition: transform 0.3s ease, visibility 0.3s ease; - } - - .nav-links li:not(.profile-menu) { - margin-top: 10px; - } - - .nav-links li a:hover::after { - visibility: visible; - transform: scaleX(1); - } - - /* Opsiyonel: Çizgi ile metin arasındaki boşluğu ayarlar */ - .nav-links li a:hover { - padding-bottom: px; - } - - /* Opsiyonel: Çizgiyi blurlamak için */ - .nav-links li a:hover::after { - backdrop-filter: blur(50px); /* Blurlama miktarını ayarlayabilirsiniz */ - } - - .logo-container { - display: flex; - align-items: center; - margin-left: 10px; - } - - .logo-container a, - .logo-container a:link, - .logo-container a:visited { - color: greenyellow; - text-decoration: none; - } - - .logo-container a .logo { - color: greenyellow; /* Ya da istediğiniz rengi belirtin */ - } - - .profile-menu { - position: relative; - } - - .profile-submenu { - display: none; - position: absolute; - top: 100%; - right: 0; /* Alt menüyü tamamen sağa yerleştirme */ - background-color: rgba(51, 51, 51, 0.8); /* Menü arka plan rengi */ - border-radius: 8px; - padding: 10px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - } - - .profile-menu:hover .profile-submenu { - display: block; - z-index: 900; - - } - - .profile-submenu a { - color: white; - text-decoration: none; - display: flex; - padding: 5px; - } - - .profile-submenu a:hover { - background-color: #333; /* Hover rengi */ - } - - .profile-image { - overflow: hidden; - border-radius: 50%; /* Profil resmini yuvarlak yapar */ - } - - .profile-image img { - width: 48px; - height: 48px; - border-radius: 50%; /* Profil resmini yuvarlak yapar */ - transition: transform 0.3s ease; /* Dönme animasyonu için */ - } - - .profile-menu:hover .profile-image img { - transform: rotate(360deg); /* Hover durumunda döndürme animasyonu */ - } - - .logo img { - width: 48px; - height: 48px; - margin-right: 10px; - } - - .logo { - font-family: 'alagard', sans-serif; - font-size: 1.5em; - display: flex; - align-items: center; - } - - .nav-links { - list-style: none; - display: flex; - margin: 0; - padding: 0; - } - - .nav-links li { - margin-right: 20px; - } - - .nav-links a { - text-decoration: none; - color: white; - } - - .burger-menu { - font-size: 2.5em; - cursor: pointer; - display: none; - z-index: 1; - } - - .container-top { - margin-top: 10px; - display: flex; - justify-content: center; - overflow-y: auto; - z-index: 2; - } - - .card { - background-color: #F1F1FB; - padding: 20px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - border-radius: 8px; - max-width: 1300px; - width: 100%; - max-height: auto; - height: auto; - margin: 0 auto; /* Ortalamak için */ - } - - @media screen and (max-width: 768px) { - .nav-links { - display: none; - flex-direction: column; - position: absolute; - top: 80px; - left: 0; - width: 100%; - background-color: rgba(51, 51, 51, 0.5); /* R: 51, G: 51, B: 51, Alfa: 0.5 (50% saydamlık) */ - z-index: 1; - backdrop-filter: blur(10px); /* Bulanıklık miktarını ayarlayabilirsiniz */ - transition: display 0.3s ease-in-out; - } - - .burger-menu { - display: block; - - } - - .profile-submenu { - display: none; - position: absolute; - flex-direction: column; - left: 0; - background-color: rgba(51, 51, 51, 0.8); - border-radius: 8px; - padding: 10px; - transition: display 0.3s ease-in-out; - - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - } - - .profile-submenu { - margin-top: 20px; - } - - .nav-links.show { - display: flex; - } - - .nav-links li { - margin: 0; - text-align: center; - margin-bottom: 10px; /* İtemler arasına boşluk ekle */ - } - - .nav-links li:not(.profile-menu) { - margin-top: 0px; - } - - .container-top { - margin-top: 60px; - } - - .navbar { - padding: 10px; /* Navbar'ın padding'ini artır */ - } - - .logo { - font-size: 1.2em; /* Logo font boyutunu küçült */ - } - } - - .order-card { - color: #fff; - } +/* NavBar */ + +.navbar { + background-color: rgba(51, 51, 51, 0); /* R: 51, G: 51, B: 51, Alfa: 0.7 (70% saydamlık) */ + padding: 5px; + display: flex; + justify-content: space-between; + align-items: center; + color: greenyellow; + } + + .nav-links li { + cursor:pointer; + font-family: 'Pixeboy-z8XGD'; + } + + .nav-links li a i { + margin-right: 5px; /* İkon ile metin arasındaki boşluğu ayarlar */ + font-size: 0.8em; + color: white; + } + + .nav-links li a { + cursor:pointer; + font-size: 1.2em; + color: greenyellow; + position: relative; + } + + .nav-links li a::after { + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 2px; /* Çizgi kalınlığını ayarlayabilirsiniz */ + background-color: red; /* Çizgi rengini ayarlayabilirsiniz */ + visibility: hidden; + transform: scaleX(0); + transition: transform 0.3s ease, visibility 0.3s ease; + } + + .nav-links li:not(.profile-menu) { + margin-top: 10px; + } + + .nav-links li a:hover::after { + visibility: visible; + transform: scaleX(1); + } + + /* Opsiyonel: Çizgi ile metin arasındaki boşluğu ayarlar */ + .nav-links li a:hover { + padding-bottom: px; + } + + /* Opsiyonel: Çizgiyi blurlamak için */ + .nav-links li a:hover::after { + backdrop-filter: blur(50px); /* Blurlama miktarını ayarlayabilirsiniz */ + } + + .logo-container { + display: flex; + align-items: center; + margin-left: 10px; + } + + .logo-container a, + .logo-container a:link, + .logo-container a:visited { + color: greenyellow; + text-decoration: none; + } + + .logo-container a .logo { + color: greenyellow; /* Ya da istediğiniz rengi belirtin */ + } + + .profile-menu { + position: relative; + } + + .profile-submenu { + display: none; + position: absolute; + top: 100%; + right: 0; /* Alt menüyü tamamen sağa yerleştirme */ + background-color: rgba(51, 51, 51, 0.8); /* Menü arka plan rengi */ + border-radius: 8px; + padding: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + + .profile-menu:hover .profile-submenu { + display: block; + z-index: 900; + + } + + .profile-submenu a { + color: white; + text-decoration: none; + display: flex; + padding: 5px; + } + + .profile-submenu a:hover { + background-color: #333; /* Hover rengi */ + } + + .profile-image { + overflow: hidden; + border-radius: 50%; /* Profil resmini yuvarlak yapar */ + } + + .profile-image img { + width: 48px; + height: 48px; + border-radius: 50%; /* Profil resmini yuvarlak yapar */ + transition: transform 0.3s ease; /* Dönme animasyonu için */ + } + + .profile-menu:hover .profile-image img { + transform: rotate(360deg); /* Hover durumunda döndürme animasyonu */ + } + + .logo img { + width: 48px; + height: 48px; + margin-right: 10px; + } + + .logo { + font-family: 'alagard', sans-serif; + font-size: 1.5em; + display: flex; + align-items: center; + } + + .nav-links { + list-style: none; + display: flex; + margin: 0; + padding: 0; + } + + .nav-links li { + margin-right: 20px; + } + + .nav-links a { + text-decoration: none; + color: white; + } + + .burger-menu { + font-size: 2.5em; + cursor: pointer; + display: none; + z-index: 1; + } + + .container-top { + margin-top: 10px; + display: flex; + justify-content: center; + overflow-y: auto; + z-index: 2; + } + + .card { + background-color: #F1F1FB; + padding: 20px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + border-radius: 8px; + max-width: 1300px; + width: 100%; + max-height: auto; + height: auto; + margin: 0 auto; /* Ortalamak için */ + } + + @media screen and (max-width: 768px) { + .nav-links { + display: none; + flex-direction: column; + position: absolute; + top: 80px; + left: 0; + width: 100%; + background-color: rgba(51, 51, 51, 0.5); /* R: 51, G: 51, B: 51, Alfa: 0.5 (50% saydamlık) */ + z-index: 1; + backdrop-filter: blur(10px); /* Bulanıklık miktarını ayarlayabilirsiniz */ + transition: display 0.3s ease-in-out; + } + + .burger-menu { + display: block; + + } + + .profile-submenu { + display: none; + position: absolute; + flex-direction: column; + left: 0; + background-color: rgba(51, 51, 51, 0.8); + border-radius: 8px; + padding: 10px; + transition: display 0.3s ease-in-out; + + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + } + + .profile-submenu { + margin-top: 20px; + } + + .nav-links.show { + display: flex; + } + + .nav-links li { + margin: 0; + text-align: center; + margin-bottom: 10px; /* İtemler arasına boşluk ekle */ + } + + .nav-links li:not(.profile-menu) { + margin-top: 0px; + } + + .container-top { + margin-top: 60px; + } + + .navbar { + padding: 10px; /* Navbar'ın padding'ini artır */ + } + + .logo { + font-size: 1.2em; /* Logo font boyutunu küçült */ + } + } + + .order-card { + color: #fff; + } \ No newline at end of file diff --git a/indianpong/static/css/ranking.css b/indianpong/static/css/ranking.css index 5d380fad..3642629f 100644 --- a/indianpong/static/css/ranking.css +++ b/indianpong/static/css/ranking.css @@ -1,463 +1,463 @@ - -/* .badge { - display: inline-block; - min-width: 24px; - padding: 0 6px; - color: #181824; - font-size: .9333333333rem; - font-weight: 600; - line-height: 1.6rem; - text-align: center; - background: #eff2fe; - border-radius: 12px -} - */ - - -.rankings-card { - background-color: rgba(241, 241, 251, 0.3) !important; - backdrop-filter: blur(3px); /* Arka planı 10 piksel bulanıklaştır */ - padding: 20px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - border-radius: 8px; - max-width: 1300px; - width: 100%; - height: auto; /* Yüksekliği otomatik ayarla */ - max-height: auto; - margin: 0 auto; /* Ortalamak için */ -} - -.data { - overflow: auto; - font-size: .9333333333rem -} - -.data .data-container { - min-width: fit-content -} - -.data .data-container .data-row { - display: flex; - align-items: center -} - -.data .data-container .data-row .data-cell { - flex: 1; - padding: 0 8px; - color: #eff2fe -} - -/* .data .data-body .data-row .data-cell:not(:nth-of-type(2)):not(:nth-of-type(3)):not(:nth-of-type(4)) { - - text-align: center; -} */ - -.data .data-body .data-row .data-cell:nth-of-type(1):nth-of-type(5):nth-of-type(6):nth-of-type(7) { - - text-align: center; -} - -.data .data-head .data-row .data-cell:nth-of-type(1):nth-of-type(3){ - - min-width: 75px; -} - - - -.data .data-container .data-row .data-cell.data-cell--xsm { - flex: .1 -} - -.data .data-container .data-row .data-cell.data-cell--sm { - flex: .5 -} - -.data .data-container .data-row .data-cell.data-cell--md { - flex: 1.5 -} - -.data .data-container .data-row .data-cell.data-cell--lg { - flex: 2 -} - -.data .data-container .data-row .data-cell:first-child { - padding-left: 0 -} - -.data .data-container .data-row .data-cell:last-child .data-filter { - border: 0 -} - -.data .data-container .data-row .data-cell .data-filter { - display: flex; - justify-content: space-between; - align-items: center; - padding: .5625rem .3125rem; - font-size: .8rem; - /* font-family: 'Pixeboy-z8XGD'; */ - font-weight: 600; - text-transform: uppercase; - border-right: 1px dashed #303044 -} - -.data .data-container .data-row .data-cell .data-filter:hover svg { - fill: #181824 -} - -.data .data-container .data-row .data-cell .data-filter svg { - width: 18px; - margin-top: .1rem; - margin-left: .4rem; - fill: #303044 -} - -.data .data-container .data-row .data-cell .data-filter.data-filter--clickable { - cursor: pointer -} - -.data .data-container .data-head { - color: #303044; - font-size: .8666666667rem; - background: #abaabf; - border: 1px solid transparent -} - -.data .data-container .data-head .data-cell { - color: #232334 -} - -.data .data-container .data-body { - padding: 15px 0 -} - -.data .data-container .data-body .data-item { - position: relative; - padding: 20px 0; - border: 1px solid rgba(171, 170, 191, .4); - border-radius: 12px; - text-decoration: none; - cursor: pointer; -} - -.data .data-container .data-body .data-item:not(:last-child) { - margin-bottom: 15px -} - -.data .data-container .data-body .data-item .data-row { - display: flex; - align-items: center -} - -.data .data-container .data-body .data-item .data-row .data-cell { - padding-left: 1rem -} - -.data .data-container .data-body .data-item.data-title-wrapper:hover { - color: #fff; - background: #c21aa5; - box-shadow: 0 4px 3px #0000001a, 0 0 1px #0000001a -} - -.data .data-container .data-body .data-item.data-title-wrapper:hover .label { - background: rgba(255, 255, 255, .3); - border: 0 -} - -.data .data-container .data-body .data-item.data-title-wrapper:hover .data-cell--title a { - color: #fff -} - -.data .data-container .data-body .data-item.data-title-wrapper .data-cell--title { - z-index: 5; - display: block; - line-height: 1.7em -} - -.data .data-container .data-body .data-item.data-title-wrapper .data-cell--title a { - color: #fff -} - -.data .data-container .data-body .data-item.data-title-wrapper .data-cell--title a:before { - content: ""; - position: absolute; - top: 0; - left: 0; - display: block; - width: 100%; - height: 100% -} - -/* Leaderboard podium */ - -.leaderboard-podium { - display: flex; - width: 85%; - margin: auto auto 55px -} - -.leaderboard-winner { - position: relative; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: 33.3333333333%; - color: #fff; - background-color: #232334; - border: 1px solid #303044; - border-radius: 10px; - transform: perspective(1000px); - transform-style: preserve-3d; - transition: all .2s ease-in; - text-decoration: none; - -} - -.leaderboard-winner:hover { - border: 1px solid #F99601 -} - -.leaderboard-winner:not(:last-child) { - margin-right: 25px -} - -.leaderboard-winner:not(.leaderboard-winner--rank1) { - top: 15px -} - -.leaderboard-winner.leaderboard-winner--rank1 { - order: 2; - background-color: #181824; - border-color: transparent; - cursor:pointer; -} - -.leaderboard-winner.leaderboard-winner--rank1you { - order: 2; - background-color: rgb(255, 187, 0); - border-color: transparent; -} - - -.leaderboard-winner.leaderboard-winner--rank1:before { - content: ""; - position: absolute; - z-index: 2; - width: 100%; - height: 100%; - background-color: #181824; - border-radius: 10px -} - -.leaderboard-winner.leaderboard-winner--rank1you:hover { - content: ""; - background-color: #181824; -} - - -.leaderboard-winner.leaderboard-winner--rank1:after { - content: ""; - position: absolute; - z-index: 0; - /* background: linear-gradient(45deg, #f00 0%, #ff9a00 10%, #d0de21 20%, #4fdc4a 30%, #3fdad8 40%, #2fc9e2 50%, #1c7fee 60%, #5f15f2 70%, #ba0cf8 80%, #fb07d9 90%, #f00 100%) repeat 0% 0%/300% 100%; */ - background: greenyellow; - border-radius: 10px; - transform: translateZ(-1px); - transition: inset .2s ease-in; - animation: rgb 6s linear infinite; - inset: -2px -} - -.leaderboard-winner.leaderboard-winner--rank1:hover:after { - inset: -3px -} - -.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-header, -.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-footer { - z-index: 3 -} - -.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-header .winner-img { - aspect-ratio: 1/1; - object-fit: cover; - /* border: 2px solid rgba(195, 194, 212, .3); */ -} - -.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-header .badge { - color: #fff; - background: #F99601 -} - -.leaderboard-winner.leaderboard-winner--rank2 .leaderboard-winner-header .badge { - color: #fff; - /* background: #F99601 */ -} - -.leaderboard-winner.leaderboard-winner--rank3 .leaderboard-winner-header .badge { - color: #fff; - /* background: #F99601 */ -} - -.leaderboard-winner.leaderboard-winner--rank2 { - order: 1; - cursor: pointer; -} - -.leaderboard-winner.leaderboard-winner--rank3 { - order: 3; - cursor: pointer; -} - -.leaderboard-winner .leaderboard-winner-header { - display: flex; - flex-direction: column; - align-items: center; - padding: 25px 15px 0 -} - -.leaderboard-winner .leaderboard-winner-header .winner-img { - aspect-ratio: 1/1; - object-fit: cover; - width: 7rem; - height: 7rem; - /* border: 2px solid rgba(195, 194, 212, .3); */ - border-radius: 55px; - box-shadow: 1px 1px 4px 2px #0003 -} - -.leaderboard-winner .leaderboard-winner-header h3 { - margin: 10px 0; - font-size: 1.0666666667rem; - font-weight: 400 -} - -.leaderboard-winner .leaderboard-winner-header span { - font-size: .7333333333rem -} - -.leaderboard-winner .leaderboard-winner-footer { - width: 100%; - font-size: 1.0666666667rem; - border-radius: 0 0 10px 10px -} - -.leaderboard-winner .leaderboard-winner-footer ul { - display: flex; - justify-content: space-between; - padding: 0 15px 15px; - margin-top: -20px -} - -.leaderboard-winner .leaderboard-winner-footer ul small { - font-size: .8rem -} - - -/* Leaderboard ranking */ - -.leaderboard-ranking { - padding: 25px 15px 10px; - background: #453a4e; - border-radius: 10px -} - -.leaderboard-ranking .data .data-container .data-head { - font-size: .8rem; - background-color: #181824; - border-radius: 5px -} - -.leaderboard-ranking .data .data-container .data-head .data-cell { - color: #fff -} - -.leaderboard-ranking .data .data-container .data-body img { - aspect-ratio: 1/1; - object-fit: cover; - width: 2.6666666667rem; - border-radius: 100%; - aspect-ratio: 1/1; - object-fit: cover; - margin-bottom:2px !important; -} - -.leaderboard-ranking .data .data-container .data-body .data-item { - position: relative; - display: block; - padding: 5px; - background-color: #232334; - border: 1px solid #181824; - transition: background-color .1s ease-in -} - -.leaderboard-ranking .data .data-container .data-body .data-item:hover { - background-color: #F99601 -} - -.leaderboard-ranking .data .data-container .data-body .data-item .data-content { - font-size: 1.0666666667rem -} - -.leaderboard-ranking .data .data-container .data-body .data-item .data-content .label { - margin-left: -1rem; - text-transform: lowercase; - background-color: #fff -} - -.leaderboard-ranking .data .leaderboard-pro:after { - top: initial; - right: initial; - bottom: .3333333333rem; - left: 1.7333333333rem; - font-size: .6rem -} - -ul li { - list-style: none -} - - -@media screen and (max-width: 1024px) { - .leaderboard-podium { - flex-wrap: wrap; - } - .leaderboard-winner { - width: 100%; - margin-right: 2%; - margin-bottom: 20px; - } - .leaderboard-winner:not(:last-child) { - margin-right: 0; - } - .leaderboard-winner.leaderboard-winner--rank1 { - order: 1; - background-color: #181824; - margin-bottom: 5px; - border-color: transparent - } - .leaderboard-winner.leaderboard-winner--rank2 { - order: 2; - - } - - .leaderboard-winner.leaderboard-winner--rank3 { - order: 33; - } -} - -.page-link { - cursor:pointer; -} - -.page-link-search { - cursor:auto !important; - color: tomato; -} - -.page-item.active .page-link-rankings, -.page-link.active { - background-color: #ff9500 !important; - border-color: #ff9500 !important; - color: #fff !important; - font-size: 1em !important; -} + +/* .badge { + display: inline-block; + min-width: 24px; + padding: 0 6px; + color: #181824; + font-size: .9333333333rem; + font-weight: 600; + line-height: 1.6rem; + text-align: center; + background: #eff2fe; + border-radius: 12px +} + */ + + +.rankings-card { + background-color: rgba(241, 241, 251, 0.3) !important; + backdrop-filter: blur(3px); /* Arka planı 10 piksel bulanıklaştır */ + padding: 20px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + border-radius: 8px; + max-width: 1300px; + width: 100%; + height: auto; /* Yüksekliği otomatik ayarla */ + max-height: auto; + margin: 0 auto; /* Ortalamak için */ +} + +.data { + overflow: auto; + font-size: .9333333333rem +} + +.data .data-container { + min-width: fit-content +} + +.data .data-container .data-row { + display: flex; + align-items: center +} + +.data .data-container .data-row .data-cell { + flex: 1; + padding: 0 8px; + color: #eff2fe +} + +/* .data .data-body .data-row .data-cell:not(:nth-of-type(2)):not(:nth-of-type(3)):not(:nth-of-type(4)) { + + text-align: center; +} */ + +.data .data-body .data-row .data-cell:nth-of-type(1):nth-of-type(5):nth-of-type(6):nth-of-type(7) { + + text-align: center; +} + +.data .data-head .data-row .data-cell:nth-of-type(1):nth-of-type(3){ + + min-width: 75px; +} + + + +.data .data-container .data-row .data-cell.data-cell--xsm { + flex: .1 +} + +.data .data-container .data-row .data-cell.data-cell--sm { + flex: .5 +} + +.data .data-container .data-row .data-cell.data-cell--md { + flex: 1.5 +} + +.data .data-container .data-row .data-cell.data-cell--lg { + flex: 2 +} + +.data .data-container .data-row .data-cell:first-child { + padding-left: 0 +} + +.data .data-container .data-row .data-cell:last-child .data-filter { + border: 0 +} + +.data .data-container .data-row .data-cell .data-filter { + display: flex; + justify-content: space-between; + align-items: center; + padding: .5625rem .3125rem; + font-size: .8rem; + /* font-family: 'Pixeboy-z8XGD'; */ + font-weight: 600; + text-transform: uppercase; + border-right: 1px dashed #303044 +} + +.data .data-container .data-row .data-cell .data-filter:hover svg { + fill: #181824 +} + +.data .data-container .data-row .data-cell .data-filter svg { + width: 18px; + margin-top: .1rem; + margin-left: .4rem; + fill: #303044 +} + +.data .data-container .data-row .data-cell .data-filter.data-filter--clickable { + cursor: pointer +} + +.data .data-container .data-head { + color: #303044; + font-size: .8666666667rem; + background: #abaabf; + border: 1px solid transparent +} + +.data .data-container .data-head .data-cell { + color: #232334 +} + +.data .data-container .data-body { + padding: 15px 0 +} + +.data .data-container .data-body .data-item { + position: relative; + padding: 20px 0; + border: 1px solid rgba(171, 170, 191, .4); + border-radius: 12px; + text-decoration: none; + cursor: pointer; +} + +.data .data-container .data-body .data-item:not(:last-child) { + margin-bottom: 15px +} + +.data .data-container .data-body .data-item .data-row { + display: flex; + align-items: center +} + +.data .data-container .data-body .data-item .data-row .data-cell { + padding-left: 1rem +} + +.data .data-container .data-body .data-item.data-title-wrapper:hover { + color: #fff; + background: #c21aa5; + box-shadow: 0 4px 3px #0000001a, 0 0 1px #0000001a +} + +.data .data-container .data-body .data-item.data-title-wrapper:hover .label { + background: rgba(255, 255, 255, .3); + border: 0 +} + +.data .data-container .data-body .data-item.data-title-wrapper:hover .data-cell--title a { + color: #fff +} + +.data .data-container .data-body .data-item.data-title-wrapper .data-cell--title { + z-index: 5; + display: block; + line-height: 1.7em +} + +.data .data-container .data-body .data-item.data-title-wrapper .data-cell--title a { + color: #fff +} + +.data .data-container .data-body .data-item.data-title-wrapper .data-cell--title a:before { + content: ""; + position: absolute; + top: 0; + left: 0; + display: block; + width: 100%; + height: 100% +} + +/* Leaderboard podium */ + +.leaderboard-podium { + display: flex; + width: 85%; + margin: auto auto 55px +} + +.leaderboard-winner { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 33.3333333333%; + color: #fff; + background-color: #232334; + border: 1px solid #303044; + border-radius: 10px; + transform: perspective(1000px); + transform-style: preserve-3d; + transition: all .2s ease-in; + text-decoration: none; + +} + +.leaderboard-winner:hover { + border: 1px solid #F99601 +} + +.leaderboard-winner:not(:last-child) { + margin-right: 25px +} + +.leaderboard-winner:not(.leaderboard-winner--rank1) { + top: 15px +} + +.leaderboard-winner.leaderboard-winner--rank1 { + order: 2; + background-color: #181824; + border-color: transparent; + cursor:pointer; +} + +.leaderboard-winner.leaderboard-winner--rank1you { + order: 2; + background-color: rgb(255, 187, 0); + border-color: transparent; +} + + +.leaderboard-winner.leaderboard-winner--rank1:before { + content: ""; + position: absolute; + z-index: 2; + width: 100%; + height: 100%; + background-color: #181824; + border-radius: 10px +} + +.leaderboard-winner.leaderboard-winner--rank1you:hover { + content: ""; + background-color: #181824; +} + + +.leaderboard-winner.leaderboard-winner--rank1:after { + content: ""; + position: absolute; + z-index: 0; + /* background: linear-gradient(45deg, #f00 0%, #ff9a00 10%, #d0de21 20%, #4fdc4a 30%, #3fdad8 40%, #2fc9e2 50%, #1c7fee 60%, #5f15f2 70%, #ba0cf8 80%, #fb07d9 90%, #f00 100%) repeat 0% 0%/300% 100%; */ + background: greenyellow; + border-radius: 10px; + transform: translateZ(-1px); + transition: inset .2s ease-in; + animation: rgb 6s linear infinite; + inset: -2px +} + +.leaderboard-winner.leaderboard-winner--rank1:hover:after { + inset: -3px +} + +.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-header, +.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-footer { + z-index: 3 +} + +.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-header .winner-img { + aspect-ratio: 1/1; + object-fit: cover; + /* border: 2px solid rgba(195, 194, 212, .3); */ +} + +.leaderboard-winner.leaderboard-winner--rank1 .leaderboard-winner-header .badge { + color: #fff; + background: #F99601 +} + +.leaderboard-winner.leaderboard-winner--rank2 .leaderboard-winner-header .badge { + color: #fff; + /* background: #F99601 */ +} + +.leaderboard-winner.leaderboard-winner--rank3 .leaderboard-winner-header .badge { + color: #fff; + /* background: #F99601 */ +} + +.leaderboard-winner.leaderboard-winner--rank2 { + order: 1; + cursor: pointer; +} + +.leaderboard-winner.leaderboard-winner--rank3 { + order: 3; + cursor: pointer; +} + +.leaderboard-winner .leaderboard-winner-header { + display: flex; + flex-direction: column; + align-items: center; + padding: 25px 15px 0 +} + +.leaderboard-winner .leaderboard-winner-header .winner-img { + aspect-ratio: 1/1; + object-fit: cover; + width: 7rem; + height: 7rem; + /* border: 2px solid rgba(195, 194, 212, .3); */ + border-radius: 55px; + box-shadow: 1px 1px 4px 2px #0003 +} + +.leaderboard-winner .leaderboard-winner-header h3 { + margin: 10px 0; + font-size: 1.0666666667rem; + font-weight: 400 +} + +.leaderboard-winner .leaderboard-winner-header span { + font-size: .7333333333rem +} + +.leaderboard-winner .leaderboard-winner-footer { + width: 100%; + font-size: 1.0666666667rem; + border-radius: 0 0 10px 10px +} + +.leaderboard-winner .leaderboard-winner-footer ul { + display: flex; + justify-content: space-between; + padding: 0 15px 15px; + margin-top: -20px +} + +.leaderboard-winner .leaderboard-winner-footer ul small { + font-size: .8rem +} + + +/* Leaderboard ranking */ + +.leaderboard-ranking { + padding: 25px 15px 10px; + background: #453a4e; + border-radius: 10px +} + +.leaderboard-ranking .data .data-container .data-head { + font-size: .8rem; + background-color: #181824; + border-radius: 5px +} + +.leaderboard-ranking .data .data-container .data-head .data-cell { + color: #fff +} + +.leaderboard-ranking .data .data-container .data-body img { + aspect-ratio: 1/1; + object-fit: cover; + width: 2.6666666667rem; + border-radius: 100%; + aspect-ratio: 1/1; + object-fit: cover; + margin-bottom:2px !important; +} + +.leaderboard-ranking .data .data-container .data-body .data-item { + position: relative; + display: block; + padding: 5px; + background-color: #232334; + border: 1px solid #181824; + transition: background-color .1s ease-in +} + +.leaderboard-ranking .data .data-container .data-body .data-item:hover { + background-color: #F99601 +} + +.leaderboard-ranking .data .data-container .data-body .data-item .data-content { + font-size: 1.0666666667rem +} + +.leaderboard-ranking .data .data-container .data-body .data-item .data-content .label { + margin-left: -1rem; + text-transform: lowercase; + background-color: #fff +} + +.leaderboard-ranking .data .leaderboard-pro:after { + top: initial; + right: initial; + bottom: .3333333333rem; + left: 1.7333333333rem; + font-size: .6rem +} + +ul li { + list-style: none +} + + +@media screen and (max-width: 1024px) { + .leaderboard-podium { + flex-wrap: wrap; + } + .leaderboard-winner { + width: 100%; + margin-right: 2%; + margin-bottom: 20px; + } + .leaderboard-winner:not(:last-child) { + margin-right: 0; + } + .leaderboard-winner.leaderboard-winner--rank1 { + order: 1; + background-color: #181824; + margin-bottom: 5px; + border-color: transparent + } + .leaderboard-winner.leaderboard-winner--rank2 { + order: 2; + + } + + .leaderboard-winner.leaderboard-winner--rank3 { + order: 33; + } +} + +.page-link { + cursor:pointer; +} + +.page-link-search { + cursor:auto !important; + color: tomato; +} + +.page-item.active .page-link-rankings, +.page-link.active { + background-color: #ff9500 !important; + border-color: #ff9500 !important; + color: #fff !important; + font-size: 1em !important; +} diff --git a/indianpong/static/css/remote-player.css b/indianpong/static/css/remote-player.css index d65d9a7d..cfb79c90 100644 --- a/indianpong/static/css/remote-player.css +++ b/indianpong/static/css/remote-player.css @@ -1,184 +1,184 @@ -.pongCanvas { - display: flex; - border: 8px solid rgb(178, 178, 178); - border-style: ridge; - width: 900px; - height: 600px; - margin-top: 30px; - background-color: gray; -} - -.matchmaking-button { - display: flex; - text-align: center; - margin-bottom: 1em; -} - -.other-button { - display: flex; - text-align: center; - margin-bottom: 1em; -} - - -.game-over-remote { - display: none; - position: absolute; - width: 300px; - top: 50%; - left: 55%; - transform: translate(-50%, -50%); - padding: 20px; - background-color: rgba(0, 0, 0, 0.8); - text-align: center; - font-family: Arial, sans-serif; - border-radius: 10px; - } - - - .game-over-remote p { - font-family: 'Pixeboy-z8XGD', sans-serif; - font-size: 20px; - font-weight: bold; - margin-top: -20px; - color: palegreen; - } - - .game-over-remote h1 { - font-size: 48px; - font-family: 'Pixeboy-z8XGD', sans-serif; - margin-bottom: 10px; - } - - .game-over-remote h2 { - font-size: 24px; - color: #ffffff; - font-family: 'Pixeboy-z8XGD', sans-serif; - margin-bottom: 20px; - } - - -.left-card { - width: 300px; - height: 600px; - background-color: #ddd; - padding: 10px; - margin-right: 2em; /* İstediğiniz boşluk değerini ayarlayabilirsiniz */ - margin-left: 1em; - margin-top: 2em; - float: left; -} - -.form-check-input[type="checkbox"] { - transform: scale(1.2); /* Büyüklüğü istediğiniz oranda ayarlayabilirsiniz */ -} - -.selectedmode { - font-size: 14px; - font-weight: bold; - text-align: center; - color:tomato; -} - -.game-mode-info { - display: none; - font-size: 11px !important; - text-align: center; - color: rgb(0, 136, 255); -} - -.game-mode-info-select { - display: block; - text-align: center; -} - -.abilitiesInfo { - display: none; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - padding: 20px; - background-color: rgba(1, 2, 1, 0.5); - width: 700px; - height: 500px; - border-radius: 10px; -} - -.invite-button { - border-color: #26b948; - color: #28a745; - text-align: center; - border-radius: 6px; - background-color: transparent; - width: 32px; - height: 32px; -} - -.invite-button:hover { - background-color: #28a745; - color: white; -} - - -.accept-button { - display: none; - border-color: #007bff; - margin-left: 5px; - color: #007bff; - text-align: center; - border-radius: 6px; - background-color: transparent; - width: 32px; - height: 32px; -} - -.accept-button:hover { - background-color: #007bff; - color: white; -} - -.decline-button { - display: none; - border-color: #dc3545; - margin-left: 5px; - color: #dc3545; - text-align: center; - border-radius: 6px; - background-color: transparent; - width: 32px; - height: 32px; -} - -.decline-button:hover { - background-color: #dc3545; - color: white; -} - - -.custom-table { - border-collapse: collapse; - width: 100%; -} - -.custom-table th, .custom-table td { - border: 1px solid #ddd; - padding: 3px; - text-align: center; -} - -.custom-table tr:hover { - background-color: #b6b6b6; -} - - -.canvas-container { - float: left; -} - - -.toast-close:hover { - cursor: pointer; - color: #000; +.pongCanvas { + display: flex; + border: 8px solid rgb(178, 178, 178); + border-style: ridge; + width: 900px; + height: 600px; + margin-top: 30px; + background-color: gray; +} + +.matchmaking-button { + display: flex; + text-align: center; + margin-bottom: 1em; +} + +.other-button { + display: flex; + text-align: center; + margin-bottom: 1em; +} + + +.game-over-remote { + display: none; + position: absolute; + width: 300px; + top: 50%; + left: 55%; + transform: translate(-50%, -50%); + padding: 20px; + background-color: rgba(0, 0, 0, 0.8); + text-align: center; + font-family: Arial, sans-serif; + border-radius: 10px; + } + + + .game-over-remote p { + font-family: 'Pixeboy-z8XGD', sans-serif; + font-size: 20px; + font-weight: bold; + margin-top: -20px; + color: palegreen; + } + + .game-over-remote h1 { + font-size: 48px; + font-family: 'Pixeboy-z8XGD', sans-serif; + margin-bottom: 10px; + } + + .game-over-remote h2 { + font-size: 24px; + color: #ffffff; + font-family: 'Pixeboy-z8XGD', sans-serif; + margin-bottom: 20px; + } + + +.left-card { + width: 300px; + height: 600px; + background-color: #ddd; + padding: 10px; + margin-right: 2em; /* İstediğiniz boşluk değerini ayarlayabilirsiniz */ + margin-left: 1em; + margin-top: 2em; + float: left; +} + +.form-check-input[type="checkbox"] { + transform: scale(1.2); /* Büyüklüğü istediğiniz oranda ayarlayabilirsiniz */ +} + +.selectedmode { + font-size: 14px; + font-weight: bold; + text-align: center; + color:tomato; +} + +.game-mode-info { + display: none; + font-size: 11px !important; + text-align: center; + color: rgb(0, 136, 255); +} + +.game-mode-info-select { + display: block; + text-align: center; +} + +.abilitiesInfo { + display: none; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; + padding: 20px; + background-color: rgba(1, 2, 1, 0.5); + width: 700px; + height: 500px; + border-radius: 10px; +} + +.invite-button { + border-color: #26b948; + color: #28a745; + text-align: center; + border-radius: 6px; + background-color: transparent; + width: 32px; + height: 32px; +} + +.invite-button:hover { + background-color: #28a745; + color: white; +} + + +.accept-button { + display: none; + border-color: #007bff; + margin-left: 5px; + color: #007bff; + text-align: center; + border-radius: 6px; + background-color: transparent; + width: 32px; + height: 32px; +} + +.accept-button:hover { + background-color: #007bff; + color: white; +} + +.decline-button { + display: none; + border-color: #dc3545; + margin-left: 5px; + color: #dc3545; + text-align: center; + border-radius: 6px; + background-color: transparent; + width: 32px; + height: 32px; +} + +.decline-button:hover { + background-color: #dc3545; + color: white; +} + + +.custom-table { + border-collapse: collapse; + width: 100%; +} + +.custom-table th, .custom-table td { + border: 1px solid #ddd; + padding: 3px; + text-align: center; +} + +.custom-table tr:hover { + background-color: #b6b6b6; +} + + +.canvas-container { + float: left; +} + + +.toast-close:hover { + cursor: pointer; + color: #000; } \ No newline at end of file diff --git a/indianpong/static/css/room-list.css b/indianpong/static/css/room-list.css index a576a391..ae260166 100644 --- a/indianpong/static/css/room-list.css +++ b/indianpong/static/css/room-list.css @@ -1,168 +1,168 @@ -@import url('https://fonts.googleapis.com/css2?family=Black+Ops+One&family=Honk&family=Jacquarda+Bastarda+9&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=Silkscreen:wght@400;700&display=swap'); -/* Room List */ - -:root { - --card-height: 300px; - --card-width: calc(var(--card-height) / 1.5); - } - -.room-wrapper { - max-width: 1000px; - margin: auto; - text-align: left; - display: flex; - flex-wrap: wrap; - } - -.pong-room, .rps-room { - margin-top: 4em; -} - -.pong-room a, .rps-room a { - text-decoration: none; -} - - -.game-room-card { - width: var(--card-width); - height: var(--card-height); - position: relative; - display: flex; - justify-content: center; - align-items: flex-end; - padding: 0 36px; - perspective: 2500px; - margin: 0 25px; - } - - .cover-image { - width: 100%; - max-height: 300px !important; - height: 300px; - object-fit: cover; - filter: brightness(0.5); - } - - .cover-image-started { - width: 100%; - max-height: 300px !important; - height: 300px; - object-fit: cover; - filter: hue-rotate(170deg) brightness(0.5); - } - - .cover-image-ended { - width: 100%; - max-height: 300px !important; - height: 300px; - object-fit: cover; - filter: grayscale(80%) brightness(0.5); - } - - .wrapper-rooms { - transition: all 0.5s; - position: absolute; - width: 100%; - z-index: -1; - } - - .game-room-card:hover .wrapper-rooms { - transform: perspective(900px) translateY(-5%) rotateX(25deg) translateZ(0); - box-shadow: 2px 35px 32px -8px rgba(0, 0, 0, 0.75); - -webkit-box-shadow: 2px 35px 32px -8px rgba(0, 0, 0, 0.75); - -moz-box-shadow: 2px 35px 32px -8px rgba(0, 0, 0, 0.75); - } - - .wrapper-rooms::before, - .wrapper-rooms::after { - content: ""; - opacity: 0; - width: 100%; - height: 80px; - transition: all 0.5s; - position: absolute; - left: 0; - } - .wrapper-rooms::before { - top: 0; - height: 100%; - background-image: linear-gradient( - to top, - transparent 46%, - rgba(12, 13, 19, 0.5) 68%, - rgba(12, 13, 19) 97% - ); - } - .wrapper-rooms::after { - bottom: 0; - opacity: 1; - background-image: linear-gradient( - to bottom, - transparent 46%, - rgba(12, 13, 19, 0.5) 68%, - rgba(12, 13, 19) 97% - ); - } - - .game-room-card:hover .wrapper-rooms::before, - .wrapper-rooms::after { - opacity: 1; - } - - .game-room-card:hover .wrapper-rooms::after { - height: 120px; - } - - .title-room { - width: 100%; - font-family: "Roboto", sans-serif; - font-weight: bold; - text-align: center; - font-style: normal; - color:white; - transition: transform 0.5s; - - } - - .title-room h4 { - margin-bottom: -2px; - } - - .title-room p { - margin-top: -6px; - } - - .game-room-card:hover .title { - transform: translate3d(0%, -50px, 100px); - } - - .character { - width: 100%; - opacity: 0; - transition: all 0.5s; - position: absolute; - z-index: -1; - } - - .game-room-card:hover .character { - opacity: 1; - transform: translate3d(0%, -30%, 100px); - } - - - .page-link { - cursor:pointer; -} - -.page-link-search { - cursor:auto !important; - color: tomato; -} - -.page-item.active .page-link-roomlist, -.page-link-roomlist.active { - background-color: #ff9500 !important; - border-color: #ff9500 !important; - color: #fff !important; - font-size: 1em !important; -} +@import url('https://fonts.googleapis.com/css2?family=Black+Ops+One&family=Honk&family=Jacquarda+Bastarda+9&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=Silkscreen:wght@400;700&display=swap'); +/* Room List */ + +:root { + --card-height: 300px; + --card-width: calc(var(--card-height) / 1.5); + } + +.room-wrapper { + max-width: 1000px; + margin: auto; + text-align: left; + display: flex; + flex-wrap: wrap; + } + +.pong-room, .rps-room { + margin-top: 4em; +} + +.pong-room a, .rps-room a { + text-decoration: none; +} + + +.game-room-card { + width: var(--card-width); + height: var(--card-height); + position: relative; + display: flex; + justify-content: center; + align-items: flex-end; + padding: 0 36px; + perspective: 2500px; + margin: 0 25px; + } + + .cover-image { + width: 100%; + max-height: 300px !important; + height: 300px; + object-fit: cover; + filter: brightness(0.5); + } + + .cover-image-started { + width: 100%; + max-height: 300px !important; + height: 300px; + object-fit: cover; + filter: hue-rotate(170deg) brightness(0.5); + } + + .cover-image-ended { + width: 100%; + max-height: 300px !important; + height: 300px; + object-fit: cover; + filter: grayscale(80%) brightness(0.5); + } + + .wrapper-rooms { + transition: all 0.5s; + position: absolute; + width: 100%; + z-index: -1; + } + + .game-room-card:hover .wrapper-rooms { + transform: perspective(900px) translateY(-5%) rotateX(25deg) translateZ(0); + box-shadow: 2px 35px 32px -8px rgba(0, 0, 0, 0.75); + -webkit-box-shadow: 2px 35px 32px -8px rgba(0, 0, 0, 0.75); + -moz-box-shadow: 2px 35px 32px -8px rgba(0, 0, 0, 0.75); + } + + .wrapper-rooms::before, + .wrapper-rooms::after { + content: ""; + opacity: 0; + width: 100%; + height: 80px; + transition: all 0.5s; + position: absolute; + left: 0; + } + .wrapper-rooms::before { + top: 0; + height: 100%; + background-image: linear-gradient( + to top, + transparent 46%, + rgba(12, 13, 19, 0.5) 68%, + rgba(12, 13, 19) 97% + ); + } + .wrapper-rooms::after { + bottom: 0; + opacity: 1; + background-image: linear-gradient( + to bottom, + transparent 46%, + rgba(12, 13, 19, 0.5) 68%, + rgba(12, 13, 19) 97% + ); + } + + .game-room-card:hover .wrapper-rooms::before, + .wrapper-rooms::after { + opacity: 1; + } + + .game-room-card:hover .wrapper-rooms::after { + height: 120px; + } + + .title-room { + width: 100%; + font-family: "Roboto", sans-serif; + font-weight: bold; + text-align: center; + font-style: normal; + color:white; + transition: transform 0.5s; + + } + + .title-room h4 { + margin-bottom: -2px; + } + + .title-room p { + margin-top: -6px; + } + + .game-room-card:hover .title { + transform: translate3d(0%, -50px, 100px); + } + + .character { + width: 100%; + opacity: 0; + transition: all 0.5s; + position: absolute; + z-index: -1; + } + + .game-room-card:hover .character { + opacity: 1; + transform: translate3d(0%, -30%, 100px); + } + + + .page-link { + cursor:pointer; +} + +.page-link-search { + cursor:auto !important; + color: tomato; +} + +.page-item.active .page-link-roomlist, +.page-link-roomlist.active { + background-color: #ff9500 !important; + border-color: #ff9500 !important; + color: #fff !important; + font-size: 1em !important; +} diff --git a/indianpong/static/css/rps.css b/indianpong/static/css/rps.css index e59acaab..e26ee037 100644 --- a/indianpong/static/css/rps.css +++ b/indianpong/static/css/rps.css @@ -1,455 +1,455 @@ -/* Font */ -@import url("https://fonts.googleapis.com/css2?family=Barlow+Semi+Condensed:wght@600;700&display=swap"); -@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); - -:root { - --light-text: #ffffff; - --dark-text: hsl(229, 25%, 31%); - --score-text: hsl(229, 64%, 46%); - --outline: hsl(217, 16%, 45%); - --bg-grad-1: hsl(214, 47%, 23%); - --bg-grad-2: hsl(237, 49%, 15%); - --scissors-1: hsl(39, 89%, 49%); - --scissors-2: hsl(40, 84%, 53%); - --paper-1: hsl(230, 89%, 62%); - --paper-2: hsl(230, 89%, 65%); - --godthings-1: hsl(112, 71%, 56%); - --godthings-2: hsl(112, 70%, 56%); - --cheater-1: hsl(181, 71%, 56%); - --cheater-2: hsl(181, 70%, 56%); - --rock-1: hsl(349, 71%, 52%); - --rock-2: hsl(349, 70%, 56%); - --shadow-light: #00000026; - --shadow-med: #0000004d; -} - -.container-top { - font-family: "Barlow Semi Condensed", sans-serif; - margin-top: 10px; - flex-direction: column; - justify-content: center; - overflow-x: hidden; - z-index: 2; -} - - -.form-check-input[type="checkbox"] { - transform: scale(1.2); /* Büyüklüğü istediğiniz oranda ayarlayabilirsiniz */ -} - -.selectedmode { - font-size: 14px; - font-weight: bold; - text-align: center; - color:tomato; -} - -.game-mode-info { - display: none; - font-size: 16px !important; - text-align: center; - color: rgb(0, 136, 255); -} - -.game-mode-info-select { - display: block; - text-align: center; -} - - -.rps-header-text { - color: white; - font-family: "Poppins", sans-serif; - font-weight: 700; - font-style: normal; - text-align: center; -} - -.header-top { - margin-left: auto; - margin-right: auto; -} - -.header { - display: flex; - justify-content: space-between; - align-items: center; - height: 150px; - max-width: 700px; - width: 100%; - border: 3px solid var(--outline); - border-radius: 20px; - padding: 1rem 1.4rem 1rem 2rem; -} - -.score { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - background: #fff; - border-radius: 10px; - width: 150px; - height: 100%; - line-height: 1; -} - - -.player1_name { - font-size: 1rem; - letter-spacing: 0.1em; - color: orangered; -} - -.player2_name { - font-size: 1rem; - letter-spacing: 0.1em; - color: orangered; -} - -.score__title { - font-size: 1.1rem; - letter-spacing: 0.1em; - color: var(--score-text); -} - -.score__number1 { - font-size: 4rem; - font-weight: 700; - color: var(--dark-text); -} - -.score__number2 { - font-size: 4rem; - font-weight: 700; - color: var(--dark-text); -} - - -/* Game */ -.game { - position: relative; - display: grid; - grid-template-columns: (repeat(4, 1fr)); - grid-template-areas: - "cheater godthings" - "paper scissors" - "rock rock"; - place-items: center; - height: 30rem; - padding-top: 2rem; -} - -.game::before { - content: ""; - position: absolute; - width: 100%; - height: 100%; - left: 28%; - top: 35%; - z-index: -1; -} - -.choice-btn { - border: none; - outline: none; - background: none; - cursor: pointer; -} - -.choice { - position: relative; - width: 8rem; - height: 8rem; - background: #fff; - border-radius: 50%; - display: grid; - place-items: center; - box-shadow: inset 0 0.5rem var(--shadow-light); -} - -.choice::before, -.choice::after { - content: ""; - position: absolute; - left: -15%; - top: -15%; - width: 130%; - height: 130%; - border-radius: 50%; - z-index: -1; -} - -.choice::after { - opacity: 0; - transition: opacity 0.4s ease; -} - -.choice-btn:focus .choice::after { - opacity: 1; - box-shadow: 0 0 0 2rem #223351; - z-index: -2; -} - -.choice img { - transform: scale(1.5); -} - -.choice.paper::before { - background: linear-gradient(to bottom, var(--paper-1), var(--paper-2)); - box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--paper-2); -} - -.choice.godthings::before { - background: linear-gradient(to bottom, var(--godthings-1), var(--godthings-2)); - box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--godthings-2); -} - -.choice.cheater::before { - background: linear-gradient(to bottom, var(--cheater-1), var(--cheater-2)); - box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--cheater-2); -} - -.choice.scissors::before { - background: linear-gradient(to bottom, var(--scissors-1), var(--scissors-2)); - box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--scissors-2); -} - -.choice.rock::before { - background: linear-gradient(to bottom, var(--rock-1), var(--rock-2)); - box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--rock-2); -} - -.choice-btn[data-choice="paper"] { - grid-area: paper; - -} - -.choice-btn[data-choice="godthings"] { - grid-area: godthings; - margin-bottom: 3rem; -} - -.choice-btn[data-choice="cheater"] { - grid-area: cheater; - margin-bottom: 3rem; -} - -.choice-btn[data-choice="scissors"] { - grid-area: scissors; -} - -.choice-btn[data-choice="rock"] { - grid-area: rock; -} - -/* Results */ -.results { - display: grid; - grid-template-columns: repeat(2, 1fr); - place-items: center; - grid-template-areas: - "you-title ai-title" - "you-picked ai-picked"; - max-width: 1000px; - margin: 0 auto; -} - -.results__heading { - color: white; - font-size: 1.5rem; - letter-spacing: 0.1em; - padding: 4rem 0 8rem; -} - -.results__result { - min-width: 10rem; - min-height: 10rem; - background: #16213d; - border-radius: 50%; - transform: scale(1.4); - z-index: -1; -} - -.results__heading:first-of-type { - grid-area: you-title; -} - -.results__heading:last-of-type { - grid-area: ai-title; -} - -.results__result:first-of-type { - grid-area: you-picked; -} - -.results__result:last-of-type { - grid-area: ai-picked; -} - -.results.show-winner { - grid-template-columns: repeat(3, 1fr); - grid-template-areas: - "you-title . ai-title" - "you-picked result-winner ai-picked"; -} - -.winner .choice::after { - box-shadow: 0 0 0 40px #293251, 0 0 0 80px #232c4b, 0 0 0 130px #1e2949; - animation: winner 1s ease forwards; -} - -@keyframes winner { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -.results__winner { - grid-area: result-winner; - display: grid; - place-items: center; -} - -.results__text { - color: white; - font-size: 3.5rem; -} - -.play-again { - background: #fff; - outline: none; - border: 2px solid transparent; - border-radius: 0.6rem; - color: var(--dark-text); - padding: 0.6rem 3.5rem; - font-family: inherit; - text-transform: inherit; - font-size: 1.3rem; - letter-spacing: 0.1em; - cursor: pointer; -} - -.play-again:focus { - border: 2px solid var(--outline); -} - -/* Rules Button */ -.rules-btn { - position: absolute; - bottom: 2rem; - right: 2rem; - background: none; - outline: none; - border: 2px solid var(--outline); - border-radius: 0.6rem; - color: var(--light-text); - padding: 0.6rem 2.5rem; - font-family: inherit; - text-transform: inherit; - font-size: 1.3rem; - letter-spacing: 0.1em; - cursor: pointer; -} - -.rules-btn:focus { - border: 2px solid #fff; -} - -/* Rules Modal */ -/* .modal { - position: absolute; - height: 100%; - width: 100%; - top: 0; - left: 0; - display: grid; - place-items: center; - background: var(--shadow-med); - opacity: 0; - transition: opacity 0.3s ease-in-out; - pointer-events: none; -} - -.modal__container { - background: #fff; - border-radius: 0.5rem; -} - -.modal__header { - display: flex; - width: 100%; - justify-content: space-between; - padding: 2rem 2rem 1rem; -} - -.modal__heading { - font-size: 1.5rem; - color: var(--dark-text); -} - -.close-btn { - border: none; - outline: none; - background: none; - cursor: pointer; -} - -.rules-img { - padding: 2rem 4rem; -} - -.show-modal { - opacity: 1; - pointer-events: initial; -} */ - -/* Footer */ -.footer { - position: absolute; - bottom: 2rem; - width: 100%; - padding: 0 2rem; - text-align: center; -} - -.attribution { - font-size: 12px; - text-align: center; -} - -.attribution a { - color: #ff652f; -} - -/* Utilities */ -.preload * { - transition: none; -} - -.hidden { - display: none; - margin-top: 2em; - margin-bottom: -3em; -} - -.user-count { - color:tomato; - text-align:center; - font-size: 26px; - font-family: "VT323", monospace; - margin-bottom: 8px; -} - -.user-count-text { - color: white; - font-size: 20px; - text-align:center; - font-family: "VT323", monospace; - margin-bottom:5px; - margin-top: 2em; +/* Font */ +@import url("https://fonts.googleapis.com/css2?family=Barlow+Semi+Condensed:wght@600;700&display=swap"); +@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); + +:root { + --light-text: #ffffff; + --dark-text: hsl(229, 25%, 31%); + --score-text: hsl(229, 64%, 46%); + --outline: hsl(217, 16%, 45%); + --bg-grad-1: hsl(214, 47%, 23%); + --bg-grad-2: hsl(237, 49%, 15%); + --scissors-1: hsl(39, 89%, 49%); + --scissors-2: hsl(40, 84%, 53%); + --paper-1: hsl(230, 89%, 62%); + --paper-2: hsl(230, 89%, 65%); + --godthings-1: hsl(112, 71%, 56%); + --godthings-2: hsl(112, 70%, 56%); + --cheater-1: hsl(181, 71%, 56%); + --cheater-2: hsl(181, 70%, 56%); + --rock-1: hsl(349, 71%, 52%); + --rock-2: hsl(349, 70%, 56%); + --shadow-light: #00000026; + --shadow-med: #0000004d; +} + +.container-top { + font-family: "Barlow Semi Condensed", sans-serif; + margin-top: 10px; + flex-direction: column; + justify-content: center; + overflow-x: hidden; + z-index: 2; +} + + +.form-check-input[type="checkbox"] { + transform: scale(1.2); /* Büyüklüğü istediğiniz oranda ayarlayabilirsiniz */ +} + +.selectedmode { + font-size: 14px; + font-weight: bold; + text-align: center; + color:tomato; +} + +.game-mode-info { + display: none; + font-size: 16px !important; + text-align: center; + color: rgb(0, 136, 255); +} + +.game-mode-info-select { + display: block; + text-align: center; +} + + +.rps-header-text { + color: white; + font-family: "Poppins", sans-serif; + font-weight: 700; + font-style: normal; + text-align: center; +} + +.header-top { + margin-left: auto; + margin-right: auto; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + height: 150px; + max-width: 700px; + width: 100%; + border: 3px solid var(--outline); + border-radius: 20px; + padding: 1rem 1.4rem 1rem 2rem; +} + +.score { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: #fff; + border-radius: 10px; + width: 150px; + height: 100%; + line-height: 1; +} + + +.player1_name { + font-size: 1rem; + letter-spacing: 0.1em; + color: orangered; +} + +.player2_name { + font-size: 1rem; + letter-spacing: 0.1em; + color: orangered; +} + +.score__title { + font-size: 1.1rem; + letter-spacing: 0.1em; + color: var(--score-text); +} + +.score__number1 { + font-size: 4rem; + font-weight: 700; + color: var(--dark-text); +} + +.score__number2 { + font-size: 4rem; + font-weight: 700; + color: var(--dark-text); +} + + +/* Game */ +.game { + position: relative; + display: grid; + grid-template-columns: (repeat(4, 1fr)); + grid-template-areas: + "cheater godthings" + "paper scissors" + "rock rock"; + place-items: center; + height: 30rem; + padding-top: 2rem; +} + +.game::before { + content: ""; + position: absolute; + width: 100%; + height: 100%; + left: 28%; + top: 35%; + z-index: -1; +} + +.choice-btn { + border: none; + outline: none; + background: none; + cursor: pointer; +} + +.choice { + position: relative; + width: 8rem; + height: 8rem; + background: #fff; + border-radius: 50%; + display: grid; + place-items: center; + box-shadow: inset 0 0.5rem var(--shadow-light); +} + +.choice::before, +.choice::after { + content: ""; + position: absolute; + left: -15%; + top: -15%; + width: 130%; + height: 130%; + border-radius: 50%; + z-index: -1; +} + +.choice::after { + opacity: 0; + transition: opacity 0.4s ease; +} + +.choice-btn:focus .choice::after { + opacity: 1; + box-shadow: 0 0 0 2rem #223351; + z-index: -2; +} + +.choice img { + transform: scale(1.5); +} + +.choice.paper::before { + background: linear-gradient(to bottom, var(--paper-1), var(--paper-2)); + box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--paper-2); +} + +.choice.godthings::before { + background: linear-gradient(to bottom, var(--godthings-1), var(--godthings-2)); + box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--godthings-2); +} + +.choice.cheater::before { + background: linear-gradient(to bottom, var(--cheater-1), var(--cheater-2)); + box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--cheater-2); +} + +.choice.scissors::before { + background: linear-gradient(to bottom, var(--scissors-1), var(--scissors-2)); + box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--scissors-2); +} + +.choice.rock::before { + background: linear-gradient(to bottom, var(--rock-1), var(--rock-2)); + box-shadow: 0 0.5rem var(--shadow-med), 0 0.5rem var(--rock-2); +} + +.choice-btn[data-choice="paper"] { + grid-area: paper; + +} + +.choice-btn[data-choice="godthings"] { + grid-area: godthings; + margin-bottom: 3rem; +} + +.choice-btn[data-choice="cheater"] { + grid-area: cheater; + margin-bottom: 3rem; +} + +.choice-btn[data-choice="scissors"] { + grid-area: scissors; +} + +.choice-btn[data-choice="rock"] { + grid-area: rock; +} + +/* Results */ +.results { + display: grid; + grid-template-columns: repeat(2, 1fr); + place-items: center; + grid-template-areas: + "you-title ai-title" + "you-picked ai-picked"; + max-width: 1000px; + margin: 0 auto; +} + +.results__heading { + color: white; + font-size: 1.5rem; + letter-spacing: 0.1em; + padding: 4rem 0 8rem; +} + +.results__result { + min-width: 10rem; + min-height: 10rem; + background: #16213d; + border-radius: 50%; + transform: scale(1.4); + z-index: -1; +} + +.results__heading:first-of-type { + grid-area: you-title; +} + +.results__heading:last-of-type { + grid-area: ai-title; +} + +.results__result:first-of-type { + grid-area: you-picked; +} + +.results__result:last-of-type { + grid-area: ai-picked; +} + +.results.show-winner { + grid-template-columns: repeat(3, 1fr); + grid-template-areas: + "you-title . ai-title" + "you-picked result-winner ai-picked"; +} + +.winner .choice::after { + box-shadow: 0 0 0 40px #293251, 0 0 0 80px #232c4b, 0 0 0 130px #1e2949; + animation: winner 1s ease forwards; +} + +@keyframes winner { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +.results__winner { + grid-area: result-winner; + display: grid; + place-items: center; +} + +.results__text { + color: white; + font-size: 3.5rem; +} + +.play-again { + background: #fff; + outline: none; + border: 2px solid transparent; + border-radius: 0.6rem; + color: var(--dark-text); + padding: 0.6rem 3.5rem; + font-family: inherit; + text-transform: inherit; + font-size: 1.3rem; + letter-spacing: 0.1em; + cursor: pointer; +} + +.play-again:focus { + border: 2px solid var(--outline); +} + +/* Rules Button */ +.rules-btn { + position: absolute; + bottom: 2rem; + right: 2rem; + background: none; + outline: none; + border: 2px solid var(--outline); + border-radius: 0.6rem; + color: var(--light-text); + padding: 0.6rem 2.5rem; + font-family: inherit; + text-transform: inherit; + font-size: 1.3rem; + letter-spacing: 0.1em; + cursor: pointer; +} + +.rules-btn:focus { + border: 2px solid #fff; +} + +/* Rules Modal */ +/* .modal { + position: absolute; + height: 100%; + width: 100%; + top: 0; + left: 0; + display: grid; + place-items: center; + background: var(--shadow-med); + opacity: 0; + transition: opacity 0.3s ease-in-out; + pointer-events: none; +} + +.modal__container { + background: #fff; + border-radius: 0.5rem; +} + +.modal__header { + display: flex; + width: 100%; + justify-content: space-between; + padding: 2rem 2rem 1rem; +} + +.modal__heading { + font-size: 1.5rem; + color: var(--dark-text); +} + +.close-btn { + border: none; + outline: none; + background: none; + cursor: pointer; +} + +.rules-img { + padding: 2rem 4rem; +} + +.show-modal { + opacity: 1; + pointer-events: initial; +} */ + +/* Footer */ +.footer { + position: absolute; + bottom: 2rem; + width: 100%; + padding: 0 2rem; + text-align: center; +} + +.attribution { + font-size: 12px; + text-align: center; +} + +.attribution a { + color: #ff652f; +} + +/* Utilities */ +.preload * { + transition: none; +} + +.hidden { + display: none; + margin-top: 2em; + margin-bottom: -3em; +} + +.user-count { + color:tomato; + text-align:center; + font-size: 26px; + font-family: "VT323", monospace; + margin-bottom: 8px; +} + +.user-count-text { + color: white; + font-size: 20px; + text-align:center; + font-family: "VT323", monospace; + margin-bottom:5px; + margin-top: 2em; } \ No newline at end of file diff --git a/indianpong/static/css/tournament-room.css b/indianpong/static/css/tournament-room.css index e8fec001..4a9795b5 100644 --- a/indianpong/static/css/tournament-room.css +++ b/indianpong/static/css/tournament-room.css @@ -1,458 +1,458 @@ - - -/* Game Room */ - -.indian-logo { - text-align: center; - } - - .logo-indian { - width: 150px; - height: 150px; - } - - .game-room-buttons { - text-align: center; - display:flex; - justify-content: center; - align-items: center; - } - - .tournament-description { - text-align: center; - color: red; - font-weight: bold; - font-size: 12px; - } - - .leave-button { - text-align: center; - background-color: rgba(255, 255, 255); - color: #454c55; - font-size: 14px; - font-weight: 600; - height: 52px; - line-height: 52px; - text-transform: uppercase; - border: none; - cursor: pointer; - margin-right: 1em !important; - margin-left: 1em !important; - padding: 0 5px; - width: 180px; - min-width: 180px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - transition: background .2s; - margin: 15px 0; - display: inline-block; - margin-bottom: 3em; - } - - .leave-button:hover { - background-color: rgba(255, 255, 255, 0.207); - } - - /* Eğer bi class'ınızı özelleştirmek istiyorsanız, bi class'ını kullanabilirsiniz. */ - - .leave-button .bi-x-circle-fill { - color: red; /* Belirli ikonun rengi */ - } - - .leave-button .bi-flag-fill { - color: green; /* Diğer ikonun rengi */ - } - - .leave-button .bi-calendar-check-fill { - color:#5c5be5; - } - - .leave-button .bi-4-square-fill { - color:#5c5be5; - } - - .player-wrapper { - max-width: 520px; - margin: auto; - text-align:center; - } - - .place { - text-align: left; - width: 90px; - height: 150px; - display: inline-block; - margin: 0px 15px; - vertical-align: top; - } - - .avatar-container img { - height: 90px; - width: 90px; - object-fit: cover; - } - - .winner-container { - display:flex; - justify-content:center; - text-align:center; - align-items:center; - flex-direction: column; - } - - .winner-avatar { - height: 90px; - width: 90px; - object-fit: cover; - border: 3px solid greenyellow; - } - - .avatar-container-creator { - height: 90px; - width: 90px; - object-fit: cover; - border: 1px solid orangered; - } - - .winner-info { - margin-top:8px; - } - - .crown-icon { - width: 20px; /* Taç ikonunun genişliği */ - height: auto; /* Otomatik yükseklik ayarı */ - margin-top: -5px; - } - - .losers-winner-text { - color: tomato; - text-align:center; - font-style:italic; - font-weight: bold; - font-size: 14px; - } - - .winner-guy-text { - color: greenyellow; - text-align:center; - font-style:italic; - font-weight: bold; - font-size: 14px; - } - - .player-info { - font-size: 15px; - font-weight: 700; - } - - .truncate-pseudo { - color: orange; - text-align: center; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; - } - - .truncate-pseudo-creator { - color: orangered; - text-align: center; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; - } - - .game-room-avatar { - border: 1px solid #dadada; - max-width: 100%; - aspect-ratio: 1/1; - object-fit: cover; - height: 100%; - } - - .game-room-avatar-winner { - max-width: 100%; - aspect-ratio: 1/1; - object-fit: cover; - height: 100%; - } - - .game-room-avatar-none { - border: 1px solid #dadada; - width: 100%; - left: 0; - top: 0; - } - - .right-refresh { - position: absolute; - right:25px; - - font-size: 1.2em; - } - - .refresh-button { - cursor: pointer; - color: white; - } - - .refresh-button:hover { - color: greenyellow; - } - - -/* Game Room Area */ - -.game-chart-middle { - text-align: center; - } - - .game-chart-middle h1, - .game-chart-middle h2 { - font-size: 2rem; - font-weight: 900; - margin-bottom: 0.5em;; - font-family: 'Roboto', sans-serif; - } - - .game-bracket-area { - margin-right: auto; - margin-left: auto; - width: 50%; - } - - #game-bracket-section { - display: none; - - } - - #gameroombracket { - display: none; /* veya başka bir değer */ - } - - - .theme { - height: 100%; - width: 100%; - position: absolute; - } - .bracket { - padding: 40px; - margin: 5px; - } - .bracket { - display: flex; - flex-direction: row; - position: relative; - } - .column { - display: flex; - flex-direction: column; - min-height: 100%; - justify-content: space-around; - align-content: center; - } - .match { - position: relative; - display: flex; - flex-direction: column; - min-width: 240px; - max-width: 240px; - height: 62px; - margin: 12px 24px 12px 0; - } - .match .match-top { - border-radius: 2px 2px 0 0; - } - .match .match-bottom { - border-radius: 0 0 2px 2px; - } - .match .team { - display: flex; - align-items: center; - width: 100%; - height: 100%; - border: 1px solid rgb(255, 255, 255); - position: relative; - } - .match .team span { - padding-left: 8px; - color: #ffffff; - font-weight: bold; - } - .match .team span:last-child { - padding-right: 8px; - } - .match .team .score { - margin-left: auto; - } - .match .team:first-child { - margin-bottom: -1px; - } - .match-lines { - display: block; - position: absolute; - top: 50%; - bottom: 0; - margin-top: 0px; - right: -1px; - } - .match-lines .line { - background: red; - position: absolute; - } - .match-lines .line.one { - height: 1px; - width: 12px; - } - .match-lines .line.two { - height: 44px; - width: 1px; - left: 11px; - } - .match-lines.alt { - left: -12px; - } - .match:nth-child(even) .match-lines .line.two { - transform: translate(0, -100%); - } - .column:first-child .match-lines.alt { - display: none; - } - .column:last-child .match-lines { - display: none; - } - .column:last-child .match-lines.alt { - display: block; - } - .column:nth-child(2) .match-lines .line.two { - height: 88px; - } - .column:nth-child(3) .match-lines .line.two { - height: 175px; - } - .column:nth-child(4) .match-lines .line.two { - height: 262px; - } - .column:nth-child(5) .match-lines .line.two { - height: 349px; - } - - .match-link-a { - margin-left:auto; - margin-right:-7.5em; - } - - .match-link { - font-size: 16px; - color: tomato !important; - } - - .match-link:hover { - color: rgb(0, 110, 255) !important; - cursor: pointer; - } - - .disable-image .image, - .disable-seed .seed, - .disable-name .name, - .disable-score .score { - display: none !important; - - } - .disable-borders { - border-width: 0px !important; - } - .disable-borders .team { - border-width: 0px !important; - } - .disable-seperator .match-top { - border-bottom: 0px !important; - } - .disable-seperator .match-bottom { - border-top: 0px !important; - } - .disable-seperator .team:first-child { - margin-bottom: 0px; - } - - - - -.bracket-area { - justify-content: center !important; - } - - -.tournament-create { - display: flex; - justify-content: center; - align-items: center; -} - - -.tournament-create-text { - text-align: center; - margin-top: 2em; - color: white; -} - -.tournament-custom-text { - text-align: center; - color: white; - top: 50%; - left: 50%; -} - -.card-body-tournament { - background-color: #00000054; -} - -.tournamentInfos { - justify-content: center; - width: 700px; - height: 500px; - text-align: center; - border-radius: 10px; - margin-top: 1em; -} - -.localGameText { - color: greenyellow; - font-size: 36px; - margin: 0 0 20px; -} - -.tournamentGame-Text { - color: greenyellow; - font-size: 20px; - font-weight: bold; - margin-bottom: 5px; - margin-top: 10px; -} - -.input-style { - padding: 10px; - border: 2px solid #ccc; - width: 70%; - border-radius: 5px; - font-size: 13px; - color: #555; - outline: none; -} - -.input-style:focus { - border-color: #007bff; - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); -} - -.form-select { - width: 462px !important; -} - -.btn { - margin-top: 2em; - width: 300px; + + +/* Game Room */ + +.indian-logo { + text-align: center; + } + + .logo-indian { + width: 150px; + height: 150px; + } + + .game-room-buttons { + text-align: center; + display:flex; + justify-content: center; + align-items: center; + } + + .tournament-description { + text-align: center; + color: red; + font-weight: bold; + font-size: 12px; + } + + .leave-button { + text-align: center; + background-color: rgba(255, 255, 255); + color: #454c55; + font-size: 14px; + font-weight: 600; + height: 52px; + line-height: 52px; + text-transform: uppercase; + border: none; + cursor: pointer; + margin-right: 1em !important; + margin-left: 1em !important; + padding: 0 5px; + width: 180px; + min-width: 180px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + transition: background .2s; + margin: 15px 0; + display: inline-block; + margin-bottom: 3em; + } + + .leave-button:hover { + background-color: rgba(255, 255, 255, 0.207); + } + + /* Eğer bi class'ınızı özelleştirmek istiyorsanız, bi class'ını kullanabilirsiniz. */ + + .leave-button .bi-x-circle-fill { + color: red; /* Belirli ikonun rengi */ + } + + .leave-button .bi-flag-fill { + color: green; /* Diğer ikonun rengi */ + } + + .leave-button .bi-calendar-check-fill { + color:#5c5be5; + } + + .leave-button .bi-4-square-fill { + color:#5c5be5; + } + + .player-wrapper { + max-width: 520px; + margin: auto; + text-align:center; + } + + .place { + text-align: left; + width: 90px; + height: 150px; + display: inline-block; + margin: 0px 15px; + vertical-align: top; + } + + .avatar-container img { + height: 90px; + width: 90px; + object-fit: cover; + } + + .winner-container { + display:flex; + justify-content:center; + text-align:center; + align-items:center; + flex-direction: column; + } + + .winner-avatar { + height: 90px; + width: 90px; + object-fit: cover; + border: 3px solid greenyellow; + } + + .avatar-container-creator { + height: 90px; + width: 90px; + object-fit: cover; + border: 1px solid orangered; + } + + .winner-info { + margin-top:8px; + } + + .crown-icon { + width: 20px; /* Taç ikonunun genişliği */ + height: auto; /* Otomatik yükseklik ayarı */ + margin-top: -5px; + } + + .losers-winner-text { + color: tomato; + text-align:center; + font-style:italic; + font-weight: bold; + font-size: 14px; + } + + .winner-guy-text { + color: greenyellow; + text-align:center; + font-style:italic; + font-weight: bold; + font-size: 14px; + } + + .player-info { + font-size: 15px; + font-weight: 700; + } + + .truncate-pseudo { + color: orange; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; + } + + .truncate-pseudo-creator { + color: orangered; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; + } + + .game-room-avatar { + border: 1px solid #dadada; + max-width: 100%; + aspect-ratio: 1/1; + object-fit: cover; + height: 100%; + } + + .game-room-avatar-winner { + max-width: 100%; + aspect-ratio: 1/1; + object-fit: cover; + height: 100%; + } + + .game-room-avatar-none { + border: 1px solid #dadada; + width: 100%; + left: 0; + top: 0; + } + + .right-refresh { + position: absolute; + right:25px; + + font-size: 1.2em; + } + + .refresh-button { + cursor: pointer; + color: white; + } + + .refresh-button:hover { + color: greenyellow; + } + + +/* Game Room Area */ + +.game-chart-middle { + text-align: center; + } + + .game-chart-middle h1, + .game-chart-middle h2 { + font-size: 2rem; + font-weight: 900; + margin-bottom: 0.5em;; + font-family: 'Roboto', sans-serif; + } + + .game-bracket-area { + margin-right: auto; + margin-left: auto; + width: 50%; + } + + #game-bracket-section { + display: none; + + } + + #gameroombracket { + display: none; /* veya başka bir değer */ + } + + + .theme { + height: 100%; + width: 100%; + position: absolute; + } + .bracket { + padding: 40px; + margin: 5px; + } + .bracket { + display: flex; + flex-direction: row; + position: relative; + } + .column { + display: flex; + flex-direction: column; + min-height: 100%; + justify-content: space-around; + align-content: center; + } + .match { + position: relative; + display: flex; + flex-direction: column; + min-width: 240px; + max-width: 240px; + height: 62px; + margin: 12px 24px 12px 0; + } + .match .match-top { + border-radius: 2px 2px 0 0; + } + .match .match-bottom { + border-radius: 0 0 2px 2px; + } + .match .team { + display: flex; + align-items: center; + width: 100%; + height: 100%; + border: 1px solid rgb(255, 255, 255); + position: relative; + } + .match .team span { + padding-left: 8px; + color: #ffffff; + font-weight: bold; + } + .match .team span:last-child { + padding-right: 8px; + } + .match .team .score { + margin-left: auto; + } + .match .team:first-child { + margin-bottom: -1px; + } + .match-lines { + display: block; + position: absolute; + top: 50%; + bottom: 0; + margin-top: 0px; + right: -1px; + } + .match-lines .line { + background: red; + position: absolute; + } + .match-lines .line.one { + height: 1px; + width: 12px; + } + .match-lines .line.two { + height: 44px; + width: 1px; + left: 11px; + } + .match-lines.alt { + left: -12px; + } + .match:nth-child(even) .match-lines .line.two { + transform: translate(0, -100%); + } + .column:first-child .match-lines.alt { + display: none; + } + .column:last-child .match-lines { + display: none; + } + .column:last-child .match-lines.alt { + display: block; + } + .column:nth-child(2) .match-lines .line.two { + height: 88px; + } + .column:nth-child(3) .match-lines .line.two { + height: 175px; + } + .column:nth-child(4) .match-lines .line.two { + height: 262px; + } + .column:nth-child(5) .match-lines .line.two { + height: 349px; + } + + .match-link-a { + margin-left:auto; + margin-right:-7.5em; + } + + .match-link { + font-size: 16px; + color: tomato !important; + } + + .match-link:hover { + color: rgb(0, 110, 255) !important; + cursor: pointer; + } + + .disable-image .image, + .disable-seed .seed, + .disable-name .name, + .disable-score .score { + display: none !important; + + } + .disable-borders { + border-width: 0px !important; + } + .disable-borders .team { + border-width: 0px !important; + } + .disable-seperator .match-top { + border-bottom: 0px !important; + } + .disable-seperator .match-bottom { + border-top: 0px !important; + } + .disable-seperator .team:first-child { + margin-bottom: 0px; + } + + + + +.bracket-area { + justify-content: center !important; + } + + +.tournament-create { + display: flex; + justify-content: center; + align-items: center; +} + + +.tournament-create-text { + text-align: center; + margin-top: 2em; + color: white; +} + +.tournament-custom-text { + text-align: center; + color: white; + top: 50%; + left: 50%; +} + +.card-body-tournament { + background-color: #00000054; +} + +.tournamentInfos { + justify-content: center; + width: 700px; + height: 500px; + text-align: center; + border-radius: 10px; + margin-top: 1em; +} + +.localGameText { + color: greenyellow; + font-size: 36px; + margin: 0 0 20px; +} + +.tournamentGame-Text { + color: greenyellow; + font-size: 20px; + font-weight: bold; + margin-bottom: 5px; + margin-top: 10px; +} + +.input-style { + padding: 10px; + border: 2px solid #ccc; + width: 70%; + border-radius: 5px; + font-size: 13px; + color: #555; + outline: none; +} + +.input-style:focus { + border-color: #007bff; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.form-select { + width: 462px !important; +} + +.btn { + margin-top: 2em; + width: 300px; } \ No newline at end of file diff --git a/indianpong/static/js/base-chat.js b/indianpong/static/js/base-chat.js index 68e4d96e..92b8980a 100644 --- a/indianpong/static/js/base-chat.js +++ b/indianpong/static/js/base-chat.js @@ -1,34 +1,34 @@ - export function getChat(username) { - if (!username) { - return; - } - - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - - fetch(`/start_chat/${username}`, { - method: 'POST', - body: JSON.stringify({ username: username }), - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrftoken - }, - }) - .then(response => { - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - return response.json(); - }) - .then(data => { - if (!data.room_id) { - throw new Error('Invalid response: missing room_id'); - } - - const roomId = data.room_id; - const newUrl = `/chat/${roomId}/`; - swapApp(newUrl); - }) - .catch(error => { - console.error('Error:', error.message); - }); -} + export function getChat(username) { + if (!username) { + return; + } + + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + + fetch(`/start_chat/${username}`, { + method: 'POST', + body: JSON.stringify({ username: username }), + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken + }, + }) + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + return response.json(); + }) + .then(data => { + if (!data.room_id) { + throw new Error('Invalid response: missing room_id'); + } + + const roomId = data.room_id; + const newUrl = `/chat/${roomId}/`; + swapApp(newUrl); + }) + .catch(error => { + console.error('Error:', error.message); + }); +} diff --git a/indianpong/static/js/burger.js b/indianpong/static/js/burger.js index d243af06..a721196f 100644 --- a/indianpong/static/js/burger.js +++ b/indianpong/static/js/burger.js @@ -1,10 +1,10 @@ -export function initializeBurger () { - document.querySelector(".burger-menu").addEventListener("click", function () { - var navLinks = document.querySelector(".nav-links"); - if (navLinks.classList.contains("show")) { - navLinks.classList.remove("show"); - } else { - navLinks.classList.add("show"); - } - }); +export function initializeBurger () { + document.querySelector(".burger-menu").addEventListener("click", function () { + var navLinks = document.querySelector(".nav-links"); + if (navLinks.classList.contains("show")) { + navLinks.classList.remove("show"); + } else { + navLinks.classList.add("show"); + } + }); } \ No newline at end of file diff --git a/indianpong/static/js/chat.js b/indianpong/static/js/chat.js index 2fae4891..f08e96b2 100644 --- a/indianpong/static/js/chat.js +++ b/indianpong/static/js/chat.js @@ -89,7 +89,7 @@ const langMessages = { const unfollowButton = document.getElementById("unfollow"); const messages = document.getElementById("messages"); - const chatsocket = new WebSocket("ws://" + window.location.host + "/ws/chat/" + roomName + "/") + const chatsocket = new WebSocket("wss://" + window.location.host + "/ws/chat/" + roomName + "/") chatsocket.onopen = function (e) { console.log("socket opened") diff --git a/indianpong/static/js/create-tournament.js b/indianpong/static/js/create-tournament.js index 8e6e7f0d..5f4c1e5f 100644 --- a/indianpong/static/js/create-tournament.js +++ b/indianpong/static/js/create-tournament.js @@ -1,42 +1,42 @@ -export function createTournament() { - - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - const toast = new bootstrap.Toast(liveToast); - toast.show(); - setTimeout(function() { - toast.hide(); - }, 8000); -} - var form = document.getElementById('TournamentForm'); - var formData = new FormData(form); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - fetch('/tournament-create', { - method: 'POST', - headers: { - 'X-CSRFToken': csrftoken - }, - body: formData - }) - .then(response => response.text()) - .then(data => { - if (data.includes("/tournament-room/")) - swapApp(data); - else { - showToast(`${data}`, `text-bg-danger`, `bi bi-bug-fill`); - } - }) - .catch(error => { - console.error(error); - }); +export function createTournament() { + + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + const toast = new bootstrap.Toast(liveToast); + toast.show(); + setTimeout(function() { + toast.hide(); + }, 8000); +} + var form = document.getElementById('TournamentForm'); + var formData = new FormData(form); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + fetch('/tournament-create', { + method: 'POST', + headers: { + 'X-CSRFToken': csrftoken + }, + body: formData + }) + .then(response => response.text()) + .then(data => { + if (data.includes("/tournament-room/")) + swapApp(data); + else { + showToast(`${data}`, `text-bg-danger`, `bi bi-bug-fill`); + } + }) + .catch(error => { + console.error(error); + }); } \ No newline at end of file diff --git a/indianpong/static/js/game/local-game.js b/indianpong/static/js/game/local-game.js index 3ccd3377..8329ed97 100644 --- a/indianpong/static/js/game/local-game.js +++ b/indianpong/static/js/game/local-game.js @@ -1,416 +1,416 @@ -export function LocalGame() { -const canvas = document.getElementById('pongCanvas'); -var gameStartInfos = document.getElementById("gameStartInfos"); -var startButton = document.getElementById("startButton"); -var ctx = canvas.getContext("2d"); -canvas.width = 800; -canvas.height = 600; - - - - -const translationswin = { - 'hi': ' आप जीत गए', - 'pt': ' você ganhou', - 'tr': ' kazandınız', - 'en': ' you win' // Varsayılan İngilizce metin -}; - -const translationslose = { - 'hi': ' आप हार गए', - 'pt': ' você perdeu', - 'tr': ' kaybettiniz', - 'en': ' you lose' // Varsayılan İngilizce metin -}; - -const canvasContainer = document.querySelector('.ai-game'); -var player1Name = "Player 1" -var player2Name = "Player 2" -var gameMode = "Vanilla"; - -const paddleColor = document.querySelector('.container-top').dataset.paddlecolor; -const playgroundColor = document.querySelector('.container-top').dataset.playgroundcolor; -canvas.style.borderColor = playgroundColor; // Set the border color to the specified color - -/* Cordinates of the canvas */ -var textWidth1 = ctx.measureText(player1Name + ": " + score1).width; -var textWidth2 = ctx.measureText(player2Name + ": " + score2).width; - - -var usernameX = 10; -var usernameY = 20; -// player2 metni sağ üst köşede -var player2nameX = canvas.width - textWidth2 - 10; -var player2nameY = 20; - -// if giantMan abilities equiped -var abilities_paddleHeight = (gameMode == "Abilities") ? 115 : 100; -var paddleWidth = 10; -var paddleHeight = 100; -var paddleSpeed = 15; -var paddleY = (canvas.height - paddleHeight) / 2; -var paddle1 = {x: 0, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; -var paddle2 = {x: canvas.width - paddleWidth, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; - -// Ball object -var ball = {x: canvas.width / 2, y: canvas.height / 2, radius: 10, speed: 5, dx: 1, dy: 1}; - -// Scores -var score1 = 0; -var score2 = 0; - -var MAX_SCORE = 3; - -// Player Abilities -var likeaCheaterCount = 0; -var fastandFuriousCount = 0; -var frozenBallCount = 0; -var Player2FrozenBallCount = 0; -var Player2LikeaCheaterCount = 0; -var Player2FastandFuriousCount = 0; - -var isFrozenBallActive = false; - -// Add a new variable to track if the game is paused -let isScored = false; -var isPaused = true; -let upPressed = false; -let downPressed = false; -let upPressedPlayer2 = false; -let downPressedPlayer2 = false; - - -function resetAbilities() { - likeaCheaterCount = 0; - fastandFuriousCount = 0; - frozenBallCount = 0; - Player2FrozenBallCount = 0; - Player2LikeaCheaterCount = 0; - Player2FastandFuriousCount = 0; -} - -// Update the ball and paddle positions -function update() { - // If the game is paused, don't update anything - if (isPaused) return; - - ball.x += ball.speed * ball.dx; - ball.y += ball.speed * ball.dy; - - // Check for collisions with paddles - if (ball.y + ball.radius >= paddle1.y && ball.y - ball.radius <= paddle1.y + paddle1.height && ball.dx < 0) { - if (ball.x - ball.radius <= paddle1.x + paddle1.width) { - if (gameMode == "Abilities") { - if (Math.random() <= 0.5) { - ball.speed += 0.25; - } - } - ball.x = paddle1.x + paddle1.width + ball.radius; - ball.dx *= -1; - if (ball.y < paddle1.y + 0.2 * paddle1.height || ball.y > paddle1.y + 0.8 * paddle1.height) { - ball.speed *= 1.2; // Increase speed by 20% - paddleSpeed *= 1.2; - } - } - } - if (ball.y + ball.radius >= paddle2.y && ball.y - ball.radius <= paddle2.y + paddle2.height && ball.dx > 0) { - if (ball.x + ball.radius >= paddle2.x) { - if (gameMode == "Abilities") { - if (Math.random() <= 0.5) { - ball.speed += 0.25; - } - } - ball.x = paddle2.x - ball.radius; - ball.dx *= -1; - if (ball.y < paddle2.y + 0.2 * paddle2.height || ball.y > paddle2.y + 0.8 * paddle2.height) { - ball.speed *= 1.2; // Increase speed by 20% - paddleSpeed *= 1.2; - } - } - } - - // Check for collisions with top/bottom walls - if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) { - ball.dy *= -1; - } - - // Check for collisions with left/right walls (scoring) - if (ball.x + ball.radius > canvas.width) { - score1++; - resetBall(); - } else if (ball.x - ball.radius < 0) { - score2++; - resetBall(); - } - - // Check for game over - if (score1 == MAX_SCORE || score2 == MAX_SCORE) { - showGameOverScreen(); - } - - // Move the paddle1 - if (upPressed && paddle1.y > 0 && !isScored) { - paddle1.y -= paddle1.dy; - } else if (downPressed && paddle1.y < canvas.height - paddle1.height && !isScored) { - paddle1.y += paddle1.dy; - } - - // Move the paddle2 - if (upPressedPlayer2 && paddle2.y > 0 && !isScored) { - paddle2.y -= paddle2.dy; - } else if (downPressedPlayer2 && paddle2.y < canvas.height - paddle2.height && !isScored) { - paddle2.y += paddle2.dy; - } - - // Prevent the paddles from moving off the canvas - if (paddle1.y < 0) { - paddle1.y = 0; - } else if (paddle1.y > canvas.height - paddle1.height) { - paddle1.y = canvas.height - paddle1.height; - } - if (paddle2.y < 0) { - paddle2.y = 0; - } else if (paddle2.y > canvas.height - paddle2.height) { - paddle2.y = canvas.height - paddle2.height; - } -} - -/// Draw everything -function render() { - - ctx.clearRect(0, 0, canvas.width, canvas.height); - - // Create a radial gradient for the background - var gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 10, canvas.width / 2, canvas.height / 2, 300); - gradient.addColorStop(0, 'lightgrey'); - gradient.addColorStop(1, 'darkgrey'); - ctx.fillStyle = gradient; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - // Draw the middle dotted line - ctx.beginPath(); - ctx.setLineDash([5, 15]); - ctx.moveTo(canvas.width / 2, 0); - ctx.lineTo(canvas.width / 2, canvas.height); - ctx.strokeStyle = "black"; - ctx.stroke(); - - // Draw the middle dotted circle - ctx.beginPath(); - ctx.arc(canvas.width / 2, canvas.height / 2, 50, 0, Math.PI * 2, false); - ctx.setLineDash([5, 15]); - ctx.stroke(); - - // Add shadow to the paddles - ctx.shadowColor = 'black'; - ctx.shadowBlur = 10; - ctx.shadowOffsetX = 5; - ctx.shadowOffsetY = 5; - - ctx.fillStyle = paddleColor - ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); - // If paddle2 is on the right, draw the shadow to the left - ctx.shadowOffsetX = -5; - ctx.shadowOffsetY = 5; - ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); - - // Add shiny effect to the ball - ctx.beginPath(); - ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, false); - var gradient = ctx.createRadialGradient(ball.x, ball.y, 0, ball.x, ball.y, ball.radius); - gradient.addColorStop(0, 'white'); - gradient.addColorStop(0.1, 'gold'); - gradient.addColorStop(1, 'darkorange'); - ctx.fillStyle = gradient; - ctx.fill(); - ctx.closePath(); - - // Reset shadow properties - ctx.shadowColor = 'transparent'; - ctx.shadowBlur = 0; - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - - ctx.font = "16px Roboto"; - ctx.fillStyle = 'white'; - ctx.fillText(player1Name + ": " + score1, usernameX, usernameY); - ctx.fillText(player2Name + ": " + score2, player2nameX, player2nameY); -} - - -// The main game loop -var main = function () { - // Request to do this again ASAP - if (!isPaused) { - update(); - render(); - } - - localGameAnimationId = requestAnimationFrame(main); -}; - -// Cross-browser support for requestAnimationFrame -var w = window; -requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame; - -// Let's play this game! -main(); - - - -// Reset the ball to the center -function resetBall() { - isScored = true; - isPaused = true; - ball.speed = 5; - paddleSpeed = 14; - ball.dx = -ball.dx; - ball.dy = -ball.dy; - setTimeout(() => { - ball.x = canvas.width / 2; - ball.y = canvas.height / 2; - isPaused = false; - isScored = false; - }, 500); -} - -function frozenBallAbility() { - var nowBallSpeed = ball.speed; - isFrozenBallActive = true; - ball.speed = 0; - setTimeout(function() { - ball.speed = nowBallSpeed; - isFrozenBallActive = false; - }, 2000); -} - -function likeaCheaterAbility(whichPlayer) { - if (whichPlayer == "Player2") { - score2++; - if (score1 > 0) { - score1--; - } - } - else if (whichPlayer == "Player1") { - score1++; - if (score2 > 0) { - score2--; - } - } -} - -function fastandFuriousAbility() { - ball.speed += 10; -} - -// Control paddle1 with w, s keys -document.addEventListener("keydown", function(event) { - if (event.key === "w" || event.key === "W") { - upPressed = true; - } - else if (event.key === "s" || event.key === "S") { - downPressed = true; - } - else if (event.key === '1' && likeaCheaterCount < 1 && gameMode == "Abilities") { - likeaCheaterAbility("Player1"); - likeaCheaterCount += 1; - } - else if (event.key === '2' && fastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { - fastandFuriousAbility(); - fastandFuriousCount += 1; - } - else if (event.key === '3' && frozenBallCount < 1 && gameMode == "Abilities") { - frozenBallAbility(); - frozenBallCount += 1; - } -}); - -// Control paddle2 with arrow keys -document.addEventListener("keydown", function(event) { - if (event.key === "ArrowUp") { - upPressedPlayer2 = true; - } else if (event.key === "ArrowDown") { - downPressedPlayer2 = true; - } - else if (event.key === '8' && Player2LikeaCheaterCount < 1 && gameMode == "Abilities") { - likeaCheaterAbility("Player2"); - Player2LikeaCheaterCount += 1; - } - else if (event.key === '9' && Player2FastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { - fastandFuriousAbility(); - Player2FastandFuriousCount += 1; - } - else if (event.key === '0' && Player2FrozenBallCount < 1 && gameMode == "Abilities") { - frozenBallAbility(); - Player2FrozenBallCount += 1; - } -}); - -document.addEventListener("keyup", function(event) { - if (event.key === "w" || event.key === "W" ) { - upPressed = false; - } else if (event.key === "s" || event.key === "S") { - downPressed = false; - } -}); - -document.addEventListener("keyup", function(event) { - if (event.key === "ArrowUp") { - upPressedPlayer2 = false; - } else if (event.key === "ArrowDown") { - downPressedPlayer2 = false; - } -}); - -function showCanvas() { - pongCanvas.style.display = "block"; - gameStartInfos.style.display = "none"; - isPaused = false; - } - -// Reset the paddle1 position? -function resetPaddles() { - paddle1.y = (canvas.height - abilities_paddleHeight) / 2; - paddle2.y = (canvas.height - abilities_paddleHeight) / 2; -} - -function resetGame() { - score1 = 0; - score2 = 0; - resetBall(); - resetPaddles(); - resetAbilities(); -} - - -// Oyun bitiş ekranını gösteren fonksiyon -function showGameOverScreen() { - isPaused = true; - var winnerText = (score1 == MAX_SCORE) ? player1Name + (selectedLanguage && translationswin[selectedLanguage] ? translationswin[selectedLanguage] : translationswin['en']) : player2Name + (selectedLanguage && translationswin[selectedLanguage] ? translationswin[selectedLanguage] : translationswin['en']); - document.getElementById('winnerText').innerText = winnerText; - document.getElementById('gameOverScreen').style.display = 'block'; -} - -// Oyunu tekrar başlatan fonksiyon -function restartGame() { - document.getElementById('gameOverScreen').style.display = 'none'; - resetGame(); -} - -// Çıkış yapma işlemleri -function exitGame() { - swapApp('/pong-game-find') -} - -document.getElementById('restartButton').addEventListener('click', restartGame); -document.getElementById('exitButton').addEventListener('click', exitGame); - -startButton.addEventListener("click", function() { - player1Name = document.getElementById("player1Name").value; - player2Name = document.getElementById("player2Name").value; - MAX_SCORE = document.getElementById("maxScore").value; - gameMode = document.getElementById("gameMode").value; - showCanvas(); -}); - +export function LocalGame() { +const canvas = document.getElementById('pongCanvas'); +var gameStartInfos = document.getElementById("gameStartInfos"); +var startButton = document.getElementById("startButton"); +var ctx = canvas.getContext("2d"); +canvas.width = 800; +canvas.height = 600; + + + + +const translationswin = { + 'hi': ' आप जीत गए', + 'pt': ' você ganhou', + 'tr': ' kazandınız', + 'en': ' you win' // Varsayılan İngilizce metin +}; + +const translationslose = { + 'hi': ' आप हार गए', + 'pt': ' você perdeu', + 'tr': ' kaybettiniz', + 'en': ' you lose' // Varsayılan İngilizce metin +}; + +const canvasContainer = document.querySelector('.ai-game'); +var player1Name = "Player 1" +var player2Name = "Player 2" +var gameMode = "Vanilla"; + +const paddleColor = document.querySelector('.container-top').dataset.paddlecolor; +const playgroundColor = document.querySelector('.container-top').dataset.playgroundcolor; +canvas.style.borderColor = playgroundColor; // Set the border color to the specified color + +/* Cordinates of the canvas */ +var textWidth1 = ctx.measureText(player1Name + ": " + score1).width; +var textWidth2 = ctx.measureText(player2Name + ": " + score2).width; + + +var usernameX = 10; +var usernameY = 20; +// player2 metni sağ üst köşede +var player2nameX = canvas.width - textWidth2 - 10; +var player2nameY = 20; + +// if giantMan abilities equiped +var abilities_paddleHeight = (gameMode == "Abilities") ? 115 : 100; +var paddleWidth = 10; +var paddleHeight = 100; +var paddleSpeed = 15; +var paddleY = (canvas.height - paddleHeight) / 2; +var paddle1 = {x: 0, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; +var paddle2 = {x: canvas.width - paddleWidth, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; + +// Ball object +var ball = {x: canvas.width / 2, y: canvas.height / 2, radius: 10, speed: 5, dx: 1, dy: 1}; + +// Scores +var score1 = 0; +var score2 = 0; + +var MAX_SCORE = 3; + +// Player Abilities +var likeaCheaterCount = 0; +var fastandFuriousCount = 0; +var frozenBallCount = 0; +var Player2FrozenBallCount = 0; +var Player2LikeaCheaterCount = 0; +var Player2FastandFuriousCount = 0; + +var isFrozenBallActive = false; + +// Add a new variable to track if the game is paused +let isScored = false; +var isPaused = true; +let upPressed = false; +let downPressed = false; +let upPressedPlayer2 = false; +let downPressedPlayer2 = false; + + +function resetAbilities() { + likeaCheaterCount = 0; + fastandFuriousCount = 0; + frozenBallCount = 0; + Player2FrozenBallCount = 0; + Player2LikeaCheaterCount = 0; + Player2FastandFuriousCount = 0; +} + +// Update the ball and paddle positions +function update() { + // If the game is paused, don't update anything + if (isPaused) return; + + ball.x += ball.speed * ball.dx; + ball.y += ball.speed * ball.dy; + + // Check for collisions with paddles + if (ball.y + ball.radius >= paddle1.y && ball.y - ball.radius <= paddle1.y + paddle1.height && ball.dx < 0) { + if (ball.x - ball.radius <= paddle1.x + paddle1.width) { + if (gameMode == "Abilities") { + if (Math.random() <= 0.5) { + ball.speed += 0.25; + } + } + ball.x = paddle1.x + paddle1.width + ball.radius; + ball.dx *= -1; + if (ball.y < paddle1.y + 0.2 * paddle1.height || ball.y > paddle1.y + 0.8 * paddle1.height) { + ball.speed *= 1.2; // Increase speed by 20% + paddleSpeed *= 1.2; + } + } + } + if (ball.y + ball.radius >= paddle2.y && ball.y - ball.radius <= paddle2.y + paddle2.height && ball.dx > 0) { + if (ball.x + ball.radius >= paddle2.x) { + if (gameMode == "Abilities") { + if (Math.random() <= 0.5) { + ball.speed += 0.25; + } + } + ball.x = paddle2.x - ball.radius; + ball.dx *= -1; + if (ball.y < paddle2.y + 0.2 * paddle2.height || ball.y > paddle2.y + 0.8 * paddle2.height) { + ball.speed *= 1.2; // Increase speed by 20% + paddleSpeed *= 1.2; + } + } + } + + // Check for collisions with top/bottom walls + if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) { + ball.dy *= -1; + } + + // Check for collisions with left/right walls (scoring) + if (ball.x + ball.radius > canvas.width) { + score1++; + resetBall(); + } else if (ball.x - ball.radius < 0) { + score2++; + resetBall(); + } + + // Check for game over + if (score1 == MAX_SCORE || score2 == MAX_SCORE) { + showGameOverScreen(); + } + + // Move the paddle1 + if (upPressed && paddle1.y > 0 && !isScored) { + paddle1.y -= paddle1.dy; + } else if (downPressed && paddle1.y < canvas.height - paddle1.height && !isScored) { + paddle1.y += paddle1.dy; + } + + // Move the paddle2 + if (upPressedPlayer2 && paddle2.y > 0 && !isScored) { + paddle2.y -= paddle2.dy; + } else if (downPressedPlayer2 && paddle2.y < canvas.height - paddle2.height && !isScored) { + paddle2.y += paddle2.dy; + } + + // Prevent the paddles from moving off the canvas + if (paddle1.y < 0) { + paddle1.y = 0; + } else if (paddle1.y > canvas.height - paddle1.height) { + paddle1.y = canvas.height - paddle1.height; + } + if (paddle2.y < 0) { + paddle2.y = 0; + } else if (paddle2.y > canvas.height - paddle2.height) { + paddle2.y = canvas.height - paddle2.height; + } +} + +/// Draw everything +function render() { + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Create a radial gradient for the background + var gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 10, canvas.width / 2, canvas.height / 2, 300); + gradient.addColorStop(0, 'lightgrey'); + gradient.addColorStop(1, 'darkgrey'); + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + // Draw the middle dotted line + ctx.beginPath(); + ctx.setLineDash([5, 15]); + ctx.moveTo(canvas.width / 2, 0); + ctx.lineTo(canvas.width / 2, canvas.height); + ctx.strokeStyle = "black"; + ctx.stroke(); + + // Draw the middle dotted circle + ctx.beginPath(); + ctx.arc(canvas.width / 2, canvas.height / 2, 50, 0, Math.PI * 2, false); + ctx.setLineDash([5, 15]); + ctx.stroke(); + + // Add shadow to the paddles + ctx.shadowColor = 'black'; + ctx.shadowBlur = 10; + ctx.shadowOffsetX = 5; + ctx.shadowOffsetY = 5; + + ctx.fillStyle = paddleColor + ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); + // If paddle2 is on the right, draw the shadow to the left + ctx.shadowOffsetX = -5; + ctx.shadowOffsetY = 5; + ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); + + // Add shiny effect to the ball + ctx.beginPath(); + ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, false); + var gradient = ctx.createRadialGradient(ball.x, ball.y, 0, ball.x, ball.y, ball.radius); + gradient.addColorStop(0, 'white'); + gradient.addColorStop(0.1, 'gold'); + gradient.addColorStop(1, 'darkorange'); + ctx.fillStyle = gradient; + ctx.fill(); + ctx.closePath(); + + // Reset shadow properties + ctx.shadowColor = 'transparent'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + + ctx.font = "16px Roboto"; + ctx.fillStyle = 'white'; + ctx.fillText(player1Name + ": " + score1, usernameX, usernameY); + ctx.fillText(player2Name + ": " + score2, player2nameX, player2nameY); +} + + +// The main game loop +var main = function () { + // Request to do this again ASAP + if (!isPaused) { + update(); + render(); + } + + localGameAnimationId = requestAnimationFrame(main); +}; + +// Cross-browser support for requestAnimationFrame +var w = window; +requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame; + +// Let's play this game! +main(); + + + +// Reset the ball to the center +function resetBall() { + isScored = true; + isPaused = true; + ball.speed = 5; + paddleSpeed = 14; + ball.dx = -ball.dx; + ball.dy = -ball.dy; + setTimeout(() => { + ball.x = canvas.width / 2; + ball.y = canvas.height / 2; + isPaused = false; + isScored = false; + }, 500); +} + +function frozenBallAbility() { + var nowBallSpeed = ball.speed; + isFrozenBallActive = true; + ball.speed = 0; + setTimeout(function() { + ball.speed = nowBallSpeed; + isFrozenBallActive = false; + }, 2000); +} + +function likeaCheaterAbility(whichPlayer) { + if (whichPlayer == "Player2") { + score2++; + if (score1 > 0) { + score1--; + } + } + else if (whichPlayer == "Player1") { + score1++; + if (score2 > 0) { + score2--; + } + } +} + +function fastandFuriousAbility() { + ball.speed += 10; +} + +// Control paddle1 with w, s keys +document.addEventListener("keydown", function(event) { + if (event.key === "w" || event.key === "W") { + upPressed = true; + } + else if (event.key === "s" || event.key === "S") { + downPressed = true; + } + else if (event.key === '1' && likeaCheaterCount < 1 && gameMode == "Abilities") { + likeaCheaterAbility("Player1"); + likeaCheaterCount += 1; + } + else if (event.key === '2' && fastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { + fastandFuriousAbility(); + fastandFuriousCount += 1; + } + else if (event.key === '3' && frozenBallCount < 1 && gameMode == "Abilities") { + frozenBallAbility(); + frozenBallCount += 1; + } +}); + +// Control paddle2 with arrow keys +document.addEventListener("keydown", function(event) { + if (event.key === "ArrowUp") { + upPressedPlayer2 = true; + } else if (event.key === "ArrowDown") { + downPressedPlayer2 = true; + } + else if (event.key === '8' && Player2LikeaCheaterCount < 1 && gameMode == "Abilities") { + likeaCheaterAbility("Player2"); + Player2LikeaCheaterCount += 1; + } + else if (event.key === '9' && Player2FastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { + fastandFuriousAbility(); + Player2FastandFuriousCount += 1; + } + else if (event.key === '0' && Player2FrozenBallCount < 1 && gameMode == "Abilities") { + frozenBallAbility(); + Player2FrozenBallCount += 1; + } +}); + +document.addEventListener("keyup", function(event) { + if (event.key === "w" || event.key === "W" ) { + upPressed = false; + } else if (event.key === "s" || event.key === "S") { + downPressed = false; + } +}); + +document.addEventListener("keyup", function(event) { + if (event.key === "ArrowUp") { + upPressedPlayer2 = false; + } else if (event.key === "ArrowDown") { + downPressedPlayer2 = false; + } +}); + +function showCanvas() { + pongCanvas.style.display = "block"; + gameStartInfos.style.display = "none"; + isPaused = false; + } + +// Reset the paddle1 position? +function resetPaddles() { + paddle1.y = (canvas.height - abilities_paddleHeight) / 2; + paddle2.y = (canvas.height - abilities_paddleHeight) / 2; +} + +function resetGame() { + score1 = 0; + score2 = 0; + resetBall(); + resetPaddles(); + resetAbilities(); +} + + +// Oyun bitiş ekranını gösteren fonksiyon +function showGameOverScreen() { + isPaused = true; + var winnerText = (score1 == MAX_SCORE) ? player1Name + (selectedLanguage && translationswin[selectedLanguage] ? translationswin[selectedLanguage] : translationswin['en']) : player2Name + (selectedLanguage && translationswin[selectedLanguage] ? translationswin[selectedLanguage] : translationswin['en']); + document.getElementById('winnerText').innerText = winnerText; + document.getElementById('gameOverScreen').style.display = 'block'; +} + +// Oyunu tekrar başlatan fonksiyon +function restartGame() { + document.getElementById('gameOverScreen').style.display = 'none'; + resetGame(); +} + +// Çıkış yapma işlemleri +function exitGame() { + swapApp('/pong-game-find') +} + +document.getElementById('restartButton').addEventListener('click', restartGame); +document.getElementById('exitButton').addEventListener('click', exitGame); + +startButton.addEventListener("click", function() { + player1Name = document.getElementById("player1Name").value; + player2Name = document.getElementById("player2Name").value; + MAX_SCORE = document.getElementById("maxScore").value; + gameMode = document.getElementById("gameMode").value; + showCanvas(); +}); + } \ No newline at end of file diff --git a/indianpong/static/js/game/localTournament.js b/indianpong/static/js/game/localTournament.js index 119bb183..43f6207e 100644 --- a/indianpong/static/js/game/localTournament.js +++ b/indianpong/static/js/game/localTournament.js @@ -1,545 +1,545 @@ -export function localTournament() { -const canvas = document.getElementById('pongCanvas'); -var gameStartInfos = document.getElementById("tournament-start-info"); -var gameInfoTournament = document.getElementById("game-info-tournament"); -var startButton = document.getElementById("startButton"); -var startTournament = document.getElementById("startTournament"); -var ctx = canvas.getContext("2d"); -canvas.width = 800; -canvas.height = 600; - - -const canvasContainer = document.querySelector('.ai-game'); -var gameMode = "Vanilla"; - -/* Tournament */ -var playerNames = []; -var matches = []; -const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); -const selectedLanguage = cookie ? cookie.split('=')[1] : 'en'; - -var matchCount = 0; - -const paddleColor = document.querySelector('.container-top').dataset.paddlecolor; -const playgroundColor = document.querySelector('.container-top').dataset.playgroundcolor; -canvas.style.borderColor = playgroundColor; // Set the border color to the specified color - -/* Cordinates of the canvas */ -var textWidth1 = ctx.measureText(matches[matchCount] + ": " + score1).width; -var textWidth2 = ctx.measureText(matches[matchCount] + ": " + score2).width; - - -var usernameX = 10; -var usernameY = 20; -// player2 metni sağ üst köşede -var player2nameX = canvas.width - textWidth2 - 10; -var player2nameY = 20; - -// if giantMan abilities equiped -var abilities_paddleHeight = (gameMode == "Abilities") ? 115 : 100; -var paddleWidth = 10; -var paddleHeight = 100; -var paddleSpeed = 15; -var paddleY = (canvas.height - paddleHeight) / 2; -var paddle1 = {x: 0, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; -var paddle2 = {x: canvas.width - paddleWidth, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; - -// Ball object -var ball = {x: canvas.width / 2, y: canvas.height / 2, radius: 10, speed: 10, dx: 1, dy: 1}; - -// Scores -var isGameStarted = false; - -var score1 = 0; -var score2 = 0; - -var MAX_SCORE = 3; - -// Player Abilities -var likeaCheaterCount = 0; -var fastandFuriousCount = 0; -var frozenBallCount = 0; -var Player2FrozenBallCount = 0; -var Player2LikeaCheaterCount = 0; -var Player2FastandFuriousCount = 0; - -var isFrozenBallActive = false; - -// Add a new variable to track if the game is paused -let isScored = false; -var isPaused = true; -let upPressed = false; -let downPressed = false; -let upPressedPlayer2 = false; -let downPressedPlayer2 = false; - - -function resetAbilities() { - likeaCheaterCount = 0; - fastandFuriousCount = 0; - frozenBallCount = 0; - Player2FrozenBallCount = 0; - Player2LikeaCheaterCount = 0; - Player2FastandFuriousCount = 0; -} - -// Update the ball and paddle positions -function update() { - // If the game is paused, don't update anything - if (isPaused) return; - - ball.x += ball.speed * ball.dx; - ball.y += ball.speed * ball.dy; - - // Check for collisions with paddles - if (ball.y + ball.radius >= paddle1.y && ball.y - ball.radius <= paddle1.y + paddle1.height && ball.dx < 0) { - if (ball.x - ball.radius <= paddle1.x + paddle1.width) { - if (gameMode == "Abilities") { - if (Math.random() <= 0.5) { - ball.speed += 0.25; - } - } - ball.x = paddle1.x + paddle1.width + ball.radius; - ball.dx *= -1; - if (ball.y < paddle1.y + 0.2 * paddle1.height || ball.y > paddle1.y + 0.8 * paddle1.height) { - ball.speed *= 1.2; // Increase speed by 20% - paddleSpeed *= 1.2; - } - } - } - if (ball.y + ball.radius >= paddle2.y && ball.y - ball.radius <= paddle2.y + paddle2.height && ball.dx > 0) { - if (ball.x + ball.radius >= paddle2.x) { - if (gameMode == "Abilities") { - if (Math.random() <= 0.5) { - ball.speed += 0.25; - } - } - ball.x = paddle2.x - ball.radius; - ball.dx *= -1; - if (ball.y < paddle2.y + 0.2 * paddle2.height || ball.y > paddle2.y + 0.8 * paddle2.height) { - ball.speed *= 1.2; // Increase speed by 20% - paddleSpeed *= 1.2; - } - } - } - - // Check for collisions with top/bottom walls - if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) { - ball.dy *= -1; - } - - // Check for collisions with left/right walls (scoring) - if (ball.x + ball.radius > canvas.width) { - score1++; - resetBall(); - } else if (ball.x - ball.radius < 0) { - score2++; - resetBall(); - } - - // Check for game over - if (score1 == MAX_SCORE || score2 == MAX_SCORE) { - if (matchCount < 2) { - showGameOverScreen(score1 == MAX_SCORE ? matches[matchCount].player1 : matches[matchCount].player2); - } - else { - isPaused = true; - showGameOverTournament(score1 == MAX_SCORE ? matches[matchCount].player1 : matches[matchCount].player2); - } - } - - // Move the paddle1 - if (upPressed && paddle1.y > 0 && !isScored) { - paddle1.y -= paddle1.dy; - } else if (downPressed && paddle1.y < canvas.height - paddle1.height && !isScored) { - paddle1.y += paddle1.dy; - } - - // Move the paddle2 - if (upPressedPlayer2 && paddle2.y > 0 && !isScored) { - paddle2.y -= paddle2.dy; - } else if (downPressedPlayer2 && paddle2.y < canvas.height - paddle2.height && !isScored) { - paddle2.y += paddle2.dy; - } - - // Prevent the paddles from moving off the canvas - if (paddle1.y < 0) { - paddle1.y = 0; - } else if (paddle1.y > canvas.height - paddle1.height) { - paddle1.y = canvas.height - paddle1.height; - } - if (paddle2.y < 0) { - paddle2.y = 0; - } else if (paddle2.y > canvas.height - paddle2.height) { - paddle2.y = canvas.height - paddle2.height; - } -} - -/// Draw everything -function render() { - - ctx.clearRect(0, 0, canvas.width, canvas.height); - - // Create a radial gradient for the background - var gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 10, canvas.width / 2, canvas.height / 2, 300); - gradient.addColorStop(0, 'lightgrey'); - gradient.addColorStop(1, 'darkgrey'); - ctx.fillStyle = gradient; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - // Draw the middle dotted line - ctx.beginPath(); - ctx.setLineDash([5, 15]); - ctx.moveTo(canvas.width / 2, 0); - ctx.lineTo(canvas.width / 2, canvas.height); - ctx.strokeStyle = "black"; - ctx.stroke(); - - // Draw the middle dotted circle - ctx.beginPath(); - ctx.arc(canvas.width / 2, canvas.height / 2, 50, 0, Math.PI * 2, false); - ctx.setLineDash([5, 15]); - ctx.stroke(); - - // Add shadow to the paddles - ctx.shadowColor = 'black'; - ctx.shadowBlur = 10; - ctx.shadowOffsetX = 5; - ctx.shadowOffsetY = 5; - - ctx.fillStyle = paddleColor - ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); - // If paddle2 is on the right, draw the shadow to the left - ctx.shadowOffsetX = -5; - ctx.shadowOffsetY = 5; - ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); - - // Add shiny effect to the ball - ctx.beginPath(); - ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, false); - var gradient = ctx.createRadialGradient(ball.x, ball.y, 0, ball.x, ball.y, ball.radius); - gradient.addColorStop(0, 'white'); - gradient.addColorStop(0.1, 'gold'); - gradient.addColorStop(1, 'darkorange'); - ctx.fillStyle = gradient; - ctx.fill(); - ctx.closePath(); - - // Reset shadow properties - ctx.shadowColor = 'transparent'; - ctx.shadowBlur = 0; - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - - ctx.font = "16px Roboto"; - ctx.fillStyle = 'white'; - - - if (matchCount === 0) { - ctx.fillText(matches[matchCount].player1 + ": " + score1, usernameX, usernameY); - ctx.fillText(matches[matchCount].player2 + ": " + score2, player2nameX, player2nameY); - } - else if (matchCount === 1) { - ctx.fillText(matches[matchCount].player1 + ": " + score1, usernameX, usernameY); - ctx.fillText(matches[matchCount].player2 + ": " + score2, player2nameX, player2nameY); - } - else if (matchCount === 2) { - ctx.fillText(matches[matchCount].player1 + ": " + score1, usernameX, usernameY); - ctx.fillText(matches[matchCount].player2 + ": " + score2, player2nameX, player2nameY); - } -} - - -// The main game loop -var main = function () { - // Request to do this again ASAP - if (!isPaused) { - update(); - render(); - } - - localTournamentAnimationId = requestAnimationFrame(main); -}; - -// Cross-browser support for requestAnimationFrame -var w = window; -requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame; - -// Let's play this game! -main(); - - - -// Reset the ball to the center -function resetBall() { - isScored = true; - isPaused = true; - ball.speed = 10; - paddleSpeed = 14; - ball.dx = -ball.dx; - ball.dy = -ball.dy; - setTimeout(() => { - ball.x = canvas.width / 2; - ball.y = canvas.height / 2; - isPaused = false; - isScored = false; - }, 500); -} - -function frozenBallAbility() { - var nowBallSpeed = ball.speed; - isFrozenBallActive = true; - ball.speed = 0; - setTimeout(function() { - ball.speed = nowBallSpeed; - isFrozenBallActive = false; - }, 2000); -} - -function likeaCheaterAbility(whichPlayer) { - if (whichPlayer == "Player2") { - score2++; - if (score1 > 0) { - score1--; - } - } - else if (whichPlayer == "Player1") { - score1++; - - if (score2 > 0) { - score2--; - } - } -} - -function fastandFuriousAbility() { - ball.speed += 10; -} - -// Control paddle1 with w, s keys -document.addEventListener("keydown", function(event) { - if (event.key === "w" || event.key === "W") { - upPressed = true; - } - else if (event.key === "s" || event.key === "S") { - downPressed = true; - } - else if (event.key === '1' && likeaCheaterCount < 1 && gameMode == "Abilities") { - likeaCheaterAbility("Player1"); - likeaCheaterCount += 1; - } - else if (event.key === '2' && fastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { - fastandFuriousAbility(); - fastandFuriousCount += 1; - } - else if (event.key === '3' && frozenBallCount < 1 && gameMode == "Abilities") { - frozenBallAbility(); - frozenBallCount += 1; - } -}); - -// Control paddle2 with arrow keys -document.addEventListener("keydown", function(event) { - if (event.key === "ArrowUp") { - upPressedPlayer2 = true; - } else if (event.key === "ArrowDown") { - downPressedPlayer2 = true; - } - else if (event.key === '8' && Player2LikeaCheaterCount < 1 && gameMode == "Abilities") { - likeaCheaterAbility("Player2"); - Player2LikeaCheaterCount += 1; - } - else if (event.key === '9' && Player2FastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { - fastandFuriousAbility(); - Player2FastandFuriousCount += 1; - } - else if (event.key === '0' && Player2FrozenBallCount < 1 && gameMode == "Abilities") { - frozenBallAbility(); - Player2FrozenBallCount += 1; - } -}); - -document.addEventListener("keyup", function(event) { - if (event.key === "w" || event.key === "W" ) { - upPressed = false; - } else if (event.key === "s" || event.key === "S") { - downPressed = false; - } -}); - -document.addEventListener("keyup", function(event) { - if (event.key === "ArrowUp") { - upPressedPlayer2 = false; - } else if (event.key === "ArrowDown") { - downPressedPlayer2 = false; - } -}); - -function showCanvas() { - pongCanvas.style.display = "block"; - gameStartInfos.style.display = "none"; - gameInfoTournament.style.display = "block"; - isPaused = false; - isGameStarted = true; - } - -// Reset the paddle1 position? -function resetPaddles() { - paddle1.y = (canvas.height - abilities_paddleHeight) / 2; - paddle2.y = (canvas.height - abilities_paddleHeight) / 2; -} - -function resetGame() { - score1 = 0; - score2 = 0; - resetBall(); - resetPaddles(); - resetAbilities(); -} - -// Oyun bitiş ekranını gösteren fonksiyon -function showGameOverScreen(player1, player2) { - gameInfoTournament.style.display = "none"; - var message = " wins!"; - var tournamentText = "Tournament is over! "; - if (selectedLanguage == 'hi') { - message = " जीत!"; - tournamentText = "टूर्नामेंट ख़त्म हो गया है! "; - } - else if (selectedLanguage == 'pt') { - message = " vence!"; - tournamentText = "O torneio acabou! "; - } - else if (selectedLanguage == 'tr') { - message = " kazandI!"; - tournamentText = "Turnuva bitti! "; - } - else { - message = " wins!"; - tournamentText = "Tournament is over! "; - } - - var winnerText = (score1 == MAX_SCORE) ? player1 + message : player2 + message; - document.getElementById('winnerText').innerText = winnerText; - document.getElementById('gameOverScreen').style.display = 'block'; - var winnerName = (score1 == MAX_SCORE) ? player1 : player2; - if (matchCount === 0) { - var match = { - player1: winnerName, - player2: "Player2" - }; - matches.push(match); - } - else if (matchCount === 1) { - matches[2].player2 = winnerName; - } - if (isPaused == false) { - matchCount++; - if (matchCount === 3) - document.getElementById('winnerText').innerText = tournamentText + winnerName + message; - } - isPaused = true; -} - -function showGameOverTournament(winner) { - isGameStarted = false; - gameInfoTournament.style.display = "none"; - var winnerText = winner + " wins the tournament!"; - if (selectedLanguage === "tr") { - winnerText = winner + " turnuvayI kazandI!"; - } - else if (selectedLanguage === 'hi') { - winnerText = winner + " टूर्नामेंट जीतता है!"; - } - else if (selectedLanguage === 'pt') { - winnerText = winner + " vence o torneio!"; - } - - document.getElementById('winnerTextTournament').innerText = winnerText; - document.getElementById('gameOverScreenTournament').style.display = 'block'; -} - -function showBracket() { - gameStartInfos.style.display = "none"; - canvas.style.display = "none"; - // Oyuncu isimlerini karıştır - playerNames.sort(() => Math.random() - 0.5); - - // Oyuncu isimlerini rastgele çiftler oluştur - while (playerNames.length > 1) { - var randomIndex1 = Math.floor(Math.random() * playerNames.length); - var player1 = playerNames[randomIndex1]; - playerNames.splice(randomIndex1, 1); - - var randomIndex2 = Math.floor(Math.random() * playerNames.length); - var player2 = playerNames[randomIndex2]; - playerNames.splice(randomIndex2, 1); - - var match = { - player1: player1, - player2: player2 - }; - matches.push(match); - } - - - - document.getElementById('top-name-1').innerText = matches[0].player1; - document.getElementById('top-name-2').innerText = matches[0].player2; - - document.getElementById('bottom-name-1').innerText = matches[1].player1; - document.getElementById('bottom-name-2').innerText = matches[1].player2; - - document.getElementById('final-name-1').innerText = matches[0].player1.substring(0,6) + " / " + matches[0].player2.substring(0,6); - document.getElementById('final-name-2').innerText = matches[1].player1.substring(0,6) + " / " + matches[1].player2.substring(0,6); - - document.getElementById('show-bracket').style.display = 'block'; -} - -// Oyunu tekrar başlatan fonksiyon -function restartGame() { - document.getElementById('gameOverScreen').style.display = 'none'; - gameInfoTournament.style.display = "block"; - resetGame(); -} - - -// Çıkış yapma işlemleri -function exitGame() { - swapApp('/pong-game-find') -} - -document.getElementById('restartButton').addEventListener('click', restartGame); -document.getElementById('exitButtonTournament').addEventListener('click', exitGame); - -function replaceTurkishCharacters(str) { - var turkishMap = { - 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', - 'ğ':'g', 'Ğ':'G', 'ü':'u', 'Ü':'U', - 'ö':'o', 'Ö':'O', 'ç':'c', 'Ç':'C' - }; - return str.replace(/ş|Ş|ı|İ|ğ|Ğ|ü|Ü|ö|Ö|ç|Ç/g, function(match) { - return turkishMap[match]; - }); -} - -startButton.addEventListener("click", function() { - var player1Name = replaceTurkishCharacters(document.getElementById("player1Name").value.substring(0, 8)); - var player2Name = replaceTurkishCharacters(document.getElementById("player2Name").value.substring(0, 8)); - var player3Name = replaceTurkishCharacters(document.getElementById("player3Name").value.substring(0, 8)); - var player4Name = replaceTurkishCharacters(document.getElementById("player4Name").value.substring(0, 8)); - playerNames.push(player1Name); - playerNames.push(player2Name); - playerNames.push(player3Name); - playerNames.push(player4Name); - MAX_SCORE = document.getElementById("maxScore").value; - gameMode = document.getElementById("gameMode").value; - - showBracket(); -}); - -startTournament.addEventListener("click", function() { - document.getElementById('show-bracket').style.display = 'none'; - showCanvas(); -}); +export function localTournament() { +const canvas = document.getElementById('pongCanvas'); +var gameStartInfos = document.getElementById("tournament-start-info"); +var gameInfoTournament = document.getElementById("game-info-tournament"); +var startButton = document.getElementById("startButton"); +var startTournament = document.getElementById("startTournament"); +var ctx = canvas.getContext("2d"); +canvas.width = 800; +canvas.height = 600; + + +const canvasContainer = document.querySelector('.ai-game'); +var gameMode = "Vanilla"; + +/* Tournament */ +var playerNames = []; +var matches = []; +const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); +const selectedLanguage = cookie ? cookie.split('=')[1] : 'en'; + +var matchCount = 0; + +const paddleColor = document.querySelector('.container-top').dataset.paddlecolor; +const playgroundColor = document.querySelector('.container-top').dataset.playgroundcolor; +canvas.style.borderColor = playgroundColor; // Set the border color to the specified color + +/* Cordinates of the canvas */ +var textWidth1 = ctx.measureText(matches[matchCount] + ": " + score1).width; +var textWidth2 = ctx.measureText(matches[matchCount] + ": " + score2).width; + + +var usernameX = 10; +var usernameY = 20; +// player2 metni sağ üst köşede +var player2nameX = canvas.width - textWidth2 - 10; +var player2nameY = 20; + +// if giantMan abilities equiped +var abilities_paddleHeight = (gameMode == "Abilities") ? 115 : 100; +var paddleWidth = 10; +var paddleHeight = 100; +var paddleSpeed = 15; +var paddleY = (canvas.height - paddleHeight) / 2; +var paddle1 = {x: 0, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; +var paddle2 = {x: canvas.width - paddleWidth, y: paddleY, width: paddleWidth, height: abilities_paddleHeight, dy: paddleSpeed}; + +// Ball object +var ball = {x: canvas.width / 2, y: canvas.height / 2, radius: 10, speed: 10, dx: 1, dy: 1}; + +// Scores +var isGameStarted = false; + +var score1 = 0; +var score2 = 0; + +var MAX_SCORE = 3; + +// Player Abilities +var likeaCheaterCount = 0; +var fastandFuriousCount = 0; +var frozenBallCount = 0; +var Player2FrozenBallCount = 0; +var Player2LikeaCheaterCount = 0; +var Player2FastandFuriousCount = 0; + +var isFrozenBallActive = false; + +// Add a new variable to track if the game is paused +let isScored = false; +var isPaused = true; +let upPressed = false; +let downPressed = false; +let upPressedPlayer2 = false; +let downPressedPlayer2 = false; + + +function resetAbilities() { + likeaCheaterCount = 0; + fastandFuriousCount = 0; + frozenBallCount = 0; + Player2FrozenBallCount = 0; + Player2LikeaCheaterCount = 0; + Player2FastandFuriousCount = 0; +} + +// Update the ball and paddle positions +function update() { + // If the game is paused, don't update anything + if (isPaused) return; + + ball.x += ball.speed * ball.dx; + ball.y += ball.speed * ball.dy; + + // Check for collisions with paddles + if (ball.y + ball.radius >= paddle1.y && ball.y - ball.radius <= paddle1.y + paddle1.height && ball.dx < 0) { + if (ball.x - ball.radius <= paddle1.x + paddle1.width) { + if (gameMode == "Abilities") { + if (Math.random() <= 0.5) { + ball.speed += 0.25; + } + } + ball.x = paddle1.x + paddle1.width + ball.radius; + ball.dx *= -1; + if (ball.y < paddle1.y + 0.2 * paddle1.height || ball.y > paddle1.y + 0.8 * paddle1.height) { + ball.speed *= 1.2; // Increase speed by 20% + paddleSpeed *= 1.2; + } + } + } + if (ball.y + ball.radius >= paddle2.y && ball.y - ball.radius <= paddle2.y + paddle2.height && ball.dx > 0) { + if (ball.x + ball.radius >= paddle2.x) { + if (gameMode == "Abilities") { + if (Math.random() <= 0.5) { + ball.speed += 0.25; + } + } + ball.x = paddle2.x - ball.radius; + ball.dx *= -1; + if (ball.y < paddle2.y + 0.2 * paddle2.height || ball.y > paddle2.y + 0.8 * paddle2.height) { + ball.speed *= 1.2; // Increase speed by 20% + paddleSpeed *= 1.2; + } + } + } + + // Check for collisions with top/bottom walls + if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) { + ball.dy *= -1; + } + + // Check for collisions with left/right walls (scoring) + if (ball.x + ball.radius > canvas.width) { + score1++; + resetBall(); + } else if (ball.x - ball.radius < 0) { + score2++; + resetBall(); + } + + // Check for game over + if (score1 == MAX_SCORE || score2 == MAX_SCORE) { + if (matchCount < 2) { + showGameOverScreen(score1 == MAX_SCORE ? matches[matchCount].player1 : matches[matchCount].player2); + } + else { + isPaused = true; + showGameOverTournament(score1 == MAX_SCORE ? matches[matchCount].player1 : matches[matchCount].player2); + } + } + + // Move the paddle1 + if (upPressed && paddle1.y > 0 && !isScored) { + paddle1.y -= paddle1.dy; + } else if (downPressed && paddle1.y < canvas.height - paddle1.height && !isScored) { + paddle1.y += paddle1.dy; + } + + // Move the paddle2 + if (upPressedPlayer2 && paddle2.y > 0 && !isScored) { + paddle2.y -= paddle2.dy; + } else if (downPressedPlayer2 && paddle2.y < canvas.height - paddle2.height && !isScored) { + paddle2.y += paddle2.dy; + } + + // Prevent the paddles from moving off the canvas + if (paddle1.y < 0) { + paddle1.y = 0; + } else if (paddle1.y > canvas.height - paddle1.height) { + paddle1.y = canvas.height - paddle1.height; + } + if (paddle2.y < 0) { + paddle2.y = 0; + } else if (paddle2.y > canvas.height - paddle2.height) { + paddle2.y = canvas.height - paddle2.height; + } +} + +/// Draw everything +function render() { + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Create a radial gradient for the background + var gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 10, canvas.width / 2, canvas.height / 2, 300); + gradient.addColorStop(0, 'lightgrey'); + gradient.addColorStop(1, 'darkgrey'); + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + // Draw the middle dotted line + ctx.beginPath(); + ctx.setLineDash([5, 15]); + ctx.moveTo(canvas.width / 2, 0); + ctx.lineTo(canvas.width / 2, canvas.height); + ctx.strokeStyle = "black"; + ctx.stroke(); + + // Draw the middle dotted circle + ctx.beginPath(); + ctx.arc(canvas.width / 2, canvas.height / 2, 50, 0, Math.PI * 2, false); + ctx.setLineDash([5, 15]); + ctx.stroke(); + + // Add shadow to the paddles + ctx.shadowColor = 'black'; + ctx.shadowBlur = 10; + ctx.shadowOffsetX = 5; + ctx.shadowOffsetY = 5; + + ctx.fillStyle = paddleColor + ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); + // If paddle2 is on the right, draw the shadow to the left + ctx.shadowOffsetX = -5; + ctx.shadowOffsetY = 5; + ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); + + // Add shiny effect to the ball + ctx.beginPath(); + ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, false); + var gradient = ctx.createRadialGradient(ball.x, ball.y, 0, ball.x, ball.y, ball.radius); + gradient.addColorStop(0, 'white'); + gradient.addColorStop(0.1, 'gold'); + gradient.addColorStop(1, 'darkorange'); + ctx.fillStyle = gradient; + ctx.fill(); + ctx.closePath(); + + // Reset shadow properties + ctx.shadowColor = 'transparent'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + + ctx.font = "16px Roboto"; + ctx.fillStyle = 'white'; + + + if (matchCount === 0) { + ctx.fillText(matches[matchCount].player1 + ": " + score1, usernameX, usernameY); + ctx.fillText(matches[matchCount].player2 + ": " + score2, player2nameX, player2nameY); + } + else if (matchCount === 1) { + ctx.fillText(matches[matchCount].player1 + ": " + score1, usernameX, usernameY); + ctx.fillText(matches[matchCount].player2 + ": " + score2, player2nameX, player2nameY); + } + else if (matchCount === 2) { + ctx.fillText(matches[matchCount].player1 + ": " + score1, usernameX, usernameY); + ctx.fillText(matches[matchCount].player2 + ": " + score2, player2nameX, player2nameY); + } +} + + +// The main game loop +var main = function () { + // Request to do this again ASAP + if (!isPaused) { + update(); + render(); + } + + localTournamentAnimationId = requestAnimationFrame(main); +}; + +// Cross-browser support for requestAnimationFrame +var w = window; +requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame; + +// Let's play this game! +main(); + + + +// Reset the ball to the center +function resetBall() { + isScored = true; + isPaused = true; + ball.speed = 10; + paddleSpeed = 14; + ball.dx = -ball.dx; + ball.dy = -ball.dy; + setTimeout(() => { + ball.x = canvas.width / 2; + ball.y = canvas.height / 2; + isPaused = false; + isScored = false; + }, 500); +} + +function frozenBallAbility() { + var nowBallSpeed = ball.speed; + isFrozenBallActive = true; + ball.speed = 0; + setTimeout(function() { + ball.speed = nowBallSpeed; + isFrozenBallActive = false; + }, 2000); +} + +function likeaCheaterAbility(whichPlayer) { + if (whichPlayer == "Player2") { + score2++; + if (score1 > 0) { + score1--; + } + } + else if (whichPlayer == "Player1") { + score1++; + + if (score2 > 0) { + score2--; + } + } +} + +function fastandFuriousAbility() { + ball.speed += 10; +} + +// Control paddle1 with w, s keys +document.addEventListener("keydown", function(event) { + if (event.key === "w" || event.key === "W") { + upPressed = true; + } + else if (event.key === "s" || event.key === "S") { + downPressed = true; + } + else if (event.key === '1' && likeaCheaterCount < 1 && gameMode == "Abilities") { + likeaCheaterAbility("Player1"); + likeaCheaterCount += 1; + } + else if (event.key === '2' && fastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { + fastandFuriousAbility(); + fastandFuriousCount += 1; + } + else if (event.key === '3' && frozenBallCount < 1 && gameMode == "Abilities") { + frozenBallAbility(); + frozenBallCount += 1; + } +}); + +// Control paddle2 with arrow keys +document.addEventListener("keydown", function(event) { + if (event.key === "ArrowUp") { + upPressedPlayer2 = true; + } else if (event.key === "ArrowDown") { + downPressedPlayer2 = true; + } + else if (event.key === '8' && Player2LikeaCheaterCount < 1 && gameMode == "Abilities") { + likeaCheaterAbility("Player2"); + Player2LikeaCheaterCount += 1; + } + else if (event.key === '9' && Player2FastandFuriousCount < 1 && gameMode == "Abilities" && isFrozenBallActive == false) { + fastandFuriousAbility(); + Player2FastandFuriousCount += 1; + } + else if (event.key === '0' && Player2FrozenBallCount < 1 && gameMode == "Abilities") { + frozenBallAbility(); + Player2FrozenBallCount += 1; + } +}); + +document.addEventListener("keyup", function(event) { + if (event.key === "w" || event.key === "W" ) { + upPressed = false; + } else if (event.key === "s" || event.key === "S") { + downPressed = false; + } +}); + +document.addEventListener("keyup", function(event) { + if (event.key === "ArrowUp") { + upPressedPlayer2 = false; + } else if (event.key === "ArrowDown") { + downPressedPlayer2 = false; + } +}); + +function showCanvas() { + pongCanvas.style.display = "block"; + gameStartInfos.style.display = "none"; + gameInfoTournament.style.display = "block"; + isPaused = false; + isGameStarted = true; + } + +// Reset the paddle1 position? +function resetPaddles() { + paddle1.y = (canvas.height - abilities_paddleHeight) / 2; + paddle2.y = (canvas.height - abilities_paddleHeight) / 2; +} + +function resetGame() { + score1 = 0; + score2 = 0; + resetBall(); + resetPaddles(); + resetAbilities(); +} + +// Oyun bitiş ekranını gösteren fonksiyon +function showGameOverScreen(player1, player2) { + gameInfoTournament.style.display = "none"; + var message = " wins!"; + var tournamentText = "Tournament is over! "; + if (selectedLanguage == 'hi') { + message = " जीत!"; + tournamentText = "टूर्नामेंट ख़त्म हो गया है! "; + } + else if (selectedLanguage == 'pt') { + message = " vence!"; + tournamentText = "O torneio acabou! "; + } + else if (selectedLanguage == 'tr') { + message = " kazandI!"; + tournamentText = "Turnuva bitti! "; + } + else { + message = " wins!"; + tournamentText = "Tournament is over! "; + } + + var winnerText = (score1 == MAX_SCORE) ? player1 + message : player2 + message; + document.getElementById('winnerText').innerText = winnerText; + document.getElementById('gameOverScreen').style.display = 'block'; + var winnerName = (score1 == MAX_SCORE) ? player1 : player2; + if (matchCount === 0) { + var match = { + player1: winnerName, + player2: "Player2" + }; + matches.push(match); + } + else if (matchCount === 1) { + matches[2].player2 = winnerName; + } + if (isPaused == false) { + matchCount++; + if (matchCount === 3) + document.getElementById('winnerText').innerText = tournamentText + winnerName + message; + } + isPaused = true; +} + +function showGameOverTournament(winner) { + isGameStarted = false; + gameInfoTournament.style.display = "none"; + var winnerText = winner + " wins the tournament!"; + if (selectedLanguage === "tr") { + winnerText = winner + " turnuvayI kazandI!"; + } + else if (selectedLanguage === 'hi') { + winnerText = winner + " टूर्नामेंट जीतता है!"; + } + else if (selectedLanguage === 'pt') { + winnerText = winner + " vence o torneio!"; + } + + document.getElementById('winnerTextTournament').innerText = winnerText; + document.getElementById('gameOverScreenTournament').style.display = 'block'; +} + +function showBracket() { + gameStartInfos.style.display = "none"; + canvas.style.display = "none"; + // Oyuncu isimlerini karıştır + playerNames.sort(() => Math.random() - 0.5); + + // Oyuncu isimlerini rastgele çiftler oluştur + while (playerNames.length > 1) { + var randomIndex1 = Math.floor(Math.random() * playerNames.length); + var player1 = playerNames[randomIndex1]; + playerNames.splice(randomIndex1, 1); + + var randomIndex2 = Math.floor(Math.random() * playerNames.length); + var player2 = playerNames[randomIndex2]; + playerNames.splice(randomIndex2, 1); + + var match = { + player1: player1, + player2: player2 + }; + matches.push(match); + } + + + + document.getElementById('top-name-1').innerText = matches[0].player1; + document.getElementById('top-name-2').innerText = matches[0].player2; + + document.getElementById('bottom-name-1').innerText = matches[1].player1; + document.getElementById('bottom-name-2').innerText = matches[1].player2; + + document.getElementById('final-name-1').innerText = matches[0].player1.substring(0,6) + " / " + matches[0].player2.substring(0,6); + document.getElementById('final-name-2').innerText = matches[1].player1.substring(0,6) + " / " + matches[1].player2.substring(0,6); + + document.getElementById('show-bracket').style.display = 'block'; +} + +// Oyunu tekrar başlatan fonksiyon +function restartGame() { + document.getElementById('gameOverScreen').style.display = 'none'; + gameInfoTournament.style.display = "block"; + resetGame(); +} + + +// Çıkış yapma işlemleri +function exitGame() { + swapApp('/pong-game-find') +} + +document.getElementById('restartButton').addEventListener('click', restartGame); +document.getElementById('exitButtonTournament').addEventListener('click', exitGame); + +function replaceTurkishCharacters(str) { + var turkishMap = { + 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', + 'ğ':'g', 'Ğ':'G', 'ü':'u', 'Ü':'U', + 'ö':'o', 'Ö':'O', 'ç':'c', 'Ç':'C' + }; + return str.replace(/ş|Ş|ı|İ|ğ|Ğ|ü|Ü|ö|Ö|ç|Ç/g, function(match) { + return turkishMap[match]; + }); +} + +startButton.addEventListener("click", function() { + var player1Name = replaceTurkishCharacters(document.getElementById("player1Name").value.substring(0, 8)); + var player2Name = replaceTurkishCharacters(document.getElementById("player2Name").value.substring(0, 8)); + var player3Name = replaceTurkishCharacters(document.getElementById("player3Name").value.substring(0, 8)); + var player4Name = replaceTurkishCharacters(document.getElementById("player4Name").value.substring(0, 8)); + playerNames.push(player1Name); + playerNames.push(player2Name); + playerNames.push(player3Name); + playerNames.push(player4Name); + MAX_SCORE = document.getElementById("maxScore").value; + gameMode = document.getElementById("gameMode").value; + + showBracket(); +}); + +startTournament.addEventListener("click", function() { + document.getElementById('show-bracket').style.display = 'none'; + showCanvas(); +}); } \ No newline at end of file diff --git a/indianpong/static/js/game/sockPong.js b/indianpong/static/js/game/sockPong.js index b50c7de4..43b09ec4 100644 --- a/indianpong/static/js/game/sockPong.js +++ b/indianpong/static/js/game/sockPong.js @@ -1,805 +1,805 @@ -export function RemotePong() { - -const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); -const lang = cookie ? cookie.split('=')[1] : 'en'; - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - const toast = new bootstrap.Toast(liveToast); - toast.show(); - setTimeout(function() { - toast.hide(); - }, 8000); -} - - // Extract game_id and game_type from the URL -const pathArray = window.location.pathname.split('/'); -const gameType = pathArray[2]; // Assuming game_type is the third segment of the URL -const gameId = pathArray[3]; // Assuming game_id is the fourth segment of the URL - - -// Connect to the WebSocket server using the extracted game_id and game_type -const matchsocket = new WebSocket(`ws://${window.location.host}/ws/remote-game/${gameType}/${gameId}/`); //? Maybe we need to pass game type and game id here - - -const canvas = document.getElementById('pongCanvas'); -var ctx = canvas.getContext("2d"); -canvas.width = 800; -canvas.height = 600; - -const checkbox = document.getElementById('flexSwitchCheckDefault'); -const selectedGameModeLabel = document.getElementById('selectedGameMode'); - -let gameMode = "Vanilla"; - -// Custom items -const leftArea = document.getElementById('left-area-display'); -const paddleColor = document.querySelector('.left-card').dataset.paddlecolor; -const playgroundColor = document.querySelector('.left-card').dataset.playgroundcolor; -canvas.style.borderColor = playgroundColor; -const giantMan = document.querySelector('.left-card').dataset.giantman; -const likeaCheater = document.querySelector('.left-card').dataset.likeacheater; -const fastandFurious = document.querySelector('.left-card').dataset.fastandfurious; -const rageofFire = document.querySelector('.left-card').dataset.rageoffire; -const frozenBall = document.querySelector('.left-card').dataset.frozenball; -const tournament = document.querySelector('.left-card').dataset.tournament; - -let likeaCheaterCount = 0; -let fastandFuriousCount = 0; -let frozenBallCount = 0; - -let isFrozenBallActive = false; - -// Paddle objects -var paddleWidth = 10; -var paddleHeight = 100; -var paddleY = (canvas.height - paddleHeight) / 2; -var paddle1 = {x: 0, y: paddleY, width: paddleWidth, height: paddleHeight}; -var paddle2 = {x: canvas.width - paddleWidth, y: paddleY, width: paddleWidth, height: paddleHeight}; - -// Ball object -var ball = {x: canvas.width / 2, y: canvas.height / 2, radius: 10}; - -// maybe merge with my object -var player1 = {username: '', score: 0}; -var player2 = {username: '', score: 0}; - -var my = { - username: '', opponent_username: '', game_id: '', tournament_id: '', -}; - -let upPressed = false; -let downPressed = false; - -//Button -//const startButton = document.getElementById('startButton'); -const leaveButton = document.getElementById('leaveButton'); -leaveButton.style.display = 'none'; -const gameOverScreen = document.getElementById('gameOverScreen'); -const matchmakingButton = document.getElementById('matchmakingButton'); -//const restartButton = document.getElementById('restartButton'); -//startButton.style.display = 'none'; -//restartButton.style.display = 'none'; - -// Envai -var textWidth1 = ctx.measureText(player1.username + ": " + player1.score).width; -var textWidth2 = ctx.measureText(player2.username + ": " + player2.score).width; - -/// Draw everything -function render() { - - ctx.clearRect(0, 0, canvas.width, canvas.height); - - // Create a radial gradient for the background - var gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 10, canvas.width / 2, canvas.height / 2, 300); - gradient.addColorStop(0, 'lightgrey'); - gradient.addColorStop(1, 'darkgrey'); - ctx.fillStyle = gradient; - ctx.fillRect(0, 0, canvas.width, canvas.height); - - // Draw the middle dotted line - ctx.beginPath(); - ctx.setLineDash([5, 15]); - ctx.moveTo(canvas.width / 2, 0); - ctx.lineTo(canvas.width / 2, canvas.height); - ctx.strokeStyle = "black"; - ctx.stroke(); - - // Draw the middle dotted circle - ctx.beginPath(); - ctx.arc(canvas.width / 2, canvas.height / 2, 50, 0, Math.PI * 2, false); - ctx.setLineDash([5, 15]); - ctx.stroke(); - - - // Add shadow to the paddles - ctx.shadowColor = 'black'; - ctx.shadowBlur = 10; - ctx.shadowOffsetX = 5; - ctx.shadowOffsetY = 5; - - ctx.fillStyle = paddleColor; - ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); - // If paddle2 is on the right, draw the shadow to the left - ctx.shadowOffsetX = -5; - ctx.shadowOffsetY = 5; - ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); - - // Add shiny effect to the ball - ctx.beginPath(); - ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, false); - var gradient = ctx.createRadialGradient(ball.x, ball.y, 0, ball.x, ball.y, ball.radius); - gradient.addColorStop(0, 'white'); - gradient.addColorStop(0.1, 'gold'); - gradient.addColorStop(1, 'darkorange'); - ctx.fillStyle = gradient; - ctx.fill(); - ctx.closePath(); - - // Reset shadow properties - ctx.shadowColor = 'transparent'; - ctx.shadowBlur = 0; - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - - ctx.font = "14px Roboto"; - ctx.fillStyle = 'white'; - ctx.fillText(player1.username + ": " + player1.score, 50, 20); - ctx.fillText(player2.username + ": " + player2.score, canvas.width - textWidth2 - 80, 20); -} - -var requestId; - -// The main game loop -var startGame = function () { - - - BallRequest(); - updatePaddlePosition(); - render(); - // Request to do this again ASAP - requestId = requestAnimationFrame(startGame); -}; - -// When you want to stop the game loop -var stopGame = function() { - cancelAnimationFrame(requestId); -}; - -function gameUtilsReset() { - likeaCheaterCount = 0; - fastandFuriousCount = 0; - frozenBallCount = 0; - isFrozenBallActive = false; - - if (giantMan == "true" && (gameMode === "Abilities" || tournament === "abilities")) - sendAbility("giantMan"); - if (rageofFire == "true" && (gameMode === "Abilities" || tournament === "abilities")) - sendAbility("rageofFire"); -} - -// Cross-browser support for requestAnimationFrame -var w = window; -requestAnimationFrame = - w.requestAnimationFrame || - w.webkitRequestAnimationFrame || - w.msRequestAnimationFrame || - w.mozRequestAnimationFrame; - -function paddleMove(player, y) { - if (player === player1.username) { - paddle1.y = y; - } else if (player === player2.username) { - paddle2.y = y; - } -} - -function ballMove(x, y) { - ball.x = x; - ball.y = y; -} - -function scoreUpdate(player1_score, player2_score) { - player1.score = player1_score; - player2.score = player2_score; -} - -matchsocket.onopen = function (e) { - // Show some greeting message - console.log('WebSocket connection established'); -} - -matchsocket.onclose = function (e) { - //clearInterval(BallRequest); - stopGame(); - console.error('WebSocket connection closed'); -} - -matchsocket.onerror = function (e) { - console.error('Error: ' + e.data); - //clearInterval(BallRequest); - stopGame(); -} - -matchsocket.onmessage = function (e) { - const data = JSON.parse(e.data); - //console.log(data); - switch (data.type) { - case 'inlobby': - // Self send message - console.log('In lobby', data.user); - if (my.username === '') { - my.username = data.user; - } - // Take online users usernames and display them - addUsersToTable(data.users); - console.log('Online users', data.users); - break; - - case 'user.inlobby': - // Send others i joined the lobby - console.log('User in lobby', data.user); - // Add user to online users list - if (data.user !== my.username) { - addUsersToTable([data.user]); - } - if (lang === 'tr') - showToast(data.user + ' katıldı!', 'text-bg-success', 'bi bi-check-circle-fill') - else if (lang === 'hi') - showToast(data.user + ' शामिल हो गया!', 'text-bg-success', 'bi bi-check-circle-fill') - else if (lang === 'pt') - showToast(data.user + ' entrou!', 'text-bg-success', 'bi bi-check-circle-fill') - else - showToast(data.user + ' joined!', 'text-bg-success', 'bi bi-check-circle-fill') - break; - - case 'user.outlobby': - // Send others user left the lobby - console.log('User out lobby', data.user); - // Remove user from online users list - removeUserFromTable(data.user); - if (lang === 'tr') - showToast(data.user + ' ayrıldı!', 'text-bg-danger', 'bi bi-check-circle-fill') - else if (lang === 'hi') - showToast(data.user + ' चला गया!', 'text-bg-danger', 'bi bi-check-circle-fill') - else if (lang === 'pt') - showToast(data.user + ' saiu!', 'text-bg-danger', 'bi bi-check-circle-fill') - else - showToast(data.user + ' left!', 'text-bg-danger', 'bi bi-check-circle-fill') - break; - - case 'game.disconnected': - //clearInterval(BallRequest); - stopGame(); - gameOverScreen.style.display = 'block'; - showToast(`${data.disconnected} disconnected You are automatically winner`, 'text-bg-danger', 'bi bi-check-circle-fill') - console.log('Player disconnected', data.disconnected); - - case 'game.invite': - // Tell user that he/she is invited to a game - console.log('Game invite', data.inviter); - console.log('data: ', data.invitee + " " + my.username) - // Display the modal for accepting or declining the invitation - - hideInviteButtons(data.inviter, data.invitee); - - const acceptButton = document.getElementById(`acceptButton${data.inviter}`); - const declineButton = document.getElementById(`declineButton${data.inviter}`); - if (data.invitee === my.username) { - if (lang === 'tr') - showToast(`${data.inviter} tarafından bir oyun daveti aldınız`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`${data.inviter} द्वारा आपको एक खेल आमंत्रण मिला है`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`Você recebeu um convite de jogo de ${data.inviter}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else - showToast(`You received a game invitation from ${data.inviter}`, 'text-bg-success', 'bi bi-check-circle-fill') - acceptButton.style.display = 'flex'; - declineButton.style.display = 'flex'; - } - - acceptButton.onclick = function () { - accept(data.inviter); - acceptButton.style.display = 'none'; - declineButton.style.display = 'none'; - }; - - declineButton.onclick = function () { - decline(data.inviter); - acceptButton.style.display = 'none'; - declineButton.style.display = 'none'; - }; - - console.log(`Invited Group: ${data.inviter} vs ${data.invitee}`); - break; - - case 'tournament.match': - player1.username = data.player1; - player2.username = data.player2; - my.game_id = data.game_id; - my.tournament_id = data.tournament_id; - leftArea.style.display = 'none'; - if (lang === 'tr') - showToast(`Turnuva maçı başladı! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`टूर्नामेंट मैच शुरू हो गया! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`Jogo de torneio começou! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else - showToast(`Tournament match started! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - - render(); - showToast('Press Space to start the game', 'text-bg-primary', 'bi bi-exclamation-triangle-fill') - - document.addEventListener("keydown", SpaceKeyDown); - - console.log(`Tournament Id: ${data.tournament_id}, Match Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); - break; - - case 'chat.game': - player1.username = data.player1; - player2.username = data.player2; - my.game_id = data.game_id; - if (lang === 'tr') - showToast(`Chat maçı başladı! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`टूर्नामेंट मैच शुरू हो गया! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`Jogo de torneio começou! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else - showToast(`Chat match started! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - - render(); - showToast('Press Space to start the game', 'text-bg-primary', 'bi bi-exclamation-triangle-fill') - - document.addEventListener("keydown", SpaceKeyDown); - - console.log(`Match Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); - break; - - case 'game.accept': - player1.username = data.accepted; - player2.username = data.accepter; - my.game_id = data.game_id; - if (data.accepter === my.username) { - if (lang === 'tr') - showToast(`Davetiniz ${data.accepted} tarafından kabul edildi`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`आपका निमंत्रण ${data.accepted} द्वारा स्वीकृत किया गया`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`Seu convite foi aceito por ${data.accepted}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else - showToast(`You accepted the game invitation from ${data.accepted}`, 'text-bg-success', 'bi bi-check-circle-fill'); - my.opponent_username = data.accepted; // if gerekir mi? - } - else if (data.accepted === my.username) { - if (lang === 'tr') - showToast(`Davetiniz ${data.accepter} tarafından kabul edildi`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`आपका निमंत्रण ${data.accepter} द्वारा स्वीकृत किया गया`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`Seu convite foi aceito por ${data.accepter}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else - showToast(`Your invitation is accepted by ${data.accepter}`, 'text-bg-success', 'bi bi-check-circle-fill'); - my.opponent_username = data.accepter; // if gerekir mi? - } - render(); - showToast('Press Space to start the game', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); - - - document.addEventListener("keydown", SpaceKeyDown); - - console.log(`Accepted Game Id: ${data.game_id} => ${data.accepted} vs ${data.accepter}`); - break; - - case 'game.decline': - if (data.declined === my.username) { - if (lang === 'tr') - showToast(`Davetiniz ${data.decliner} tarafından reddedildi`, 'text-bg-danger', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`आपका निमंत्रण ${data.decliner} द्वारा अस्वीकार किया गया`, 'text-bg-danger', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`Seu convite foi recusado por ${data.decliner}`, 'text-bg-danger', 'bi bi-check-circle-fill'); - else - showToast(`Your invitation is declined by ${data.decliner}`, 'text-bg-danger', 'bi bi-check-circle-fill'); - } - console.log(`Declined Game => ${data.declined} vs ${data.decliner}`); - break; - - case 'game.start': - // if they vote for Start, start the game otherwise update votes - // Start the game - checkbox.disabled = true; - leftArea.style.display = 'none'; - if (data.vote == 2) { - if (lang === 'tr') - showToast(`3 saniye içinde ${player1.username} ve ${player2.username} arasında oyun başlıyor`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`3 सेकंड में ${player1.username} और ${player2.username} के बीच खेल शुरू हो रहा है`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`Jogo começando em 3 segundos entre ${player1.username} e ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else - showToast(`Game starting in 3 sec between ${player1.username} and ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); - - leaveButton.style.display = 'block'; - gameUtilsReset(); - - // make invitationMessage disappear after 3 seconds - - leaveButton.onclick = function () { - leaveGame(); - leaveButton.style.display = 'none'; - } - - // Control paddle1 with w, s keys - document.addEventListener("keydown", function(event) { - if (event.key === "w" || event.key === "W" || event.key === "ArrowUp") { - upPressed = true; - } else if (event.key === "s" || event.key === "S"|| event.key === "ArrowDown") { - downPressed = true; - } - if (event.key === '1' && likeaCheaterCount < 1 && likeaCheater == "true" && (gameMode === "Abilities" || tournament === "abilities")) { - sendAbility("likeaCheater"); - showToast('You used like a cheater!', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); - likeaCheaterCount += 1; - } - else if (event.key === '2' && fastandFuriousCount < 1 && fastandFurious == "true" && isFrozenBallActive == false && (gameMode === "Abilities" || tournament === "abilities")) { - sendAbility("fastandFurious"); - showToast('You used fast and furious!', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); - fastandFuriousCount += 1; - } - else if (event.key === '3' && frozenBallCount < 1 && frozenBall == "true" && (gameMode === "Abilities" || tournament === "abilities")) { - sendAbility("frozenBall"); - showToast('You used frozen ball!', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); - isFrozenBallActive = true; - setTimeout(function () { - isFrozenBallActive = false; - }, 3000); - frozenBallCount += 1; - } - }); - - document.addEventListener("keyup", function(event) { - if (event.key === "w" || event.key === "W" || event.key === "ArrowUp") { - upPressed = false; - } else if (event.key === "s" || event.key === "S"|| event.key === "ArrowDown") { - downPressed = false; - } - }); - - setTimeout(function () { - startGame(); - }, 3000); - // Ask ball coordinates every 16 milliseconds - //setInterval(BallRequest, 16); - - console.log(`Started Game Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); - } - else if (data.vote == 1) { - console.log(`Waiting for Game Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); - } - else if (data.vote == 0) { - console.log(`None of the players hit space Game Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); - } - break; - - case 'game.leave': - //clearInterval(BallRequest); - leftArea.style.display = 'block'; - stopGame(); - var left_score = data.left_score; - var opponent_score = data.opponent_score; - var winner = data.winner; - var loser = data.loser; - document.getElementById('winnerText').innerText = winner; - document.getElementById('loserText').innerText = loser; - gameOverScreen.style.display = 'block'; - // Show some left game message with scores etc. - //showToast(`${data.left} left the game. Winner is ${winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); - // maybe put restart - leaveButton.style.display = 'none'; - console.log(`Left Game Id: ${data.game_id}`); - break; - - case 'game.end': - //clearInterval(BallRequest); - leftArea.style.display = 'block'; - stopGame(); - checkbox.disabled = false; - player1.score = data.player1_score; - player2.score = data.player2_score; - - var winner = data.winner; - var loser = data.loser; - console.log('Winner: ' + winner + ' Loser: ' + loser + ' Player1 score: ' + player1.score + ' Player2 score: ' + player2.score); - document.getElementById('winnerText').innerText = winner; - document.getElementById('loserText').innerText = loser; - gameOverScreen.style.display = 'block'; - // Show some game ended message with scores etc - if (lang === 'tr') - showToast(`Oyun bitti. Kazanan ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'hi') - showToast(`खेल समाप्त हो गया। विजेता ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else if (lang === 'pt') - showToast(`O jogo acabou. Vencedor é ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); - else - showToast(`Game is ended. Winner is ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); - // maybe put restart - - console.log(`Ended Game Id: ${data.game_id} => ${data.winner} won`); - break; - - case 'game.pause': - // Pause the game - console.log('Game id: ' + data.game_id + ' paused'); - break; - - case 'game.resume': - // Resume the game - console.log('Game id: ' + data.game_id + ' resumed'); - break; - - case 'game.ball': - //get ball position and update it - ballMove(data.x, data.y) - scoreUpdate(data.player1_score, data.player2_score) - //console.log(`Moving Ball Id: ${data.game_id} for ball: ${data.x} ${data.y}`); - break; - - case 'game.paddle': - //get paddle position and update it - paddleMove(data.player, data.y) - //console.log(`Moving Paddle Id: ${data.game_id} for ${data.player}: ${data.y}`); - break; - - case 'game.ability': - console.log(data.ability + ' is used!') - if (data.ability == 'giantMan' && (gameMode === "Abilities" || tournament === "abilities")) { - if (data.player == player1.username) - paddle1.height = 115 - else if (data.player == player2.username) - paddle2.height = 115 - - break; - - }}; -} - -matchsocket.sendJSON = function (data) { - matchsocket.send(JSON.stringify(data)); -} - -function addUsersToTable(usersArray) { - var tableBody = document.querySelector('.custom-table tbody'); - - usersArray.forEach(function(username) { - var row = document.createElement('tr'); - var usernameCell = document.createElement('td'); - usernameCell.textContent = username; - var actionsCell = document.createElement('td'); - - // Create buttons - var btnGroup = document.createElement('div'); - btnGroup.className = "btn-group"; - btnGroup.style.display = "flex"; - btnGroup.style.justifyContent = "center"; - - var inviteButton = document.createElement('button'); - inviteButton.type = "button"; - inviteButton.className = "invite-button"; - inviteButton.id = "inviteButton" + username; - inviteButton.innerHTML = ''; - - var acceptButton = document.createElement('button'); - acceptButton.type = "button"; - acceptButton.className = "accept-button"; - acceptButton.id = "acceptButton" + username; - acceptButton.innerHTML = ''; - - var declineButton = document.createElement('button'); - declineButton.type = "button"; - declineButton.className = "decline-button"; - declineButton.id = "declineButton" + username; - declineButton.innerHTML = ''; - - // Add buttons to button group - btnGroup.appendChild(inviteButton); - btnGroup.appendChild(acceptButton); - btnGroup.appendChild(declineButton); - - actionsCell.appendChild(btnGroup); - row.appendChild(usernameCell); - row.appendChild(actionsCell); - tableBody.appendChild(row); - - // Add event listener to invite button - inviteButton.addEventListener('click', function() { - invite('false', username); - }); - }); -} - -function removeUserFromTable(username) { - var tableBody = document.querySelector('.custom-table tbody'); - var rows = tableBody.querySelectorAll('tr'); - - rows.forEach(function(row) { - var usernameCell = row.querySelector('td:first-child'); - if (usernameCell.textContent.trim() === username.trim()) { - tableBody.removeChild(row); - } - }); -} - - - -function invite(matchmaking = 'false', username) { - // Get necessary data and call socket.sendJSON - if (lang === 'tr') - showToast(`Oyuna ${username} davet ettiniz`, 'text-bg-success', 'bi bi-check-circle-fill') - else if (lang === 'hi') - showToast(`आपने ${username} को एक खेल के लिए आमंत्रित किया`, 'text-bg-success', 'bi bi-check-circle-fill') - else if (lang === 'pt') - showToast(`Você convidou ${username} para um jogo`, 'text-bg-success', 'bi bi-check-circle-fill') - else - showToast(`You invited ${username} to a game`, 'text-bg-success', 'bi bi-check-circle-fill') - matchsocket.sendJSON({ - action: 'invite', - matchmaking: matchmaking, - invitee_username: username, - }); -} - -matchmakingButton.onclick = function () { - invite('true', ''); -} - -//---------------------------------------------- - -function hideInviteButtons(username1, username2) { - // Get the invite buttons for the two users - const inviteButton1 = document.getElementById(`inviteButton${username1}`); - const inviteButton2 = document.getElementById(`inviteButton${username2}`); - - // Hide the invite buttons - if (inviteButton1) inviteButton1.style.display = 'none'; - if (inviteButton2) inviteButton2.style.display = 'none'; -} - -function exitGame() { - console.log("id: " + my.game_id); - matchsocket.sendJSON({ - action: 'exit', - game_id: my.game_id, - }); - - swapApp('/pong-game-find') -} - -function accept(inviter) { - // Get necessary data and call socket.sendJSON - matchsocket.sendJSON({ - action: 'accept', - inviter_username: inviter, - }); -} - -function decline(inviter) { - // Get necessary data and call socket.sendJSON - matchsocket.sendJSON({ - action: 'decline', - inviter_username: inviter, - }); -} - -// Vote count ll be 1 at start if -function startRequest(player1, player2) { - matchsocket.sendJSON({ - action: 'start.request', - game_id: my.game_id, - opponent: my.opponent_username, - vote: 1, - }); -} - -function SpaceKeyDown(event) { - if (event.code === "Space") { - startRequest(my.username, my.opponent_username); - // Remove the event listener after it has been triggered once - document.removeEventListener("keydown", SpaceKeyDown); - } -} - - -function leaveGame() { - matchsocket.sendJSON({ - action: 'leave.game', - game_id: my.game_id, - left: my.username, - opponent: my.opponent_username, - }); -} - -// send this in keydown event -function PaddleRequest(direction) { - // Get necessary data and call socket.sendJSON - matchsocket.sendJSON({ - action: 'paddle', - game_id: my.game_id, - direction: direction - }); -} - -function updatePaddlePosition() { - if (upPressed) { - PaddleRequest('up'); - } else if (downPressed) { - PaddleRequest('down'); - } -} - -function sendAbility(ability) { - matchsocket.sendJSON({ - action: 'ability', - abilities: ability, - game_id: my.game_id, - }); -} - - - -// send this in setInterval(update, 16) this ll be game state -function BallRequest() { - // Get necessary data and call socket.sendJSON - matchsocket.sendJSON({ - action: 'ball', - game_id: my.game_id, - }); -} - -document.getElementById('exitButton').addEventListener('click', exitGame); - -checkbox.addEventListener('change', function() { - // Checkbox'un durumuna göre etiketin innerHTML değerini değiştirme - if (checkbox.checked) { - gameMode = "Abilities"; - if (lang === 'tr') - selectedGameModeLabel.innerHTML = "Yetenekler"; - else if (lang === 'hi') - selectedGameModeLabel.innerHTML = "क्षमताएँ"; - else if (lang === 'pt') - selectedGameModeLabel.innerHTML = "Habilidades"; - else - selectedGameModeLabel.innerHTML = "Abilities"; - } else { - gameMode = "Vanilla"; - if (lang === 'tr') - selectedGameModeLabel.innerHTML = "Vanilya"; - else if (lang === 'hi') - selectedGameModeLabel.innerHTML = "वैनिला"; - else if (lang === 'pt') - selectedGameModeLabel.innerHTML = "Baunilha"; - else - selectedGameModeLabel.innerHTML = "Vanilla"; - } -}); - -const gameModeSelect = document.getElementById("gameModeSelect"); - -gameModeSelect.addEventListener("mouseenter", function() { - document.querySelector(".game-mode-info").style.display = "block"; -}); - -gameModeSelect.addEventListener("mouseleave", function() { - document.querySelector(".game-mode-info").style.display = "none"; -}); +export function RemotePong() { + +const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); +const lang = cookie ? cookie.split('=')[1] : 'en'; + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + const toast = new bootstrap.Toast(liveToast); + toast.show(); + setTimeout(function() { + toast.hide(); + }, 8000); +} + + // Extract game_id and game_type from the URL +const pathArray = window.location.pathname.split('/'); +const gameType = pathArray[2]; // Assuming game_type is the third segment of the URL +const gameId = pathArray[3]; // Assuming game_id is the fourth segment of the URL + + +// Connect to the WebSocket server using the extracted game_id and game_type +const matchsocket = new WebSocket(`wss://${window.location.host}/ws/remote-game/${gameType}/${gameId}/`); //? Maybe we need to pass game type and game id here + + +const canvas = document.getElementById('pongCanvas'); +var ctx = canvas.getContext("2d"); +canvas.width = 800; +canvas.height = 600; + +const checkbox = document.getElementById('flexSwitchCheckDefault'); +const selectedGameModeLabel = document.getElementById('selectedGameMode'); + +let gameMode = "Vanilla"; + +// Custom items +const leftArea = document.getElementById('left-area-display'); +const paddleColor = document.querySelector('.left-card').dataset.paddlecolor; +const playgroundColor = document.querySelector('.left-card').dataset.playgroundcolor; +canvas.style.borderColor = playgroundColor; +const giantMan = document.querySelector('.left-card').dataset.giantman; +const likeaCheater = document.querySelector('.left-card').dataset.likeacheater; +const fastandFurious = document.querySelector('.left-card').dataset.fastandfurious; +const rageofFire = document.querySelector('.left-card').dataset.rageoffire; +const frozenBall = document.querySelector('.left-card').dataset.frozenball; +const tournament = document.querySelector('.left-card').dataset.tournament; + +let likeaCheaterCount = 0; +let fastandFuriousCount = 0; +let frozenBallCount = 0; + +let isFrozenBallActive = false; + +// Paddle objects +var paddleWidth = 10; +var paddleHeight = 100; +var paddleY = (canvas.height - paddleHeight) / 2; +var paddle1 = {x: 0, y: paddleY, width: paddleWidth, height: paddleHeight}; +var paddle2 = {x: canvas.width - paddleWidth, y: paddleY, width: paddleWidth, height: paddleHeight}; + +// Ball object +var ball = {x: canvas.width / 2, y: canvas.height / 2, radius: 10}; + +// maybe merge with my object +var player1 = {username: '', score: 0}; +var player2 = {username: '', score: 0}; + +var my = { + username: '', opponent_username: '', game_id: '', tournament_id: '', +}; + +let upPressed = false; +let downPressed = false; + +//Button +//const startButton = document.getElementById('startButton'); +const leaveButton = document.getElementById('leaveButton'); +leaveButton.style.display = 'none'; +const gameOverScreen = document.getElementById('gameOverScreen'); +const matchmakingButton = document.getElementById('matchmakingButton'); +//const restartButton = document.getElementById('restartButton'); +//startButton.style.display = 'none'; +//restartButton.style.display = 'none'; + +// Envai +var textWidth1 = ctx.measureText(player1.username + ": " + player1.score).width; +var textWidth2 = ctx.measureText(player2.username + ": " + player2.score).width; + +/// Draw everything +function render() { + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Create a radial gradient for the background + var gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 10, canvas.width / 2, canvas.height / 2, 300); + gradient.addColorStop(0, 'lightgrey'); + gradient.addColorStop(1, 'darkgrey'); + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + // Draw the middle dotted line + ctx.beginPath(); + ctx.setLineDash([5, 15]); + ctx.moveTo(canvas.width / 2, 0); + ctx.lineTo(canvas.width / 2, canvas.height); + ctx.strokeStyle = "black"; + ctx.stroke(); + + // Draw the middle dotted circle + ctx.beginPath(); + ctx.arc(canvas.width / 2, canvas.height / 2, 50, 0, Math.PI * 2, false); + ctx.setLineDash([5, 15]); + ctx.stroke(); + + + // Add shadow to the paddles + ctx.shadowColor = 'black'; + ctx.shadowBlur = 10; + ctx.shadowOffsetX = 5; + ctx.shadowOffsetY = 5; + + ctx.fillStyle = paddleColor; + ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height); + // If paddle2 is on the right, draw the shadow to the left + ctx.shadowOffsetX = -5; + ctx.shadowOffsetY = 5; + ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height); + + // Add shiny effect to the ball + ctx.beginPath(); + ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, false); + var gradient = ctx.createRadialGradient(ball.x, ball.y, 0, ball.x, ball.y, ball.radius); + gradient.addColorStop(0, 'white'); + gradient.addColorStop(0.1, 'gold'); + gradient.addColorStop(1, 'darkorange'); + ctx.fillStyle = gradient; + ctx.fill(); + ctx.closePath(); + + // Reset shadow properties + ctx.shadowColor = 'transparent'; + ctx.shadowBlur = 0; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + + ctx.font = "14px Roboto"; + ctx.fillStyle = 'white'; + ctx.fillText(player1.username + ": " + player1.score, 50, 20); + ctx.fillText(player2.username + ": " + player2.score, canvas.width - textWidth2 - 80, 20); +} + +var requestId; + +// The main game loop +var startGame = function () { + + + BallRequest(); + updatePaddlePosition(); + render(); + // Request to do this again ASAP + requestId = requestAnimationFrame(startGame); +}; + +// When you want to stop the game loop +var stopGame = function() { + cancelAnimationFrame(requestId); +}; + +function gameUtilsReset() { + likeaCheaterCount = 0; + fastandFuriousCount = 0; + frozenBallCount = 0; + isFrozenBallActive = false; + + if (giantMan == "true" && (gameMode === "Abilities" || tournament === "abilities")) + sendAbility("giantMan"); + if (rageofFire == "true" && (gameMode === "Abilities" || tournament === "abilities")) + sendAbility("rageofFire"); +} + +// Cross-browser support for requestAnimationFrame +var w = window; +requestAnimationFrame = + w.requestAnimationFrame || + w.webkitRequestAnimationFrame || + w.msRequestAnimationFrame || + w.mozRequestAnimationFrame; + +function paddleMove(player, y) { + if (player === player1.username) { + paddle1.y = y; + } else if (player === player2.username) { + paddle2.y = y; + } +} + +function ballMove(x, y) { + ball.x = x; + ball.y = y; +} + +function scoreUpdate(player1_score, player2_score) { + player1.score = player1_score; + player2.score = player2_score; +} + +matchsocket.onopen = function (e) { + // Show some greeting message + console.log('WebSocket connection established'); +} + +matchsocket.onclose = function (e) { + //clearInterval(BallRequest); + stopGame(); + console.error('WebSocket connection closed'); +} + +matchsocket.onerror = function (e) { + console.error('Error: ' + e.data); + //clearInterval(BallRequest); + stopGame(); +} + +matchsocket.onmessage = function (e) { + const data = JSON.parse(e.data); + //console.log(data); + switch (data.type) { + case 'inlobby': + // Self send message + console.log('In lobby', data.user); + if (my.username === '') { + my.username = data.user; + } + // Take online users usernames and display them + addUsersToTable(data.users); + console.log('Online users', data.users); + break; + + case 'user.inlobby': + // Send others i joined the lobby + console.log('User in lobby', data.user); + // Add user to online users list + if (data.user !== my.username) { + addUsersToTable([data.user]); + } + if (lang === 'tr') + showToast(data.user + ' katıldı!', 'text-bg-success', 'bi bi-check-circle-fill') + else if (lang === 'hi') + showToast(data.user + ' शामिल हो गया!', 'text-bg-success', 'bi bi-check-circle-fill') + else if (lang === 'pt') + showToast(data.user + ' entrou!', 'text-bg-success', 'bi bi-check-circle-fill') + else + showToast(data.user + ' joined!', 'text-bg-success', 'bi bi-check-circle-fill') + break; + + case 'user.outlobby': + // Send others user left the lobby + console.log('User out lobby', data.user); + // Remove user from online users list + removeUserFromTable(data.user); + if (lang === 'tr') + showToast(data.user + ' ayrıldı!', 'text-bg-danger', 'bi bi-check-circle-fill') + else if (lang === 'hi') + showToast(data.user + ' चला गया!', 'text-bg-danger', 'bi bi-check-circle-fill') + else if (lang === 'pt') + showToast(data.user + ' saiu!', 'text-bg-danger', 'bi bi-check-circle-fill') + else + showToast(data.user + ' left!', 'text-bg-danger', 'bi bi-check-circle-fill') + break; + + case 'game.disconnected': + //clearInterval(BallRequest); + stopGame(); + gameOverScreen.style.display = 'block'; + showToast(`${data.disconnected} disconnected You are automatically winner`, 'text-bg-danger', 'bi bi-check-circle-fill') + console.log('Player disconnected', data.disconnected); + + case 'game.invite': + // Tell user that he/she is invited to a game + console.log('Game invite', data.inviter); + console.log('data: ', data.invitee + " " + my.username) + // Display the modal for accepting or declining the invitation + + hideInviteButtons(data.inviter, data.invitee); + + const acceptButton = document.getElementById(`acceptButton${data.inviter}`); + const declineButton = document.getElementById(`declineButton${data.inviter}`); + if (data.invitee === my.username) { + if (lang === 'tr') + showToast(`${data.inviter} tarafından bir oyun daveti aldınız`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`${data.inviter} द्वारा आपको एक खेल आमंत्रण मिला है`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`Você recebeu um convite de jogo de ${data.inviter}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else + showToast(`You received a game invitation from ${data.inviter}`, 'text-bg-success', 'bi bi-check-circle-fill') + acceptButton.style.display = 'flex'; + declineButton.style.display = 'flex'; + } + + acceptButton.onclick = function () { + accept(data.inviter); + acceptButton.style.display = 'none'; + declineButton.style.display = 'none'; + }; + + declineButton.onclick = function () { + decline(data.inviter); + acceptButton.style.display = 'none'; + declineButton.style.display = 'none'; + }; + + console.log(`Invited Group: ${data.inviter} vs ${data.invitee}`); + break; + + case 'tournament.match': + player1.username = data.player1; + player2.username = data.player2; + my.game_id = data.game_id; + my.tournament_id = data.tournament_id; + leftArea.style.display = 'none'; + if (lang === 'tr') + showToast(`Turnuva maçı başladı! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`टूर्नामेंट मैच शुरू हो गया! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`Jogo de torneio começou! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else + showToast(`Tournament match started! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + + render(); + showToast('Press Space to start the game', 'text-bg-primary', 'bi bi-exclamation-triangle-fill') + + document.addEventListener("keydown", SpaceKeyDown); + + console.log(`Tournament Id: ${data.tournament_id}, Match Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); + break; + + case 'chat.game': + player1.username = data.player1; + player2.username = data.player2; + my.game_id = data.game_id; + if (lang === 'tr') + showToast(`Chat maçı başladı! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`टूर्नामेंट मैच शुरू हो गया! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`Jogo de torneio começou! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else + showToast(`Chat match started! ${player1.username} vs ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + + render(); + showToast('Press Space to start the game', 'text-bg-primary', 'bi bi-exclamation-triangle-fill') + + document.addEventListener("keydown", SpaceKeyDown); + + console.log(`Match Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); + break; + + case 'game.accept': + player1.username = data.accepted; + player2.username = data.accepter; + my.game_id = data.game_id; + if (data.accepter === my.username) { + if (lang === 'tr') + showToast(`Davetiniz ${data.accepted} tarafından kabul edildi`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`आपका निमंत्रण ${data.accepted} द्वारा स्वीकृत किया गया`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`Seu convite foi aceito por ${data.accepted}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else + showToast(`You accepted the game invitation from ${data.accepted}`, 'text-bg-success', 'bi bi-check-circle-fill'); + my.opponent_username = data.accepted; // if gerekir mi? + } + else if (data.accepted === my.username) { + if (lang === 'tr') + showToast(`Davetiniz ${data.accepter} tarafından kabul edildi`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`आपका निमंत्रण ${data.accepter} द्वारा स्वीकृत किया गया`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`Seu convite foi aceito por ${data.accepter}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else + showToast(`Your invitation is accepted by ${data.accepter}`, 'text-bg-success', 'bi bi-check-circle-fill'); + my.opponent_username = data.accepter; // if gerekir mi? + } + render(); + showToast('Press Space to start the game', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); + + + document.addEventListener("keydown", SpaceKeyDown); + + console.log(`Accepted Game Id: ${data.game_id} => ${data.accepted} vs ${data.accepter}`); + break; + + case 'game.decline': + if (data.declined === my.username) { + if (lang === 'tr') + showToast(`Davetiniz ${data.decliner} tarafından reddedildi`, 'text-bg-danger', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`आपका निमंत्रण ${data.decliner} द्वारा अस्वीकार किया गया`, 'text-bg-danger', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`Seu convite foi recusado por ${data.decliner}`, 'text-bg-danger', 'bi bi-check-circle-fill'); + else + showToast(`Your invitation is declined by ${data.decliner}`, 'text-bg-danger', 'bi bi-check-circle-fill'); + } + console.log(`Declined Game => ${data.declined} vs ${data.decliner}`); + break; + + case 'game.start': + // if they vote for Start, start the game otherwise update votes + // Start the game + checkbox.disabled = true; + leftArea.style.display = 'none'; + if (data.vote == 2) { + if (lang === 'tr') + showToast(`3 saniye içinde ${player1.username} ve ${player2.username} arasında oyun başlıyor`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`3 सेकंड में ${player1.username} और ${player2.username} के बीच खेल शुरू हो रहा है`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`Jogo começando em 3 segundos entre ${player1.username} e ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else + showToast(`Game starting in 3 sec between ${player1.username} and ${player2.username}`, 'text-bg-success', 'bi bi-check-circle-fill'); + + leaveButton.style.display = 'block'; + gameUtilsReset(); + + // make invitationMessage disappear after 3 seconds + + leaveButton.onclick = function () { + leaveGame(); + leaveButton.style.display = 'none'; + } + + // Control paddle1 with w, s keys + document.addEventListener("keydown", function(event) { + if (event.key === "w" || event.key === "W" || event.key === "ArrowUp") { + upPressed = true; + } else if (event.key === "s" || event.key === "S"|| event.key === "ArrowDown") { + downPressed = true; + } + if (event.key === '1' && likeaCheaterCount < 1 && likeaCheater == "true" && (gameMode === "Abilities" || tournament === "abilities")) { + sendAbility("likeaCheater"); + showToast('You used like a cheater!', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); + likeaCheaterCount += 1; + } + else if (event.key === '2' && fastandFuriousCount < 1 && fastandFurious == "true" && isFrozenBallActive == false && (gameMode === "Abilities" || tournament === "abilities")) { + sendAbility("fastandFurious"); + showToast('You used fast and furious!', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); + fastandFuriousCount += 1; + } + else if (event.key === '3' && frozenBallCount < 1 && frozenBall == "true" && (gameMode === "Abilities" || tournament === "abilities")) { + sendAbility("frozenBall"); + showToast('You used frozen ball!', 'text-bg-primary', 'bi bi-exclamation-triangle-fill'); + isFrozenBallActive = true; + setTimeout(function () { + isFrozenBallActive = false; + }, 3000); + frozenBallCount += 1; + } + }); + + document.addEventListener("keyup", function(event) { + if (event.key === "w" || event.key === "W" || event.key === "ArrowUp") { + upPressed = false; + } else if (event.key === "s" || event.key === "S"|| event.key === "ArrowDown") { + downPressed = false; + } + }); + + setTimeout(function () { + startGame(); + }, 3000); + // Ask ball coordinates every 16 milliseconds + //setInterval(BallRequest, 16); + + console.log(`Started Game Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); + } + else if (data.vote == 1) { + console.log(`Waiting for Game Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); + } + else if (data.vote == 0) { + console.log(`None of the players hit space Game Id: ${data.game_id} => ${data.player1} vs ${data.player2}`); + } + break; + + case 'game.leave': + //clearInterval(BallRequest); + leftArea.style.display = 'block'; + stopGame(); + var left_score = data.left_score; + var opponent_score = data.opponent_score; + var winner = data.winner; + var loser = data.loser; + document.getElementById('winnerText').innerText = winner; + document.getElementById('loserText').innerText = loser; + gameOverScreen.style.display = 'block'; + // Show some left game message with scores etc. + //showToast(`${data.left} left the game. Winner is ${winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); + // maybe put restart + leaveButton.style.display = 'none'; + console.log(`Left Game Id: ${data.game_id}`); + break; + + case 'game.end': + //clearInterval(BallRequest); + leftArea.style.display = 'block'; + stopGame(); + checkbox.disabled = false; + player1.score = data.player1_score; + player2.score = data.player2_score; + + var winner = data.winner; + var loser = data.loser; + console.log('Winner: ' + winner + ' Loser: ' + loser + ' Player1 score: ' + player1.score + ' Player2 score: ' + player2.score); + document.getElementById('winnerText').innerText = winner; + document.getElementById('loserText').innerText = loser; + gameOverScreen.style.display = 'block'; + // Show some game ended message with scores etc + if (lang === 'tr') + showToast(`Oyun bitti. Kazanan ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'hi') + showToast(`खेल समाप्त हो गया। विजेता ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else if (lang === 'pt') + showToast(`O jogo acabou. Vencedor é ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); + else + showToast(`Game is ended. Winner is ${data.winner}`, 'text-bg-success', 'bi bi-check-circle-fill'); + // maybe put restart + + console.log(`Ended Game Id: ${data.game_id} => ${data.winner} won`); + break; + + case 'game.pause': + // Pause the game + console.log('Game id: ' + data.game_id + ' paused'); + break; + + case 'game.resume': + // Resume the game + console.log('Game id: ' + data.game_id + ' resumed'); + break; + + case 'game.ball': + //get ball position and update it + ballMove(data.x, data.y) + scoreUpdate(data.player1_score, data.player2_score) + //console.log(`Moving Ball Id: ${data.game_id} for ball: ${data.x} ${data.y}`); + break; + + case 'game.paddle': + //get paddle position and update it + paddleMove(data.player, data.y) + //console.log(`Moving Paddle Id: ${data.game_id} for ${data.player}: ${data.y}`); + break; + + case 'game.ability': + console.log(data.ability + ' is used!') + if (data.ability == 'giantMan' && (gameMode === "Abilities" || tournament === "abilities")) { + if (data.player == player1.username) + paddle1.height = 115 + else if (data.player == player2.username) + paddle2.height = 115 + + break; + + }}; +} + +matchsocket.sendJSON = function (data) { + matchsocket.send(JSON.stringify(data)); +} + +function addUsersToTable(usersArray) { + var tableBody = document.querySelector('.custom-table tbody'); + + usersArray.forEach(function(username) { + var row = document.createElement('tr'); + var usernameCell = document.createElement('td'); + usernameCell.textContent = username; + var actionsCell = document.createElement('td'); + + // Create buttons + var btnGroup = document.createElement('div'); + btnGroup.className = "btn-group"; + btnGroup.style.display = "flex"; + btnGroup.style.justifyContent = "center"; + + var inviteButton = document.createElement('button'); + inviteButton.type = "button"; + inviteButton.className = "invite-button"; + inviteButton.id = "inviteButton" + username; + inviteButton.innerHTML = ''; + + var acceptButton = document.createElement('button'); + acceptButton.type = "button"; + acceptButton.className = "accept-button"; + acceptButton.id = "acceptButton" + username; + acceptButton.innerHTML = ''; + + var declineButton = document.createElement('button'); + declineButton.type = "button"; + declineButton.className = "decline-button"; + declineButton.id = "declineButton" + username; + declineButton.innerHTML = ''; + + // Add buttons to button group + btnGroup.appendChild(inviteButton); + btnGroup.appendChild(acceptButton); + btnGroup.appendChild(declineButton); + + actionsCell.appendChild(btnGroup); + row.appendChild(usernameCell); + row.appendChild(actionsCell); + tableBody.appendChild(row); + + // Add event listener to invite button + inviteButton.addEventListener('click', function() { + invite('false', username); + }); + }); +} + +function removeUserFromTable(username) { + var tableBody = document.querySelector('.custom-table tbody'); + var rows = tableBody.querySelectorAll('tr'); + + rows.forEach(function(row) { + var usernameCell = row.querySelector('td:first-child'); + if (usernameCell.textContent.trim() === username.trim()) { + tableBody.removeChild(row); + } + }); +} + + + +function invite(matchmaking = 'false', username) { + // Get necessary data and call socket.sendJSON + if (lang === 'tr') + showToast(`Oyuna ${username} davet ettiniz`, 'text-bg-success', 'bi bi-check-circle-fill') + else if (lang === 'hi') + showToast(`आपने ${username} को एक खेल के लिए आमंत्रित किया`, 'text-bg-success', 'bi bi-check-circle-fill') + else if (lang === 'pt') + showToast(`Você convidou ${username} para um jogo`, 'text-bg-success', 'bi bi-check-circle-fill') + else + showToast(`You invited ${username} to a game`, 'text-bg-success', 'bi bi-check-circle-fill') + matchsocket.sendJSON({ + action: 'invite', + matchmaking: matchmaking, + invitee_username: username, + }); +} + +matchmakingButton.onclick = function () { + invite('true', ''); +} + +//---------------------------------------------- + +function hideInviteButtons(username1, username2) { + // Get the invite buttons for the two users + const inviteButton1 = document.getElementById(`inviteButton${username1}`); + const inviteButton2 = document.getElementById(`inviteButton${username2}`); + + // Hide the invite buttons + if (inviteButton1) inviteButton1.style.display = 'none'; + if (inviteButton2) inviteButton2.style.display = 'none'; +} + +function exitGame() { + console.log("id: " + my.game_id); + matchsocket.sendJSON({ + action: 'exit', + game_id: my.game_id, + }); + + swapApp('/pong-game-find') +} + +function accept(inviter) { + // Get necessary data and call socket.sendJSON + matchsocket.sendJSON({ + action: 'accept', + inviter_username: inviter, + }); +} + +function decline(inviter) { + // Get necessary data and call socket.sendJSON + matchsocket.sendJSON({ + action: 'decline', + inviter_username: inviter, + }); +} + +// Vote count ll be 1 at start if +function startRequest(player1, player2) { + matchsocket.sendJSON({ + action: 'start.request', + game_id: my.game_id, + opponent: my.opponent_username, + vote: 1, + }); +} + +function SpaceKeyDown(event) { + if (event.code === "Space") { + startRequest(my.username, my.opponent_username); + // Remove the event listener after it has been triggered once + document.removeEventListener("keydown", SpaceKeyDown); + } +} + + +function leaveGame() { + matchsocket.sendJSON({ + action: 'leave.game', + game_id: my.game_id, + left: my.username, + opponent: my.opponent_username, + }); +} + +// send this in keydown event +function PaddleRequest(direction) { + // Get necessary data and call socket.sendJSON + matchsocket.sendJSON({ + action: 'paddle', + game_id: my.game_id, + direction: direction + }); +} + +function updatePaddlePosition() { + if (upPressed) { + PaddleRequest('up'); + } else if (downPressed) { + PaddleRequest('down'); + } +} + +function sendAbility(ability) { + matchsocket.sendJSON({ + action: 'ability', + abilities: ability, + game_id: my.game_id, + }); +} + + + +// send this in setInterval(update, 16) this ll be game state +function BallRequest() { + // Get necessary data and call socket.sendJSON + matchsocket.sendJSON({ + action: 'ball', + game_id: my.game_id, + }); +} + +document.getElementById('exitButton').addEventListener('click', exitGame); + +checkbox.addEventListener('change', function() { + // Checkbox'un durumuna göre etiketin innerHTML değerini değiştirme + if (checkbox.checked) { + gameMode = "Abilities"; + if (lang === 'tr') + selectedGameModeLabel.innerHTML = "Yetenekler"; + else if (lang === 'hi') + selectedGameModeLabel.innerHTML = "क्षमताएँ"; + else if (lang === 'pt') + selectedGameModeLabel.innerHTML = "Habilidades"; + else + selectedGameModeLabel.innerHTML = "Abilities"; + } else { + gameMode = "Vanilla"; + if (lang === 'tr') + selectedGameModeLabel.innerHTML = "Vanilya"; + else if (lang === 'hi') + selectedGameModeLabel.innerHTML = "वैनिला"; + else if (lang === 'pt') + selectedGameModeLabel.innerHTML = "Baunilha"; + else + selectedGameModeLabel.innerHTML = "Vanilla"; + } +}); + +const gameModeSelect = document.getElementById("gameModeSelect"); + +gameModeSelect.addEventListener("mouseenter", function() { + document.querySelector(".game-mode-info").style.display = "block"; +}); + +gameModeSelect.addEventListener("mouseleave", function() { + document.querySelector(".game-mode-info").style.display = "none"; +}); } \ No newline at end of file diff --git a/indianpong/static/js/inventory.js b/indianpong/static/js/inventory.js index 268ad7c5..058d8565 100644 --- a/indianpong/static/js/inventory.js +++ b/indianpong/static/js/inventory.js @@ -1,148 +1,148 @@ -function initializeInventory(){ - const inventoryInfos = document.getElementsByClassName('inventory-info'); // .inventory-info'ya erişim - const smallWalletNames = document.getElementsByClassName('small-wallet-name'); - - for (let i = 0; i < smallWalletNames.length; i++) { - smallWalletNames[i].addEventListener('mouseover', () => { - inventoryInfos[i].style.visibility = 'visible'; - }); - - smallWalletNames[i].addEventListener('mouseout', () => { - inventoryInfos[i].style.visibility = 'hidden'; - }); - }; -} - - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - - var toastContent = liveToast.querySelector('.fw-semibold'); - var toastIcon = liveToast.querySelector('.i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - - const toast = new bootstrap.Toast(liveToast); - toast.show(); - } - - function openSetPropertyModal(itemName, itemWhatIs) { - document.getElementById('itemNameInput').value = itemName; - var propertyContent = document.getElementById('propertyContent'); - if (itemName === "My Playground" || itemName === "My Beautiful Paddle") { - itemWhatIs = itemWhatIs || '#000000'; - propertyContent.innerHTML = ` - - - `; - } else { - itemWhatIs = itemWhatIs || 'IndianAI'; - propertyContent.innerHTML = ` - - - `; - } - - var modal = new bootstrap.Modal(document.getElementById('setPropertyModal'), { backdrop: false, keyboard: false }); - modal.show(); - - } - - function saveProperty(username ,itemId) { - const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); - const lang = cookie ? cookie.split('=')[1] : 'en'; - var itemName = document.getElementById('itemNameInput').value; - if (itemName === "My Playground" || itemName === "My Beautiful Paddle") { - whatis = document.getElementById('color').value; - } else { - whatis = document.getElementById('propertyName').value; - } - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - - const form = document.getElementById('store_item_form' + itemId); - const formData = new FormData(form); - - - fetch(`/inventory/${username}/`, { - method: form.method, - body: formData, - headers: { - 'X-CSRFToken': csrftoken - } - }) - .then(response => response.text()) - .then(text => { - let button = document.getElementById(`button-${itemName}`); - button.setAttribute('data-whatis', whatis); - if (lang === 'tr') - showToast(`${itemName} öğesini başarıyla özelleştirdin!`, `text-bg-success`, `bi bi-shop`); - else if (lang === 'hi') - showToast(`आपने ${itemName} आइटम को सफलतापूर्वक अनुकूलित किया है!`, `text-bg-success`, `bi bi-shop`); - else if (lang === 'pt') - showToast(`Você personalizou com sucesso o item ${itemName}!`, `text-bg-success`, `bi bi-shop`); - else - showToast(`You have successfully customized ${itemName} item!`, `text-bg-success`, `bi bi-shop`); - }) - .catch((error) => { - console.error('Error:', error); - }); - } - - function submitInventoryItemForm(username, itemName) { - const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); - const lang = cookie ? cookie.split('=')[1] : 'en'; - const form = document.getElementById('store_item_form' + itemName); - const formData = new FormData(form); - // Access the data-is-equipped attribute - let isEquipped = form.getAttribute('data-is-equipped'); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - - - let toastMessage; - let toastIcon; - if (isEquipped == 'True') { - if (lang === 'tr') - toastMessage = `${itemName} öğesini başarıyla çıkardın!`; // You successfully unequipped the item! - else if (lang === 'hi') - toastMessage = `आपने ${itemName} आइटम को सफलतापूर्वक अनइक्विप किया है!`; - else if (lang === 'pt') - toastMessage = `Você desequipou com sucesso o item ${itemName}!`; - else - toastMessage = `You have successfully unequipped ${itemName} item!`; - toastIcon = `bi bi-x-circle-fill`; // Change this to the icon you want to show when unequipping - } else { - if (lang === 'tr') - toastMessage = `${itemName} öğesini başarıyla kuşandın!`; // You successfully equipped the item! - else if (lang === 'hi') - toastMessage = `आपने ${itemName} आइटम को सफलतापूर्वक इक्विप किया है!`; - else if (lang === 'pt') - toastMessage = `Você equipou com sucesso o item ${itemName}!`; - else - toastMessage = `You have successfully equipped ${itemName} item!`; - toastIcon = `bi bi-check-circle-fill`; - } - - - fetch(`/inventory/${username}/`, { - method: form.method, - body: formData, - headers: { - 'X-CSRFToken': csrftoken - } - }) - .then(response => response.text()) - .then(data => { - // Change the value of data-is-equipped attribute - form.setAttribute('data-is-equipped', isEquipped == 'True' ? 'False' : 'True'); - document.body.innerHTML = data; - showToast(toastMessage, `text-bg-success`, toastIcon); - }) - .catch((error) => { - console.error('Error:', error); - }); +function initializeInventory(){ + const inventoryInfos = document.getElementsByClassName('inventory-info'); // .inventory-info'ya erişim + const smallWalletNames = document.getElementsByClassName('small-wallet-name'); + + for (let i = 0; i < smallWalletNames.length; i++) { + smallWalletNames[i].addEventListener('mouseover', () => { + inventoryInfos[i].style.visibility = 'visible'; + }); + + smallWalletNames[i].addEventListener('mouseout', () => { + inventoryInfos[i].style.visibility = 'hidden'; + }); + }; +} + + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + + var toastContent = liveToast.querySelector('.fw-semibold'); + var toastIcon = liveToast.querySelector('.i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + + const toast = new bootstrap.Toast(liveToast); + toast.show(); + } + + function openSetPropertyModal(itemName, itemWhatIs) { + document.getElementById('itemNameInput').value = itemName; + var propertyContent = document.getElementById('propertyContent'); + if (itemName === "My Playground" || itemName === "My Beautiful Paddle") { + itemWhatIs = itemWhatIs || '#000000'; + propertyContent.innerHTML = ` + + + `; + } else { + itemWhatIs = itemWhatIs || 'IndianAI'; + propertyContent.innerHTML = ` + + + `; + } + + var modal = new bootstrap.Modal(document.getElementById('setPropertyModal'), { backdrop: false, keyboard: false }); + modal.show(); + + } + + function saveProperty(username ,itemId) { + const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); + const lang = cookie ? cookie.split('=')[1] : 'en'; + var itemName = document.getElementById('itemNameInput').value; + if (itemName === "My Playground" || itemName === "My Beautiful Paddle") { + whatis = document.getElementById('color').value; + } else { + whatis = document.getElementById('propertyName').value; + } + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + + const form = document.getElementById('store_item_form' + itemId); + const formData = new FormData(form); + + + fetch(`/inventory/${username}/`, { + method: form.method, + body: formData, + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(response => response.text()) + .then(text => { + let button = document.getElementById(`button-${itemName}`); + button.setAttribute('data-whatis', whatis); + if (lang === 'tr') + showToast(`${itemName} öğesini başarıyla özelleştirdin!`, `text-bg-success`, `bi bi-shop`); + else if (lang === 'hi') + showToast(`आपने ${itemName} आइटम को सफलतापूर्वक अनुकूलित किया है!`, `text-bg-success`, `bi bi-shop`); + else if (lang === 'pt') + showToast(`Você personalizou com sucesso o item ${itemName}!`, `text-bg-success`, `bi bi-shop`); + else + showToast(`You have successfully customized ${itemName} item!`, `text-bg-success`, `bi bi-shop`); + }) + .catch((error) => { + console.error('Error:', error); + }); + } + + function submitInventoryItemForm(username, itemName) { + const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); + const lang = cookie ? cookie.split('=')[1] : 'en'; + const form = document.getElementById('store_item_form' + itemName); + const formData = new FormData(form); + // Access the data-is-equipped attribute + let isEquipped = form.getAttribute('data-is-equipped'); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + + + let toastMessage; + let toastIcon; + if (isEquipped == 'True') { + if (lang === 'tr') + toastMessage = `${itemName} öğesini başarıyla çıkardın!`; // You successfully unequipped the item! + else if (lang === 'hi') + toastMessage = `आपने ${itemName} आइटम को सफलतापूर्वक अनइक्विप किया है!`; + else if (lang === 'pt') + toastMessage = `Você desequipou com sucesso o item ${itemName}!`; + else + toastMessage = `You have successfully unequipped ${itemName} item!`; + toastIcon = `bi bi-x-circle-fill`; // Change this to the icon you want to show when unequipping + } else { + if (lang === 'tr') + toastMessage = `${itemName} öğesini başarıyla kuşandın!`; // You successfully equipped the item! + else if (lang === 'hi') + toastMessage = `आपने ${itemName} आइटम को सफलतापूर्वक इक्विप किया है!`; + else if (lang === 'pt') + toastMessage = `Você equipou com sucesso o item ${itemName}!`; + else + toastMessage = `You have successfully equipped ${itemName} item!`; + toastIcon = `bi bi-check-circle-fill`; + } + + + fetch(`/inventory/${username}/`, { + method: form.method, + body: formData, + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(response => response.text()) + .then(data => { + // Change the value of data-is-equipped attribute + form.setAttribute('data-is-equipped', isEquipped == 'True' ? 'False' : 'True'); + document.body.innerHTML = data; + showToast(toastMessage, `text-bg-success`, toastIcon); + }) + .catch((error) => { + console.error('Error:', error); + }); } \ No newline at end of file diff --git a/indianpong/static/js/login.js b/indianpong/static/js/login.js index 0113ecec..6db18986 100644 --- a/indianpong/static/js/login.js +++ b/indianpong/static/js/login.js @@ -1,61 +1,61 @@ -export function initializeLogin() { - const passwordInput = document.getElementById('id_password'); - const toggleButton = document.getElementById('togglePassword'); - - toggleButton.addEventListener('mousedown', function() { - passwordInput.type = 'text'; - toggleButton.classList.remove('bi-eye-slash-fill'); - toggleButton.classList.add('bi-eye-fill'); - }); - - toggleButton.addEventListener('mouseup', function() { - passwordInput.type = 'password'; - toggleButton.classList.remove('bi-eye-fill'); - toggleButton.classList.add('bi-eye-slash-fill'); - }); - passwordInput.addEventListener('input', function() { - toggleButton.style.display = this.value.trim() !== '' ? 'block' : 'none'; - }); -} - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - - const toast = new bootstrap.Toast(liveToast); - toast.show(); - } - -export function makeLogin(check) { - if(!check) - return; - var form = document.getElementById('loginForm'); - var formData = new FormData(form); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - fetch('/login', { - method: 'POST', - headers: { - 'X-CSRFToken': csrftoken - }, - body: formData - }) - .then(response => response.text()) - .then(data => { - if (data == "dashboard") - swapApp('/dashboard'); - else { - showToast(`${data}`, `text-bg-danger`, `bi bi-bug-fill`); - } - }) - .catch(error => { - console.error(error); - }); +export function initializeLogin() { + const passwordInput = document.getElementById('id_password'); + const toggleButton = document.getElementById('togglePassword'); + + toggleButton.addEventListener('mousedown', function() { + passwordInput.type = 'text'; + toggleButton.classList.remove('bi-eye-slash-fill'); + toggleButton.classList.add('bi-eye-fill'); + }); + + toggleButton.addEventListener('mouseup', function() { + passwordInput.type = 'password'; + toggleButton.classList.remove('bi-eye-fill'); + toggleButton.classList.add('bi-eye-slash-fill'); + }); + passwordInput.addEventListener('input', function() { + toggleButton.style.display = this.value.trim() !== '' ? 'block' : 'none'; + }); +} + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + + const toast = new bootstrap.Toast(liveToast); + toast.show(); + } + +export function makeLogin(check) { + if(!check) + return; + var form = document.getElementById('loginForm'); + var formData = new FormData(form); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + fetch('/login', { + method: 'POST', + headers: { + 'X-CSRFToken': csrftoken + }, + body: formData + }) + .then(response => response.text()) + .then(data => { + if (data == "dashboard") + swapApp('/dashboard'); + else { + showToast(`${data}`, `text-bg-danger`, `bi bi-bug-fill`); + } + }) + .catch(error => { + console.error(error); + }); } \ No newline at end of file diff --git a/indianpong/static/js/navigation.js b/indianpong/static/js/navigation.js index e1daa674..4167d39f 100644 --- a/indianpong/static/js/navigation.js +++ b/indianpong/static/js/navigation.js @@ -1,220 +1,220 @@ -import { initializeBurger } from './burger.js'; -import { getChat } from './base-chat.js' -import { innerChat } from './chat.js'; -import { makeRegister, initializeSignup } from './signup.js'; -import { makeLogin, initializeLogin } from './login.js'; -import { editProfile, editPassword, editSocial, deleteAccount, changeAvatar, displaySection, unblockButon } from './profile-settings.js'; -import { matchHistoryChanger, toggleGame, followButton, unfollowButton } from './profile.js'; -import { Game } from './game/play-ai.js'; -import { LocalGame } from './game/local-game.js'; -import { localTournament } from './game/localTournament.js'; -import { Rps } from './rps.js'; -import { RemotePong } from './game/sockPong.js'; -import { RemoteRps } from './sockRps.js'; -import { createTournament } from './create-tournament.js'; -import { initializeSearch, makeSearch } from './search.js'; -import { displaySectionGame, joinTournament, leaveTournament, startTournament, showToast } from './tournament-room.js'; - -export function getCookie(name) { - const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); - return cookieValue ? cookieValue.pop() : ''; -} - -const fill = document.querySelector('.progress-bar-fill'); - -document.addEventListener('DOMContentLoaded', function() { - updateApp(window.location.pathname); -}); - -function updateApp(path) { - showLoadingScreen(); - fetch(path) - .then(response => response.text()) - .then(html => { - document.body.innerHTML = html; - pageHandler(path); - hideLoadingScreen(); - }) - .catch(error => console.error(error)); -} - -function updateTitle(path) { - // Split the path by slashes - var parts = path.split('/'); - - if (parts.length > 0) { - // Remove the first empty string from the parts array - parts.shift(); - - // Map over each part to capitalize the first letter - var titleParts = parts.map(function(part) { - return part.charAt(0).toUpperCase() + part.slice(1); - }); - - // Join the title parts with spaces - var title = titleParts.join(' '); - } - else { - // If there are no parts, set the title to 'Home' - var title = 'Indian-Pong'; - } - - if (!title) - title = 'Indian-Pong'; - // Set the document title - document.title = title; -} - -function swapApp(path) { - //currentPath = window.location.pathname; - window.history.pushState({}, '', path); - updateApp(path); - updateTitle(path); -} - -window.initializeBurger = initializeBurger; -window.swapApp = swapApp; -window.getChat = getChat; -window.innerChat = innerChat; -window.makeRegister = makeRegister; -window.initializeSignup = initializeSignup; -window.makeLogin = makeLogin; -window.initializeLogin = initializeLogin; -window.editProfile = editProfile; -window.editPassword = editPassword; -window.editSocial = editSocial; -window.deleteAccount = deleteAccount; -window.changeAvatar = changeAvatar; -window.displaySection = displaySection; -window.matchHistoryChanger = matchHistoryChanger; -window.toggleGame = toggleGame; -window.followButton = followButton; -window.unfollowButton = unfollowButton; -window.Game = Game; -window.LocalGame = LocalGame; -window.localTournament = localTournament; -window.Rps = Rps; -window.createTournament = createTournament; -window.unblockButon = unblockButon; -window.RemotePong = RemotePong; -window.RemoteRps = RemoteRps; -window.initializeSearch = initializeSearch; -window.makeSearch = makeSearch; -window.displaySectionGame = displaySectionGame; -window.startTournament = startTournament; -window.joinTournament = joinTournament; -window.leaveTournament = leaveTournament; - -window.onpopstate = function(event) { - if (window.location.hash == '') { - updateApp(window.location.pathname); - } -}; - - -function pageHandler(path) { - const pathParts = path.split('/'); - getCookie(); - if (animationId) - cancelAnimationFrame(animationId); - if (localTournamentAnimationId) - cancelAnimationFrame(localTournamentAnimationId); - if (localGameAnimationId) - cancelAnimationFrame(localGameAnimationId); - - if (path.includes('/login')) { - makeLogin(); - initializeLogin(); - } - else if (path.includes('/signup')) { - makeRegister(); - initializeSignup(); - } - else if(path.includes('/settings')) { - editProfile(); - editPassword(); - editSocial(); - deleteAccount(); - changeAvatar(); - displaySection(); - unblockButon(); - } - else if(path.includes('/profile/')) { - matchHistoryChanger(); - toggleGame(); - followButton(); - unfollowButton(); - } - else if (path.includes('/friends/')) { - getChat(); - } - else if(path.includes('/search')) { - //addScript('search'); - initializeSearch(); - makeSearch(); - } - else if(path.includes('/store/')) { - //addScript('store'); - const script = document.createElement('script'); - script.src = '/static/js/store.js'; - document.body.appendChild(script); - } - else if(path.includes('/inventory/')) { - //addScript('inventory'); - const script = document.createElement('script'); - script.src = '/static/js/inventory.js'; - document.body.appendChild(script); - } - else if (pathParts[1] === 'chat' && pathParts.length === 3) { - getChat(); - } - else if (pathParts[1] === 'chat' && pathParts.length === 4) { - innerChat(); - } - else if (path.includes('/play-ai/')) { - Game(); - } - else if (path.includes('/local-game')) { - LocalGame(); - } - else if (path.includes('/local-tournament')) { - localTournament(); - } - else if (path.includes('/play-rps-ai')) { - Rps(); - } - else if (path.includes('/remote-game/')) { - RemotePong(); - } - else if (path.includes('/play-rps')) { - RemoteRps(); - } - else if (path.includes('/tournament-room/')) { - displaySectionGame(); - startTournament(); - joinTournament(); - leaveTournament(); - showToast(); - } - - if (path != '/' && path != '/login' && path != '/signup') - initializeBurger(); -} - -function showLoadingScreen() { - document.getElementById('loading-bar').style.width = '100%';; -} - -// Yükleme ekranını gizle -function hideLoadingScreen() { - document.getElementById('loading-bar').style.width = '0';; -} - -/* function showProgressBar() { - document.querySelector('.progress-bar').style.display = 'block'; -} - -function hideProgressBar() { - document.querySelector('.progress-bar').style.display = 'none'; -} */ - +import { initializeBurger } from './burger.js'; +import { getChat } from './base-chat.js' +import { innerChat } from './chat.js'; +import { makeRegister, initializeSignup } from './signup.js'; +import { makeLogin, initializeLogin } from './login.js'; +import { editProfile, editPassword, editSocial, deleteAccount, changeAvatar, displaySection, unblockButon } from './profile-settings.js'; +import { matchHistoryChanger, toggleGame, followButton, unfollowButton } from './profile.js'; +import { Game } from './game/play-ai.js'; +import { LocalGame } from './game/local-game.js'; +import { localTournament } from './game/localTournament.js'; +import { Rps } from './rps.js'; +import { RemotePong } from './game/sockPong.js'; +import { RemoteRps } from './sockRps.js'; +import { createTournament } from './create-tournament.js'; +import { initializeSearch, makeSearch } from './search.js'; +import { displaySectionGame, joinTournament, leaveTournament, startTournament, showToast } from './tournament-room.js'; + +export function getCookie(name) { + const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); + return cookieValue ? cookieValue.pop() : ''; +} + +const fill = document.querySelector('.progress-bar-fill'); + +document.addEventListener('DOMContentLoaded', function() { + updateApp(window.location.pathname); +}); + +function updateApp(path) { + showLoadingScreen(); + fetch(path) + .then(response => response.text()) + .then(html => { + document.body.innerHTML = html; + pageHandler(path); + hideLoadingScreen(); + }) + .catch(error => console.error(error)); +} + +function updateTitle(path) { + // Split the path by slashes + var parts = path.split('/'); + + if (parts.length > 0) { + // Remove the first empty string from the parts array + parts.shift(); + + // Map over each part to capitalize the first letter + var titleParts = parts.map(function(part) { + return part.charAt(0).toUpperCase() + part.slice(1); + }); + + // Join the title parts with spaces + var title = titleParts.join(' '); + } + else { + // If there are no parts, set the title to 'Home' + var title = 'Indian-Pong'; + } + + if (!title) + title = 'Indian-Pong'; + // Set the document title + document.title = title; +} + +function swapApp(path) { + //currentPath = window.location.pathname; + window.history.pushState({}, '', path); + updateApp(path); + updateTitle(path); +} + +window.initializeBurger = initializeBurger; +window.swapApp = swapApp; +window.getChat = getChat; +window.innerChat = innerChat; +window.makeRegister = makeRegister; +window.initializeSignup = initializeSignup; +window.makeLogin = makeLogin; +window.initializeLogin = initializeLogin; +window.editProfile = editProfile; +window.editPassword = editPassword; +window.editSocial = editSocial; +window.deleteAccount = deleteAccount; +window.changeAvatar = changeAvatar; +window.displaySection = displaySection; +window.matchHistoryChanger = matchHistoryChanger; +window.toggleGame = toggleGame; +window.followButton = followButton; +window.unfollowButton = unfollowButton; +window.Game = Game; +window.LocalGame = LocalGame; +window.localTournament = localTournament; +window.Rps = Rps; +window.createTournament = createTournament; +window.unblockButon = unblockButon; +window.RemotePong = RemotePong; +window.RemoteRps = RemoteRps; +window.initializeSearch = initializeSearch; +window.makeSearch = makeSearch; +window.displaySectionGame = displaySectionGame; +window.startTournament = startTournament; +window.joinTournament = joinTournament; +window.leaveTournament = leaveTournament; + +window.onpopstate = function(event) { + if (window.location.hash == '') { + updateApp(window.location.pathname); + } +}; + + +function pageHandler(path) { + const pathParts = path.split('/'); + getCookie(); + if (animationId) + cancelAnimationFrame(animationId); + if (localTournamentAnimationId) + cancelAnimationFrame(localTournamentAnimationId); + if (localGameAnimationId) + cancelAnimationFrame(localGameAnimationId); + + if (path.includes('/login')) { + makeLogin(); + initializeLogin(); + } + else if (path.includes('/signup')) { + makeRegister(); + initializeSignup(); + } + else if(path.includes('/settings')) { + editProfile(); + editPassword(); + editSocial(); + deleteAccount(); + changeAvatar(); + displaySection(); + unblockButon(); + } + else if(path.includes('/profile/')) { + matchHistoryChanger(); + toggleGame(); + followButton(); + unfollowButton(); + } + else if (path.includes('/friends/')) { + getChat(); + } + else if(path.includes('/search')) { + //addScript('search'); + initializeSearch(); + makeSearch(); + } + else if(path.includes('/store/')) { + //addScript('store'); + const script = document.createElement('script'); + script.src = '/static/js/store.js'; + document.body.appendChild(script); + } + else if(path.includes('/inventory/')) { + //addScript('inventory'); + const script = document.createElement('script'); + script.src = '/static/js/inventory.js'; + document.body.appendChild(script); + } + else if (pathParts[1] === 'chat' && pathParts.length === 3) { + getChat(); + } + else if (pathParts[1] === 'chat' && pathParts.length === 4) { + innerChat(); + } + else if (path.includes('/play-ai/')) { + Game(); + } + else if (path.includes('/local-game')) { + LocalGame(); + } + else if (path.includes('/local-tournament')) { + localTournament(); + } + else if (path.includes('/play-rps-ai')) { + Rps(); + } + else if (path.includes('/remote-game/')) { + RemotePong(); + } + else if (path.includes('/play-rps')) { + RemoteRps(); + } + else if (path.includes('/tournament-room/')) { + displaySectionGame(); + startTournament(); + joinTournament(); + leaveTournament(); + showToast(); + } + + if (path != '/' && path != '/login' && path != '/signup') + initializeBurger(); +} + +function showLoadingScreen() { + document.getElementById('loading-bar').style.width = '100%';; +} + +// Yükleme ekranını gizle +function hideLoadingScreen() { + document.getElementById('loading-bar').style.width = '0';; +} + +/* function showProgressBar() { + document.querySelector('.progress-bar').style.display = 'block'; +} + +function hideProgressBar() { + document.querySelector('.progress-bar').style.display = 'none'; +} */ + diff --git a/indianpong/static/js/profile-settings.js b/indianpong/static/js/profile-settings.js index 68709029..c51ee7a4 100644 --- a/indianpong/static/js/profile-settings.js +++ b/indianpong/static/js/profile-settings.js @@ -1,284 +1,284 @@ -function getCookie(name) { - const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); - return cookieValue ? cookieValue.pop() : ''; -} - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - const toast = new bootstrap.Toast(liveToast); - toast.show(); - setTimeout(function() { - toast.hide(); - }, 8000); -} - -export function editProfile(username) { - if (!username) - return; - - var formData = new FormData(); // FormData nesnesi oluştur - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - const lang = getCookie('selectedLanguage'); - - // Form verilerini al - formData.append('username', document.getElementById('id_username_profile').value); - formData.append('email', document.getElementById('id_email_profile').value); - formData.append('displayname', document.getElementById('id_displayname_profile').value); - formData.append('profile_form', 'profile_form'); - // CSRF token'ı eklemek - - fetch(`/profile/${username}/settings`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrftoken - }, - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - const message = document.querySelector('.container-top').dataset.message; - if (message) - showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); - else { - - if (lang === 'tr') { - showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'hi') { - showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'pt') - showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); - else { - showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } - } - - }) - .catch(error => { - console.error('Error:', error); - }); -}; - -export function editPassword(username) { - if (!username) - return; - - var formData = new FormData(); // FormData nesnesi oluştur - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - formData.append('old_password', document.getElementById('id_old_password').value); - formData.append('new_password1', document.getElementById('id_new_password1').value); - formData.append('new_password2', document.getElementById('id_new_password2').value); - formData.append('password_form', 'password_form'); - const lang = getCookie('selectedLanguage'); - fetch(`/profile/${username}/settings`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrftoken - } - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - const message = document.querySelector('.container-top').dataset.message; - var currentFragment = window.location.hash.substring(1); - displaySection(currentFragment); - if (message) { - showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); - } else { - if (lang === 'tr') { - showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'hi') { - showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'pt') - showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); - else { - showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } - } - }) - .catch(error => { - console.error('Error:', error); - }); -}; - -export function editSocial(username) { - if (!username) - return; - - var formData = new FormData(); // FormData nesnesi oluştur - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - formData.append('linkedin', document.getElementById('id_linkedin').value); - formData.append('twitter', document.getElementById('id_twitter').value); - formData.append('intra42', document.getElementById('id_intra42').value); - formData.append('github', document.getElementById('id_github').value); - formData.append('social_form', 'social_form'); - const lang = getCookie('selectedLanguage'); - fetch(`/profile/${username}/settings`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrftoken - } - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - const message = document.querySelector('.container-top').dataset.message; - var currentFragment = window.location.hash.substring(1); - displaySection(currentFragment); - if (message) { - showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); - } else { - if (lang === 'tr') { - showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'hi') { - showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'pt') - showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); - else { - showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } - } - }) - .catch(error => { - console.error('Error:', error); - }); - -}; - -export function deleteAccount(username) { - if (!username) - return; - - var formData = new FormData(); // FormData nesnesi oluştur - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - formData.append('email', document.getElementById('id_email').value); - formData.append('delete_account_form', 'delete_account_form'); - const lang = getCookie('selectedLanguage'); - fetch(`/profile/${username}/settings`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrftoken - } - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - }) - .catch(error => { - console.error('Error:', error); - }); -}; - -export function changeAvatar(username) { - - if (!username) - return; - - const fileInput = document.getElementById('id_avatar'); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - var file = fileInput.files[0]; - const lang = getCookie('selectedLanguage'); - if (file.size > 2 * 1024 * 1024) { // 1MB - showToast("Photo must be under 2MB!", "text-bg-danger", "bi bi-image"); - } - else { - var formData = new FormData(); // FormData nesnesini oluştur - formData.append('avatar', file); - // avatar_form verisini ekle - formData.append('avatar_form', 'avatar_form'); - // CSRF token'ı eklemek - fetch(`/profile/${username}/settings`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrftoken - }, - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - const message = document.querySelector('.container-top').dataset.message; - const error = document.querySelector('.container-top').dataset.error; - if (message) { - showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); - } else { - if (lang === 'tr') { - showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'hi') { - showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'pt') { - showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else { - showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } - } - }) - .catch(error => { - console.error('Error:', error); - }); - } -} - -export function unblockButon(username, blockedusername) { - if (!blockedusername || !username) - return; - - var formData = new FormData(); // FormData nesnesi oluştur - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - formData.append('blockedusername', blockedusername); - formData.append('unblock_form', 'unblock_form'); - const lang = getCookie('selectedLanguage'); - fetch(`/profile/${username}/settings`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrftoken - } - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - var currentFragment = window.location.hash.substring(1); - displaySection(currentFragment); - const message = document.querySelector('.container-top').dataset.message; - if (message) { - showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); - } else { - if (lang === 'tr') { - showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'hi') { - showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); - } else if (lang === 'pt') - showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); - else { - showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); - } - } - }) -} - -export function displaySection(sectionId) { - var sections = ["editProfile", "addSocial", "closeAccount", "blockedUsers", "changePassword"]; - if (!sectionId) - return; - for (var i = 0; i < sections.length; i++) { - var section = document.getElementById(sections[i]); - if (sections[i] === sectionId) { - section.style.display = 'block'; - } else { - section.style.display = 'none'; - } - } +function getCookie(name) { + const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); + return cookieValue ? cookieValue.pop() : ''; +} + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + const toast = new bootstrap.Toast(liveToast); + toast.show(); + setTimeout(function() { + toast.hide(); + }, 8000); +} + +export function editProfile(username) { + if (!username) + return; + + var formData = new FormData(); // FormData nesnesi oluştur + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + const lang = getCookie('selectedLanguage'); + + // Form verilerini al + formData.append('username', document.getElementById('id_username_profile').value); + formData.append('email', document.getElementById('id_email_profile').value); + formData.append('displayname', document.getElementById('id_displayname_profile').value); + formData.append('profile_form', 'profile_form'); + // CSRF token'ı eklemek + + fetch(`/profile/${username}/settings`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrftoken + }, + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + const message = document.querySelector('.container-top').dataset.message; + if (message) + showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); + else { + + if (lang === 'tr') { + showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'hi') { + showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'pt') + showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); + else { + showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } + } + + }) + .catch(error => { + console.error('Error:', error); + }); +}; + +export function editPassword(username) { + if (!username) + return; + + var formData = new FormData(); // FormData nesnesi oluştur + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + formData.append('old_password', document.getElementById('id_old_password').value); + formData.append('new_password1', document.getElementById('id_new_password1').value); + formData.append('new_password2', document.getElementById('id_new_password2').value); + formData.append('password_form', 'password_form'); + const lang = getCookie('selectedLanguage'); + fetch(`/profile/${username}/settings`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + const message = document.querySelector('.container-top').dataset.message; + var currentFragment = window.location.hash.substring(1); + displaySection(currentFragment); + if (message) { + showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); + } else { + if (lang === 'tr') { + showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'hi') { + showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'pt') + showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); + else { + showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } + } + }) + .catch(error => { + console.error('Error:', error); + }); +}; + +export function editSocial(username) { + if (!username) + return; + + var formData = new FormData(); // FormData nesnesi oluştur + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + formData.append('linkedin', document.getElementById('id_linkedin').value); + formData.append('twitter', document.getElementById('id_twitter').value); + formData.append('intra42', document.getElementById('id_intra42').value); + formData.append('github', document.getElementById('id_github').value); + formData.append('social_form', 'social_form'); + const lang = getCookie('selectedLanguage'); + fetch(`/profile/${username}/settings`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + const message = document.querySelector('.container-top').dataset.message; + var currentFragment = window.location.hash.substring(1); + displaySection(currentFragment); + if (message) { + showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); + } else { + if (lang === 'tr') { + showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'hi') { + showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'pt') + showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); + else { + showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } + } + }) + .catch(error => { + console.error('Error:', error); + }); + +}; + +export function deleteAccount(username) { + if (!username) + return; + + var formData = new FormData(); // FormData nesnesi oluştur + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + formData.append('email', document.getElementById('id_email').value); + formData.append('delete_account_form', 'delete_account_form'); + const lang = getCookie('selectedLanguage'); + fetch(`/profile/${username}/settings`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + }) + .catch(error => { + console.error('Error:', error); + }); +}; + +export function changeAvatar(username) { + + if (!username) + return; + + const fileInput = document.getElementById('id_avatar'); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + var file = fileInput.files[0]; + const lang = getCookie('selectedLanguage'); + if (file.size > 2 * 1024 * 1024) { // 1MB + showToast("Photo must be under 2MB!", "text-bg-danger", "bi bi-image"); + } + else { + var formData = new FormData(); // FormData nesnesini oluştur + formData.append('avatar', file); + // avatar_form verisini ekle + formData.append('avatar_form', 'avatar_form'); + // CSRF token'ı eklemek + fetch(`/profile/${username}/settings`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrftoken + }, + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + const message = document.querySelector('.container-top').dataset.message; + const error = document.querySelector('.container-top').dataset.error; + if (message) { + showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); + } else { + if (lang === 'tr') { + showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'hi') { + showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'pt') { + showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else { + showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } + } + }) + .catch(error => { + console.error('Error:', error); + }); + } +} + +export function unblockButon(username, blockedusername) { + if (!blockedusername || !username) + return; + + var formData = new FormData(); // FormData nesnesi oluştur + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + formData.append('blockedusername', blockedusername); + formData.append('unblock_form', 'unblock_form'); + const lang = getCookie('selectedLanguage'); + fetch(`/profile/${username}/settings`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + var currentFragment = window.location.hash.substring(1); + displaySection(currentFragment); + const message = document.querySelector('.container-top').dataset.message; + if (message) { + showToast(message, 'text-bg-success', 'bi bi-check-circle-fill'); + } else { + if (lang === 'tr') { + showToast('Bir hata oluştu.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'hi') { + showToast('कोई त्रुटि हुई।', 'text-bg-danger', 'bi bi-x-circle-fill'); + } else if (lang === 'pt') + showToast('Ocorreu um erro.', 'text-bg-danger', 'bi bi-x-circle-fill'); + else { + showToast('An error occurred.', 'text-bg-danger', 'bi bi-x-circle-fill'); + } + } + }) +} + +export function displaySection(sectionId) { + var sections = ["editProfile", "addSocial", "closeAccount", "blockedUsers", "changePassword"]; + if (!sectionId) + return; + for (var i = 0; i < sections.length; i++) { + var section = document.getElementById(sections[i]); + if (sections[i] === sectionId) { + section.style.display = 'block'; + } else { + section.style.display = 'none'; + } + } } \ No newline at end of file diff --git a/indianpong/static/js/profile.js b/indianpong/static/js/profile.js index b89f1158..cb5b3446 100644 --- a/indianpong/static/js/profile.js +++ b/indianpong/static/js/profile.js @@ -1,96 +1,96 @@ -var isRPSVisibleHistory = true; - -export function matchHistoryChanger(status) { - - if (!status) - return; - var switcherBtn = document.querySelector(".changer-btn"); - var historyPong = document.getElementById('match-history-pong'); - var historyRPS = document.getElementById('match-history-rps'); - isRPSVisibleHistory = !isRPSVisibleHistory; - - if (isRPSVisibleHistory) { - // Ping pong istatistiklerini göster - historyPong.style.display = 'block'; - historyRPS.style.display = 'none'; - switcherBtn.innerHTML = '🏓'; // HTML içeriğine Unicode karakterini ekleyin - } else { - // RPS istatistiklerini göster - historyPong.style.display = 'none'; - historyRPS.style.display = 'block'; - switcherBtn.innerHTML = '✂️'; // HTML içeriğine Unicode karakterini ekleyin - } - - // Durumu tersine çevir -} - -var isRPSVisibleStats = true; - -export function toggleGame(status) { - if (!status) - return; - var switcherBtn = document.querySelector(".switch-btn"); - var statsPong = document.getElementById('stats-info-pong'); - var statsRPS = document.getElementById('stats-info-rps'); - isRPSVisibleStats = !isRPSVisibleStats; - - if (isRPSVisibleStats) { - // Ping pong istatistiklerini göster - statsPong.style.display = 'block'; - statsRPS.style.display = 'none'; - switcherBtn.innerHTML = '🏓'; // HTML içeriğine Unicode karakterini ekleyin - } else { - // RPS istatistiklerini göster - statsPong.style.display = 'none'; - statsRPS.style.display = 'block'; - switcherBtn.innerHTML = '✂️'; // HTML içeriğine Unicode karakterini ekleyin - } - - // Durumu tersine çevir -} - -export function followButton(username) { - if(!username) - return; - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - var button = document.getElementById('followbtn'); - var button2 = document.getElementById('unfollowbtn'); - fetch(`/follow_unfollow/${username}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrftoken - }, - body: JSON.stringify({ action: "follow" }) - }) - .then(response => response.json()) - .then(data => { - if (data['status'] === 'ok') { - button.style.display = 'none'; - button2.style.display = 'block'; - } - }); -} - -export function unfollowButton(username) { - if(!username) - return; - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - var button = document.getElementById('unfollowbtn'); - var button2 = document.getElementById('followbtn'); - fetch(`/follow_unfollow/${username}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrftoken - }, - body: JSON.stringify({ action: "unfollow" }) - }) - .then(response => response.json()) - .then(data => { - if (data['status'] === 'ok') { - button.style.display = 'none'; - button2.style.display = 'block'; - } - }); -} +var isRPSVisibleHistory = true; + +export function matchHistoryChanger(status) { + + if (!status) + return; + var switcherBtn = document.querySelector(".changer-btn"); + var historyPong = document.getElementById('match-history-pong'); + var historyRPS = document.getElementById('match-history-rps'); + isRPSVisibleHistory = !isRPSVisibleHistory; + + if (isRPSVisibleHistory) { + // Ping pong istatistiklerini göster + historyPong.style.display = 'block'; + historyRPS.style.display = 'none'; + switcherBtn.innerHTML = '🏓'; // HTML içeriğine Unicode karakterini ekleyin + } else { + // RPS istatistiklerini göster + historyPong.style.display = 'none'; + historyRPS.style.display = 'block'; + switcherBtn.innerHTML = '✂️'; // HTML içeriğine Unicode karakterini ekleyin + } + + // Durumu tersine çevir +} + +var isRPSVisibleStats = true; + +export function toggleGame(status) { + if (!status) + return; + var switcherBtn = document.querySelector(".switch-btn"); + var statsPong = document.getElementById('stats-info-pong'); + var statsRPS = document.getElementById('stats-info-rps'); + isRPSVisibleStats = !isRPSVisibleStats; + + if (isRPSVisibleStats) { + // Ping pong istatistiklerini göster + statsPong.style.display = 'block'; + statsRPS.style.display = 'none'; + switcherBtn.innerHTML = '🏓'; // HTML içeriğine Unicode karakterini ekleyin + } else { + // RPS istatistiklerini göster + statsPong.style.display = 'none'; + statsRPS.style.display = 'block'; + switcherBtn.innerHTML = '✂️'; // HTML içeriğine Unicode karakterini ekleyin + } + + // Durumu tersine çevir +} + +export function followButton(username) { + if(!username) + return; + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + var button = document.getElementById('followbtn'); + var button2 = document.getElementById('unfollowbtn'); + fetch(`/follow_unfollow/${username}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken + }, + body: JSON.stringify({ action: "follow" }) + }) + .then(response => response.json()) + .then(data => { + if (data['status'] === 'ok') { + button.style.display = 'none'; + button2.style.display = 'block'; + } + }); +} + +export function unfollowButton(username) { + if(!username) + return; + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + var button = document.getElementById('unfollowbtn'); + var button2 = document.getElementById('followbtn'); + fetch(`/follow_unfollow/${username}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken + }, + body: JSON.stringify({ action: "unfollow" }) + }) + .then(response => response.json()) + .then(data => { + if (data['status'] === 'ok') { + button.style.display = 'none'; + button2.style.display = 'block'; + } + }); +} diff --git a/indianpong/static/js/rps.js b/indianpong/static/js/rps.js index 8b74266d..3e469338 100644 --- a/indianpong/static/js/rps.js +++ b/indianpong/static/js/rps.js @@ -1,350 +1,350 @@ -export function Rps() { -// Prevent animation on load -setTimeout(() => { - document.body.classList.remove("preload"); -}, 200); - -const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); -const selectedLanguage = cookie ? cookie.split('=')[1] : 'en'; - -const translationswin = { - 'hi': 'आप जीत गए', - 'pt': 'você ganhou', - 'tr': 'kazandınız', - 'en': 'you win' // Varsayılan İngilizce metin -}; - -const translationslose = { - 'hi': 'आप हार गए', - 'pt': 'você perdeu', - 'tr': 'kaybettiniz', - 'en': 'you lose' // Varsayılan İngilizce metin -}; - -const CHOICES = [ - { - name: "paper", - beats: "rock", - }, - { - name: "scissors", - beats: "paper", - }, - { - name: "rock", - beats: "scissors", - }, - { - name: "godthings", - beats: "all", - }, - { - name: "cheater", - beats: "all", - } -]; -const choiceButtons = document.querySelectorAll(".choice-btn"); -const gameDiv = document.querySelector(".game"); -const resultsDiv = document.querySelector(".results"); -const resultDivs = document.querySelectorAll(".results__result"); - -const resultWinner = document.querySelector(".results__winner"); -const resultText = document.querySelector(".results__text"); - -const playAgainBtn = document.querySelector(".play-again"); - -const scoreNumber1 = document.querySelector(".score__number1"); -const scoreNumber2 = document.querySelector(".score__number2"); - -const cheater = document.querySelector('.container-top').dataset.cheater; -const godthings = document.querySelector('.container-top').dataset.godthings; -const username = document.querySelector('.container-top').dataset.username; - -const ischeater = (cheater === "true") ? true : false; -const isgodthings = (godthings === "true") ? true : false; - -var start_time; - -let cheatercount = 0; -let godthingscount = 0; -let nowChoice = ""; - -let aicheater = "inactive"; - -const MAX_SCORE_RPS = 3; -let score = 0; - -const ICON_PATH = document.querySelector('.container-top').dataset.iconpath; - - -// Game Logic -choiceButtons.forEach((button) => { - button.addEventListener("click", () => { - if (!start_time) - start_time = new Date(); - const choiceName = button.dataset.choice; - const choice = CHOICES.find((choice) => choice.name === choiceName); - nowChoice = choice.name; - choose(choice); - }); -}); - -function choose(choice) { - // Cheater kontrolü - const aichoice = aiChoose(); - if (choice.name === "cheater" && ischeater === true && cheatercount < 1) { - cheatercount++; - document.getElementById("cheater-choice").style.display = "none"; - } - else if (choice.name === "godthings" && isgodthings === true && godthingscount < 1) { - godthingscount++; - document.getElementById("godthings-choice").style.display = "none"; - } - - displayResults([choice, aichoice]); - displayWinner([choice, aichoice]); - -} - - -function filterChoices(excludedChoices) { - return CHOICES.filter(choice => !excludedChoices.includes(choice.name)); -} - -var aicheaterused = false; -var aigodthingsused = false; - -function aiChoose() { - var filteredChoices = []; - if (cheater === "true" || godthings === "true") { - if (aicheaterused === false && aigodthingsused === false) { - filteredChoices = filterChoices([]); - } - else if (aicheaterused === true && aigodthingsused === true) { - filteredChoices = filterChoices(["cheater", "godthings"]); - } - else if (aicheaterused === true) { - filteredChoices = filterChoices(["cheater"]); - } else if (aigodthingsused === true) { - filteredChoices = filterChoices(["godthings"]); - } - } else { - filteredChoices = filterChoices(["cheater", "godthings"]); - } - var chosenOption = chooseRandom(filteredChoices); - if (chosenOption.name === "cheater") { - aicheaterused = true; - } else if (chosenOption.name === "godthings") { - aigodthingsused = true; - } - - return chosenOption; -} - - -function chooseRandom(choices) { - return choices[Math.floor(Math.random() * choices.length)]; -} - - -function displayResults(results) { - resultDivs.forEach((resultDiv, idx) => { - setTimeout(() => { - resultDiv.innerHTML = ` -
- ${results[idx].name} -
- `; - }, idx * 1000); - - }); - - gameDiv.classList.toggle("hidden"); - resultsDiv.classList.toggle("hidden"); -} - -function displayWinner(results) { - setTimeout(() => { - const winner = isWinner(results); - if (winner == "user") { - resultText.innerText = selectedLanguage ? translationswin[selectedLanguage] : translationswin['en'] ; - resultDivs[0].classList.toggle("winner"); - keepScore(1, results[0].name); - } else if (winner == "ai") { - resultText.innerText = selectedLanguage ? translationslose[selectedLanguage] : translationslose['en'] ; - resultDivs[1].classList.toggle("winner"); - keepScore(-1, results[1].name); - } else { - resultText.innerText = selectedLanguage === "hi" ? "खींचना" : - selectedLanguage === "pt" ? "empate" : - selectedLanguage === "tr" ? "berabere": - "draw"; - } - - if (MAX_SCORE_RPS == parseInt(scoreNumber1.innerText) || MAX_SCORE_RPS == parseInt(scoreNumber2.innerText)) { - showGameOverScreenRPS(); - } - else { - resultWinner.classList.toggle("hidden"); - resultsDiv.classList.toggle("show-winner"); - } - - }, 1000); -} - -function showGameOverScreenRPS() { - resultsDiv.classList.toggle("show-winner"); - var winnerText = (selectedLanguage && selectedLanguage in translationswin && scoreNumber1.innerText == MAX_SCORE_RPS) ? translationswin[selectedLanguage] : translationslose[selectedLanguage] || translationslose['en']; - document.getElementById('winnerText').innerText = winnerText; - const isWin = (scoreNumber1.innerText == MAX_SCORE_RPS) ? true : false; - const Result = (scoreNumber1.innerText == MAX_SCORE_RPS) ? "win" : "defeat"; - if (isWin) { - sendWinnerToBackend(username, "IndianAI", parseInt(scoreNumber1.innerText), parseInt(scoreNumber2.innerText), start_time); - document.getElementById('winnerText').style.color = 'green'; - document.getElementById('gameOverScreen').style.backgroundColor = 'rgba(11, 22, 8, 0.8)'; - } - else { - sendWinnerToBackend("IndianAI", username, parseInt(scoreNumber2.innerText), parseInt(scoreNumber1.innerText), start_time); - document.getElementById('winnerText').style.color = 'red'; - document.getElementById('gameOverScreen').style.backgroundColor = 'rgba(20, 5, 5, 0.8)'; - } - - document.getElementById('gameOverScreen').style.display = 'block'; -} - -document.getElementById('restartButton').addEventListener('click', resetGameRPS); -document.getElementById('exitButton').addEventListener('click', exitGame); - -function resetGameRPS() { - document.getElementById('gameOverScreen').style.display = 'none'; - scoreNumber1.innerText = 0; - scoreNumber2.innerText = 0; - cheatercount = 0; - godthingscount = 0; - aigodthingsused = false; - aicheaterused = false; - PlayAgainRPS(); -} - -function exitGame() { - swapApp('/rps-game-find') -} - -function isWinner(results) { - const player1 = results[0].name; - const player2 = results[1].name; - - if (player1 === player2 || (player1 === "godthings" && player2 === "cheater") || (player1 === "cheater" && player2 === "godthings")) { - return "draw"; - } - - // ilk oyuncunun seçimi Godthings ise ve ikinci oyuncu Godthings değilse, ilk oyuncu kazanır - if (player1 === "godthings" && player2 !== "godthings") { - return "user"; - } - - // ikinci oyuncunun seçimi Godthings ise ve ilk oyuncu Godthings değilse, ikinci oyuncu kazanır - if (player2 === "godthings" && player1 !== "godthings") { - return "ai"; - } - - // ilk oyuncunun seçimi Cheater ise ve ikinci oyuncu Cheater değilse, ilk oyuncu kazanır - if (player1 === "cheater" && player2 !== "cheater") { - return "user"; - } - - // ikinci oyuncunun seçimi Cheater ise ve ilk oyuncu Cheater değilse, ikinci oyuncu kazanır - if (player2 === "cheater" && player1 !== "cheater") { - return "ai"; - } - - // iki oyuncudan birinin seçimi Godthings veya Cheater ise ve diğeri değilse, bu oyuncu kazanır - if (player1 === "godthings" || player1 === "cheater" || player2 === "godthings" || player2 === "cheater") { - return player1 === "godthings" || player1 === "cheater" ? "user" : "ai"; - } - - // Diğer durumda, kazananı belirlemek için normal kuralları kullan - return results[0].beats === results[1].name ? "user" : "ai"; -} - -function keepScore(point, name) { - const tempscore = Math.abs(point); - if (point > 0) { - scoreNumber1.innerText = parseInt(scoreNumber1.innerText) + tempscore; - if (name === "cheater" && parseInt(scoreNumber2.innerText) > 0) - scoreNumber2.innerText = parseInt(scoreNumber2.innerText) - 1; - } else { - scoreNumber2.innerText = parseInt(scoreNumber2.innerText) + tempscore; - if (name === "cheater" && parseInt(scoreNumber1.innerText) > 0) - scoreNumber1.innerText = parseInt(scoreNumber1.innerText) - tempscore; - } -} - -function PlayAgainRPS() { - gameDiv.classList.toggle("hidden"); - resultsDiv.classList.toggle("hidden"); - - resultDivs.forEach((resultDiv) => { - resultDiv.innerHTML = ""; - resultDiv.classList.remove("winner"); - }); - - //resultText.innerText = ""; - if (cheater == "true") - document.getElementById("cheater-choice").style.display = "inline-block"; - if (godthings == "true") - document.getElementById("godthings-choice").style.display = "inline-block"; - resultsDiv.classList.toggle("show-winner"); - -} -// Play Again -playAgainBtn.addEventListener("click", () => { - gameDiv.classList.toggle("hidden"); - resultsDiv.classList.toggle("hidden"); - - resultDivs.forEach((resultDiv) => { - resultDiv.innerHTML = ""; - resultDiv.classList.remove("winner"); - }); - - resultText.innerText = ""; - resultWinner.classList.toggle("hidden"); - resultsDiv.classList.toggle("show-winner"); -}); - -function sendWinnerToBackend(winner, loser, winnerscore, loserscore, start_time) { - const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value; - var finish_time = new Date(); - const data = { - game: "rps", - winner: winner, - loser: loser, - winnerscore: winnerscore, - loserscore: loserscore, - start_time: start_time, - finish_time: finish_time - }; - - fetch('/update_winner/', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrfToken, - }, - body: JSON.stringify(data) - }) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); - }) - .then(data => { - - }) - .catch(error => { - console.error('There was a problem updating the winner:', error); - }); -} - +export function Rps() { +// Prevent animation on load +setTimeout(() => { + document.body.classList.remove("preload"); +}, 200); + +const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); +const selectedLanguage = cookie ? cookie.split('=')[1] : 'en'; + +const translationswin = { + 'hi': 'आप जीत गए', + 'pt': 'você ganhou', + 'tr': 'kazandınız', + 'en': 'you win' // Varsayılan İngilizce metin +}; + +const translationslose = { + 'hi': 'आप हार गए', + 'pt': 'você perdeu', + 'tr': 'kaybettiniz', + 'en': 'you lose' // Varsayılan İngilizce metin +}; + +const CHOICES = [ + { + name: "paper", + beats: "rock", + }, + { + name: "scissors", + beats: "paper", + }, + { + name: "rock", + beats: "scissors", + }, + { + name: "godthings", + beats: "all", + }, + { + name: "cheater", + beats: "all", + } +]; +const choiceButtons = document.querySelectorAll(".choice-btn"); +const gameDiv = document.querySelector(".game"); +const resultsDiv = document.querySelector(".results"); +const resultDivs = document.querySelectorAll(".results__result"); + +const resultWinner = document.querySelector(".results__winner"); +const resultText = document.querySelector(".results__text"); + +const playAgainBtn = document.querySelector(".play-again"); + +const scoreNumber1 = document.querySelector(".score__number1"); +const scoreNumber2 = document.querySelector(".score__number2"); + +const cheater = document.querySelector('.container-top').dataset.cheater; +const godthings = document.querySelector('.container-top').dataset.godthings; +const username = document.querySelector('.container-top').dataset.username; + +const ischeater = (cheater === "true") ? true : false; +const isgodthings = (godthings === "true") ? true : false; + +var start_time; + +let cheatercount = 0; +let godthingscount = 0; +let nowChoice = ""; + +let aicheater = "inactive"; + +const MAX_SCORE_RPS = 3; +let score = 0; + +const ICON_PATH = document.querySelector('.container-top').dataset.iconpath; + + +// Game Logic +choiceButtons.forEach((button) => { + button.addEventListener("click", () => { + if (!start_time) + start_time = new Date(); + const choiceName = button.dataset.choice; + const choice = CHOICES.find((choice) => choice.name === choiceName); + nowChoice = choice.name; + choose(choice); + }); +}); + +function choose(choice) { + // Cheater kontrolü + const aichoice = aiChoose(); + if (choice.name === "cheater" && ischeater === true && cheatercount < 1) { + cheatercount++; + document.getElementById("cheater-choice").style.display = "none"; + } + else if (choice.name === "godthings" && isgodthings === true && godthingscount < 1) { + godthingscount++; + document.getElementById("godthings-choice").style.display = "none"; + } + + displayResults([choice, aichoice]); + displayWinner([choice, aichoice]); + +} + + +function filterChoices(excludedChoices) { + return CHOICES.filter(choice => !excludedChoices.includes(choice.name)); +} + +var aicheaterused = false; +var aigodthingsused = false; + +function aiChoose() { + var filteredChoices = []; + if (cheater === "true" || godthings === "true") { + if (aicheaterused === false && aigodthingsused === false) { + filteredChoices = filterChoices([]); + } + else if (aicheaterused === true && aigodthingsused === true) { + filteredChoices = filterChoices(["cheater", "godthings"]); + } + else if (aicheaterused === true) { + filteredChoices = filterChoices(["cheater"]); + } else if (aigodthingsused === true) { + filteredChoices = filterChoices(["godthings"]); + } + } else { + filteredChoices = filterChoices(["cheater", "godthings"]); + } + var chosenOption = chooseRandom(filteredChoices); + if (chosenOption.name === "cheater") { + aicheaterused = true; + } else if (chosenOption.name === "godthings") { + aigodthingsused = true; + } + + return chosenOption; +} + + +function chooseRandom(choices) { + return choices[Math.floor(Math.random() * choices.length)]; +} + + +function displayResults(results) { + resultDivs.forEach((resultDiv, idx) => { + setTimeout(() => { + resultDiv.innerHTML = ` +
+ ${results[idx].name} +
+ `; + }, idx * 1000); + + }); + + gameDiv.classList.toggle("hidden"); + resultsDiv.classList.toggle("hidden"); +} + +function displayWinner(results) { + setTimeout(() => { + const winner = isWinner(results); + if (winner == "user") { + resultText.innerText = selectedLanguage ? translationswin[selectedLanguage] : translationswin['en'] ; + resultDivs[0].classList.toggle("winner"); + keepScore(1, results[0].name); + } else if (winner == "ai") { + resultText.innerText = selectedLanguage ? translationslose[selectedLanguage] : translationslose['en'] ; + resultDivs[1].classList.toggle("winner"); + keepScore(-1, results[1].name); + } else { + resultText.innerText = selectedLanguage === "hi" ? "खींचना" : + selectedLanguage === "pt" ? "empate" : + selectedLanguage === "tr" ? "berabere": + "draw"; + } + + if (MAX_SCORE_RPS == parseInt(scoreNumber1.innerText) || MAX_SCORE_RPS == parseInt(scoreNumber2.innerText)) { + showGameOverScreenRPS(); + } + else { + resultWinner.classList.toggle("hidden"); + resultsDiv.classList.toggle("show-winner"); + } + + }, 1000); +} + +function showGameOverScreenRPS() { + resultsDiv.classList.toggle("show-winner"); + var winnerText = (selectedLanguage && selectedLanguage in translationswin && scoreNumber1.innerText == MAX_SCORE_RPS) ? translationswin[selectedLanguage] : translationslose[selectedLanguage] || translationslose['en']; + document.getElementById('winnerText').innerText = winnerText; + const isWin = (scoreNumber1.innerText == MAX_SCORE_RPS) ? true : false; + const Result = (scoreNumber1.innerText == MAX_SCORE_RPS) ? "win" : "defeat"; + if (isWin) { + sendWinnerToBackend(username, "IndianAI", parseInt(scoreNumber1.innerText), parseInt(scoreNumber2.innerText), start_time); + document.getElementById('winnerText').style.color = 'green'; + document.getElementById('gameOverScreen').style.backgroundColor = 'rgba(11, 22, 8, 0.8)'; + } + else { + sendWinnerToBackend("IndianAI", username, parseInt(scoreNumber2.innerText), parseInt(scoreNumber1.innerText), start_time); + document.getElementById('winnerText').style.color = 'red'; + document.getElementById('gameOverScreen').style.backgroundColor = 'rgba(20, 5, 5, 0.8)'; + } + + document.getElementById('gameOverScreen').style.display = 'block'; +} + +document.getElementById('restartButton').addEventListener('click', resetGameRPS); +document.getElementById('exitButton').addEventListener('click', exitGame); + +function resetGameRPS() { + document.getElementById('gameOverScreen').style.display = 'none'; + scoreNumber1.innerText = 0; + scoreNumber2.innerText = 0; + cheatercount = 0; + godthingscount = 0; + aigodthingsused = false; + aicheaterused = false; + PlayAgainRPS(); +} + +function exitGame() { + swapApp('/rps-game-find') +} + +function isWinner(results) { + const player1 = results[0].name; + const player2 = results[1].name; + + if (player1 === player2 || (player1 === "godthings" && player2 === "cheater") || (player1 === "cheater" && player2 === "godthings")) { + return "draw"; + } + + // ilk oyuncunun seçimi Godthings ise ve ikinci oyuncu Godthings değilse, ilk oyuncu kazanır + if (player1 === "godthings" && player2 !== "godthings") { + return "user"; + } + + // ikinci oyuncunun seçimi Godthings ise ve ilk oyuncu Godthings değilse, ikinci oyuncu kazanır + if (player2 === "godthings" && player1 !== "godthings") { + return "ai"; + } + + // ilk oyuncunun seçimi Cheater ise ve ikinci oyuncu Cheater değilse, ilk oyuncu kazanır + if (player1 === "cheater" && player2 !== "cheater") { + return "user"; + } + + // ikinci oyuncunun seçimi Cheater ise ve ilk oyuncu Cheater değilse, ikinci oyuncu kazanır + if (player2 === "cheater" && player1 !== "cheater") { + return "ai"; + } + + // iki oyuncudan birinin seçimi Godthings veya Cheater ise ve diğeri değilse, bu oyuncu kazanır + if (player1 === "godthings" || player1 === "cheater" || player2 === "godthings" || player2 === "cheater") { + return player1 === "godthings" || player1 === "cheater" ? "user" : "ai"; + } + + // Diğer durumda, kazananı belirlemek için normal kuralları kullan + return results[0].beats === results[1].name ? "user" : "ai"; +} + +function keepScore(point, name) { + const tempscore = Math.abs(point); + if (point > 0) { + scoreNumber1.innerText = parseInt(scoreNumber1.innerText) + tempscore; + if (name === "cheater" && parseInt(scoreNumber2.innerText) > 0) + scoreNumber2.innerText = parseInt(scoreNumber2.innerText) - 1; + } else { + scoreNumber2.innerText = parseInt(scoreNumber2.innerText) + tempscore; + if (name === "cheater" && parseInt(scoreNumber1.innerText) > 0) + scoreNumber1.innerText = parseInt(scoreNumber1.innerText) - tempscore; + } +} + +function PlayAgainRPS() { + gameDiv.classList.toggle("hidden"); + resultsDiv.classList.toggle("hidden"); + + resultDivs.forEach((resultDiv) => { + resultDiv.innerHTML = ""; + resultDiv.classList.remove("winner"); + }); + + //resultText.innerText = ""; + if (cheater == "true") + document.getElementById("cheater-choice").style.display = "inline-block"; + if (godthings == "true") + document.getElementById("godthings-choice").style.display = "inline-block"; + resultsDiv.classList.toggle("show-winner"); + +} +// Play Again +playAgainBtn.addEventListener("click", () => { + gameDiv.classList.toggle("hidden"); + resultsDiv.classList.toggle("hidden"); + + resultDivs.forEach((resultDiv) => { + resultDiv.innerHTML = ""; + resultDiv.classList.remove("winner"); + }); + + resultText.innerText = ""; + resultWinner.classList.toggle("hidden"); + resultsDiv.classList.toggle("show-winner"); +}); + +function sendWinnerToBackend(winner, loser, winnerscore, loserscore, start_time) { + const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value; + var finish_time = new Date(); + const data = { + game: "rps", + winner: winner, + loser: loser, + winnerscore: winnerscore, + loserscore: loserscore, + start_time: start_time, + finish_time: finish_time + }; + + fetch('/update_winner/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrfToken, + }, + body: JSON.stringify(data) + }) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) + .then(data => { + + }) + .catch(error => { + console.error('There was a problem updating the winner:', error); + }); +} + } \ No newline at end of file diff --git a/indianpong/static/js/search.js b/indianpong/static/js/search.js index a3033684..3dea4999 100644 --- a/indianpong/static/js/search.js +++ b/indianpong/static/js/search.js @@ -1,75 +1,75 @@ -function getCookie(name) { - const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); - return cookieValue ? cookieValue.pop() : ''; -} - -export function initializeSearch() { - - const followButtons = document.querySelectorAll(".button-follow"); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - followButtons.forEach((button) => { - button.addEventListener('click', (e) => { - const username = e.target.getAttribute('data-username'); - const lang = getCookie('selectedLanguage'); - let action = e.target.innerHTML.trim(); - if (action == "अनुसरण करना" || action == "Seguir" || action == "Takip Et" || action == "Follow") { - action = "follow" - } else if (action == "अनफ़ॉलो" || action == "Deixar" || action == "Takipten Çık" || action == "Unfollow") { - action = "unfollow" - } - fetch(`/follow_unfollow/${username}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrftoken - }, - body: JSON.stringify({ action: action }) - }) - .then(response => response.json()) - .then(data => { - if (data['status'] === 'ok') { - if (lang == 'hi') { - e.target.innerHTML = data['action'] === 'follow' ? 'अनफ़ॉलो' : 'अनुसरण करना'; - e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; - } - else if(lang == 'tr') { - e.target.innerHTML = data['action'] === 'follow' ? 'Takipten Çık' : 'Takip Et'; - e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; - } - else if (lang == 'pt') { - e.target.innerHTML = data['action'] === 'follow' ? 'Deixar' : 'Seguir'; - e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; - } - else { - e.target.innerHTML = data['action'] === 'follow' ? 'Unfollow' : 'Follow'; - e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; - } - } - }); - }); - }); -} - -export function makeSearch(action) { - if (!action) - return; - - var form = document.getElementById('searchForm'); - var formData = new FormData(form); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - fetch('/search', { - method: 'POST', - headers: { - 'X-CSRFToken': csrftoken - }, - body: formData - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - initializeSearch(); - }) - .catch(error => { - console.error(error); - }); +function getCookie(name) { + const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); + return cookieValue ? cookieValue.pop() : ''; +} + +export function initializeSearch() { + + const followButtons = document.querySelectorAll(".button-follow"); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + followButtons.forEach((button) => { + button.addEventListener('click', (e) => { + const username = e.target.getAttribute('data-username'); + const lang = getCookie('selectedLanguage'); + let action = e.target.innerHTML.trim(); + if (action == "अनुसरण करना" || action == "Seguir" || action == "Takip Et" || action == "Follow") { + action = "follow" + } else if (action == "अनफ़ॉलो" || action == "Deixar" || action == "Takipten Çık" || action == "Unfollow") { + action = "unfollow" + } + fetch(`/follow_unfollow/${username}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken + }, + body: JSON.stringify({ action: action }) + }) + .then(response => response.json()) + .then(data => { + if (data['status'] === 'ok') { + if (lang == 'hi') { + e.target.innerHTML = data['action'] === 'follow' ? 'अनफ़ॉलो' : 'अनुसरण करना'; + e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; + } + else if(lang == 'tr') { + e.target.innerHTML = data['action'] === 'follow' ? 'Takipten Çık' : 'Takip Et'; + e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; + } + else if (lang == 'pt') { + e.target.innerHTML = data['action'] === 'follow' ? 'Deixar' : 'Seguir'; + e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; + } + else { + e.target.innerHTML = data['action'] === 'follow' ? 'Unfollow' : 'Follow'; + e.target.style.backgroundColor = data['action'] === 'follow' ? 'black' : '#dc3545'; + } + } + }); + }); + }); +} + +export function makeSearch(action) { + if (!action) + return; + + var form = document.getElementById('searchForm'); + var formData = new FormData(form); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + fetch('/search', { + method: 'POST', + headers: { + 'X-CSRFToken': csrftoken + }, + body: formData + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + initializeSearch(); + }) + .catch(error => { + console.error(error); + }); } \ No newline at end of file diff --git a/indianpong/static/js/signup.js b/indianpong/static/js/signup.js index 657caf8e..b8121b74 100644 --- a/indianpong/static/js/signup.js +++ b/indianpong/static/js/signup.js @@ -1,141 +1,141 @@ -export function initializeSignup() { - const passwordInput1 = document.getElementById('id_password1'); - const passwordInput2 = document.getElementById('id_password2'); - const toggleButton1 = document.getElementById('togglePassword1'); - const toggleButton2 = document.getElementById('togglePassword2'); - - toggleButton1.addEventListener('mousedown', function() { - passwordInput1.type = 'text'; - toggleButton1.classList.remove('bi-eye-slash-fill'); - toggleButton1.classList.add('bi-eye-fill'); - }); - - toggleButton1.addEventListener('mouseup', function() { - passwordInput1.type = 'password'; - toggleButton1.classList.remove('bi-eye-fill'); - toggleButton1.classList.add('bi-eye-slash-fill'); - }); - - toggleButton2.addEventListener('mousedown', function() { - passwordInput2.type = 'text'; - toggleButton2.classList.remove('bi-eye-slash-fill'); - toggleButton2.classList.add('bi-eye-fill'); - }); - - toggleButton2.addEventListener('mouseup', function() { - passwordInput2.type = 'password'; - toggleButton2.classList.remove('bi-eye-fill'); - toggleButton2.classList.add('bi-eye-slash-fill'); - }); - - passwordInput1.addEventListener('input', function() { - toggleButton1.style.display = this.value.trim() !== '' ? 'block' : 'none'; - }); - - passwordInput2.addEventListener('input', function() { - toggleButton2.style.display = this.value.trim() !== '' ? 'block' : 'none'; - }); - - function getCookie(name) { - const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); - return cookieValue ? cookieValue.pop() : ''; - } - - const fileInput = document.getElementById('id_avatar'); - if (fileInput) { - fileInput.addEventListener('change', function(event) { - const selectedLanguage = getCookie('selectedLanguage'); - var file = this.files[0]; - if (file && file.size > 2 * 1024 * 1024) { - var messages = { - 'en': "Photo must be under 2MB!", - 'tr': "Fotoğraf 2MB'dan küçük olmalıdır!", - 'hi': "फोटो 2MB से कम होना चाहिए!", - 'pt': "A foto deve ter menos de 2MB!" - }; - var message = messages[selectedLanguage] || "Photo must be under 2MB!"; - showToast(message, "text-bg-danger", "bi bi-image"); - this.value = ''; - } - else { - var messages = { - 'en': "Photo added!", - 'tr': "Fotoğraf eklendi!", - 'hi': "फोटो जोड़ दी गई!", - 'pt': "Foto adicionada!" - }; - var message = messages[selectedLanguage] || "Photo added!"; - showToast(message, "text-bg-success", "bi bi-image"); - } - }); - } -} - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - const toast = new bootstrap.Toast(liveToast); - toast.show(); - setTimeout(function() { - toast.hide(); - }, 8000); -} - -export function makeRegister(check) { - if (!check) - return; - const selectedLanguage = getCookie('selectedLanguage'); - if (document.getElementById('gdprCheckbox').checked == false) { - if (selectedLanguage == 'en') - showToast("Please accept the terms and conditions", "text-bg-danger", "bi bi-exclamation-triangle-fill"); - else if (selectedLanguage == 'tr') - showToast("Lütfen şartları ve koşulları kabul edin", "text-bg-danger", "bi bi-exclamation-triangle-fill"); - else if (selectedLanguage == 'hi') - showToast("कृपया नियम और शर्तों को स्वीकार करें", "text-bg-danger", "bi bi-exclamation-triangle-fill"); - else if (selectedLanguage == 'pt') - showToast("Por favor, aceite os termos e condições", "text-bg-danger", "bi bi-exclamation-triangle-fill"); - return; - } - var form = document.getElementById('registerForm'); - var formData = new FormData(form); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - - if (formData.get['username'] == 'IndianAI') { - if (selectedLanguage == 'en') - showToast("Username is not allowed", "text-bg-danger", "bi bi-person-x-fill"); - else if (selectedLanguage == 'tr') - showToast("Kullanıcı adı izin verilmiyor", "text-bg-danger", "bi bi-person-x-fill"); - else if (selectedLanguage == 'hi') - showToast("उपयोगकर्ता नाम अनुमत नहीं है", "text-bg-danger", "bi bi-person-x-fill"); - else if (selectedLanguage == 'pt') - showToast("Nome de usuário não permitido", "text-bg-danger", "bi bi-person-x-fill"); - } - fetch('/signup', { - method: 'POST', - headers: { - 'X-CSRFToken': csrftoken - }, - body: formData - }) - .then(response => response.text()) - .then(data => { - if (data == "login") { - swapApp('/login'); - } else { - document.body.innerHTML = data; - } - }) - .catch(error => { - console.error(error); - }); -} - +export function initializeSignup() { + const passwordInput1 = document.getElementById('id_password1'); + const passwordInput2 = document.getElementById('id_password2'); + const toggleButton1 = document.getElementById('togglePassword1'); + const toggleButton2 = document.getElementById('togglePassword2'); + + toggleButton1.addEventListener('mousedown', function() { + passwordInput1.type = 'text'; + toggleButton1.classList.remove('bi-eye-slash-fill'); + toggleButton1.classList.add('bi-eye-fill'); + }); + + toggleButton1.addEventListener('mouseup', function() { + passwordInput1.type = 'password'; + toggleButton1.classList.remove('bi-eye-fill'); + toggleButton1.classList.add('bi-eye-slash-fill'); + }); + + toggleButton2.addEventListener('mousedown', function() { + passwordInput2.type = 'text'; + toggleButton2.classList.remove('bi-eye-slash-fill'); + toggleButton2.classList.add('bi-eye-fill'); + }); + + toggleButton2.addEventListener('mouseup', function() { + passwordInput2.type = 'password'; + toggleButton2.classList.remove('bi-eye-fill'); + toggleButton2.classList.add('bi-eye-slash-fill'); + }); + + passwordInput1.addEventListener('input', function() { + toggleButton1.style.display = this.value.trim() !== '' ? 'block' : 'none'; + }); + + passwordInput2.addEventListener('input', function() { + toggleButton2.style.display = this.value.trim() !== '' ? 'block' : 'none'; + }); + + function getCookie(name) { + const cookieValue = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)'); + return cookieValue ? cookieValue.pop() : ''; + } + + const fileInput = document.getElementById('id_avatar'); + if (fileInput) { + fileInput.addEventListener('change', function(event) { + const selectedLanguage = getCookie('selectedLanguage'); + var file = this.files[0]; + if (file && file.size > 2 * 1024 * 1024) { + var messages = { + 'en': "Photo must be under 2MB!", + 'tr': "Fotoğraf 2MB'dan küçük olmalıdır!", + 'hi': "फोटो 2MB से कम होना चाहिए!", + 'pt': "A foto deve ter menos de 2MB!" + }; + var message = messages[selectedLanguage] || "Photo must be under 2MB!"; + showToast(message, "text-bg-danger", "bi bi-image"); + this.value = ''; + } + else { + var messages = { + 'en': "Photo added!", + 'tr': "Fotoğraf eklendi!", + 'hi': "फोटो जोड़ दी गई!", + 'pt': "Foto adicionada!" + }; + var message = messages[selectedLanguage] || "Photo added!"; + showToast(message, "text-bg-success", "bi bi-image"); + } + }); + } +} + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + const toast = new bootstrap.Toast(liveToast); + toast.show(); + setTimeout(function() { + toast.hide(); + }, 8000); +} + +export function makeRegister(check) { + if (!check) + return; + const selectedLanguage = getCookie('selectedLanguage'); + if (document.getElementById('gdprCheckbox').checked == false) { + if (selectedLanguage == 'en') + showToast("Please accept the terms and conditions", "text-bg-danger", "bi bi-exclamation-triangle-fill"); + else if (selectedLanguage == 'tr') + showToast("Lütfen şartları ve koşulları kabul edin", "text-bg-danger", "bi bi-exclamation-triangle-fill"); + else if (selectedLanguage == 'hi') + showToast("कृपया नियम और शर्तों को स्वीकार करें", "text-bg-danger", "bi bi-exclamation-triangle-fill"); + else if (selectedLanguage == 'pt') + showToast("Por favor, aceite os termos e condições", "text-bg-danger", "bi bi-exclamation-triangle-fill"); + return; + } + var form = document.getElementById('registerForm'); + var formData = new FormData(form); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + + if (formData.get['username'] == 'IndianAI') { + if (selectedLanguage == 'en') + showToast("Username is not allowed", "text-bg-danger", "bi bi-person-x-fill"); + else if (selectedLanguage == 'tr') + showToast("Kullanıcı adı izin verilmiyor", "text-bg-danger", "bi bi-person-x-fill"); + else if (selectedLanguage == 'hi') + showToast("उपयोगकर्ता नाम अनुमत नहीं है", "text-bg-danger", "bi bi-person-x-fill"); + else if (selectedLanguage == 'pt') + showToast("Nome de usuário não permitido", "text-bg-danger", "bi bi-person-x-fill"); + } + fetch('/signup', { + method: 'POST', + headers: { + 'X-CSRFToken': csrftoken + }, + body: formData + }) + .then(response => response.text()) + .then(data => { + if (data == "login") { + swapApp('/login'); + } else { + document.body.innerHTML = data; + } + }) + .catch(error => { + console.error(error); + }); +} + diff --git a/indianpong/static/js/sockRps.js b/indianpong/static/js/sockRps.js index 96c13542..3c53313b 100644 --- a/indianpong/static/js/sockRps.js +++ b/indianpong/static/js/sockRps.js @@ -1,388 +1,388 @@ -// rps.js - -export function RemoteRps() { - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - const toast = new bootstrap.Toast(liveToast); - toast.show(); - setTimeout(function() { - toast.hide(); - }, 8000); -} - -const wsEndpoint = 'ws://' + window.location.host + '/ws/rps/'; -const websocket = new WebSocket(wsEndpoint); - - -const checkbox = document.getElementById('flexSwitchCheckDefault'); -const selectedGameModeLabel = document.getElementById('selectedGameMode'); -const gameArea = document.getElementById('container-top'); -const cheaterButton = document.getElementById('cheater-choice'); -const godthingsButton = document.getElementById('godthings-choice'); -var gameMode = document.getElementById('selectedGameMode'); -const matchmakingButton = document.getElementById('matchmakingButtons'); - -const ICON_PATH = document.querySelector('.container-top').dataset.iconpath; - -const choiceButtons = document.querySelectorAll(".choice-btn"); -const gameDiv = document.querySelector(".game"); -const resultsDiv = document.querySelector(".results"); -const resultDivs = document.querySelectorAll(".results__result"); - -const resultWinner = document.querySelector(".results__winner"); -const resultText = document.querySelector(".results__text"); - -const scoreNumber1 = document.querySelector(".score__number1"); -const scoreNumber2 = document.querySelector(".score__number2"); - -const player1Picked = document.getElementById("player1_picked"); -const player2Picked = document.getElementById("player2_picked"); - -let cheaterAbilities = false; -let godthingsAbilities = false; - -let score = 0; - -let abilityStatus = false; - -// Prevent animation on load -setTimeout(() => { - document.body.classList.remove("preload"); -}, 500); - -// maybe merge with my object -var player1 = {username: '', score: 0}; -var player2 = {username: '', score: 0}; - -var my = { - username: '', opponent_username: '', game_id: '', -}; - -function scoreUpdate(player1_score, player2_score) { - player1.score = player1_score; - scoreNumber1.innerText = player1_score; - player2.score = player2_score; - scoreNumber2.innerText = player2_score; -} - -websocket.onopen = function (e) { - // Show some greeting message - console.log('WebSocket connection established'); -} - -websocket.onclose = function (e) { - // stop the game - console.error('WebSocket connection closed'); -} - -websocket.onerror = function (e) { - console.error('Error: ' + e.data.error); - // stop the game -} - -websocket.onmessage = function (e) { - const data = JSON.parse(e.data); - switch (data.type) { - case 'insearch': - // Self send message - console.log('In search', data.user); - if (my.username === '') { - my.username = data.user; - } - // Take online users usernames and display them - addUserCount(data.user_count); - console.log('Online users', data.user_count); - break; - - case 'user.insearch': - // Send others i joined the lobby - console.log('User in search', data.user); - // Add user to online users list - if (data.user !== my.username) { - addUserCount(1); - } - - if (selectedLanguage === 'tr') - showToast(data.user + ' katıldı!', 'text-bg-success', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'hi') - showToast(data.user + ' शामिल हो गया!', 'text-bg-success', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'pt') - showToast(data.user + ' entrou!', 'text-bg-success', 'bi bi-check-circle-fill') - else - showToast(data.user + ' joined!', 'text-bg-success', 'bi bi-check-circle-fill') - break; - case 'user.outsearch': - // Send others user left the lobby - console.log('User out search', data.user); - // Remove user from online users list - addUserCount(-1); - if (selectedLanguage === 'tr') - showToast(data.user + ' ayrıldı!', 'text-bg-danger', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'hi') - showToast(data.user + ' चला गया!', 'text-bg-danger', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'pt') - showToast(data.user + ' saiu!', 'text-bg-danger', 'bi bi-check-circle-fill') - else - showToast(data.user + ' left!', 'text-bg-danger', 'bi bi-check-circle-fill') - break; - case 'game.disconnected': - // stop the game - gameOverScreen.style.display = 'block'; //? check - if (selectedLanguage === 'tr') - showToast(`${data.disconnected} bağlantısı kesildi. Otomatik olarak kazanan sizsiniz`, 'text-bg-danger', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'hi') - showToast(`${data.disconnected} डिस्कनेक्ट हो गया आप ऑटोमेटिक विनर हैं`, 'text-bg-danger', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'pt') - showToast(`${data.disconnected} desconectado Você é o vencedor automaticamente`, 'text-bg-danger', 'bi bi-check-circle-fill') - else - showToast(`${data.disconnected} disconnected You are automatically winner`, 'text-bg-danger', 'bi bi-check-circle-fill') - break; - case 'start': - // Start the game - my.game_id = data.game_id; - player1.username = data.player1; - player2.username = data.player2; - - - gameArea.style.visibility = "visible"; - matchmakingButton.style.display = "none"; - if (abilityStatus) { - cheaterButton.style.display = 'block'; - godthingsButton.style.display = 'block'; - } - - document.getElementById("player1Name").innerText = player1.username; - document.getElementById("player2Name").innerText = player2.username; - - if (selectedLanguage === 'tr') - showToast('Oyun başladı', 'text-bg-success', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'hi') - showToast('खेल शुरू हुआ', 'text-bg-success', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'pt') - showToast('Jogo começou', 'text-bg-success', 'bi bi-check-circle-fill') - else - showToast('Game started', 'text-bg-success', 'bi bi-check-circle-fill') - break; - - case 'matchmaking.notfound': - // Matchmaking found - if (selectedLanguage === 'tr') - showToast('Rakip bulunamadı', 'text-bg-danger', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'hi') - showToast('विरोधी नहीं मिला', 'text-bg-danger', 'bi bi-check-circle-fill') - else if (selectedLanguage === 'pt') - showToast('Oponente não encontrado', 'text-bg-danger', 'bi bi-check-circle-fill') - else - showToast('No opponent found', 'text-bg-danger', 'bi bi-check-circle-fill') - break; - - case 'result': - // Game result - var result = data.result; - var game_id = data.game_id; - var player1_choice = data.player1_choice; - var player2_choice = data.player2_choice; - var player1_score = data.player1_score; - var player2_score = data.player2_score; - - if (my.username === player1.username && player1_choice === "LIKEACHEATER") - cheaterAbilities = true; - else if (my.username === player2.username && player2_choice === "LIKEACHEATER") - cheaterAbilities = true; - if (my.username === player1.username && player1_choice === "GODOFTHINGS") - godthingsAbilities = true; - else if (my.username === player2.username && player2_choice === "GODOFTHINGS") - godthingsAbilities = true; - - scoreUpdate(player1_score, player2_score); - - displayResults([player1_choice, player2_choice]); - displayWinner(result); - break; - - } - } - -function addUserCount(count) { - console.log('User count', count); - var userCountElement = document.getElementById('userCount'); - var currentCount = parseInt(userCountElement.innerText); - - userCountElement.innerText = currentCount + count; - -} -function searchOpponent() { - // Search for opponent - checkbox.disabled = true; - websocket.send(JSON.stringify({ - type: 'matchmaking' - })); -} - -function sendChoice(choice) { - // Send choice to opponent - console.log(choice); - websocket.send(JSON.stringify({ - type: 'choice', - game_id: my.game_id, - choice: choice, // rock, paper, scissors, godthings, cheater - })); -} - -//------------------- - - -// Game Logic -choiceButtons.forEach((button) => { - button.addEventListener("click", () => { - const choiceName = button.dataset.choice; - sendChoice(choiceName); - choiceButtons.forEach(btn => { - btn.disabled = true; - }); - }); -}); - - -function displayResults(results) { - player1Picked.innerHTML = - selectedLanguage === 'tr' ? player1.username + " seçti" : - selectedLanguage === 'hi' ? player1.username + " चुना" : - selectedLanguage === 'pt' ? player1.username + " escolheu" : - player1.username + " picked"; - - player2Picked.innerHTML = - selectedLanguage === 'tr' ? player2.username + " seçti" : - selectedLanguage === 'hi' ? player2.username + " चुना" : - selectedLanguage === 'pt' ? player2.username + " escolheu" : - player2.username + " picked"; - - resultDivs.forEach((resultDiv, idx) => { - setTimeout(() => { - - resultDiv.innerHTML = ` -
- ${results[idx].toLowerCase()} -
- `; - }, idx * 1000); - }); - - gameDiv.classList.toggle("hidden"); - resultsDiv.classList.toggle("hidden"); -} - -function displayWinner(result) { - setTimeout(() => { - if (result === "PLAYER1_WIN") { - var langResult = selectedLanguage === 'tr' ? " kazandı" : selectedLanguage === 'hi' ? " जीता" : selectedLanguage === 'pt' ? " ganhou" : " win"; - resultText.innerText = player1.username + langResult; - resultDivs[0].classList.toggle("winner"); - } else if (result === "PLAYER2_WIN") { - var langResult = selectedLanguage === 'tr' ? " kazandı" : selectedLanguage === 'hi' ? " जीता" : selectedLanguage === 'pt' ? " ganhou" : " win"; - resultText.innerText = player2.username + langResult; - resultDivs[1].classList.toggle("winner"); - } else if (result === "DRAW") { - var langResult = selectedLanguage === 'tr' ? " berabere" : selectedLanguage === 'hi' ? " बराबरी" : selectedLanguage === 'pt' ? " empate" : " draw"; - resultText.innerText = langResult; - } - else { - var resultWinnerText = selectedLanguage === 'tr' ? " oyunu kazandı" : selectedLanguage === 'hi' ? " जीत गया" : selectedLanguage === 'pt' ? " ganhou o jogo" : " won the game"; - if (player1.score > player2.score) - resultWinner.innerText = player1.username + resultWinnerText; - else - resultWinner.innerText = player2.username + resultWinnerText; - resultWinner.classList.toggle("hidden"); - resultsDiv.classList.toggle("hidden"); - showGameOverScreen(); - } - resultWinner.classList.toggle("hidden"); - }, 1000); - if (result != "OVER") { - setTimeout(() => { - if (cheaterAbilities) - cheaterButton.style.display = "none"; - else if (godthingsAbilities) - godthingsButton.style.display = "none"; - gameDiv.classList.toggle("hidden"); - resultsDiv.classList.toggle("hidden"); - - resultDivs.forEach((resultDiv) => { - resultDiv.innerHTML = ""; - resultDiv.classList.remove("winner"); - }); - - resultText.innerText = ""; - resultWinner.classList.toggle("hidden"); - resultsDiv.classList.toggle("show-winner"); - - choiceButtons.forEach(btn => { - btn.disabled = false; - }); - }, 3000); - } -} - -function showGameOverScreen() { - var winnerText = (player1.score == 3) ? player1.username : player2.username; - document.getElementById('winnerText').innerText = selectedLanguage === 'tr' ? winnerText + " kazandı" : selectedLanguage === 'hi' ? winnerText + " जीता" : selectedLanguage === 'pt' ? winnerText + " ganhou" : winnerText + " win"; - document.getElementById('gameOverScreen').style.backgroundColor = 'rgba(11, 22, 8, 0.8)'; - document.getElementById('gameOverScreen').style.display = 'block'; -} - -document.getElementById('ponggamebtn').addEventListener('click', searchOpponent); - -checkbox.addEventListener('change', function() { - // Checkbox'un durumuna göre etiketin innerHTML değerini değiştirme - if (checkbox.checked) { - gameMode = "Abilities"; - abilityStatus = true; - if (selectedLanguage === 'tr') - selectedGameModeLabel.innerHTML = "Yetenekler"; - else if (selectedLanguage === 'hi') - selectedGameModeLabel.innerHTML = "क्षमताएँ"; - else if (selectedLanguage === 'pt') - selectedGameModeLabel.innerHTML = "Habilidades"; - else - selectedGameModeLabel.innerHTML = "Abilities"; - } else { - gameMode = "Vanilla"; - abilityStatus = false; - if (selectedLanguage === 'tr') - selectedGameModeLabel.innerHTML = "Vanilya"; - else if (selectedLanguage === 'hi') - selectedGameModeLabel.innerHTML = "वैनिला"; - else if (selectedLanguage === 'pt') - selectedGameModeLabel.innerHTML = "Baunilha"; - else - selectedGameModeLabel.innerHTML = "Vanilla"; - } -}); - -const gameModeSelect = document.getElementById("gameModeSelect"); - -gameModeSelect.addEventListener("mouseenter", function() { - document.querySelector(".game-mode-info").style.display = "block"; -}); - -gameModeSelect.addEventListener("mouseleave", function() { - document.querySelector(".game-mode-info").style.display = "none"; -}); -// Show/Hide Rules - -document.getElementById('exitButton').addEventListener('click', exitGame); - -function exitGame() { - swapApp('/rps-game-find') -} +// rps.js + +export function RemoteRps() { + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + const toast = new bootstrap.Toast(liveToast); + toast.show(); + setTimeout(function() { + toast.hide(); + }, 8000); +} + +const wsEndpoint = 'wss://' + window.location.host + '/ws/rps/'; +const websocket = new WebSocket(wsEndpoint); + + +const checkbox = document.getElementById('flexSwitchCheckDefault'); +const selectedGameModeLabel = document.getElementById('selectedGameMode'); +const gameArea = document.getElementById('container-top'); +const cheaterButton = document.getElementById('cheater-choice'); +const godthingsButton = document.getElementById('godthings-choice'); +var gameMode = document.getElementById('selectedGameMode'); +const matchmakingButton = document.getElementById('matchmakingButtons'); + +const ICON_PATH = document.querySelector('.container-top').dataset.iconpath; + +const choiceButtons = document.querySelectorAll(".choice-btn"); +const gameDiv = document.querySelector(".game"); +const resultsDiv = document.querySelector(".results"); +const resultDivs = document.querySelectorAll(".results__result"); + +const resultWinner = document.querySelector(".results__winner"); +const resultText = document.querySelector(".results__text"); + +const scoreNumber1 = document.querySelector(".score__number1"); +const scoreNumber2 = document.querySelector(".score__number2"); + +const player1Picked = document.getElementById("player1_picked"); +const player2Picked = document.getElementById("player2_picked"); + +let cheaterAbilities = false; +let godthingsAbilities = false; + +let score = 0; + +let abilityStatus = false; + +// Prevent animation on load +setTimeout(() => { + document.body.classList.remove("preload"); +}, 500); + +// maybe merge with my object +var player1 = {username: '', score: 0}; +var player2 = {username: '', score: 0}; + +var my = { + username: '', opponent_username: '', game_id: '', +}; + +function scoreUpdate(player1_score, player2_score) { + player1.score = player1_score; + scoreNumber1.innerText = player1_score; + player2.score = player2_score; + scoreNumber2.innerText = player2_score; +} + +websocket.onopen = function (e) { + // Show some greeting message + console.log('WebSocket connection established'); +} + +websocket.onclose = function (e) { + // stop the game + console.error('WebSocket connection closed'); +} + +websocket.onerror = function (e) { + console.error('Error: ' + e.data.error); + // stop the game +} + +websocket.onmessage = function (e) { + const data = JSON.parse(e.data); + switch (data.type) { + case 'insearch': + // Self send message + console.log('In search', data.user); + if (my.username === '') { + my.username = data.user; + } + // Take online users usernames and display them + addUserCount(data.user_count); + console.log('Online users', data.user_count); + break; + + case 'user.insearch': + // Send others i joined the lobby + console.log('User in search', data.user); + // Add user to online users list + if (data.user !== my.username) { + addUserCount(1); + } + + if (selectedLanguage === 'tr') + showToast(data.user + ' katıldı!', 'text-bg-success', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'hi') + showToast(data.user + ' शामिल हो गया!', 'text-bg-success', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'pt') + showToast(data.user + ' entrou!', 'text-bg-success', 'bi bi-check-circle-fill') + else + showToast(data.user + ' joined!', 'text-bg-success', 'bi bi-check-circle-fill') + break; + case 'user.outsearch': + // Send others user left the lobby + console.log('User out search', data.user); + // Remove user from online users list + addUserCount(-1); + if (selectedLanguage === 'tr') + showToast(data.user + ' ayrıldı!', 'text-bg-danger', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'hi') + showToast(data.user + ' चला गया!', 'text-bg-danger', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'pt') + showToast(data.user + ' saiu!', 'text-bg-danger', 'bi bi-check-circle-fill') + else + showToast(data.user + ' left!', 'text-bg-danger', 'bi bi-check-circle-fill') + break; + case 'game.disconnected': + // stop the game + gameOverScreen.style.display = 'block'; //? check + if (selectedLanguage === 'tr') + showToast(`${data.disconnected} bağlantısı kesildi. Otomatik olarak kazanan sizsiniz`, 'text-bg-danger', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'hi') + showToast(`${data.disconnected} डिस्कनेक्ट हो गया आप ऑटोमेटिक विनर हैं`, 'text-bg-danger', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'pt') + showToast(`${data.disconnected} desconectado Você é o vencedor automaticamente`, 'text-bg-danger', 'bi bi-check-circle-fill') + else + showToast(`${data.disconnected} disconnected You are automatically winner`, 'text-bg-danger', 'bi bi-check-circle-fill') + break; + case 'start': + // Start the game + my.game_id = data.game_id; + player1.username = data.player1; + player2.username = data.player2; + + + gameArea.style.visibility = "visible"; + matchmakingButton.style.display = "none"; + if (abilityStatus) { + cheaterButton.style.display = 'block'; + godthingsButton.style.display = 'block'; + } + + document.getElementById("player1Name").innerText = player1.username; + document.getElementById("player2Name").innerText = player2.username; + + if (selectedLanguage === 'tr') + showToast('Oyun başladı', 'text-bg-success', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'hi') + showToast('खेल शुरू हुआ', 'text-bg-success', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'pt') + showToast('Jogo começou', 'text-bg-success', 'bi bi-check-circle-fill') + else + showToast('Game started', 'text-bg-success', 'bi bi-check-circle-fill') + break; + + case 'matchmaking.notfound': + // Matchmaking found + if (selectedLanguage === 'tr') + showToast('Rakip bulunamadı', 'text-bg-danger', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'hi') + showToast('विरोधी नहीं मिला', 'text-bg-danger', 'bi bi-check-circle-fill') + else if (selectedLanguage === 'pt') + showToast('Oponente não encontrado', 'text-bg-danger', 'bi bi-check-circle-fill') + else + showToast('No opponent found', 'text-bg-danger', 'bi bi-check-circle-fill') + break; + + case 'result': + // Game result + var result = data.result; + var game_id = data.game_id; + var player1_choice = data.player1_choice; + var player2_choice = data.player2_choice; + var player1_score = data.player1_score; + var player2_score = data.player2_score; + + if (my.username === player1.username && player1_choice === "LIKEACHEATER") + cheaterAbilities = true; + else if (my.username === player2.username && player2_choice === "LIKEACHEATER") + cheaterAbilities = true; + if (my.username === player1.username && player1_choice === "GODOFTHINGS") + godthingsAbilities = true; + else if (my.username === player2.username && player2_choice === "GODOFTHINGS") + godthingsAbilities = true; + + scoreUpdate(player1_score, player2_score); + + displayResults([player1_choice, player2_choice]); + displayWinner(result); + break; + + } + } + +function addUserCount(count) { + console.log('User count', count); + var userCountElement = document.getElementById('userCount'); + var currentCount = parseInt(userCountElement.innerText); + + userCountElement.innerText = currentCount + count; + +} +function searchOpponent() { + // Search for opponent + checkbox.disabled = true; + websocket.send(JSON.stringify({ + type: 'matchmaking' + })); +} + +function sendChoice(choice) { + // Send choice to opponent + console.log(choice); + websocket.send(JSON.stringify({ + type: 'choice', + game_id: my.game_id, + choice: choice, // rock, paper, scissors, godthings, cheater + })); +} + +//------------------- + + +// Game Logic +choiceButtons.forEach((button) => { + button.addEventListener("click", () => { + const choiceName = button.dataset.choice; + sendChoice(choiceName); + choiceButtons.forEach(btn => { + btn.disabled = true; + }); + }); +}); + + +function displayResults(results) { + player1Picked.innerHTML = + selectedLanguage === 'tr' ? player1.username + " seçti" : + selectedLanguage === 'hi' ? player1.username + " चुना" : + selectedLanguage === 'pt' ? player1.username + " escolheu" : + player1.username + " picked"; + + player2Picked.innerHTML = + selectedLanguage === 'tr' ? player2.username + " seçti" : + selectedLanguage === 'hi' ? player2.username + " चुना" : + selectedLanguage === 'pt' ? player2.username + " escolheu" : + player2.username + " picked"; + + resultDivs.forEach((resultDiv, idx) => { + setTimeout(() => { + + resultDiv.innerHTML = ` +
+ ${results[idx].toLowerCase()} +
+ `; + }, idx * 1000); + }); + + gameDiv.classList.toggle("hidden"); + resultsDiv.classList.toggle("hidden"); +} + +function displayWinner(result) { + setTimeout(() => { + if (result === "PLAYER1_WIN") { + var langResult = selectedLanguage === 'tr' ? " kazandı" : selectedLanguage === 'hi' ? " जीता" : selectedLanguage === 'pt' ? " ganhou" : " win"; + resultText.innerText = player1.username + langResult; + resultDivs[0].classList.toggle("winner"); + } else if (result === "PLAYER2_WIN") { + var langResult = selectedLanguage === 'tr' ? " kazandı" : selectedLanguage === 'hi' ? " जीता" : selectedLanguage === 'pt' ? " ganhou" : " win"; + resultText.innerText = player2.username + langResult; + resultDivs[1].classList.toggle("winner"); + } else if (result === "DRAW") { + var langResult = selectedLanguage === 'tr' ? " berabere" : selectedLanguage === 'hi' ? " बराबरी" : selectedLanguage === 'pt' ? " empate" : " draw"; + resultText.innerText = langResult; + } + else { + var resultWinnerText = selectedLanguage === 'tr' ? " oyunu kazandı" : selectedLanguage === 'hi' ? " जीत गया" : selectedLanguage === 'pt' ? " ganhou o jogo" : " won the game"; + if (player1.score > player2.score) + resultWinner.innerText = player1.username + resultWinnerText; + else + resultWinner.innerText = player2.username + resultWinnerText; + resultWinner.classList.toggle("hidden"); + resultsDiv.classList.toggle("hidden"); + showGameOverScreen(); + } + resultWinner.classList.toggle("hidden"); + }, 1000); + if (result != "OVER") { + setTimeout(() => { + if (cheaterAbilities) + cheaterButton.style.display = "none"; + else if (godthingsAbilities) + godthingsButton.style.display = "none"; + gameDiv.classList.toggle("hidden"); + resultsDiv.classList.toggle("hidden"); + + resultDivs.forEach((resultDiv) => { + resultDiv.innerHTML = ""; + resultDiv.classList.remove("winner"); + }); + + resultText.innerText = ""; + resultWinner.classList.toggle("hidden"); + resultsDiv.classList.toggle("show-winner"); + + choiceButtons.forEach(btn => { + btn.disabled = false; + }); + }, 3000); + } +} + +function showGameOverScreen() { + var winnerText = (player1.score == 3) ? player1.username : player2.username; + document.getElementById('winnerText').innerText = selectedLanguage === 'tr' ? winnerText + " kazandı" : selectedLanguage === 'hi' ? winnerText + " जीता" : selectedLanguage === 'pt' ? winnerText + " ganhou" : winnerText + " win"; + document.getElementById('gameOverScreen').style.backgroundColor = 'rgba(11, 22, 8, 0.8)'; + document.getElementById('gameOverScreen').style.display = 'block'; +} + +document.getElementById('ponggamebtn').addEventListener('click', searchOpponent); + +checkbox.addEventListener('change', function() { + // Checkbox'un durumuna göre etiketin innerHTML değerini değiştirme + if (checkbox.checked) { + gameMode = "Abilities"; + abilityStatus = true; + if (selectedLanguage === 'tr') + selectedGameModeLabel.innerHTML = "Yetenekler"; + else if (selectedLanguage === 'hi') + selectedGameModeLabel.innerHTML = "क्षमताएँ"; + else if (selectedLanguage === 'pt') + selectedGameModeLabel.innerHTML = "Habilidades"; + else + selectedGameModeLabel.innerHTML = "Abilities"; + } else { + gameMode = "Vanilla"; + abilityStatus = false; + if (selectedLanguage === 'tr') + selectedGameModeLabel.innerHTML = "Vanilya"; + else if (selectedLanguage === 'hi') + selectedGameModeLabel.innerHTML = "वैनिला"; + else if (selectedLanguage === 'pt') + selectedGameModeLabel.innerHTML = "Baunilha"; + else + selectedGameModeLabel.innerHTML = "Vanilla"; + } +}); + +const gameModeSelect = document.getElementById("gameModeSelect"); + +gameModeSelect.addEventListener("mouseenter", function() { + document.querySelector(".game-mode-info").style.display = "block"; +}); + +gameModeSelect.addEventListener("mouseleave", function() { + document.querySelector(".game-mode-info").style.display = "none"; +}); +// Show/Hide Rules + +document.getElementById('exitButton').addEventListener('click', exitGame); + +function exitGame() { + swapApp('/rps-game-find') +} } \ No newline at end of file diff --git a/indianpong/static/js/store.js b/indianpong/static/js/store.js index 96282370..549279fa 100644 --- a/indianpong/static/js/store.js +++ b/indianpong/static/js/store.js @@ -1,68 +1,68 @@ -function initializeStore() { - - const storeInfos = document.getElementsByClassName('store-info'); // .store-info'ya erişim - const smallWalletNames = document.getElementsByClassName('small-wallet-name'); - - for (let i = 0; i < smallWalletNames.length; i++) { - smallWalletNames[i].addEventListener('mouseover', () => { - storeInfos[i].style.visibility = 'visible'; - }); - - smallWalletNames[i].addEventListener('mouseout', () => { - storeInfos[i].style.visibility = 'hidden'; - }); - } -} - -function showToast(content, status, iconClass) { - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - - const toast = new bootstrap.Toast(liveToast); - toast.show(); - - } - - function submitStoreItemForm(username, itemName, formId, price) { - const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); - const lang = cookie ? cookie.split('=')[1] : 'en'; - const form = document.getElementById('store_item_form' + formId); - const formData = new FormData(form); - var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - fetch(`/store/${username}/`, { - method: form.method, - body: formData, - headers: { - 'X-CSRFToken': csrftoken - } - }) - .then(response => response.text()) - .then(data => { - // hide the item after it is bought - const productCard = document.getElementById('product-card-' + formId); - productCard.style.display = 'none'; - //update the wallet amount with price - const walletAmount = document.querySelector('.wallet-amount'); - walletAmount.textContent = (parseInt(walletAmount.textContent) - price) + 'N₩'; - document.body.innerHTML = data; - if (lang === 'tr') - showToast(`${itemName} öğesini başarıyla satın aldın!`, `text-bg-success`, `bi bi-shop`); - else if (lang === 'hi') - showToast(`आपने ${itemName} आइटम सफलतापूर्वक खरीद लिया है!`, `text-bg-success`, `bi bi-shop`); - else if (lang === 'pt') - showToast(`Você comprou com sucesso o item ${itemName}!`, `text-bg-success`, `bi bi-shop`); - else - showToast(`You have successfully bought ${itemName} item!`, `text-bg-success`, `bi bi-shop`); - }) - .catch((error) => { - console.error('Error:', error); - }); +function initializeStore() { + + const storeInfos = document.getElementsByClassName('store-info'); // .store-info'ya erişim + const smallWalletNames = document.getElementsByClassName('small-wallet-name'); + + for (let i = 0; i < smallWalletNames.length; i++) { + smallWalletNames[i].addEventListener('mouseover', () => { + storeInfos[i].style.visibility = 'visible'; + }); + + smallWalletNames[i].addEventListener('mouseout', () => { + storeInfos[i].style.visibility = 'hidden'; + }); + } +} + +function showToast(content, status, iconClass) { + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + + const toast = new bootstrap.Toast(liveToast); + toast.show(); + + } + + function submitStoreItemForm(username, itemName, formId, price) { + const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); + const lang = cookie ? cookie.split('=')[1] : 'en'; + const form = document.getElementById('store_item_form' + formId); + const formData = new FormData(form); + var csrftoken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + fetch(`/store/${username}/`, { + method: form.method, + body: formData, + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(response => response.text()) + .then(data => { + // hide the item after it is bought + const productCard = document.getElementById('product-card-' + formId); + productCard.style.display = 'none'; + //update the wallet amount with price + const walletAmount = document.querySelector('.wallet-amount'); + walletAmount.textContent = (parseInt(walletAmount.textContent) - price) + 'N₩'; + document.body.innerHTML = data; + if (lang === 'tr') + showToast(`${itemName} öğesini başarıyla satın aldın!`, `text-bg-success`, `bi bi-shop`); + else if (lang === 'hi') + showToast(`आपने ${itemName} आइटम सफलतापूर्वक खरीद लिया है!`, `text-bg-success`, `bi bi-shop`); + else if (lang === 'pt') + showToast(`Você comprou com sucesso o item ${itemName}!`, `text-bg-success`, `bi bi-shop`); + else + showToast(`You have successfully bought ${itemName} item!`, `text-bg-success`, `bi bi-shop`); + }) + .catch((error) => { + console.error('Error:', error); + }); } \ No newline at end of file diff --git a/indianpong/static/js/tournament-room.js b/indianpong/static/js/tournament-room.js index 71d84c75..1234a475 100644 --- a/indianpong/static/js/tournament-room.js +++ b/indianpong/static/js/tournament-room.js @@ -1,144 +1,144 @@ -export function showToast(content, status, iconClass) { - if (!content || !status || !iconClass) - return; - - const liveToast = document.getElementById('liveToast'); - var toastContent = document.querySelector('#liveToast .fw-semibold'); - var toastIcon = document.querySelector('.toast-body .i-class i'); - - toastIcon.className = iconClass; - liveToast.classList.remove('text-bg-danger'); - liveToast.className = 'toast'; - liveToast.classList.add(status); - - toastContent.textContent = content; - const toast = new bootstrap.Toast(liveToast); - toast.show(); - setTimeout(function() { - toast.hide(); - }, 8000); - } - -export function displaySectionGame(sectionId) { - if (!sectionId) - return; - var sections = ["game-bracket-section", "game-room-section"]; - var buttons = ["checkbracket", "gameroombracket"]; - - var button = document.getElementById(buttons[1]); - var button2 = document.getElementById(buttons[0]); - for (var i = 0; i < sections.length; i++) { - var section = document.getElementById(sections[i]); - if (sections[i] === sectionId) { - section.style.display = 'block'; - if (sectionId === "game-bracket-section") { - button.style.display = 'inline'; - button2.style.display = 'none'; - } - else { - button.style.display = 'none'; - button2.style.display = 'inline'; - } - } else { - section.style.display = 'none'; - } - } -} - -export function joinTournament(tournamentId) { - if (!tournamentId) - return; - const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - const formData = new FormData(); - - - - formData.append('join_tournament', 'true'); - - fetch(`/tournament-room/${tournamentId}`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrfToken - }, - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - const error = document.querySelector('.container-top').dataset.error; - const sucess = document.querySelector('.container-top').dataset.sucess; - if (error) - showToast(error, 'text-bg-danger', 'bi bi-x'); - else if (sucess) - showToast(sucess, 'text-bg-success', 'bi bi-check'); - }) - .catch(error => { - console.error('Error joining tournament:', error); - }); -} - -export function startTournament(tournamentId) { - if (!tournamentId) - return; - const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - const formData = new FormData(); - - formData.append('start_tournament', 'true'); - - fetch(`/tournament-room/${tournamentId}`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrfToken - }, - }) - .then(response => response.text()) - .then(data => { - document.body.innerHTML = data; - const error = document.querySelector('.container-top').dataset.error; - const sucess = document.querySelector('.container-top').dataset.sucess; - if (error) - showToast(error, 'text-bg-danger', 'bi bi-x'); - else if (sucess) - showToast(sucess, 'text-bg-success', 'bi bi-check'); - }) - .catch(error => { - console.error('Error starting tournament:', error); - }); -} - -export function leaveTournament(tournamentId) { - if (!tournamentId) - return; - const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); - const lang = cookie ? cookie.split('=')[1] : 'en'; - const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; - const formData = new FormData(); - formData.append('leave_tournament', 'true'); - - fetch(`/tournament-room/${tournamentId}`, { - method: 'POST', - body: formData, - headers: { - 'X-CSRFToken': csrfToken - }, - }) - .then(response => response.text()) - .then(data => { - if (lang === 'tr') - showToast('Turnuvadan ayrıldınız.', 'text-bg-danger', 'bi bi-check'); - else if (lang === 'hi') - showToast('आपने टूर्नामेंट छोड़ दिया है।', 'text-bg-danger', 'bi bi-check'); - else if (lang === 'pt') - showToast('Você saiu do torneio.', 'text-bg-danger', 'bi bi-check'); - else - showToast('You have left the tournament.', 'text-bg-danger', 'bi bi-check'); - - setTimeout(function() { - swapApp('/tournament-room-list'); - }, 1000); - }) - .catch(error => { - console.error('Error leaving tournament:', error); - }); +export function showToast(content, status, iconClass) { + if (!content || !status || !iconClass) + return; + + const liveToast = document.getElementById('liveToast'); + var toastContent = document.querySelector('#liveToast .fw-semibold'); + var toastIcon = document.querySelector('.toast-body .i-class i'); + + toastIcon.className = iconClass; + liveToast.classList.remove('text-bg-danger'); + liveToast.className = 'toast'; + liveToast.classList.add(status); + + toastContent.textContent = content; + const toast = new bootstrap.Toast(liveToast); + toast.show(); + setTimeout(function() { + toast.hide(); + }, 8000); + } + +export function displaySectionGame(sectionId) { + if (!sectionId) + return; + var sections = ["game-bracket-section", "game-room-section"]; + var buttons = ["checkbracket", "gameroombracket"]; + + var button = document.getElementById(buttons[1]); + var button2 = document.getElementById(buttons[0]); + for (var i = 0; i < sections.length; i++) { + var section = document.getElementById(sections[i]); + if (sections[i] === sectionId) { + section.style.display = 'block'; + if (sectionId === "game-bracket-section") { + button.style.display = 'inline'; + button2.style.display = 'none'; + } + else { + button.style.display = 'none'; + button2.style.display = 'inline'; + } + } else { + section.style.display = 'none'; + } + } +} + +export function joinTournament(tournamentId) { + if (!tournamentId) + return; + const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + const formData = new FormData(); + + + + formData.append('join_tournament', 'true'); + + fetch(`/tournament-room/${tournamentId}`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrfToken + }, + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + const error = document.querySelector('.container-top').dataset.error; + const sucess = document.querySelector('.container-top').dataset.sucess; + if (error) + showToast(error, 'text-bg-danger', 'bi bi-x'); + else if (sucess) + showToast(sucess, 'text-bg-success', 'bi bi-check'); + }) + .catch(error => { + console.error('Error joining tournament:', error); + }); +} + +export function startTournament(tournamentId) { + if (!tournamentId) + return; + const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + const formData = new FormData(); + + formData.append('start_tournament', 'true'); + + fetch(`/tournament-room/${tournamentId}`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrfToken + }, + }) + .then(response => response.text()) + .then(data => { + document.body.innerHTML = data; + const error = document.querySelector('.container-top').dataset.error; + const sucess = document.querySelector('.container-top').dataset.sucess; + if (error) + showToast(error, 'text-bg-danger', 'bi bi-x'); + else if (sucess) + showToast(sucess, 'text-bg-success', 'bi bi-check'); + }) + .catch(error => { + console.error('Error starting tournament:', error); + }); +} + +export function leaveTournament(tournamentId) { + if (!tournamentId) + return; + const cookie = document.cookie.split('; ').find(row => row.startsWith('selectedLanguage=')); + const lang = cookie ? cookie.split('=')[1] : 'en'; + const csrfToken = document.cookie.split('; ').find(row => row.startsWith('csrftoken')).split('=')[1]; + const formData = new FormData(); + formData.append('leave_tournament', 'true'); + + fetch(`/tournament-room/${tournamentId}`, { + method: 'POST', + body: formData, + headers: { + 'X-CSRFToken': csrfToken + }, + }) + .then(response => response.text()) + .then(data => { + if (lang === 'tr') + showToast('Turnuvadan ayrıldınız.', 'text-bg-danger', 'bi bi-check'); + else if (lang === 'hi') + showToast('आपने टूर्नामेंट छोड़ दिया है।', 'text-bg-danger', 'bi bi-check'); + else if (lang === 'pt') + showToast('Você saiu do torneio.', 'text-bg-danger', 'bi bi-check'); + else + showToast('You have left the tournament.', 'text-bg-danger', 'bi bi-check'); + + setTimeout(function() { + swapApp('/tournament-room-list'); + }, 1000); + }) + .catch(error => { + console.error('Error leaving tournament:', error); + }); } \ No newline at end of file