|
@ -3,23 +3,22 @@ |
|
|
id: number; |
|
|
id: number; |
|
|
author: string; |
|
|
author: string; |
|
|
text: string; |
|
|
text: string; |
|
|
} |
|
|
} |
|
|
import { createEventDispatcher, onDestroy, onMount } from "svelte"; |
|
|
import { createEventDispatcher, onDestroy, onMount } from "svelte"; |
|
|
import { store, API_URL } from "../Auth"; |
|
|
import { store, API_URL } from "../Auth"; |
|
|
import { socket } from "../socket" |
|
|
import { socket } from "../socket"; |
|
|
import type { ChannelsType } from "./Channels.svelte"; |
|
|
import type { ChannelsType } from "./Channels.svelte"; |
|
|
import type User from "./Profile.svelte"; |
|
|
import type User from "./Profile.svelte"; |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<script lang="ts"> |
|
|
<script lang="ts"> |
|
|
|
|
|
|
|
|
let blockedUsers: Array<User> = []; |
|
|
let blockedUsers: Array<User> = []; |
|
|
let chatMembers: Array<User> = []; |
|
|
let chatMembers: Array<User> = []; |
|
|
let chatMessages: Array<chatMessagesType> = []; |
|
|
let chatMessages: Array<chatMessagesType> = []; |
|
|
export let channel: ChannelsType; |
|
|
export let channel: ChannelsType; |
|
|
let newText = ""; |
|
|
let newText = ""; |
|
|
onMount(async () => { |
|
|
onMount(async () => { |
|
|
let res = await fetch(API_URL + "/users/" + $store.ftId + "/blocked", { |
|
|
let res = await fetch(API_URL + "/users/block/" + $store.ftId, { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
@ -42,11 +41,13 @@ import type User from "./Profile.svelte"; |
|
|
|
|
|
|
|
|
const sendMessage = () => { |
|
|
const sendMessage = () => { |
|
|
if (newText !== "") { |
|
|
if (newText !== "") { |
|
|
|
|
|
/* |
|
|
const newMessage = { |
|
|
const newMessage = { |
|
|
id: chatMessages.length + 1, |
|
|
id: chatMessages.length + 1, |
|
|
author: $store.username, |
|
|
author: $store.username, |
|
|
text: newText, |
|
|
text: newText, |
|
|
}; |
|
|
}; |
|
|
|
|
|
*/ |
|
|
chatMessages = [...chatMessages.slice(-5 + 1)]; |
|
|
chatMessages = [...chatMessages.slice(-5 + 1)]; |
|
|
socket.emit("addMessage", channel.id, $store.ftId, newText); |
|
|
socket.emit("addMessage", channel.id, $store.ftId, newText); |
|
|
newText = ""; |
|
|
newText = ""; |
|
@ -83,111 +84,154 @@ import type User from "./Profile.svelte"; |
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
const blockUser = async (username: string) => { |
|
|
const blockUser = async (username: string) => { |
|
|
const res1 = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
let response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
|
const data1 = await res1.json(); |
|
|
if (response.ok) { |
|
|
const res2 = await fetch(API_URL + "/users/block/" + data1.ftId, { |
|
|
const target = await response.json(); |
|
|
|
|
|
response = await fetch(API_URL + "/users/" + target.ftId + "/block", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
method: "POST", |
|
|
method: "POST", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
|
|
|
headers: { |
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
|
|
|
|
body: JSON.stringify({ id: target.ftId }), |
|
|
}); |
|
|
}); |
|
|
if (res2.ok) { |
|
|
|
|
|
alert("User blocked"); |
|
|
|
|
|
} else { |
|
|
|
|
|
alert("Failed to block user"); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
if (response.ok) alert("User blocked"); |
|
|
|
|
|
else alert("Failed to block user"); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
const unblockUser = async (username: string) => { |
|
|
const unblockUser = async (username: string) => { |
|
|
const res1 = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
let response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
|
const data1 = await res1.json(); |
|
|
if (response.ok) { |
|
|
const res2 = await fetch(API_URL + "/users/unblock/" + data1.ftId, { |
|
|
const target = await response.json(); |
|
|
|
|
|
response = await fetch(API_URL + "/users/" + target.ftId + "/block", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
method: "DELETE", |
|
|
method: "DELETE", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
|
|
|
headers: { |
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
|
|
|
|
body: JSON.stringify({ id: target.ftId }), |
|
|
}); |
|
|
}); |
|
|
if (res2.ok) { |
|
|
|
|
|
alert("User unblocked"); |
|
|
|
|
|
} else { |
|
|
|
|
|
alert("Failed to unblock user"); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
if (response.ok) alert("User blocked"); |
|
|
|
|
|
else alert("Failed to block user"); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
const banUser = async (username: string) => { |
|
|
const banUser = async (username: string) => { |
|
|
const prompt = window.prompt("Enter ban duration in seconds"); |
|
|
let response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
const res1 = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
|
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
|
const data1 = await res1.json(); |
|
|
if (response.ok) { |
|
|
const res2 = await fetch(API_URL + "/channels/" + data1.ftId + "/ban", { |
|
|
const target = await response.json(); |
|
|
|
|
|
response = await fetch(API_URL + "/channels/" + channel.id + "/ban", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
method: "POST", |
|
|
method: "POST", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
|
|
|
headers: { |
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
|
|
|
|
body: JSON.stringify({ id: target.ftId }), |
|
|
}); |
|
|
}); |
|
|
if (res2.ok) { |
|
|
socket.emit("kickUser", channel.id, $store.ftId, target.ftId); |
|
|
socket.emit("kickUser", channel.id, $store.ftId, data1.ftId); |
|
|
} |
|
|
|
|
|
if (response.ok) { |
|
|
alert("User banned"); |
|
|
alert("User banned"); |
|
|
} else { |
|
|
} else alert("Failed to ban user"); |
|
|
alert("Failed to ban user"); |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
|
|
|
const unbanUser = async (username: string) => { |
|
|
|
|
|
let response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
|
|
|
credentials: "include", |
|
|
|
|
|
mode: "cors", |
|
|
|
|
|
}); |
|
|
|
|
|
if (response.ok) { |
|
|
|
|
|
const target = await response.json(); |
|
|
|
|
|
response = await fetch(API_URL + "/channels/" + channel.id + "/ban", { |
|
|
|
|
|
credentials: "include", |
|
|
|
|
|
method: "DELETE", |
|
|
|
|
|
mode: "cors", |
|
|
|
|
|
headers: { |
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
|
|
|
|
body: JSON.stringify({ id: target.ftId }), |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
if (response.ok) alert("User unbanned"); |
|
|
|
|
|
else alert("Failed to unban user"); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
const kickUser = async (username: string) => { |
|
|
const kickUser = async (username: string) => { |
|
|
const res = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
const response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
|
const kickedUser = await res.json(); |
|
|
if (response.ok) { |
|
|
socket.emit("kickUser", channel.id, $store.ftId, kickedUser.ftId); |
|
|
const target = await response.json(); |
|
|
|
|
|
socket.emit("kickUser", channel.id, $store.ftId, target.ftId); |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
const muteUser = async (username: string) => { |
|
|
const muteUser = async (username: string) => { |
|
|
const prompt = window.prompt("Enter mute duration in seconds"); |
|
|
const prompt = window.prompt("Enter mute duration in seconds"); |
|
|
const res1 = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
let response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
|
const data1 = await res1.json(); |
|
|
const target = await response.json(); |
|
|
const res2 = await fetch(API_URL + "/channels/" + data1.ftId + "/mute", { |
|
|
if (response.ok) { |
|
|
|
|
|
response = await fetch(API_URL + "/channels/" + channel.id + "/mute", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
method: "POST", |
|
|
method: "POST", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
|
|
|
headers: { |
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
|
|
|
|
body: JSON.stringify({ data: [target.ftId, +prompt] }), |
|
|
}); |
|
|
}); |
|
|
if (res2.ok) { |
|
|
|
|
|
alert("User muted"); |
|
|
|
|
|
} else { |
|
|
|
|
|
alert("Failed to mute user"); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
if (response.ok) alert("User muted"); |
|
|
|
|
|
else alert("Failed to mute user"); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
const adminUser = async (username: string) => { |
|
|
const adminUser = async (username: string) => { |
|
|
const res1 = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
let response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
|
const data1 = await res1.json(); |
|
|
if (response.ok) { |
|
|
const res2 = await fetch(API_URL + "/channels/" + data1.ftId + "/admin", { |
|
|
const target = await response.json(); |
|
|
|
|
|
response = await fetch(API_URL + "/channels/" + channel.id + "/admin", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
method: "POST", |
|
|
method: "POST", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
|
|
|
headers: { |
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
|
|
|
|
body: JSON.stringify({ id: target.ftId }), |
|
|
}); |
|
|
}); |
|
|
if (res2.ok) { |
|
|
} |
|
|
|
|
|
if (response.ok) { |
|
|
alert("User admined"); |
|
|
alert("User admined"); |
|
|
} else { |
|
|
} else { |
|
|
alert("Failed to admin user"); |
|
|
alert("Failed to admin user"); |
|
@ -197,46 +241,51 @@ import type User from "./Profile.svelte"; |
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
|
|
|
|
|
|
const removeAdminUser = async (username: string) => { |
|
|
const removeAdminUser = async (username: string) => { |
|
|
const res1 = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
let response = await fetch(API_URL + "/users/" + username + "/byname", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
}); |
|
|
}); |
|
|
const data1 = await res1.json(); |
|
|
if (response.ok) { |
|
|
const res2 = await fetch(API_URL + "/channels/" + data1.ftId + "/admin", { |
|
|
const target = await response.json(); |
|
|
|
|
|
response = await fetch(API_URL + "/channels/" + channel.id + "/admin", { |
|
|
credentials: "include", |
|
|
credentials: "include", |
|
|
method: "DELETE", |
|
|
method: "DELETE", |
|
|
mode: "cors", |
|
|
mode: "cors", |
|
|
|
|
|
headers: { |
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
}, |
|
|
|
|
|
body: JSON.stringify({ id: target.ftId }), |
|
|
}); |
|
|
}); |
|
|
if (res2.ok) { |
|
|
} |
|
|
alert("User admin removed"); |
|
|
if (response.ok) { |
|
|
|
|
|
alert("User admined"); |
|
|
} else { |
|
|
} else { |
|
|
alert("Failed to remove admin user"); |
|
|
alert("Failed to admin user"); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------/ |
|
|
//--------------------------------------------------------------------------------/ |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<div class="overlay"> |
|
|
<div class="overlay" > |
|
|
|
|
|
<div class="chat" on:click|stopPropagation on:keydown|stopPropagation> |
|
|
<div class="chat" on:click|stopPropagation on:keydown|stopPropagation> |
|
|
<div class="messages" > |
|
|
<div class="messages"> |
|
|
{ #each chatMessages as message } |
|
|
{#each chatMessages as message} |
|
|
<p class="message" > |
|
|
<p class="message"> |
|
|
{ #if !blockedUsers.filter((user) => user.username == message.author).length } |
|
|
{#if !blockedUsers.filter((user) => user.username == message.author).length} |
|
|
<span |
|
|
<span |
|
|
class="message-name" |
|
|
class="message-name" |
|
|
on:click = {() => openProfile(message.author)} |
|
|
on:click={() => openProfile(message.author)} |
|
|
on:keydown = {() => openProfile(message.author)} |
|
|
on:keydown={() => openProfile(message.author)} |
|
|
style = "cursor: pointer;" |
|
|
style="cursor: pointer;" |
|
|
> |
|
|
> |
|
|
{ message.author } |
|
|
{message.author} |
|
|
</span>: {message.text} |
|
|
</span>: {message.text} |
|
|
{/if} |
|
|
{/if} |
|
|
</p> |
|
|
</p> |
|
|
{/each} |
|
|
{/each} |
|
|
</div> |
|
|
</div> |
|
|
{ #if showProfileMenu } |
|
|
{#if showProfileMenu} |
|
|
<div |
|
|
<div |
|
|
class="profile-menu" |
|
|
class="profile-menu" |
|
|
on:click|stopPropagation |
|
|
on:click|stopPropagation |
|
@ -244,52 +293,72 @@ import type User from "./Profile.svelte"; |
|
|
> |
|
|
> |
|
|
<ul> |
|
|
<ul> |
|
|
<li> |
|
|
<li> |
|
|
<button on:click = {() => dispatch("send-message", selectedUser)}> Send Message </button> |
|
|
<button on:click={() => dispatch("send-message", selectedUser)}> |
|
|
|
|
|
Send Message |
|
|
|
|
|
</button> |
|
|
</li> |
|
|
</li> |
|
|
<li> |
|
|
<li> |
|
|
<button on:click = {() => dispatch("view-profile", selectedUser)}> View Profile </button> |
|
|
<button on:click={() => dispatch("view-profile", selectedUser)}> |
|
|
|
|
|
View Profile |
|
|
|
|
|
</button> |
|
|
</li> |
|
|
</li> |
|
|
<li> |
|
|
<li> |
|
|
<button on:click = {() => dispatch("add-friend", selectedUser)}> Add Friend </button> |
|
|
<button on:click={() => dispatch("add-friend", selectedUser)}> |
|
|
|
|
|
Add Friend |
|
|
|
|
|
</button> |
|
|
</li> |
|
|
</li> |
|
|
<li> |
|
|
<li> |
|
|
<button on:click = {() => dispatch("invite-to-game", selectedUser)}> Invite to Game </button> |
|
|
<button on:click={() => dispatch("invite-to-game", selectedUser)}> |
|
|
|
|
|
Invite to Game |
|
|
|
|
|
</button> |
|
|
</li> |
|
|
</li> |
|
|
<li> |
|
|
<li> |
|
|
{ #if !blockedUsers.filter((user) => user.username = selectedUser).length } |
|
|
{#if !blockedUsers.filter((user) => (user.username = selectedUser)).length} |
|
|
<button on:click = {() => blockUser(selectedUser)}> Block User </button> |
|
|
<button on:click={() => blockUser(selectedUser)}> |
|
|
{:else } |
|
|
Block User |
|
|
<button on:click = {() => unblockUser(selectedUser)}> Unblock User </button> |
|
|
</button> |
|
|
|
|
|
{:else} |
|
|
|
|
|
<button on:click={() => unblockUser(selectedUser)}> |
|
|
|
|
|
Unblock User |
|
|
|
|
|
</button> |
|
|
{/if} |
|
|
{/if} |
|
|
</li> |
|
|
</li> |
|
|
<li> <button on:click = { closeProfileMenu } > Close </button></li > |
|
|
<li><button on:click={closeProfileMenu}> Close </button></li> |
|
|
</ul> |
|
|
</ul> |
|
|
</div> |
|
|
</div> |
|
|
{/if} |
|
|
{/if} |
|
|
<form on:submit|preventDefault={ sendMessage }> |
|
|
<form on:submit|preventDefault={sendMessage}> |
|
|
<input type="text" placeholder = "Type a message..." bind:value={ newText } /> |
|
|
<input type="text" placeholder="Type a message..." bind:value={newText} /> |
|
|
<button> |
|
|
<button> |
|
|
<img src="img/send.png" alt = "send" /> |
|
|
<img src="img/send.png" alt="send" /> |
|
|
</button> |
|
|
</button> |
|
|
</form> |
|
|
</form> |
|
|
<button on:click|stopPropagation={ toggleChatMembers } on:keydown|stopPropagation > Chat Members </button> |
|
|
<button |
|
|
{ #if showChatMembers } |
|
|
on:click|stopPropagation={toggleChatMembers} |
|
|
|
|
|
on:keydown|stopPropagation |
|
|
|
|
|
> |
|
|
|
|
|
Chat Members |
|
|
|
|
|
</button> |
|
|
|
|
|
{#if showChatMembers} |
|
|
<div |
|
|
<div |
|
|
class="chatMembers" |
|
|
class="chatMembers" |
|
|
on:click|stopPropagation |
|
|
on:click|stopPropagation |
|
|
on:keydown|stopPropagation |
|
|
on:keydown|stopPropagation |
|
|
> |
|
|
/> |
|
|
</div> |
|
|
|
|
|
<ul> |
|
|
<ul> |
|
|
{ #each chatMembers as member } |
|
|
{#each chatMembers as member} |
|
|
<li> |
|
|
<li> |
|
|
<p> |
|
|
<p> |
|
|
{ member.username } |
|
|
{member.username} |
|
|
<button on:click = {() => banUser(member.username)}> ban </button> |
|
|
<button on:click={() => banUser(member.username)}> ban </button> |
|
|
<button on:click = {() => kickUser(member.username)}> kick </button> |
|
|
<button on:click={() => kickUser(member.username)}> kick </button> |
|
|
<button on:click = {() => muteUser(member.username)}> mute </button> |
|
|
<button on:click={() => muteUser(member.username)}> mute </button> |
|
|
<button on:click = {() => adminUser(member.username)}> promote </button> |
|
|
<button on:click={() => adminUser(member.username)}> |
|
|
<button on:click = {() => removeAdminUser(member.username)}> demote </button> |
|
|
promote |
|
|
|
|
|
</button> |
|
|
|
|
|
<button on:click={() => removeAdminUser(member.username)}> |
|
|
|
|
|
demote |
|
|
|
|
|
</button> |
|
|
</p> |
|
|
</p> |
|
|
</li> |
|
|
</li> |
|
|
{/each} |
|
|
{/each} |
|
@ -351,7 +420,7 @@ import type User from "./Profile.svelte"; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
button { |
|
|
button { |
|
|
background-color: #6B8E23; |
|
|
background-color: #6b8e23; |
|
|
color: #ffffff; |
|
|
color: #ffffff; |
|
|
border: none; |
|
|
border: none; |
|
|
border-radius: 5px; |
|
|
border-radius: 5px; |
|
|