tentative de merge
This commit is contained in:
		| @ -1,19 +1,18 @@ | ||||
| #app .account | ||||
| #app #main .account | ||||
| { | ||||
| 	background-color: red; | ||||
| } | ||||
|  | ||||
| #app .account, #app .profile | ||||
| #app #main | ||||
| { | ||||
| 	width: 60%; | ||||
| 	display: flex; | ||||
| 	margin-left: auto; | ||||
| 	margin-right: auto; | ||||
| 	flex-direction: column; | ||||
| 	flex-wrap: wrap; | ||||
| } | ||||
|  | ||||
| #app .profile | ||||
| #app #main .profile | ||||
| { | ||||
| 	background-color: green; | ||||
| } | ||||
							
								
								
									
										19
									
								
								frontend/static/js/api/MyProfile.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								frontend/static/js/api/MyProfile.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| import { Profile } from "./profile.js"; | ||||
|  | ||||
| class MyProfile extends Profile | ||||
| { | ||||
| 	async change_avatar(form_data) | ||||
| 	{ | ||||
| 		let response = await this.client._patch_file(`/api/profiles/me`, form_data); | ||||
| 		let response_data = await response.json() | ||||
|  | ||||
| 		return response_data; | ||||
| 	} | ||||
|  | ||||
| 	async init() | ||||
| 	{ | ||||
| 		super.init("me"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| export {MyProfile} | ||||
| @ -1,7 +1,15 @@ | ||||
| import { Client } from "./client.js"; | ||||
|  | ||||
| class Account | ||||
| { | ||||
| 	/** | ||||
| 	 * @param  {Client} client | ||||
| 	 */ | ||||
| 	constructor (client) | ||||
| 	{ | ||||
| 		/** | ||||
| 		 * @type  {Client} client | ||||
| 		 */ | ||||
| 		this.client = client; | ||||
| 	} | ||||
| 	 | ||||
| @ -28,7 +36,6 @@ class Account | ||||
| 			this.client._logged = false; | ||||
| 			return null;			 | ||||
| 		} | ||||
| 		console.log(response_data) | ||||
| 		if (response_data == "user deleted") | ||||
| 			this.client._logged = false; | ||||
| 		return response_data; | ||||
| @ -55,7 +62,7 @@ class Account | ||||
|  | ||||
| 		if (JSON.stringify(response_data) == JSON.stringify({'detail': 'Authentication credentials were not provided.'})) | ||||
| 		{ | ||||
| 			this.client._logged = false; | ||||
| 			this.client._; | ||||
| 			return null; | ||||
| 		} | ||||
| 		return response_data; | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| import { Account } from "./account.js"; | ||||
| import { MatchMaking } from "./matchmaking.js"; | ||||
| import { Profile } from "./profile.js"; | ||||
| import { Profiles } from "./profiles.js"; | ||||
| import { Channels } from './chat/channels.js'; | ||||
| import { MyProfile } from "./MyProfile.js"; | ||||
|  | ||||
| function getCookie(name) | ||||
| { | ||||
| @ -94,15 +94,23 @@ class Client | ||||
|         return response; | ||||
|     } | ||||
|  | ||||
| 	async _update_logged(state) | ||||
| 	{ | ||||
| 		if (this.logged && state) | ||||
| 		{ | ||||
| 			this.me = new MyProfile(this); | ||||
| 			await this.me.init(); | ||||
| 		} | ||||
| 		this.logged = state; | ||||
| 	} | ||||
|  | ||||
| 	async login(username, password) | ||||
| 	{ | ||||
| 		let response = await this._post("/api/accounts/login", {username: username, password: password}) | ||||
| 		let data = await response.json(); | ||||
| 		if (data.id != undefined) | ||||
| 		{ | ||||
| 			this.me = new Profile(this) | ||||
| 			await this.me.init(data.id) | ||||
| 			this.logged = true; | ||||
| 			await this._update_logged(true); | ||||
| 			return null; | ||||
| 		} | ||||
| 		return data; | ||||
| @ -111,7 +119,7 @@ class Client | ||||
| 	async logout() | ||||
| 	{ | ||||
| 		await this._get("/api/accounts/logout"); | ||||
| 		this.logged = false; | ||||
| 		await this._update_logged(false); | ||||
| 	} | ||||
|  | ||||
| 	async _test_logged() | ||||
| @ -120,10 +128,7 @@ class Client | ||||
| 		let data = await response.json(); | ||||
|  | ||||
| 		if (data.id !== undefined) | ||||
| 		{ | ||||
| 			this.me = new Profile(this) | ||||
| 			await this.me.init(data.id) | ||||
| 		} | ||||
| 			await this._update_logged(true); | ||||
| 		return data.id !== undefined; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| import { client, navigateTo } from "../index.js" | ||||
| import { Client } from "./client.js"; | ||||
|  | ||||
| class MatchMaking | ||||
| { | ||||
| 	/** | ||||
| 	 * @param  {client} client | ||||
| 	 * @param  {Client} client | ||||
| 	 */ | ||||
| 	constructor(client) | ||||
| 	{ | ||||
|  | ||||
| @ -1,7 +1,15 @@ | ||||
| import { Client } from "./client.js"; | ||||
|  | ||||
| class Profile | ||||
| { | ||||
| 	/** | ||||
| 	 * @param  {Client} client | ||||
| 	 */ | ||||
| 	constructor (client, username = undefined, avatar_url = undefined, user_id = undefined) | ||||
| 	{ | ||||
| 		/** | ||||
| 		 * @type  {Client} client | ||||
| 		 */ | ||||
| 		this.client = client; | ||||
| 		this.username = username; | ||||
| 		this.avatar_url = avatar_url | ||||
| @ -13,23 +21,10 @@ class Profile | ||||
| 		let response = await this.client._get(`/api/profiles/${user_id}`); | ||||
| 		let response_data = await response.json(); | ||||
|  | ||||
| 		this.user_id = user_id; | ||||
| 		this.user_id = response.user_id; | ||||
| 		this.username = response_data.username; | ||||
| 		this.avatar_url = response_data.avatar_url; | ||||
| 	} | ||||
|  | ||||
| 	async change_avatar(form_data) | ||||
| 	{ | ||||
| 		let response = await this.client._patch_file(`/api/profiles/${this.user_id}`, form_data); | ||||
| 		let response_data = await response.json() | ||||
|  | ||||
| 		return response_data; | ||||
| 	} | ||||
|  | ||||
| 	async setData (data) | ||||
| 	{ | ||||
| 		 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| export {Profile} | ||||
| @ -2,8 +2,14 @@ import { Profile } from "./profile.js"; | ||||
|  | ||||
| class Profiles | ||||
| { | ||||
| 	/** | ||||
| 	 * @param  {Client} client | ||||
| 	 */ | ||||
| 	constructor (client) | ||||
| 	{ | ||||
| 		/** | ||||
| 		 * @type {Client} client | ||||
| 		 */ | ||||
| 		this.client = client | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -79,6 +79,7 @@ const router = async (uri) => { | ||||
|  | ||||
| 	lastView = view; | ||||
|  | ||||
|     await client.isAuthentificate(); | ||||
|     let content = await view.getHtml(); | ||||
|     if (content == null) | ||||
|         return 1; | ||||
|  | ||||
							
								
								
									
										18
									
								
								frontend/static/js/utils/formUtils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								frontend/static/js/utils/formUtils.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| function clear(property_name, elements_id) | ||||
| { | ||||
| 	elements_id.forEach(element_id => { | ||||
| 		let element = document.getElementById(element_id) | ||||
| 		element[property_name] = "" | ||||
| 	});	 | ||||
| } | ||||
|  | ||||
| function fill_errors(errors, property_name) | ||||
| { | ||||
| 	Object.keys(errors).forEach(error_field => | ||||
| 	{ | ||||
| 		let element = document.getElementById(error_field); | ||||
| 		element[property_name] = errors[error_field]; | ||||
| 	});	 | ||||
| } | ||||
|  | ||||
| export {fill_errors, clear} | ||||
| @ -1,4 +1,5 @@ | ||||
| import { client, navigateTo } from "../index.js"; | ||||
| import { clear, fill_errors } from "../utils/formUtils.js"; | ||||
| import AbstractAuthentificateView from "./AbstractAuthentifiedView.js"; | ||||
|  | ||||
| export default class extends AbstractAuthentificateView | ||||
| @ -10,63 +11,39 @@ export default class extends AbstractAuthentificateView | ||||
|  | ||||
|     async postInit() | ||||
|     { | ||||
|         if (this.fill() === null) | ||||
|             return; | ||||
|         document.getElementById("save-account-button").onclick = this.acccount_save; | ||||
|         document.getElementById("delete-account-button").onclick = this.account_delete_accounts; | ||||
|         document.getElementById("save-account-button").onclick = this.save_account; | ||||
|         document.getElementById("delete-account-button").onclick = this.delete_account; | ||||
|         document.getElementById("save-profile-button").onclick = this.save_profile; | ||||
|     } | ||||
|  | ||||
|     async fill() | ||||
|     async delete_account() | ||||
|     { | ||||
|         let data = await client.account.get(); | ||||
|      | ||||
|         if (data === null) | ||||
|         { | ||||
|             navigateTo("/login") | ||||
|             return; | ||||
|         } | ||||
|         document.getElementById("username").value = data.username; | ||||
|     } | ||||
|  | ||||
|     async delete_accounts() | ||||
|     { | ||||
|         let current_password = document.getElementById("current_password").value; | ||||
|         let current_password = document.getElementById("current_password-input").value; | ||||
|          | ||||
|         let response_data = await client.account.delete(current_password); | ||||
|  | ||||
|         if (response_data === null) | ||||
|         console.log(await client.isAuthentificate()) | ||||
|         if (response_data === null || response_data === "user deleted") | ||||
|         { | ||||
|             navigateTo("/login"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         ["delete", "current_password"].forEach(error_field => { | ||||
|             let error_display = document.getElementById(`error_${error_field}`); | ||||
|             if (error_display != null) | ||||
|                 error_display.innerHTML = ""; | ||||
|         }); | ||||
|  | ||||
|         if (response_data === "user deleted") | ||||
|         { | ||||
|             document.getElementById(`error_delete`).innerHTML = "OK"; | ||||
|             navigateTo("/login") | ||||
|             return; | ||||
|         clear("innerHTML", ["current_password-input"]) | ||||
|         fill_errors({"current_password-input": response_data["password"]}, "innerHTML") | ||||
|     } | ||||
|  | ||||
|         document.getElementById("error_current_password").innerHTML = response_data["password"] | ||||
|     } | ||||
|  | ||||
|     async save() | ||||
|     async save_account() | ||||
|     { | ||||
|         let username = document.getElementById("username").value; | ||||
|         let new_password = document.getElementById("new_password").value; | ||||
|         let current_password = document.getElementById("current_password").value; | ||||
|         let username = document.getElementById("username-input").value; | ||||
|         let new_password = document.getElementById("new_password-input").value; | ||||
|         let current_password = document.getElementById("current_password-input").value; | ||||
|      | ||||
|         let data = {}; | ||||
|      | ||||
|         data.username = username; | ||||
|         if (new_password.length != 0) | ||||
|             data.new_password = new_password; | ||||
|  | ||||
|         let response_data = await client.account.update(data, current_password); | ||||
|  | ||||
|         if (response_data === null) | ||||
| @ -74,58 +51,55 @@ export default class extends AbstractAuthentificateView | ||||
|             navigateTo("/login"); | ||||
|             return; | ||||
|         } | ||||
|         else if (response_data === "data has been alterate") | ||||
|         { | ||||
|             navigateTo("/me"); | ||||
|             return;  | ||||
|  | ||||
|         if (response_data === "data has been alterate") | ||||
|             response_data = {"save-account": "saved"} | ||||
|  | ||||
|         clear("innerHTML", ["username", "new_password", "current_password", "save-account", "delete-account"]) | ||||
|         fill_errors(response_data, "innerHTML") | ||||
|     } | ||||
|      | ||||
|         ["username", "new_password", "current_password"].forEach(error_field => { | ||||
|             let error_display = document.getElementById(`error_${error_field}`); | ||||
|             if (error_display != null) | ||||
|                 error_display.innerHTML = ""; | ||||
|         }); | ||||
|      | ||||
|         Object.keys(response_data).forEach(error_field => { | ||||
|             let error_display = document.getElementById(`error_${error_field}`); | ||||
|             if (error_display != null) | ||||
|                 error_display.innerHTML = response_data[error_field]; | ||||
|         }); | ||||
|         let avatar = document.getElementById("avatar"); | ||||
|     async save_profile() | ||||
|     { | ||||
|         let avatar = document.getElementById("avatar-input"); | ||||
|  | ||||
|         if (avatar.files[0] !== undefined) | ||||
|         { | ||||
|             let form_data = new FormData(); | ||||
|             form_data.append("file", avatar.files[0]); | ||||
|             await client.me.change_avatar(form_data) | ||||
|             await client.me.change_avatar(form_data); | ||||
|         } | ||||
|         document.getElementById("save-profile").innerHTML = "Saved"; | ||||
|     } | ||||
|  | ||||
|     async getHtml() | ||||
|     { | ||||
|         return ` | ||||
|             <link rel="stylesheet" href="static/css/me.css"> | ||||
|             <link rel="stylesheet" href="/static/css/me.css"> | ||||
| 			<h1>ME</h1> | ||||
|             <div id="main"> | ||||
|                 <div class="account"> | ||||
|                     <h3>Account</h3> | ||||
|                 <input type="text" placeholder="username" id="username"> | ||||
|                 <span id="error_username"></span> | ||||
|                 <input type=password placeholder="new password" id="new_password"> | ||||
|                 <span id="error_new_password"></span> | ||||
|                 <input type=password placeholder="current password" id="current_password"> | ||||
|                 <span id="error_current_password"></span> | ||||
|                     <input type="text" placeholder="username" id="username-input" text=${client.me.username}> | ||||
|                     <span id="username"></span> | ||||
|                     <input type=password placeholder="new_password" id="new_password-input"> | ||||
|                     <span id="new_password"></span> | ||||
|                     <input type=password placeholder="current_password" id="current_password-input"> | ||||
|                     <span id="current_password"></span> | ||||
|  | ||||
|                     <input type="button" value="Save Credentials" id="save-account-button"> | ||||
|                 <span id="error_save"></span> | ||||
|                     <span id="save-account"></span> | ||||
|                     <input type="button" value="Delete Account" id="delete-account-button"> | ||||
|                 <span id="error_delete"></span> | ||||
|                     <span id="delete-account"></span> | ||||
|                 </div> | ||||
|                 <div class="profile"> | ||||
|                     <h3>Profile</h3> | ||||
|                 <input type="file" id="avatar" accept="image/png, image/jpeg"> | ||||
|                     <input type="file" id="avatar-input" accept="image/png, image/jpeg"> | ||||
|                     <input type="button" value="Save profile" id="save-profile-button"> | ||||
|                 <span id="error_save"></span> | ||||
|                     <span id="save-profile"></span> | ||||
|                 </div> | ||||
|                 <a href="/logout" class="nav__link" data-link>Logout</a> | ||||
|             </div> | ||||
|         `; | ||||
|     } | ||||
| } | ||||
| @ -5,7 +5,7 @@ from django.conf.urls.static import static | ||||
| from . import viewsets | ||||
|  | ||||
| urlpatterns = [ | ||||
|     path("<int:pk>", viewsets.ProfileViewSet.as_view({'get': 'retrieve', 'patch': 'partial_update'}), name="profile_page"), | ||||
|     path("me", viewsets.MyProfileViewSet.as_view({'patch': 'partial_update', 'get': 'retrieve'}), name="my_profile_page"), | ||||
|     path("<int:pk>", viewsets.ProfileViewSet.as_view({'get': 'retrieve'}), name="profile_page"), | ||||
|     path("", viewsets.ProfileViewSet.as_view({'get': 'list'}), name="profiles_list"), | ||||
|     #path("me", viewsets.ProfileViewSet.as_view(), name="my_profile_page"), | ||||
| ] + static("/static/avatars/", document_root="./avatars") | ||||
| @ -17,9 +17,7 @@ class ProfileViewSet(viewsets.ModelViewSet): | ||||
|     permission_classes = (permissions.IsAuthenticatedOrReadOnly,) | ||||
|  | ||||
|     def retrieve(self, request: HttpRequest, pk=None): | ||||
|         if (not ProfileModel.objects.filter(pk=pk).exists()): | ||||
|             return Response({"detail": "Profile not found."}, status=status.HTTP_404_NOT_FOUND) | ||||
|         instance = ProfileModel.objects.get(pk=pk) | ||||
|         instance = self.get_object() | ||||
|         instance.avatar_url.name = instance.avatar_url.name[instance.avatar_url.name.find("static") - 1:] | ||||
|         return Response(self.serializer_class(instance).data, | ||||
|                         status=status.HTTP_200_OK) | ||||
| @ -33,13 +31,27 @@ class ProfileViewSet(viewsets.ModelViewSet): | ||||
|     def perform_create(self, serializer): | ||||
|         serializer.save(user=self.request.user) | ||||
|  | ||||
|     def perform_update(self, serializer): | ||||
|         if (not ProfileModel.objects.filter(pk=pk).exists()): | ||||
|             return Response({"detail": "Profile not found."}, status=status.HTTP_404_NOT_FOUND) | ||||
|         profile: ProfileModel = ProfileModel.objects.get(pk=self.request.user.pk) | ||||
| class MyProfileViewSet(viewsets.ModelViewSet): | ||||
|  | ||||
|     serializer_class = ProfileSerializer | ||||
|     queryset = ProfileModel.objects.all | ||||
|  | ||||
|     def get_object(self): | ||||
|         obj = self.queryset().get(pk=self.request.user.pk) | ||||
|         return obj | ||||
|  | ||||
|     def perform_update(self, serializer, pk=None): | ||||
|         profile: ProfileModel = self.get_object() | ||||
|         avatar = self.request.data.get("file", None) | ||||
|         if (avatar is not None): | ||||
|             if (profile.avatar_url.name != "./profiles/static/avatars/default.avif"): | ||||
|                 profile.avatar_url.storage.delete(profile.avatar_url.name) | ||||
|             profile.avatar_url = avatar | ||||
|         profile.save() | ||||
|      | ||||
|     def retrieve(self, request: HttpRequest, pk=None): | ||||
|         print("test") | ||||
|         instance: ProfileModel = self.get_object() | ||||
|         instance.avatar_url.name = instance.avatar_url.name[instance.avatar_url.name.find("static") - 1:] | ||||
|         return Response(self.serializer_class(instance).data, | ||||
|                         status=status.HTTP_200_OK) | ||||
		Reference in New Issue
	
	Block a user