summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-04-22 02:56:09 +0500
committerilotterytea <iltsu@alright.party>2025-04-22 03:23:46 +0500
commitdf783376d2b3bdd8fe5e0e558fa781f40babd7f3 (patch)
tree3cad6b62b81a70e73cc5df60b96740e7cf3ec992
parent55c5c9ca935a9077a1fd4003e93a10c5144a6bce (diff)
feat: users
-rw-r--r--public/index.php2
-rw-r--r--public/static/img/icons/clock.pngbin0 -> 882 bytes
-rw-r--r--public/static/img/icons/door_in.pngbin0 -> 693 bytes
-rw-r--r--public/static/img/icons/emoticon_happy.pngbin0 -> 731 bytes
-rw-r--r--public/static/img/icons/heart.pngbin0 -> 749 bytes
-rw-r--r--public/static/img/icons/star.pngbin0 -> 670 bytes
-rw-r--r--public/static/img/icons/user.pngbin0 -> 741 bytes
-rw-r--r--public/static/style.css88
-rw-r--r--public/users.php418
-rw-r--r--src/emotes/single_page.php4
-rw-r--r--src/partials.php3
-rw-r--r--src/user.php36
12 files changed, 518 insertions, 33 deletions
diff --git a/public/index.php b/public/index.php
index 5619208..a9b88bd 100644
--- a/public/index.php
+++ b/public/index.php
@@ -15,7 +15,7 @@ include_once "../src/config.php";
<div class="items row" style="gap:32px;">
<a href="/emotes">Emotes</a>
- <a href="/users">Users</a>
+ <a href="/users.php">Users</a>
<a href="/emotes/upload.php">Upload</a>
<a href="/account">Account</a>
<a href="/software">Chat clients</a>
diff --git a/public/static/img/icons/clock.png b/public/static/img/icons/clock.png
new file mode 100644
index 0000000..e2672c2
--- /dev/null
+++ b/public/static/img/icons/clock.png
Binary files differ
diff --git a/public/static/img/icons/door_in.png b/public/static/img/icons/door_in.png
new file mode 100644
index 0000000..41676a0
--- /dev/null
+++ b/public/static/img/icons/door_in.png
Binary files differ
diff --git a/public/static/img/icons/emoticon_happy.png b/public/static/img/icons/emoticon_happy.png
new file mode 100644
index 0000000..6b7336e
--- /dev/null
+++ b/public/static/img/icons/emoticon_happy.png
Binary files differ
diff --git a/public/static/img/icons/heart.png b/public/static/img/icons/heart.png
new file mode 100644
index 0000000..d9ee53e
--- /dev/null
+++ b/public/static/img/icons/heart.png
Binary files differ
diff --git a/public/static/img/icons/star.png b/public/static/img/icons/star.png
new file mode 100644
index 0000000..b88c857
--- /dev/null
+++ b/public/static/img/icons/star.png
Binary files differ
diff --git a/public/static/img/icons/user.png b/public/static/img/icons/user.png
new file mode 100644
index 0000000..79f35cc
--- /dev/null
+++ b/public/static/img/icons/user.png
Binary files differ
diff --git a/public/static/style.css b/public/static/style.css
index 86013be..cb9a996 100644
--- a/public/static/style.css
+++ b/public/static/style.css
@@ -1,11 +1,14 @@
:root {
- --background-color: #d7dfcd;
+ --background-color: #c4d1b5;
--background-color-hover: #e4eed8;
--background-color-disabled: #bec6b3;
- --border-color: #b0b9a5;
+ --border-color: #95a186;
- --foreground-color: #7f9c3c;
- --foreground-color-hover: #4b5632;
+ --background-color-2: #cfdfbd;
+ --border-color-2: #849275;
+
+ --foreground-color: #425514;
+ --foreground-color-hover: #1c220c;
}
* {
@@ -15,14 +18,34 @@
font-family: Arial, Helvetica, sans-serif;
}
+h1 {
+ font-size: 26px;
+}
+
+h2 {
+ font-size: 20px;
+}
+
+h3 {
+ font-size: 16px;
+}
+
div {
display: unset;
}
+table {
+ text-align: left;
+}
+
table.vertical th {
text-align: right;
}
+table.vertical.left th {
+ text-align: left;
+}
+
table.vertical th,
table.vertical td {
padding: 2px;
@@ -50,9 +73,6 @@ form {
gap: 4px;
}
-.row {
- flex-direction: row;
-}
.container {
width: 100%;
@@ -66,7 +86,7 @@ form {
flex-direction: column;
}
-section.content {
+.content {
flex-grow: 1;
display: flex;
flex-direction: column;
@@ -79,15 +99,6 @@ section.content {
flex-direction: row;
}
-.big-gap {
- gap: 32px;
-}
-
-.center {
- justify-content: center;
- align-items: center;
-}
-
/**
------------
COUNTER
@@ -236,12 +247,6 @@ button.purple:hover,
flex-grow: 1;
}
-.row {
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
.right {
justify-content: flex-end;
}
@@ -282,6 +287,16 @@ button.purple:hover,
padding: 16px;
}
+.box .content .box {
+ background: var(--background-color-2);
+ border-color: var(--border-color-2);
+}
+
+.box .content a.box:hover {
+ background: linear-gradient(0deg, var(--background-color-hover), var(--background-color-2));
+ cursor: pointer;
+}
+
.box hr {
border-color: var(--border-color);
border-width: 1px;
@@ -358,14 +373,29 @@ a.box:hover {
gap: 16px;
}
-.accman h1 {
- font-size: 26px;
+.row {
+ display: flex;
+ flex-direction: row;
}
-.accman h2 {
- font-size: 20px;
+.column {
+ display: flex;
+ flex-direction: column;
}
-.accman h3 {
- font-size: 16px;
+.flex {
+ flex-grow: 1;
+}
+
+.small-gap {
+ gap: 8px;
+}
+
+.big-gap {
+ gap: 32px;
+}
+
+.center {
+ justify-content: center;
+ align-items: center;
} \ No newline at end of file
diff --git a/public/users.php b/public/users.php
new file mode 100644
index 0000000..73f1d54
--- /dev/null
+++ b/public/users.php
@@ -0,0 +1,418 @@
+<?php
+include_once "../src/config.php";
+include_once "../src/user.php";
+include_once "../src/partials.php";
+include_once "../src/utils.php";
+include_once "../src/accounts.php";
+authorize_user();
+session_start();
+
+$is_json = isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json";
+
+$id = $_GET["id"] ?? "";
+
+$db = new PDO(DB_URL, DB_USER, DB_PASS);
+
+if ($id == "") {
+ $page = $_GET["p"] ?? "0";
+ $limit = 50;
+ $offset = $page * $limit;
+ $stmt = $db->prepare("SELECT id, username, joined_at, last_active_at FROM users ORDER BY last_active_at DESC LIMIT ? OFFSET ?");
+ $stmt->bindParam(1, $limit, PDO::PARAM_INT);
+ $stmt->bindParam(2, $offset, PDO::PARAM_INT);
+ $stmt->execute();
+
+ $all_user_count = $db->query("SELECT COUNT(*) FROM users")->fetch()[0];
+
+ if ($is_json) {
+ header("Content-Type: application/json");
+ echo json_encode([
+ "status_code" => 200,
+ "message" => null,
+ "data" => [
+ "all_user_count" => intval($all_user_count),
+ "users" => $stmt->fetchAll(PDO::FETCH_ASSOC)
+ ]
+ ]);
+ exit;
+ }
+
+ echo '' ?>
+ <html>
+
+ <head>
+ <title>User list - alright.party</title>
+ <link rel="stylesheet" href="/static/style.css">
+ </head>
+
+ <body>
+ <div class="container">
+ <div class="wrapper">
+ <?php html_navigation_bar() ?>
+ <section class="content row">
+ <section class="sidebar">
+ <?php html_navigation_search(); ?>
+ </section>
+ <section class="content">
+ <section class="box">
+ <div class="box navtab">
+ <p><?php echo $all_user_count ?> Users</p>
+ </div>
+ <div class="box content">
+ <?php
+ if ($stmt->rowCount() != 0) {
+ echo '<table>';
+ echo '<tr>';
+ echo '<th></th><th style="width:80%;">Username</th><th>Last active</th>';
+ echo '<tr>';
+ while ($row = $stmt->fetch()) {
+ $diff = time() - strtotime($row["last_active_at"]);
+
+ $last_active = "moments";
+
+ if ($diff > 5) {
+ $last_active = format_timestamp($diff);
+ }
+
+ echo '<tr>';
+ echo '<td><img src="/static/userdata/avatars/' . $row["id"] . '" width="24" height="24"></td>';
+ echo '<td><a href="/users.php?id=' . $row["id"] . '">' . $row["username"] . '</a></td>';
+ echo "<td>$last_active ago</td>";
+ echo '</tr>';
+ }
+ echo '</table>';
+ } else {
+ echo '<p>Nothing found...</p>';
+ }
+ ?>
+ </div>
+ </section>
+ </section>
+ </section>
+ </div>
+ </div>
+ </body>
+
+ </html>
+ <?php ;
+ exit;
+}
+
+$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
+$stmt->execute([$id]);
+
+$user = null;
+
+if ($row = $stmt->fetch()) {
+ $user = new User($row);
+}
+
+if ($user == null) {
+ header("Location: /404.php");
+ exit;
+}
+
+// --- EMOTE SETS ---
+// TODO: OPTIMIZE IT ASAP!!!
+$emote_sets = [];
+$active_emote_set = null;
+
+// gathering acquired emote sets
+$stmt = $db->prepare("SELECT emote_set_id, is_default FROM acquired_emote_sets WHERE user_id = ?");
+$stmt->execute([$user->id()]);
+
+while ($row = $stmt->fetch()) {
+ // getting more info about set
+ $set_stmt = $db->prepare("SELECT id, name, size FROM emote_sets WHERE id = ?");
+ $set_stmt->execute([$row["emote_set_id"]]);
+ $set = $set_stmt->fetch();
+
+ // getting info about emote set content
+ $em_stmt = $db->prepare(
+ "SELECT e.id, e.code, e.ext FROM emotes e
+ INNER JOIN emote_set_contents AS esc
+ ON esc.emote_set_id = ?
+ WHERE esc.emote_id = e.id
+ " . ($row["is_default"] ? '' : ' LIMIT 5')
+ );
+ $em_stmt->execute([$row["emote_set_id"]]);
+
+ $emote_set = [
+ "id" => $set["id"],
+ "name" => $set["name"],
+ "size" => $set["size"],
+ "emotes" => $em_stmt->fetchAll(PDO::FETCH_ASSOC)
+ ];
+
+ if ($row["is_default"]) {
+ $active_emote_set = count($emote_sets);
+ }
+
+ array_push($emote_sets, $emote_set);
+}
+
+$active_emote_set = &$emote_sets[$active_emote_set];
+
+// gathering uploaded emotes
+$stmt = $db->prepare("SELECT e.*,
+ CASE WHEN EXISTS (
+ SELECT 1
+ FROM emote_set_contents ec
+ INNER JOIN emote_sets es ON es.id = ec.emote_set_id
+ WHERE ec.emote_id = e.id AND es.owner_id = ?
+ ) THEN 1 ELSE 0 END AS is_in_user_set
+ FROM emotes e
+ WHERE e.uploaded_by = ?
+ ORDER BY e.created_at ASC
+ ");
+$stmt->execute([$user->id(), $user->id()]);
+
+$uploaded_emotes = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+// gathering actions
+// TODO: update it when we will have action logs
+$actions = [];
+
+// TODO: add functionality
+
+// calculating contributions
+$stmt = $db->prepare("SELECT COUNT(*) FROM emotes WHERE uploaded_by = ?");
+$stmt->execute([$user->id()]);
+$contributions = $stmt->fetch()[0];
+
+// getting status
+$status = 1;
+
+// getting favorite reaction
+$fav_reaction = 1;
+
+// getting favorite emote
+$fav_emote = 1;
+
+if ($is_json) {
+ header("Content-type: application/json");
+ echo json_encode([
+ "status_code" => 200,
+ "message" => null,
+ "data" => [
+ "id" => intval($user->id()),
+ "username" => $user->username(),
+ "joined_at" => $user->joined_at(),
+ "last_active_at" => $user->last_active_at(),
+ "stats" => [
+ "status_id" => $status,
+ "contributions" => $contributions,
+ "favorite_reaction_id" => $fav_reaction,
+ "favorite_emote_id" => $fav_emote
+ ],
+ "active_emote_set_id" => $active_emote_set["id"],
+ "emote_sets" => $emote_sets,
+ "uploaded_emotes" => $uploaded_emotes,
+ "actions" => $actions
+ ]
+ ]);
+ exit;
+}
+?>
+
+<html>
+
+<head>
+ <title><?php echo $user->username() ?> - alright.party</title>
+ <link rel="stylesheet" href="/static/style.css">
+</head>
+
+<body>
+ <div class="container">
+ <div class="wrapper">
+ <?php echo html_navigation_bar() ?>
+ <section class="content row">
+ <!-- User information -->
+ <section class="user-bar column small-gap">
+ <section class="box">
+ <div class="box navtab">
+ <p>User #<?php echo $user->id() ?></p>
+ </div>
+ <div class="box content">
+ <img src="/static/userdata/avatars/<?php echo $user->id() ?>" width="96" height="96">
+ <h1><?php echo $user->username() ?></h1>
+ </div>
+ </section>
+
+ <!-- STATS -->
+ <section class="box">
+ <table class="vertical left">
+ <tr>
+ <th><img src="/static/img/icons/user.png"> I am </th>
+ <td><?php
+ if ($status == 1) {
+ echo "Gemposter";
+ } else {
+ echo "Unknown";
+ }
+ ?></td>
+ </tr>
+ <tr>
+ <th><img src="/static/img/icons/door_in.png"> Joined</th>
+ <?php
+ echo '<td title="';
+ echo date("M d, Y H:i:s", $user->joined_at());
+ echo ' UTC">about ' . format_timestamp(time() - $user->joined_at()) . " ago</td>";
+ ?>
+ </tr>
+ <tr>
+ <th><img src="/static/img/icons/clock.png"> Last activity</th>
+ <?php
+ $diff = time() - $user->last_active_at();
+ if ($diff > 60) {
+ echo '<td title="';
+ echo date("M d, Y H:i:s", $user->last_active_at());
+ echo ' UTC">about ' . format_timestamp($diff) . " ago</td>";
+ } else {
+ echo '<td>Online</td>';
+ }
+ ?>
+ </tr>
+ <tr>
+ <th><img src="/static/img/icons/star.png"> Contributed emotes</th>
+ <td><?php echo $contributions ?></td>
+ </tr>
+ <tr>
+ <th><img src="/static/img/icons/emoticon_happy.png"> Favorite reaction</th>
+ <td>
+ <?php
+ if ($fav_reaction == 1) {
+ echo 'Gem <img src="/static/img/icons/gem.png">';
+ } else {
+ echo 'Coal <img src="/static/img/icons/coal.png">';
+ }
+ ?>
+ </td>
+ </tr>
+ <?php
+ $stmt = $db->prepare("SELECT code, ext FROM emotes WHERE id = ?");
+ $stmt->execute([$fav_emote]);
+
+ if ($row = $stmt->fetch()) {
+ echo '<tr>';
+ echo '<th><img src="/static/img/icons/heart.png"> Favorite emote</th>';
+ echo '<td>';
+ echo "<a href=\"/emotes/$fav_emote\">";
+ echo $row["code"] . ' <img src="/static/userdata/emotes/' . $fav_emote . '/1x.' . $row["ext"] . '" width="16" height="16">';
+ echo '</a></td></tr>';
+ }
+ ?>
+ </table>
+ </section>
+
+ <!-- ACTIONS -->
+ <section class="box column">
+ <a href="/message/send.php?user=<?php echo $user->id() ?>">Send a message</a>
+ <a href="/report.php?user=<?php echo $user->id() ?>">Report user</a>
+ </section>
+ </section>
+
+ <!-- Emotes -->
+ <section class="column small-gap flex">
+ <!-- Emoteset -->
+ <section class="box">
+ <div class="box navtab">
+ <p>Emotes</p>
+ </div>
+ <div class="box content items">
+ <?php
+ if (!empty($emote_sets)) {
+ foreach ($emote_sets as $set_row) { ?>
+ <a href="/emotesets/<?php echo $set_row["id"] ?>" class="box">
+ <div>
+ <?php
+ echo '<p>' . $set_row["name"] . '</p>';
+
+ if ($set_row["size"]) {
+ echo '<p class="circled black">' . $set_row["size"] . '</p>';
+ }
+ ?>
+ </div>
+
+ <div>
+ <?php
+ foreach ($set_row["emotes"] as $e) {
+ echo '<img src="/static/userdata/emotes/' . $e["id"] . '/1x.' . $e["ext"] . '">';
+ }
+ ?>
+ </div>
+ </a>
+ <?php }
+ } else {
+ echo '<p>No emote sets found... ' . ((($_SESSION["user_id"] ?? "") == $id) ? 'Start adding emotes and you will have one! :)</p>' : '</p>');
+ }
+ ?>
+ </div>
+ </section>
+
+ <!-- Active emoteset -->
+ <?php
+ if ($active_emote_set != null) {
+ echo '' ?>
+ <section class="box">
+ <div class="content items">
+ <?php
+ if (!empty($active_emote_set["emotes"])) {
+ foreach ($active_emote_set["emotes"] as $emote_row) {
+ echo '<a class="box emote" href="/emotes/' . $emote_row["id"] . '">';
+ echo '<img src="/static/userdata/emotes/' . $emote_row["id"] . '/2x.' . $emote_row["ext"] . '" alt="' . $emote_row["code"] . '"/>';
+ echo '<p>' . $emote_row["code"] . '</p>';
+ echo '</a>';
+ }
+ } else {
+ echo '<p>No emotes found... ' . ((($_SESSION["user_id"] ?? "") == $id) ? 'Start adding emotes and they will appear here! :)</p>' : '</p>');
+ }
+ ?>
+ </div>
+ </section><?php
+ }
+ ?>
+
+ <!-- Uploaded emotes -->
+ <?php
+ if (!empty($uploaded_emotes)) {
+ echo '' ?>
+ <section class="box">
+ <div class="box navtab">
+ <p>Uploaded emotes</p>
+ </div>
+ <div class="box content items">
+ <?php
+ foreach ($uploaded_emotes as $emote_row) {
+ echo '<a class="box emote" href="/emotes/' . $emote_row["id"] . '">';
+ echo '<img src="/static/userdata/emotes/' . $emote_row["id"] . '/2x.' . $emote_row["ext"] . '" alt="' . $emote_row["code"] . '"/>';
+ echo '<p>' . $emote_row["code"] . '</p>';
+ echo '</a>';
+ }
+ ?>
+ </div>
+ </section><?php
+ }
+ ?>
+
+ <!-- Actions -->
+ <section class="box">
+ <div class="box navtab">
+ <p>Actions</p>
+ </div>
+ <div class="box content">
+ <?php
+ if (!empty($actions)) {
+ } else {
+ echo "<p>This user has done nothing bad or good...</p>";
+ }
+ ?>
+ </div>
+ </section>
+ </section>
+ </section>
+ </div>
+ </div>
+</body>
+
+</html> \ No newline at end of file
diff --git a/src/emotes/single_page.php b/src/emotes/single_page.php
index 92b4e24..d1fc4e8 100644
--- a/src/emotes/single_page.php
+++ b/src/emotes/single_page.php
@@ -108,7 +108,7 @@ include_once "../../src/config.php";
if ($row = $stmt->fetch()) {
$username = $row["username"];
- $link = "/users/" . $emote->get_uploaded_by();
+ $link = "/users.php?id=" . $emote->get_uploaded_by();
}
$db = null;
@@ -154,7 +154,7 @@ include_once "../../src/config.php";
<div class="items row">
<?php
while ($row = $stmt->fetch()) {
- echo '<a href="/users/' . $row["id"] . '">' . $row["username"] . '</a>';
+ echo '<a href="/users.php?id=' . $row["id"] . '">' . $row["username"] . '</a>';
}
?>
</div>
diff --git a/src/partials.php b/src/partials.php
index 8f2d2ab..0087df4 100644
--- a/src/partials.php
+++ b/src/partials.php
@@ -9,13 +9,14 @@ function html_navigation_bar()
</a>
<div class="links">
<a href="/emotes" class="button">Emotes</a>
+ <a href="/users.php" class="button">Users</a>
<a href="/emotes/upload.php" class="button">Upload</a>
<a href="/account" class="button">Account</a>
</div>
<?php
if (isset($_SESSION["user_id"])) {
echo '' ?>
- <a href="/users/<?php echo $_SESSION["user_id"] ?>" class="links" style="margin-left:auto;">
+ <a href="/users.php?id=<?php echo $_SESSION["user_id"] ?>" class="links" style="margin-left:auto;">
Signed in as <?php echo $_SESSION["user_name"] ?> <img
src="/static/userdata/avatars/<?php echo $_SESSION["user_id"] ?>" width="24" height="24" />
</a>
diff --git a/src/user.php b/src/user.php
new file mode 100644
index 0000000..c09c5d5
--- /dev/null
+++ b/src/user.php
@@ -0,0 +1,36 @@
+<?php
+class User
+{
+ private int $id;
+ private string $username;
+ private int $joined_at;
+ private int $last_active_at;
+
+ function __construct($row)
+ {
+ $this->id = $row["id"];
+ $this->username = $row["username"];
+ $this->joined_at = strtotime($row["joined_at"]);
+ $this->last_active_at = strtotime($row["last_active_at"]);
+ }
+
+ function id()
+ {
+ return $this->id;
+ }
+
+ function username()
+ {
+ return $this->username;
+ }
+
+ function joined_at()
+ {
+ return $this->joined_at;
+ }
+
+ function last_active_at()
+ {
+ return $this->last_active_at;
+ }
+} \ No newline at end of file