From 5596992e58c17431764d673fc5d04454887f2f82 Mon Sep 17 00:00:00 2001 From: ghost Date: Sat, 1 Jan 2022 14:39:18 +0200 Subject: [PATCH] implement profiles details on the People page --- database/cloud-server.mwb | Bin 6696 -> 8558 bytes .../controller/api/user/profile.php | 89 ++++++++++++++++++ src/application/model/profile.php | 87 +++++++++++++++++ src/bootstrap.php | 12 +++ .../css/template/default/module/following.css | 40 +++++++- src/public/js/module/following.js | 68 +++++++++++-- 6 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 src/application/controller/api/user/profile.php create mode 100644 src/application/model/profile.php diff --git a/database/cloud-server.mwb b/database/cloud-server.mwb index 2290574379b206bf848781684340bd97c8046dfb..851c7baa1105d8857611b7b226501238ec195718 100644 GIT binary patch literal 8558 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%0DNAD&*@e|tiv0v5egZskUsI=-> zuJhIAh-K5wTZTKF2alC4=uZN`jI5ySNIcGD3mB#*x|CI9i> zu9&z&3A*D=luQFVe!gfxczls%5fP*}^hd7Cx0n$I8A=BBkH*~Vhv7qM)Jd$mHw!4z%Y=-=%+R?^;-9Ft~ndL{@+q1Mv9uaixQWemk z*m@=p>s+h+yv|UQL~hEVkQz9XRlA%GEu}LNmEtxZaZZ=TH(Tr&$p)2-rVL4zlG3}~ zG(%xk;IAT&fcTFQ?(hEbS2_X#0AYZlr@E>FP}|o3eIidbPWOG0V literal 6696 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 W<}UB3EFB false, + 'message' => _('Internal server error'), + 'profile' => [] +]; + +if (isset($_SESSION['userName'])) { + + $userName = isset($_POST['userName']) ? Filter::userName($_POST['userName']) : $_SESSION['userName']; + + if ($userProfileVersions = $_twister->getDHT($userName, 'profile', 's')) { + + // Check user exists + if ($userId = $_modelUser->getUserId($userName)) { + + // Add DHT version if not exists + foreach ($userProfileVersions as $userProfileVersion) { + + if (!$_modelProfile->versionExists($userId, + $userProfileVersion['p']['height'], + $userProfileVersion['p']['seq'])) { + + $profile = $userProfileVersion['p']['v']; + + $_modelProfile->add($userId, + $userProfileVersion['p']['height'], + $userProfileVersion['p']['seq'], + $userProfileVersion['p']['time'], + + isset($profile['fullname']) ? $profile['fullname'] : '', + isset($profile['bio']) ? $profile['bio'] : '', + isset($profile['location']) ? $profile['location'] : '', + isset($profile['url']) ? $profile['url'] : '', + isset($profile['bitmessage']) ? $profile['bitmessage'] : '', + isset($profile['tox']) ? $profile['tox'] : ''); + } + } + } + + + // Get latest version available + if ($profileInfo = $_modelProfile->get($userId)) { + + $response = [ + 'success' => true, + 'message' => _('Profile successfully received'), + 'profile' => [ + 'userName' => $userName, + 'fullName' => $profileInfo['fullName'], + 'location' => $profileInfo['location'], + 'url' => $profileInfo['url'], + 'bitMessage' => $profileInfo['bitMessage'], + 'tox' => $profileInfo['tox'], + 'bio' => nl2br($profileInfo['bio']), + ] + ]; + + } else { + + $response = [ + 'success' => false, + 'message' => _('Profile data not available'), + 'profile' => [] + ]; + } + + } else { + + $response = [ + 'success' => false, + 'message' => _('Could not receive profile details'), + 'profile' => [] + ]; + + } + +} else { + + $response = [ + 'success' => false, + 'message' => _('Session expired. Please, reload the page.'), + 'profile' => [] + ]; +} + +header('Content-Type: application/json; charset=utf-8'); +echo json_encode($response); \ No newline at end of file diff --git a/src/application/model/profile.php b/src/application/model/profile.php new file mode 100644 index 0000000..e8101c3 --- /dev/null +++ b/src/application/model/profile.php @@ -0,0 +1,87 @@ +_db->prepare("SELECT * FROM `profile` + WHERE `userId` = ? + + ORDER BY `seq` DESC + LIMIT 1"); + + $query->execute([$userId]); + + return $query->fetch(); + + } catch (PDOException $e) { + + trigger_error($e->getMessage()); + return false; + } + } + + public function versionExists(int $userId, int $blockId, int $seq) { + + try { + + $query = $this->_db->prepare("SELECT COUNT(*) AS `total` FROM `profile` + WHERE `userId` = ? AND `blockId` = ? AND `seq` = ?"); + + $query->execute([$userId, $blockId, $seq]); + + return $query->fetch()['total']; + + } catch (PDOException $e) { + + trigger_error($e->getMessage()); + return false; + } + } + + public function add(int $userId, + int $blockId, + int $seq, + int $time, + string $fullName, + string $bio, + string $location, + string $url, + string $bitMessage, + string $tox) { + + try { + + $query = $this->_db->prepare("INSERT INTO `profile` SET `userId` = ?, + `blockId` = ?, + `seq` = ?, + `time` = ?, + `fullName` = ?, + `bio` = ?, + `location` = ?, + `url` = ?, + `bitMessage` = ?, + `tox` = ?"); + + $query->execute([$userId, + $blockId, + $seq, + $time, + $fullName, + $bio, + $location, + $url, + $bitMessage, + $tox]); + + return $this->_db->lastInsertId(); + + } catch (PDOException $e) { + + trigger_error($e->getMessage()); + return false; + } + } +} \ No newline at end of file diff --git a/src/bootstrap.php b/src/bootstrap.php index 3f2d658..170d137 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -6,6 +6,7 @@ require('config.php'); require(PROJECT_DIR . '/application/model/model.php'); require(PROJECT_DIR . '/application/model/block.php'); require(PROJECT_DIR . '/application/model/user.php'); +require(PROJECT_DIR . '/application/model/profile.php'); require(PROJECT_DIR . '/system/curl.php'); require(PROJECT_DIR . '/system/twister.php'); @@ -35,6 +36,14 @@ $_modelUser = new ModelUser( DB_PASSWORD ); +$_modelProfile = new ModelProfile( + DB_DATABASE, + DB_HOST, + DB_PORT, + DB_USER, + DB_PASSWORD +); + $_modelBlock = new ModelBlock( DB_DATABASE, DB_HOST, @@ -92,6 +101,9 @@ if (isset($_GET['_route_'])) { case 'api/user/random': require(PROJECT_DIR . '/application/controller/api/user/random.php'); break; + case 'api/user/profile': + require(PROJECT_DIR . '/application/controller/api/user/profile.php'); + break; // Multi-attribute pages default: diff --git a/src/public/css/template/default/module/following.css b/src/public/css/template/default/module/following.css index dbbaf06..5c3e8f4 100644 --- a/src/public/css/template/default/module/following.css +++ b/src/public/css/template/default/module/following.css @@ -1,7 +1,7 @@ .moduleFollowing .item { padding: 16px; margin: 0 2px 2px 2px; - color: #1c1d1e; + color: #fff; background: rgba(238, 238, 238, 0.08); border-radius: 3px; } @@ -23,7 +23,7 @@ .moduleFollowing .item .avatar { position: absolute; - top: 16px; + top: 18px; left: 16px; } @@ -36,7 +36,7 @@ .moduleFollowing .item .action { position: absolute; - top: 16px; + top: 13px; right: 16px; } @@ -57,4 +57,38 @@ padding-right: 32px; letter-spacing: 0.2px; font-size: 13px; +} + +.moduleFollowing .item .info .username { + margin-bottom: 8px; +} + +.moduleFollowing .item .info .username a { + font-weight: bold; +} + +.moduleFollowing .item .info .location { + margin-top: 4px; +} + +.moduleFollowing .item .info .bio { + font-style: italic; + margin-top: 4px; + color: #c3c8ce +} + +.moduleFollowing .item.active .info .bio { + color: #515457 +} + +.moduleFollowing .item .info .url, +.moduleFollowing .item .info .tox, +.moduleFollowing .item .info .bitMessage { + display: inline-block; + margin-right: 4px; + margin-top: 4px; +} + +.moduleFollowing .item .info .tox { + font-size: 10px } \ No newline at end of file diff --git a/src/public/js/module/following.js b/src/public/js/module/following.js index 289ce7b..31ec3dc 100644 --- a/src/public/js/module/following.js +++ b/src/public/js/module/following.js @@ -5,7 +5,8 @@ var ModuleFollowing = { append: function(list, userName) { $(list).append( $('
', { - 'class': 'item' + (userName == $(list).data('username') ? ' active' : '') + 'class': 'item' + (userName == $(list).data('username') ? ' active' : ''), + 'data-username': userName }).append( $('
', { 'class': 'avatar' @@ -23,9 +24,33 @@ var ModuleFollowing = { $('
', { 'class': 'info' }).append( - $('', { - 'href': 'people/' + userName - }).append(userName) + $('
', { + 'class': 'username' + }).append( + $('', { + 'href': 'people/' + userName + }).append(userName) + ) + ).append( + $('
', { + 'class': 'location' + }) + ).append( + $('
', { + 'class': 'bio' + }) + ).append( + $('
', { + 'class': 'url' + }) + ).append( + $('
', { + 'class': 'tox' + }) + ).append( + $('
', { + 'class': 'bitmessage' + }) ) ).append( $('
', { @@ -43,6 +68,36 @@ var ModuleFollowing = { } } }, + loadProfile: function(list, userName) { + $.ajax({ + url: 'api/user/profile', + type: 'POST', + data: { + userName: userName + }, + success: function (response) { + + if (response.success) { + + $(list).find('div[data-username="' + userName + '"] .username > a').html(response.profile.fullName ? response.profile.fullName : response.profile.userName); + $(list).find('div[data-username="' + userName + '"] .location').html(response.profile.location); + $(list).find('div[data-username="' + userName + '"] .url').html($('',{'href':response.profile.url,'class':'bi bi-link','title':'Website'})); + $(list).find('div[data-username="' + userName + '"] .bio').html(response.profile.bio); + $(list).find('div[data-username="' + userName + '"] .bitMessage').html(response.profile.bitMessage == '' ? '' : $('',{'href':'bitmessage:' + response.profile.bitMessage,'class':'bi bi-send','title':'BitMessage'})); + $(list).find('div[data-username="' + userName + '"] .tox').html(response.profile.tox == '' ? '' : $('',{'href':'tox:' + response.profile.tox,'class':'bi bi-chat-square-dots','title':'TOX'})); + + + } else { + + console.log(response.message); + + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log(textStatus, errorThrown); + } + }); + }, load: function(list, reFresh) { $.ajax({ url: 'api/follow/get', @@ -57,11 +112,12 @@ var ModuleFollowing = { $(response.users).each(function() { ModuleFollowing.template.list.item.append(list, this.userName); + ModuleFollowing.loadProfile(list, this.userName); }); } else { - alert(response.message); + console.log(response.message); } }, @@ -88,7 +144,7 @@ var ModuleFollowing = { } else { - alert(response.message); + console.log(response.message); } },