first commit
commit
a16dda44db
|
@ -0,0 +1,42 @@
|
|||
import mysql.connector
|
||||
|
||||
def change_user_role():
|
||||
# Database connection
|
||||
conn = mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="",
|
||||
database="messaging_app"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Show all users
|
||||
cursor.execute("SELECT username FROM users")
|
||||
users = cursor.fetchall()
|
||||
print("Current users:")
|
||||
for user in users:
|
||||
print(user[0])
|
||||
|
||||
print("Roles available: mod, admin")
|
||||
# Get input from user
|
||||
username = input("Enter the username: ")
|
||||
role = input("Enter the role: ")
|
||||
|
||||
# Check if the user exists in the users table
|
||||
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
|
||||
user = cursor.fetchone()
|
||||
|
||||
if user:
|
||||
# Insert into admins table
|
||||
cursor.execute("INSERT INTO admins (username, role) VALUES (%s, %s)", (username, role))
|
||||
conn.commit()
|
||||
print("User role updated successfully.")
|
||||
else:
|
||||
print("User does not exist in the users table.")
|
||||
|
||||
# Close the connection
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
change_user_role()
|
|
@ -0,0 +1,16 @@
|
|||
import mysql.connector
|
||||
|
||||
|
||||
def connect_to_db():
|
||||
conn = mysql.connector.connect(
|
||||
host="localhost", user="root", password="", database="messaging_app"
|
||||
)
|
||||
return conn
|
||||
|
||||
conn = connect_to_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("DELETE FROM group_messages")
|
||||
conn.commit()
|
||||
|
||||
print("Deleted Messages")
|
|
@ -0,0 +1,16 @@
|
|||
import mysql.connector
|
||||
|
||||
|
||||
def connect_to_db():
|
||||
conn = mysql.connector.connect(
|
||||
host="localhost", user="root", password="", database="messaging_app"
|
||||
)
|
||||
return conn
|
||||
|
||||
conn = connect_to_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("DELETE FROM private_messages")
|
||||
conn.commit()
|
||||
|
||||
print("Deleted Messages")
|
|
@ -0,0 +1,34 @@
|
|||
import mysql.connector
|
||||
|
||||
|
||||
def connect_to_db():
|
||||
conn = mysql.connector.connect(
|
||||
host="localhost", user="root", password="", database="messaging_app"
|
||||
)
|
||||
return conn
|
||||
|
||||
|
||||
def flush_database():
|
||||
conn = connect_to_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
tables = [
|
||||
"group_messages",
|
||||
"private_messages",
|
||||
]
|
||||
|
||||
for table in tables:
|
||||
try:
|
||||
cursor.execute(f"TRUNCATE TABLE {table};")
|
||||
print(f"Flushed table: {table}")
|
||||
except mysql.connector.Error as err:
|
||||
print(f"Error flushing table {table}: {err}")
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
print("All tables flushed successfully!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
flush_database()
|
|
@ -0,0 +1,42 @@
|
|||
import mysql.connector
|
||||
|
||||
|
||||
def connect_to_db():
|
||||
conn = mysql.connector.connect(
|
||||
host="localhost", user="root", password="", database="messaging_app"
|
||||
)
|
||||
return conn
|
||||
|
||||
|
||||
def flush_database():
|
||||
conn = connect_to_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
cursor.execute("SET FOREIGN_KEY_CHECKS = 0;")
|
||||
|
||||
tables = [
|
||||
"group_messages",
|
||||
"private_messages",
|
||||
"users",
|
||||
"admins",
|
||||
]
|
||||
|
||||
for table in tables:
|
||||
cursor.execute(f"TRUNCATE TABLE {table};")
|
||||
print(f"Flushed table: {table}")
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
print(f"Error flushing tables: {err}")
|
||||
|
||||
finally:
|
||||
cursor.execute("SET FOREIGN_KEY_CHECKS = 1;")
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
print("All tables flushed successfully!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
flush_database()
|
|
@ -0,0 +1,63 @@
|
|||
import mysql.connector
|
||||
from mysql.connector import errorcode
|
||||
import json
|
||||
import os
|
||||
|
||||
# Correct the path to the JSON file
|
||||
json_path = os.path.join(os.path.dirname(__file__), '..', 'dbinfo.json')
|
||||
|
||||
try:
|
||||
with open(json_path, "r") as file:
|
||||
db_info = json.load(file)
|
||||
except FileNotFoundError:
|
||||
print(f"File not found: {json_path}")
|
||||
exit(1)
|
||||
except json.JSONDecodeError:
|
||||
print(f"Error decoding JSON from file: {json_path}")
|
||||
exit(1)
|
||||
|
||||
# Ensure the required keys are in the JSON
|
||||
required_keys = ["host", "user", "password"]
|
||||
for key in required_keys:
|
||||
if key not in db_info:
|
||||
print(f"Missing required key in JSON: {key}")
|
||||
exit(1)
|
||||
|
||||
config = {
|
||||
"host": db_info["host"],
|
||||
"user": db_info["user"],
|
||||
"password": db_info["password"],
|
||||
"database": "messaging_app"
|
||||
}
|
||||
|
||||
conn = None
|
||||
|
||||
try:
|
||||
# Connect to the database
|
||||
conn = mysql.connector.connect(**config)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create the admins table
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS admins (
|
||||
username VARCHAR(255) PRIMARY KEY,
|
||||
role ENUM('mod', 'admin') NOT NULL
|
||||
)
|
||||
''')
|
||||
|
||||
# Commit the changes
|
||||
conn.commit()
|
||||
print("Admins table created successfully.")
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
|
||||
print("Something is wrong with your user name or password")
|
||||
elif err.errno == errorcode.ER_BAD_DB_ERROR:
|
||||
print("Database does not exist")
|
||||
else:
|
||||
print(err)
|
||||
finally:
|
||||
# Close the connection
|
||||
if conn is not None and conn.is_connected():
|
||||
cursor.close()
|
||||
conn.close()
|
|
@ -0,0 +1,127 @@
|
|||
import mysql.connector
|
||||
import random
|
||||
import string
|
||||
|
||||
|
||||
def connect_to_db():
|
||||
conn = mysql.connector.connect(
|
||||
host="localhost", user="root", password="", database="messaging_app"
|
||||
)
|
||||
return conn
|
||||
|
||||
|
||||
def random_string(length=20):
|
||||
letters = string.ascii_letters + string.digits
|
||||
return "".join(random.choice(letters) for i in range(length))
|
||||
|
||||
|
||||
def create_tables(cursor):
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
password VARCHAR(255) NOT NULL
|
||||
)
|
||||
""")
|
||||
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS groups (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
group_name VARCHAR(255) NOT NULL,
|
||||
created_by INT NOT NULL,
|
||||
FOREIGN KEY (created_by) REFERENCES users(id)
|
||||
)
|
||||
""")
|
||||
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS group_messages (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
group_id INT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (group_id) REFERENCES groups(id)
|
||||
)
|
||||
""")
|
||||
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS private_messages (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
sender_id INT NOT NULL,
|
||||
receiver_id INT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
FOREIGN KEY (sender_id) REFERENCES users(id),
|
||||
FOREIGN KEY (receiver_id) REFERENCES users(id)
|
||||
)
|
||||
""")
|
||||
|
||||
|
||||
def create_sample_users(cursor, num_users=10):
|
||||
for i in range(num_users):
|
||||
username = f"user{i + 1}"
|
||||
password = random_string(10)
|
||||
cursor.execute(
|
||||
"INSERT INTO users (username, password) VALUES (%s, %s)",
|
||||
(username, password),
|
||||
)
|
||||
print(f"Created {num_users} sample users.")
|
||||
|
||||
|
||||
def populate_database():
|
||||
conn = connect_to_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
create_tables(cursor)
|
||||
create_sample_users(cursor)
|
||||
|
||||
cursor.execute("SELECT COUNT(*) FROM users")
|
||||
user_count = cursor.fetchone()[0]
|
||||
print(f"Total users in database: {user_count}")
|
||||
|
||||
group_ids = []
|
||||
for i in range(1, 11):
|
||||
group_name = f"Group {i}"
|
||||
cursor.execute(
|
||||
"INSERT INTO groups (group_name, created_by) VALUES (%s, %s)",
|
||||
(group_name, 1),
|
||||
)
|
||||
group_ids.append(cursor.lastrowid)
|
||||
|
||||
print(f"Created groups with IDs: {group_ids}")
|
||||
|
||||
for _ in range(30):
|
||||
user_id = random.randint(1, user_count)
|
||||
group_id = random.choice(group_ids)
|
||||
message = f"Message from {user_id} in group {group_id}: {random_string()}"
|
||||
try:
|
||||
cursor.execute(
|
||||
"INSERT INTO group_messages (user_id, group_id, message) VALUES (%s, %s, %s)",
|
||||
(user_id, group_id, message),
|
||||
)
|
||||
except mysql.connector.Error as err:
|
||||
print(f"Error inserting group message: {err}")
|
||||
|
||||
for _ in range(30):
|
||||
sender_id = random.randint(1, user_count)
|
||||
receiver_id = random.randint(1, user_count)
|
||||
while sender_id == receiver_id:
|
||||
receiver_id = random.randint(1, user_count)
|
||||
message = (
|
||||
f"{random_string()}"
|
||||
)
|
||||
try:
|
||||
cursor.execute(
|
||||
"INSERT INTO private_messages (sender_id, receiver_id, message) VALUES (%s, %s, %s)",
|
||||
(sender_id, receiver_id, message),
|
||||
)
|
||||
except mysql.connector.Error as err:
|
||||
print(f"Error inserting private message: {err}")
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
print("Database populated with sample data!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
populate_database()
|
|
@ -0,0 +1,99 @@
|
|||
import json
|
||||
import mysql.connector
|
||||
import os
|
||||
def get_db_info():
|
||||
# Correct the path to the JSON file
|
||||
json_path = os.path.join(os.path.dirname(__file__), '..', 'dbinfo.json')
|
||||
|
||||
try:
|
||||
with open(json_path, "r") as file:
|
||||
db_info = json.load(file)
|
||||
return db_info
|
||||
except FileNotFoundError:
|
||||
print(f"File not found: {json_path}")
|
||||
exit(1)
|
||||
except json.JSONDecodeError:
|
||||
print(f"Error decoding JSON from file: {json_path}")
|
||||
exit(1)
|
||||
|
||||
def connect_to_db():
|
||||
db_info = get_db_info()
|
||||
conn = mysql.connector.connect(
|
||||
host=db_info["host"], user=db_info["user"], password=db_info["password"], database="messaging_app"
|
||||
)
|
||||
return conn
|
||||
|
||||
def create_database():
|
||||
db_info = get_db_info()
|
||||
conn = mysql.connector.connect(
|
||||
host=db_info["host"], user=db_info["user"], password=db_info["password"]
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("CREATE DATABASE IF NOT EXISTS messaging_app")
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
def create_tables():
|
||||
conn = connect_to_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(255) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS group_messages (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
file_path VARCHAR(255),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS private_messages (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
sender_id INT NOT NULL,
|
||||
receiver_id INT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
file_path VARCHAR(255),
|
||||
FOREIGN KEY (sender_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (receiver_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
cursor.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS admins (
|
||||
username VARCHAR(255) PRIMARY KEY,
|
||||
role ENUM('mod', 'admin') NOT NULL
|
||||
);
|
||||
"""
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
create_database()
|
||||
create_tables()
|
||||
print("Database and tables created successfully!")
|
||||
except FileNotFoundError as e:
|
||||
print(e)
|
|
@ -0,0 +1,25 @@
|
|||
import subprocess
|
||||
import os
|
||||
|
||||
def run_script(script_path):
|
||||
if os.path.exists(script_path):
|
||||
try:
|
||||
subprocess.run(['python3', script_path], check=True)
|
||||
print(f"Successfully ran {script_path}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running {script_path}: {e}")
|
||||
else:
|
||||
print(f"Script {script_path} does not exist.")
|
||||
|
||||
def main():
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
scripts = [
|
||||
os.path.join(base_dir, 'database-dependencies', 'updatedb.py'),
|
||||
os.path.join(base_dir, 'database-dependencies', 'makeadmintable.py')
|
||||
]
|
||||
|
||||
for script in scripts:
|
||||
run_script(script)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"host": "localhost",
|
||||
"user": "root",
|
||||
"password": ""
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
session_start();
|
||||
include './php/db.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: ./login.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$username = $_SESSION['username'];
|
||||
|
||||
$is_admin = false;
|
||||
$is_mod = false;
|
||||
|
||||
$sql_check_roles = "SELECT role FROM admins WHERE username = ?";
|
||||
$stmt_check_roles = $conn->prepare($sql_check_roles);
|
||||
$stmt_check_roles->bind_param("s", $username);
|
||||
$stmt_check_roles->execute();
|
||||
$result_check_roles = $stmt_check_roles->get_result();
|
||||
|
||||
while ($row = $result_check_roles->fetch_assoc()) {
|
||||
if ($row['role'] == 'admin') {
|
||||
$is_admin = true;
|
||||
} elseif ($row['role'] == 'mod') {
|
||||
$is_mod = true;
|
||||
}
|
||||
}
|
||||
|
||||
$stmt_check_roles->close();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if (isset($_POST['group_message'])) {
|
||||
$group_message = $_POST['group_message'];
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO group_messages (user_id, message) VALUES (?, ?)");
|
||||
$stmt->bind_param("is", $user_id, $group_message);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(['status' => 'success']);
|
||||
} else {
|
||||
echo json_encode(['status' => 'error', 'message' => $conn->error]);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$sql_group_messages = "SELECT gm.message, u.username, gm.sent_at
|
||||
FROM group_messages gm
|
||||
JOIN users u ON gm.user_id = u.id
|
||||
ORDER BY gm.sent_at DESC";
|
||||
$result_group_messages = $conn->query($sql_group_messages);
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Group Messages</title>
|
||||
<script src="./js/globalFetch.js"></script>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Welcome, <?php echo htmlspecialchars($username); ?>!</h2>
|
||||
|
||||
<h3>Public Chat</h3>
|
||||
<ul id="messageList">
|
||||
<?php
|
||||
if (!$result_group_messages->num_rows > 0) {
|
||||
echo "<li>No messages in the public group yet.</li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
|
||||
|
||||
<form id="messageForm" action="home.php" method="post" enctype="multipart/form-data">
|
||||
<textarea id="messageInput" name="group_message" rows="4" cols="50" placeholder="Type your message here..."></textarea>
|
||||
<input type="file" id="fileInput" name="file" accept="image/*,audio/*,video/*">
|
||||
<input type="button" id="sendButton" value="Send Message">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
<p><a href="private.php">Private Messages</a></p>
|
||||
<p><a href="./php/logout.php">Logout</a></p>
|
||||
<!-- <button class="settings">ads</button> -->
|
||||
</div>
|
||||
|
||||
<!-- <script src="./js/themeModal.js"></script> -->
|
||||
|
||||
<?php if ($is_admin): ?>
|
||||
<!-- Modal for Admins -->
|
||||
<div id="adminModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h2>Admin Panel</h2>
|
||||
<p>Welcome, Admin <?php echo htmlspecialchars($username); ?>!</p>
|
||||
<hr>
|
||||
<h3>Admin Actions</h3>
|
||||
<p>Remove a user</p>
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['user_to_kick'])) {
|
||||
$user_to_kick = $_POST['user_to_kick'];
|
||||
|
||||
$stmt_kick_user = $conn->prepare("DELETE FROM users WHERE id = ?");
|
||||
$stmt_kick_user->bind_param("i", $user_to_kick);
|
||||
|
||||
$conn->query("SET FOREIGN_KEY_CHECKS=0");
|
||||
|
||||
if ($stmt_kick_user->execute()) {
|
||||
$message = "User successfully removed.";
|
||||
} else {
|
||||
$message = "Error removing user: " . $conn->error;
|
||||
}
|
||||
|
||||
$conn->query("SET FOREIGN_KEY_CHECKS=1");
|
||||
|
||||
$stmt_kick_user->close();
|
||||
} else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['user_roles']) && isset($_POST['roles'])) {
|
||||
$user_roles = $_POST['user_roles'];
|
||||
$roles = $_POST['roles'];
|
||||
|
||||
if ($roles == 'no-role') {
|
||||
$stmt_remove_role = $conn->prepare("DELETE FROM admins WHERE username = (SELECT username FROM users WHERE id = ?)");
|
||||
$stmt_remove_role->bind_param("i", $user_roles);
|
||||
if ($stmt_remove_role->execute()) {
|
||||
$message = "Role successfully removed.";
|
||||
} else {
|
||||
$message = "Error removing role: " . $conn->error;
|
||||
}
|
||||
$stmt_remove_role->close();
|
||||
} else {
|
||||
$stmt_update_role = $conn->prepare("REPLACE INTO admins (username, role) VALUES ((SELECT username FROM users WHERE id = ?), ?)");
|
||||
$stmt_update_role->bind_param("is", $user_roles, $roles);
|
||||
if ($stmt_update_role->execute()) {
|
||||
$message = "Role successfully updated.";
|
||||
} else {
|
||||
$message = "Error updating role: " . $conn->error;
|
||||
}
|
||||
$stmt_update_role->close();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<form id="kickForm" action="" method="post">
|
||||
<select name="user_to_kick" id="user_to_kick">
|
||||
<?php
|
||||
$sql_users = "SELECT id, username FROM users";
|
||||
$result_users = $conn->query($sql_users);
|
||||
|
||||
if ($result_users->num_rows > 0) {
|
||||
while ($user = $result_users->fetch_assoc()) {
|
||||
echo "<option value='" . htmlspecialchars($user['id']) . "'>" . htmlspecialchars($user['username']) . "</option>";
|
||||
}
|
||||
} else {
|
||||
echo "<option value=''>No users available</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input type="submit" id="kickButton" value="Kick User">
|
||||
</form>
|
||||
<br>
|
||||
<hr>
|
||||
<p>Change user roles</p>
|
||||
|
||||
<form id="addModForm" action="" method="post">
|
||||
<select name="user_roles" id="user_roles">
|
||||
<?php
|
||||
$sql_users = "SELECT id, username FROM users";
|
||||
$result_users = $conn->query($sql_users);
|
||||
|
||||
if ($result_users->num_rows > 0) {
|
||||
while ($user = $result_users->fetch_assoc()) {
|
||||
echo "<option value='" . htmlspecialchars($user['id']) . "'>" . htmlspecialchars($user['username']) . "</option>";
|
||||
}
|
||||
} else {
|
||||
echo "<option value=''>No users available</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name="roles" id="roles">
|
||||
<option value="admin">Admin</option>
|
||||
<option value="mod">Mod</option>
|
||||
<option value="no-role">No Role</option>
|
||||
</select>
|
||||
<input type="submit" id="updateUser" value="Update User">
|
||||
</form>
|
||||
|
||||
<?php
|
||||
if (isset($message)) {
|
||||
echo "<p>$message</p>";
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var modal = document.getElementById("adminModal");
|
||||
|
||||
window.onload = function() {
|
||||
modal.style.display = "block";
|
||||
}
|
||||
</script>
|
||||
<script src="./js/pushChatScroll.js"></script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($is_mod && !$is_admin): ?>
|
||||
<!-- Modal for Mods -->
|
||||
<div id="modModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<h2>Mod Panel</h2>
|
||||
<p>Welcome, Mod <?php echo htmlspecialchars($username); ?>!</p>
|
||||
<hr>
|
||||
<h3>Mod Actions</h3>
|
||||
<p>Kick a user</p>
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['user_to_kick'])) {
|
||||
$user_to_kick = $_POST['user_to_kick'];
|
||||
|
||||
// Check if the user to kick is an admin
|
||||
$stmt_check_admin = $conn->prepare("SELECT role FROM admins WHERE username = (SELECT username FROM users WHERE id = ?)");
|
||||
$stmt_check_admin->bind_param("i", $user_to_kick);
|
||||
$stmt_check_admin->execute();
|
||||
$result_check_admin = $stmt_check_admin->get_result();
|
||||
|
||||
if ($result_check_admin->num_rows > 0) {
|
||||
$row = $result_check_admin->fetch_assoc();
|
||||
if ($row['role'] == 'admin') {
|
||||
$message = "You cannot kick an admin.";
|
||||
} else {
|
||||
$stmt_kick_user = $conn->prepare("DELETE FROM users WHERE id = ?");
|
||||
$stmt_kick_user->bind_param("i", $user_to_kick);
|
||||
|
||||
$conn->query("SET FOREIGN_KEY_CHECKS=0");
|
||||
|
||||
if ($stmt_kick_user->execute()) {
|
||||
$message = "User successfully removed.";
|
||||
} else {
|
||||
$message = "Error removing user: " . $conn->error;
|
||||
}
|
||||
|
||||
$conn->query("SET FOREIGN_KEY_CHECKS=1");
|
||||
|
||||
$stmt_kick_user->close();
|
||||
}
|
||||
} else {
|
||||
// User is not an admin, proceed to kick
|
||||
$stmt_kick_user = $conn->prepare("DELETE FROM users WHERE id = ?");
|
||||
$stmt_kick_user->bind_param("i", $user_to_kick);
|
||||
|
||||
$conn->query("SET FOREIGN_KEY_CHECKS=0");
|
||||
|
||||
if ($stmt_kick_user->execute()) {
|
||||
$message = "User successfully removed.";
|
||||
} else {
|
||||
$message = "Error removing user: " . $conn->error;
|
||||
}
|
||||
|
||||
$conn->query("SET FOREIGN_KEY_CHECKS=1");
|
||||
|
||||
$stmt_kick_user->close();
|
||||
}
|
||||
|
||||
$stmt_check_admin->close();
|
||||
}
|
||||
?>
|
||||
|
||||
<form id="kickForm" action="" method="post">
|
||||
<select name="user_to_kick" id="user_to_kick">
|
||||
<?php
|
||||
$sql_users = "SELECT id, username FROM users";
|
||||
$result_users = $conn->query($sql_users);
|
||||
|
||||
if ($result_users->num_rows > 0) {
|
||||
while ($user = $result_users->fetch_assoc()) {
|
||||
echo "<option value='" . htmlspecialchars($user['id']) . "'>" . htmlspecialchars($user['username']) . "</option>";
|
||||
}
|
||||
} else {
|
||||
echo "<option value=''>No users available</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input type="submit" id="kickButton" value="Kick User">
|
||||
</form>
|
||||
|
||||
<?php
|
||||
if (isset($message)) {
|
||||
echo "<p>$message</p>";
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var modal = document.getElementById("modModal");
|
||||
|
||||
window.onload = function() {
|
||||
modal.style.display = "block";
|
||||
}
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<script src="./js/sendGlobal.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
let lastTimestamp = '1970-01-01 00:00:00';
|
||||
|
||||
function fetchMessages() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", `./php/fetchMessages.php?last_timestamp=${encodeURIComponent(lastTimestamp)}`, true);
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
const response = JSON.parse(xhr.responseText);
|
||||
const messages = response.messages;
|
||||
lastTimestamp = response.latest_timestamp;
|
||||
|
||||
const messageList = document.getElementById("messageList");
|
||||
|
||||
messages.forEach(msg => {
|
||||
const newMessage = document.createElement("li");
|
||||
newMessage.innerHTML = msg;
|
||||
messageList.insertBefore(newMessage, messageList.firstChild);
|
||||
});
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
setInterval(fetchMessages, 1000);
|
|
@ -0,0 +1,30 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const submitButton = document.querySelector('#submit-login');
|
||||
|
||||
submitButton.addEventListener('click', (event) => {
|
||||
event.preventDefault(); // Prevent form submission
|
||||
|
||||
let username = document.querySelector('#username').value;
|
||||
let password = document.querySelector('#password').value;
|
||||
|
||||
if (!username.includes(' ')) {
|
||||
fetch('./php/login.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
if (data.includes('Invalid credentials!') || data.includes('User not found!')) {
|
||||
alert(data);
|
||||
} else {
|
||||
window.location.href = './global.php';
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
};
|
||||
});
|
||||
console.log('DOM fully loaded and parsed');
|
||||
});
|
|
@ -0,0 +1,83 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const messageForm = document.getElementById('privateMessageForm');
|
||||
const messageInput = messageForm.querySelector('textarea[name="private_message"]');
|
||||
const receiverIdInput = messageForm.querySelector('input[name="receiver_id"]');
|
||||
const fileInput = messageForm.querySelector('input[name="file"]');
|
||||
const userButtons = document.querySelectorAll('button[name="select_user"]');
|
||||
let lastTimestamp = '1970-01-01 00:00:00';
|
||||
|
||||
userButtons.forEach(button => {
|
||||
button.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
const selectedUserId = this.value;
|
||||
receiverIdInput.value = selectedUserId;
|
||||
lastTimestamp = '1970-01-01 00:00:00'; // Reset timestamp when a new user is selected
|
||||
fetchPrivateMessages(selectedUserId);
|
||||
startMessagePolling(selectedUserId);
|
||||
});
|
||||
});
|
||||
|
||||
messageForm.addEventListener('submit', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const formData = new FormData(this);
|
||||
console.log('Sending data:', Object.fromEntries(formData));
|
||||
|
||||
fetch('./php/send_private_message.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log('Response:', data);
|
||||
if (data.status === 'success') {
|
||||
fetchPrivateMessages(receiverIdInput.value);
|
||||
messageInput.value = '';
|
||||
fileInput.value = '';
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
});
|
||||
|
||||
messageInput.addEventListener('keypress', function(event) {
|
||||
if (event.key === 'Enter' && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
messageForm.dispatchEvent(new Event('submit'));
|
||||
}
|
||||
});
|
||||
|
||||
function fetchPrivateMessages(selectedUserId) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", `./php/fetch_private_messages.php?user_id=${selectedUserId}&last_timestamp=${encodeURIComponent(lastTimestamp)}`, true);
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
const response = JSON.parse(xhr.responseText);
|
||||
const messages = response.messages;
|
||||
lastTimestamp = response.latest_timestamp;
|
||||
|
||||
const messageList = document.getElementById("messageList");
|
||||
|
||||
messages.forEach(msg => {
|
||||
const newMessage = document.createElement("li");
|
||||
newMessage.innerHTML = msg;
|
||||
messageList.appendChild(newMessage);
|
||||
});
|
||||
messageList.scrollTop = messageList.scrollHeight;
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
function startMessagePolling(selectedUserId) {
|
||||
if (window.messagePollingInterval) {
|
||||
clearInterval(window.messagePollingInterval);
|
||||
}
|
||||
window.messagePollingInterval = setInterval(() => {
|
||||
fetchPrivateMessages(selectedUserId);
|
||||
}, 1000); // Poll every 1 second
|
||||
}
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const chat = document.querySelector('#messageList');
|
||||
if (chat) {
|
||||
const observer = new MutationObserver(function() {
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
});
|
||||
|
||||
observer.observe(chat, { childList: true });
|
||||
|
||||
// Initial scroll to bottom in case the list is already populated
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const submitButton = document.querySelector('#submit-register');
|
||||
|
||||
submitButton.addEventListener('click', (event) => {
|
||||
event.preventDefault(); // Prevent form submission
|
||||
|
||||
let username = document.querySelector('#username').value;
|
||||
let email = document.querySelector('#email').value; // Capture email
|
||||
let password = document.querySelector('#password').value;
|
||||
let confirm_password = document.querySelector('#confirm-password').value;
|
||||
|
||||
if (password === confirm_password) {
|
||||
fetch('./php/register.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: `username=${encodeURIComponent(username)}&email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
if (data.includes('Invalid credentials!') || data.includes('User not found!')) {
|
||||
alert(data);
|
||||
} else {
|
||||
window.location.href = './global.php';
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
} else {
|
||||
alert('Incorrect Credentials', 'Please enter the right details.');
|
||||
}
|
||||
});
|
||||
console.log('DOM fully loaded and parsed');
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
document.getElementById("sendButton").addEventListener("click", sendMessage);
|
||||
document
|
||||
.getElementById("messageInput")
|
||||
.addEventListener("keydown", function (event) {
|
||||
if (event.key === "Enter") {
|
||||
sendMessage();
|
||||
}
|
||||
});
|
||||
|
||||
function sendMessage() {
|
||||
const chat = document.querySelector('#messageList');
|
||||
if (chat) {
|
||||
const observer = new MutationObserver(function() {
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
});
|
||||
|
||||
observer.observe(chat, { childList: true });
|
||||
|
||||
// Initial scroll to bottom in case the list is already populated
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
}
|
||||
|
||||
var message = document.getElementById("messageInput").value.trim();
|
||||
var fileInput = document.getElementById("fileInput").files[0];
|
||||
|
||||
// Basic validation
|
||||
if (!message && !fileInput) {
|
||||
alert("Please enter a message or select a file.");
|
||||
return;
|
||||
}
|
||||
|
||||
var formData = new FormData();
|
||||
formData.append("group_message", message);
|
||||
|
||||
if (fileInput) {
|
||||
formData.append("file", fileInput);
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "./php/sendGlobal.php", true);
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
var response = JSON.parse(xhr.responseText);
|
||||
if (response.status === "success") {
|
||||
document.getElementById("messageInput").value = "";
|
||||
document.getElementById("fileInput").value = "";
|
||||
} else {
|
||||
alert("Error: " + response.message);
|
||||
}
|
||||
} else {
|
||||
alert("Error: Unable to send message.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(formData);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
const button = document.querySelector('.settings');
|
||||
|
||||
button.addEventListener('click', () => {
|
||||
const modal = document.createElement('div');
|
||||
modal.classList.add('settingsModal');
|
||||
|
||||
modal.innerHTML = `
|
||||
<div class="theme-options">
|
||||
<label for="background">Background Color:</label>
|
||||
<input type="color" id="background" name="background">
|
||||
|
||||
<label for="sidebar">Sidebar Color:</label>
|
||||
<input type="color" id="sidebar" name="sidebar">
|
||||
|
||||
<label for="buttons">Buttons Color:</label>
|
||||
<input type="color" id="buttons" name="buttons">
|
||||
|
||||
<label for="mention">Mention Color:</label>
|
||||
<input type="color" id="mention" name="mention">
|
||||
|
||||
<label for="mentionborder">Mention Border Color:</label>
|
||||
<input type="color" id="mentionborder" name="mentionborder">
|
||||
|
||||
<button id="applyTheme">Apply Theme</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(modal);
|
||||
|
||||
document.getElementById('applyTheme').addEventListener('click', () => {
|
||||
const background = document.getElementById('background').value;
|
||||
const sidebar = document.getElementById('sidebar').value;
|
||||
const buttons = document.getElementById('buttons').value;
|
||||
const mention = document.getElementById('mention').value;
|
||||
const mentionborder = document.getElementById('mentionborder').value;
|
||||
|
||||
document.body.style.backgroundColor = background;
|
||||
document.querySelector('.sidebar').style.backgroundColor = sidebar;
|
||||
document.querySelectorAll('input[type=button]').forEach(button => button.style.backgroundColor = buttons);
|
||||
document.querySelectorAll('.mention').forEach(mention => mention.style.backgroundColor = mention);
|
||||
document.querySelectorAll('.highlight').forEach(mention => mention.style.borderColor = mentionborder);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Strife | Login</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<section id="login">
|
||||
<h2>Welcome to Strife!</h2>
|
||||
<p>Please enter your details to log in.</p>
|
||||
<hr>
|
||||
<form>
|
||||
<label for="username">Username: </label>
|
||||
<input id="username" type="text" name="username" placeholder="Username" required>
|
||||
|
||||
<label for="password">Password: </label>
|
||||
<input id="password" type="password" name="password" placeholder="Password" required>
|
||||
|
||||
<button id="submit-login" type="submit">Submit</button>
|
||||
</form>
|
||||
<hr>
|
||||
<h3>Don't have an account?</h3>
|
||||
<p>Create one here!</p>
|
||||
<a href="./register.php">Register</a>
|
||||
</section>
|
||||
<script src="./js/login.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
$host = 'localhost';
|
||||
$user = 'root';
|
||||
$password = '';
|
||||
$dbname = 'messaging_app';
|
||||
|
||||
$conn = new mysqli($host, $user, $password, $dbname);
|
||||
|
||||
if ($conn->connect_error) {
|
||||
die("Connection failed: " . $conn->connect_error);
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
session_start();
|
||||
include './db.php';
|
||||
|
||||
$current_user = $_SESSION['username'];
|
||||
|
||||
$last_timestamp = $_GET['last_timestamp'] ?? '1970-01-01 00:00:00';
|
||||
|
||||
$timeout = 1;
|
||||
$start_time = time();
|
||||
|
||||
while (true) {
|
||||
$sql_group_messages = "SELECT gm.message, u.username, gm.sent_at, gm.file_path
|
||||
FROM group_messages gm
|
||||
JOIN users u ON gm.user_id = u.id
|
||||
WHERE gm.sent_at > ?
|
||||
ORDER BY gm.sent_at DESC
|
||||
LIMIT 25";
|
||||
|
||||
$stmt = $conn->prepare($sql_group_messages);
|
||||
$stmt->bind_param("s", $last_timestamp);
|
||||
$stmt->execute();
|
||||
$result_group_messages = $stmt->get_result();
|
||||
|
||||
if ($result_group_messages->num_rows > 0) {
|
||||
$messages = [];
|
||||
$latest_timestamp = '';
|
||||
|
||||
$sql_users = "SELECT username FROM users";
|
||||
$user_result = $conn->query($sql_users);
|
||||
$users = [];
|
||||
while ($user = $user_result->fetch_assoc()) {
|
||||
$users[$user['username']] = true;
|
||||
}
|
||||
|
||||
while ($message = $result_group_messages->fetch_assoc()) {
|
||||
$message_text = htmlspecialchars($message['message']);
|
||||
$highlight_class = '';
|
||||
|
||||
preg_match_all('/@(\w+)/', $message['message'], $mentions);
|
||||
$unique_mentions = array_unique($mentions[1]);
|
||||
foreach ($unique_mentions as $mention) {
|
||||
if (isset($users[$mention])) {
|
||||
$message_text = preg_replace('/@' . preg_quote($mention, '/') . '/', "<span class=\"mention\">@$mention</span>", $message_text, 1);
|
||||
if ($mention === $current_user) {
|
||||
$highlight_class = 'highlight';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$message_text = preg_replace('/(https?:\/\/[^\s]+)/', '<a href="$1" class="link" target="_blank">$1</a>', $message_text);
|
||||
$message_text = preg_replace('/\b(www\.[^\s]+)/', '<a href="http://$1" class="link" target="_blank">$1</a>', $message_text);
|
||||
|
||||
$output = "<span class=\"$highlight_class\"><b>" . htmlspecialchars($message['username']) . ":</b> " . $message_text;
|
||||
|
||||
if (!empty($message['file_path'])) {
|
||||
$path = '/projects/strife/uploads/';
|
||||
$full_file_path = $_SERVER['DOCUMENT_ROOT'] . $path . $message['file_path'];
|
||||
|
||||
if (file_exists($full_file_path)) {
|
||||
$file_type = mime_content_type($full_file_path);
|
||||
|
||||
if (strpos($file_type, 'image') !== false) {
|
||||
$output .= "<br><img src='$path" . htmlspecialchars($message['file_path']) . "' alt='image' style='max-width: 200px;' />";
|
||||
} elseif (strpos($file_type, 'audio') !== false) {
|
||||
$output .= "<br><audio controls><source src='$path" . htmlspecialchars($message['file_path']) . "' type='$file_type'></audio>";
|
||||
} elseif (strpos($file_type, 'video') !== false) {
|
||||
$output .= "<br><video controls style='max-width: 200px;'><source src='$path" . htmlspecialchars($message['file_path']) . "' type='$file_type'></video>";
|
||||
} else {
|
||||
$output .= "<br>Unsupported file type: " . htmlspecialchars($file_type);
|
||||
}
|
||||
} else {
|
||||
$output .= "<br>File does not exist.";
|
||||
}
|
||||
}
|
||||
|
||||
$output .= " <i>(" . htmlspecialchars($message['sent_at']) . ")</i></span>";
|
||||
$messages[] = $output;
|
||||
|
||||
if ($latest_timestamp === '' || $message['sent_at'] > $latest_timestamp) {
|
||||
$latest_timestamp = $message['sent_at'];
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['messages' => array_reverse($messages), 'latest_timestamp' => $latest_timestamp]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (time() - $start_time >= $timeout) {
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(5000);
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['messages' => [], 'latest_timestamp' => $last_timestamp]);
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
session_start();
|
||||
include 'db.php';
|
||||
|
||||
define('DECRYPTION_KEY', 'fdadsihuiads');
|
||||
|
||||
function decryptMessage($encryptedMessage, $key) {
|
||||
$data = base64_decode($encryptedMessage);
|
||||
$iv = substr($data, 0, openssl_cipher_iv_length('aes-256-cbc'));
|
||||
$encryptedMessage = substr($data, openssl_cipher_iv_length('aes-256-cbc'));
|
||||
return openssl_decrypt($encryptedMessage, 'aes-256-cbc', $key, 0, $iv);
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo json_encode(["status" => "error", "message" => "You must be logged in."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$selected_user_id = isset($_GET['user_id']) ? intval($_GET['user_id']) : 0;
|
||||
$last_timestamp = isset($_GET['last_timestamp']) ? $_GET['last_timestamp'] : '1970-01-01 00:00:00';
|
||||
|
||||
$timeout = 10; // Timeout in seconds
|
||||
$start_time = time();
|
||||
|
||||
while (true) {
|
||||
$sql_private_messages = "
|
||||
SELECT pm.message, u.username AS sender, UNIX_TIMESTAMP(pm.sent_at) AS sent_at, pm.file_path
|
||||
FROM private_messages pm
|
||||
JOIN users u ON pm.sender_id = u.id
|
||||
WHERE ((pm.sender_id = ? AND pm.receiver_id = ?)
|
||||
OR (pm.sender_id = ? AND pm.receiver_id = ?))
|
||||
AND pm.sent_at > ?
|
||||
ORDER BY pm.sent_at ASC";
|
||||
|
||||
$stmt_private_messages = $conn->prepare($sql_private_messages);
|
||||
$stmt_private_messages->bind_param("iiiis", $user_id, $selected_user_id, $selected_user_id, $user_id, $last_timestamp);
|
||||
$stmt_private_messages->execute();
|
||||
$result_private_messages = $stmt_private_messages->get_result();
|
||||
|
||||
if ($result_private_messages->num_rows > 0) {
|
||||
$private_messages = [];
|
||||
$latest_timestamp = $last_timestamp;
|
||||
|
||||
while ($row = $result_private_messages->fetch_assoc()) {
|
||||
$row['message'] = decryptMessage($row['message'], DECRYPTION_KEY);
|
||||
|
||||
$message_text = htmlspecialchars($row['message']);
|
||||
$output = "<li><b>" . htmlspecialchars($row['sender']) . ":</b> " . $message_text;
|
||||
|
||||
if (!empty($row['file_path'])) {
|
||||
$path = '/projects/strife/uploads/';
|
||||
$full_file_path = $_SERVER['DOCUMENT_ROOT'] . $path . $row['file_path'];
|
||||
|
||||
if (file_exists($full_file_path)) {
|
||||
$file_type = mime_content_type($full_file_path);
|
||||
|
||||
if (strpos($file_type, 'image') !== false) {
|
||||
$output .= "<br><img src='$path" . htmlspecialchars($row['file_path']) . "' alt='image' style='max-width: 200px;' />";
|
||||
} elseif (strpos($file_type, 'audio') !== false) {
|
||||
$output .= "<br><audio controls><source src='$path" . htmlspecialchars($row['file_path']) . "' type='$file_type'></audio>";
|
||||
} elseif (strpos($file_type, 'video') !== false) {
|
||||
$output .= "<br><video controls style='max-width: 200px;'><source src='$path" . htmlspecialchars($row['file_path']) . "' type='$file_type'></video>";
|
||||
} else {
|
||||
$output .= "<br>Unsupported file type: " . htmlspecialchars($file_type);
|
||||
}
|
||||
} else {
|
||||
$output .= "<br>File does not exist.";
|
||||
}
|
||||
}
|
||||
|
||||
$output .= " <i>(" . date('Y-m-d H:i:s', $row['sent_at']) . ")</i></li>";
|
||||
$private_messages[] = $output;
|
||||
|
||||
if ($row['sent_at'] > $latest_timestamp) {
|
||||
$latest_timestamp = date('Y-m-d H:i:s', $row['sent_at']);
|
||||
}
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['messages' => $private_messages, 'latest_timestamp' => $latest_timestamp]);
|
||||
$stmt_private_messages->close();
|
||||
$conn->close();
|
||||
exit;
|
||||
}
|
||||
|
||||
if (time() - $start_time >= $timeout) {
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(500000); // Sleep for 0.5 seconds
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['messages' => [], 'latest_timestamp' => $last_timestamp]);
|
||||
$stmt_private_messages->close();
|
||||
$conn->close();
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
session_start();
|
||||
include 'db.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$username = $_POST['username'];
|
||||
$password = $_POST['password'];
|
||||
|
||||
if (isset($conn)) {
|
||||
$sql = "SELECT * FROM users WHERE username=?";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("s", $username);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
$user = $result->fetch_assoc();
|
||||
|
||||
if (password_verify($password, $user['password'])) {
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
header("Location: home.php");
|
||||
exit;
|
||||
} else {
|
||||
echo "Invalid credentials!";
|
||||
}
|
||||
} else {
|
||||
echo "User not found!";
|
||||
}
|
||||
} else {
|
||||
echo "Database connection error!";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
session_start();
|
||||
session_destroy();
|
||||
header("Location: ../login.php");
|
||||
exit;
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
include 'db.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$username = $_POST['username'];
|
||||
$email = $_POST['email'];
|
||||
$password = password_hash($_POST['password'], PASSWORD_BCRYPT);
|
||||
|
||||
$check_sql = "SELECT * FROM users WHERE username = ? OR email = ?";
|
||||
$stmt = $conn->prepare($check_sql);
|
||||
$stmt->bind_param("ss", $username, $email);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
echo "Username or email already exists. Please choose a different one.";
|
||||
} else {
|
||||
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("sss", $username, $email, $password);
|
||||
|
||||
if ($stmt->execute() === TRUE) {
|
||||
echo "Registration successful! <a href='login.html'>Login here</a>";
|
||||
} else {
|
||||
echo "Error: " . $conn->error;
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
}
|
||||
$conn->close();
|
||||
?>
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
session_start();
|
||||
include 'db.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo json_encode(["status" => "error", "message" => "You must be logged in to send a message."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$message = isset($_POST['group_message']) ? trim($_POST['group_message']) : '';
|
||||
|
||||
$file_path = null;
|
||||
|
||||
if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
|
||||
$allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'audio/mpeg', 'video/mp4', 'audio/mp4'];
|
||||
$file_type = $_FILES['file']['type'];
|
||||
|
||||
if (!in_array($file_type, $allowed_types)) {
|
||||
echo json_encode(["status" => "error", "message" => "File type not allowed."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$upload_dir = '../uploads/';
|
||||
if (!is_dir($upload_dir)) {
|
||||
if (!mkdir($upload_dir, 0777, true) && !is_dir($upload_dir)) {
|
||||
echo json_encode(["status" => "error", "message" => "Failed to create upload directory."]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$file_name = basename($_FILES['file']['name']);
|
||||
$file_path = $upload_dir . uniqid() . "_" . $file_name;
|
||||
|
||||
if (!move_uploaded_file($_FILES['file']['tmp_name'], $file_path)) {
|
||||
echo json_encode(["status" => "error", "message" => "File upload failed."]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO group_messages (user_id, message, file_path) VALUES (?, ?, ?)");
|
||||
if ($stmt === false) {
|
||||
echo json_encode(["status" => "error", "message" => "Error preparing the statement: {$conn->error}"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param("iss", $user_id, $message, $file_path);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(["status" => "success", "message" => "Message sent successfully!"]);
|
||||
} else {
|
||||
echo json_encode(["status" => "error", "message" => "Error executing query: {$stmt->error}"]);
|
||||
error_log("Database Insert Error: {$stmt->error}");
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
session_start();
|
||||
include 'db.php';
|
||||
|
||||
define('ENCRYPTION_KEY', 'fdadsihuiads');
|
||||
|
||||
function encryptMessage($message, $key) {
|
||||
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
|
||||
$encryptedMessage = openssl_encrypt($message, 'aes-256-cbc', $key, 0, $iv);
|
||||
return base64_encode($iv . $encryptedMessage);
|
||||
}
|
||||
|
||||
function decryptMessage($encryptedMessage, $key) {
|
||||
$data = base64_decode($encryptedMessage);
|
||||
$iv = substr($data, 0, openssl_cipher_iv_length('aes-256-cbc'));
|
||||
$encryptedMessage = substr($data, openssl_cipher_iv_length('aes-256-cbc'));
|
||||
return openssl_decrypt($encryptedMessage, 'aes-256-cbc', $key, 0, $iv);
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo json_encode(["status" => "error", "message" => "You must be logged in to send a message."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$receiver_id = isset($_POST['receiver_id']) ? intval($_POST['receiver_id']) : 0;
|
||||
$message = isset($_POST['private_message']) ? trim($_POST['private_message']) : '';
|
||||
|
||||
if (empty($message) || empty($receiver_id)) {
|
||||
echo json_encode(["status" => "error", "message" => "Message or receiver ID is missing."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$file_path = null;
|
||||
|
||||
if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
|
||||
$allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'audio/mpeg', 'video/mp4', 'audio/mp4'];
|
||||
$file_type = $_FILES['file']['type'];
|
||||
|
||||
if (!in_array($file_type, $allowed_types)) {
|
||||
echo json_encode(["status" => "error", "message" => "File type not allowed."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$upload_dir = '../uploads/';
|
||||
if (!is_dir($upload_dir)) {
|
||||
if (!mkdir($upload_dir, 0777, true) && !is_dir($upload_dir)) {
|
||||
echo json_encode(["status" => "error", "message" => "Failed to create upload directory."]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$file_name = basename($_FILES['file']['name']);
|
||||
$file_path = $upload_dir . uniqid() . "_" . $file_name;
|
||||
|
||||
if (!move_uploaded_file($_FILES['file']['tmp_name'], $file_path)) {
|
||||
echo json_encode(["status" => "error", "message" => "File upload failed."]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt the message
|
||||
$encrypted_message = encryptMessage($message, ENCRYPTION_KEY);
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO private_messages (sender_id, receiver_id, message, file_path) VALUES (?, ?, ?, ?)");
|
||||
|
||||
if ($stmt === false) {
|
||||
echo json_encode(["status" => "error", "message" => "Error preparing the statement: {$conn->error}"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param("iiss", $user_id, $receiver_id, $encrypted_message, $file_path);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(["status" => "success", "message" => "Message sent successfully!"]);
|
||||
} else {
|
||||
echo json_encode(["status" => "error", "message" => "Error executing query: {$stmt->error}"]);
|
||||
error_log("Database Insert Error: {$stmt->error}");
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
} else {
|
||||
echo json_encode(["status" => "error", "message" => "Invalid request method."]);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
session_start();
|
||||
include './php/db.php';
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: ./login.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = $_SESSION['user_id'];
|
||||
$username = $_SESSION['username'];
|
||||
|
||||
// Fetch all users for messaging
|
||||
$sql_users = "SELECT id, username FROM users WHERE id != ?";
|
||||
$stmt_users = $conn->prepare($sql_users);
|
||||
$stmt_users->bind_param("i", $user_id);
|
||||
$stmt_users->execute();
|
||||
$result_users = $stmt_users->get_result();
|
||||
|
||||
$stmt_users->close();
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Private Messages</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="./js/themeModal.js"></script>
|
||||
<script src="./js/private.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Welcome, <?php echo htmlspecialchars($username); ?>!</h2>
|
||||
|
||||
<div class="messages">
|
||||
<h3>Your Private Messages</h3>
|
||||
<ul id="messageList" style="flex-direction: column;">
|
||||
<!-- Messages will be dynamically loaded here -->
|
||||
</ul>
|
||||
<form id="privateMessageForm" enctype="multipart/form-data">
|
||||
<input type="hidden" name="receiver_id" value=""> <!-- This will be set dynamically -->
|
||||
<textarea name="private_message" required placeholder="Type your message..."></textarea>
|
||||
<input type="file" name="file"> <!-- Optional file upload -->
|
||||
<button type="submit">Send Message</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="sidebar">
|
||||
<h3>Select User:</h3>
|
||||
<?php
|
||||
if ($result_users->num_rows > 0) {
|
||||
while ($user = $result_users->fetch_assoc()) {
|
||||
echo '<button type="button" name="select_user" value="' . htmlspecialchars($user['id']) . '">' . htmlspecialchars($user['username']) . '</button>';
|
||||
}
|
||||
} else {
|
||||
echo "<p>No users available.</p>";
|
||||
}
|
||||
?>
|
||||
<p><a href="global.php">Home</a></p>
|
||||
<p><a href="./php/logout.php">Logout</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
# Strife - PHP Messaging App
|
||||
|
||||
Welcome to Strife, a PHP-based messaging application.
|
||||
|
||||
## Installation
|
||||
|
||||
To get started with Strife, follow these steps:
|
||||
|
||||
1. Install the required Python packages:
|
||||
```bash
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
2. Set up the database:
|
||||
```bash
|
||||
python3 ./database/dbMasterFile.py
|
||||
```
|
||||
|
||||
You're all set! Enjoy using Strife.
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Strife | Register</title>
|
||||
<link rel="stylesheet" href="style.css"> <!-- Link to the updated CSS -->
|
||||
</head>
|
||||
<body>
|
||||
<section id="register">
|
||||
<h2>Welcome to Strife!</h2>
|
||||
<p>Please enter your details to register.</p>
|
||||
<hr>
|
||||
<form>
|
||||
<label for="username">Username: </label>
|
||||
<input id="username" type="text" name="username" placeholder="Username" required>
|
||||
|
||||
<label for="email">Email: </label> <!-- Added email input -->
|
||||
<input id="email" type="email" name="email" placeholder="Email" required>
|
||||
|
||||
<label for="password">Password: </label>
|
||||
<input id="password" type="password" name="password" placeholder="Password" required>
|
||||
|
||||
<label for="confirm-password">Confirm Password: </label>
|
||||
<input id="confirm-password" type="password" name="confirm-password" placeholder="Confirm Password" required>
|
||||
|
||||
<button id="submit-register" type="submit">Submit</button>
|
||||
</form>
|
||||
<hr>
|
||||
<h3>Already have an account?</h3>
|
||||
<p>Log in below!</p>
|
||||
<a href="login.php">Login</a>
|
||||
</section>
|
||||
<script src="./js/register.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
mysql-connector-python
|
|
@ -0,0 +1,408 @@
|
|||
/* General Reset */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Comic Sans MS', cursive;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Body Styling */
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100vh;
|
||||
background-color: #2f3136; /* Discord dark background */
|
||||
color: #ffffff; /* White text */
|
||||
padding: 0;
|
||||
font-family: 'Comic Sans MS', cursive;
|
||||
}
|
||||
|
||||
/* Shared Section Styling for Login and Register */
|
||||
#login,
|
||||
#register {
|
||||
background-color: #202225; /* Slightly darker background */
|
||||
padding: 40px 40px;
|
||||
border-radius: 10px;
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #ffffff;
|
||||
margin-bottom: 24px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #b9bbbe; /* Light gray for instructions */
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
border-top: 1px solid #4f545c;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #b9bbbe;
|
||||
margin: 16px 0 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #5865f2; /* Discord blue */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Form Styling */
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"] {
|
||||
padding: 12px 15px;
|
||||
background-color: #40444b;
|
||||
color: #dcddde;
|
||||
border: 1px solid #4f545c;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
font-size: 14px;
|
||||
transition: border-color 0.2s ease;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus {
|
||||
border-color: #5865f2;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px 20px;
|
||||
background-color: #5865f2; /* Discord blue */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s ease;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #4752c4;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #3b44a1;
|
||||
}
|
||||
|
||||
/* Add Responsiveness for smaller screens */
|
||||
@media screen and (max-width: 1024px) {
|
||||
#login,
|
||||
#register {
|
||||
width: 90%;
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* Add Responsiveness for smaller screens */
|
||||
@media screen and (max-width: 1024px) {
|
||||
.sidebar {
|
||||
width: 60px; /* Smaller sidebar on mobile */
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* User Sidebar */
|
||||
.user-sidebar {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
width: 250px;
|
||||
background-color: #202225;
|
||||
padding: 20px;
|
||||
box-shadow: -2px 0 10px rgba(0, 0, 0, 0.6);
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.user-sidebar h2 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.user-sidebar p {
|
||||
color: #b9bbbe;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-sidebar img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#adminModal,
|
||||
#modModal {
|
||||
padding: 16px;
|
||||
border-radius: 0.5rem;
|
||||
background-color: #202225;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
z-index: +1;
|
||||
}
|
||||
|
||||
#adminModal input,
|
||||
#modModal input {
|
||||
padding: 10px 20px;
|
||||
background-color: #5865f2; /* Discord blue */
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.settings {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
background-color: unset;
|
||||
padding: unset;
|
||||
border-radius: unset;
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.settings svg {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.settings:hover {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
/* Additional Styling for Logout and other elements */
|
||||
p {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p a {
|
||||
color: #5865f2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.settingsModal {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 1;
|
||||
background-color: #202225;
|
||||
padding: 16px;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
/* Left Sidebar */
|
||||
.sidebar {
|
||||
width: 240px;
|
||||
background-color: #202225; /* Slightly darker gray */
|
||||
padding: 20px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.6);
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
color: #b9bbbe; /* Light gray links */
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 10px 15px;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.sidebar a:hover {
|
||||
background-color: #3a3d42;
|
||||
}
|
||||
|
||||
/* Main Chat Area */
|
||||
.container {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
padding: 20px;
|
||||
padding-left: 270px; /* Space for the sidebar */
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
border: 2px solid orange;
|
||||
}
|
||||
|
||||
.mention {
|
||||
color: #5865f2;
|
||||
font-weight: bold;
|
||||
padding: unset;
|
||||
}
|
||||
|
||||
/* Chat Messages */
|
||||
#messageList {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
gap: 10px;
|
||||
overflow-y: auto;
|
||||
max-height: 70vh;
|
||||
}
|
||||
|
||||
#messageList li span:not(.mention) {
|
||||
padding: 12px;
|
||||
border-radius: 10px;
|
||||
background-color: #40444b; /* Dark gray background for messages */
|
||||
margin-bottom: 5px;
|
||||
word-wrap: break-word;
|
||||
max-width: 60%;
|
||||
display: inline-block;
|
||||
transition: background-color 0.3s ease;
|
||||
font-family: 'Comic Sans MS', cursive;
|
||||
}
|
||||
|
||||
#messageList li.user {
|
||||
background-color: #5865f2; /* Blue color for user messages */
|
||||
color: white;
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
#messageList li span:hover {
|
||||
background-color: #3a3d42;
|
||||
}
|
||||
|
||||
#messageList li b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Message Timestamps */
|
||||
#messageList i {
|
||||
font-size: 12px;
|
||||
color: #6e737a; /* Lighter gray for timestamps */
|
||||
}
|
||||
|
||||
/* Textarea for message input */
|
||||
#messageForm {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: flex-end;
|
||||
flex-direction: unset;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 36px;
|
||||
padding: 10px;
|
||||
background-color: #40444b;
|
||||
color: #dcddde;
|
||||
border: 1px solid #4f545c;
|
||||
border-radius: 5px;
|
||||
resize: none;
|
||||
width: 80%;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
|
||||
textarea:focus {
|
||||
border-color: #5865f2; /* Blue outline on focus */
|
||||
}
|
||||
|
||||
input[type="button"] {
|
||||
padding: 10px 20px;
|
||||
background-color: #5865f2; /* Discord blue */
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s ease;
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
input[type="button"]:hover {
|
||||
background-color: #4752c4;
|
||||
}
|
||||
|
||||
input[type="button"]:active {
|
||||
background-color: #3b44a1;
|
||||
}
|
||||
|
||||
input[type="button"]:disabled {
|
||||
background-color: #202225;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* file upload button */
|
||||
input[type="file"]::file-selector-button {
|
||||
padding: 10px 20px;
|
||||
background-color: #5865f2; /* Discord blue */
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s ease;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
/* file upload button hover state */
|
||||
input[type="file"]::file-selector-button:hover {
|
||||
background-color: #4752c4;
|
||||
}
|
||||
|
||||
/* file upload button active state */
|
||||
input[type="file"]::file-selector-button:active {
|
||||
background-color: #3b44a1;
|
||||
}
|
Loading…
Reference in New Issue