diff --git a/src/application/controller/api/post/add.php b/src/application/controller/api/post/add.php new file mode 100644 index 0000000..0dff51e --- /dev/null +++ b/src/application/controller/api/post/add.php @@ -0,0 +1,47 @@ + false, + 'message' => _('Internal server error') +]; + +if (isset($_SESSION['userName'])) { + + if (!isset($_POST['message']) || (isset($_POST['message']) && !Valid::userPost($_POST['message']))) { + + $response = [ + 'success' => false, + 'message' => _('Max 140 chars per message') + ]; + + } else if (!$userPosts = $_twister->getPosts([$_SESSION['userName']], 1)) { + + $response = [ + 'success' => false, + 'message' => _('Could not receive user post') + ]; + + } else if (isset($userPosts[0]['userpost']['k']) && $result = $_twister->newPostMessage($_SESSION['userName'], $userPosts[0]['userpost']['k'] + 1, $_POST['message'])) { + + $response = [ + 'success' => true, + 'message' => _('Post successfully sent') + ]; + + } else { + + $response = [ + 'success' => false, + 'message' => _('Could not send post message') + ]; + } + +} else { + $response = [ + 'success' => false, + 'message' => _('Session expired. Please, reload the page.') + ]; +} + +header('Content-Type: application/json; charset=utf-8'); +echo json_encode($response); \ No newline at end of file diff --git a/src/application/controller/api/post/get.php b/src/application/controller/api/post/get.php new file mode 100644 index 0000000..16ab822 --- /dev/null +++ b/src/application/controller/api/post/get.php @@ -0,0 +1,85 @@ + false, + 'message' => _('Internal server error'), + 'posts' => [], +]; + +if (isset($_SESSION['userName'])) { + + if ($result = $_twister->getPosts($_twister->getFollowing($_SESSION['userName']), + APPLICATION_MAX_POST_FEED)) { + + $posts = []; + foreach ($result as $post) { + + // Split message parts + $messages = [$post['userpost']['msg']]; + + for ($i = 0; $i <= APPLICATION_MAX_POST_SPLIT; $i++) { + + $n = sprintf('msg%s', $i); + + if (isset($post['userpost'][$n])) { + $messages[] = $post['userpost'][$n]; + } + } + + // Process reTwists + $reTwist = []; + if (isset($post['userpost']['rt'])) { + + // Split reTwists parts + $reTwists = [$post['userpost']['rt']['msg']]; + + for ($i = 0; $i <= APPLICATION_MAX_POST_SPLIT; $i++) { + + $n = sprintf('msg%s', $i); + + if (isset($post['userpost']['rt'][$n])) { + $reTwists[] = $post['userpost']['rt'][$n]; + } + } + + $reTwist = [ + 'message' => implode('', $reTwists), + 'time' => Localization::time($post['userpost']['rt']['time']), + 'userName' => $post['userpost']['rt']['n'], + 'reTwist' => $reTwist, + ]; + } + + $posts[] = [ + 'message' => implode('', $messages), + 'time' => Localization::time($post['userpost']['time']), + 'userName' => $post['userpost']['n'], + 'reTwist' => $reTwist, + ]; + } + + $response = [ + 'success' => true, + 'message' => _('Posts successfully loaded'), + 'posts' => $posts + ]; + + } else { + + $response = [ + 'success' => false, + 'message' => _('Could not receive post data'), + 'posts' => [], + ]; + } + +} else { + $response = [ + 'success' => false, + 'message' => _('Session expired'), + 'posts' => [], + ]; +} + +header('Content-Type: application/json; charset=utf-8'); +echo json_encode($response); \ No newline at end of file diff --git a/src/application/controller/following.php b/src/application/controller/following.php index 39fddbd..06849ef 100644 --- a/src/application/controller/following.php +++ b/src/application/controller/following.php @@ -1,6 +1,6 @@ getFollowing($_SESSION['username']) as $followingUserName) { +foreach ((array) $_twister->getFollowing($_SESSION['userName']) as $followingUserName) { $followingUsers[] = [ 'name' => $followingUserName diff --git a/src/application/controller/home.php b/src/application/controller/home.php index be9d115..64d578a 100644 --- a/src/application/controller/home.php +++ b/src/application/controller/home.php @@ -1,6 +1,6 @@ getFollowing($_SESSION['username']) as $followingUserName) { +foreach ((array) $_twister->getFollowing($_SESSION['userName']) as $followingUserName) { $followingUsersTotal++; } diff --git a/src/application/controller/login.php b/src/application/controller/login.php index 5bc3bcd..bdd826a 100644 --- a/src/application/controller/login.php +++ b/src/application/controller/login.php @@ -10,7 +10,7 @@ $errorUserPrivateKey = false; $metaTitle = _('Login | Twisterarmy Cloud'); // Redirect home when user already logged -if (isset($_SESSION['username'])) { +if (isset($_SESSION['userName'])) { header('Location: ' . PROJECT_HOST, true, 302); } @@ -74,7 +74,7 @@ if (isset($_POST) && $_POST) { session_start(); - $_SESSION['username'] = $userName; + $_SESSION['userName'] = $userName; // Redirect header('Location: ' . PROJECT_HOST, true, 302); diff --git a/src/application/controller/logout.php b/src/application/controller/logout.php index f0712dd..28ef6dc 100644 --- a/src/application/controller/logout.php +++ b/src/application/controller/logout.php @@ -1,7 +1,7 @@ + diff --git a/src/application/view/common/header/user.phtml b/src/application/view/common/header/user.phtml index 01b8be8..65adc6c 100644 --- a/src/application/view/common/header/user.phtml +++ b/src/application/view/common/header/user.phtml @@ -7,9 +7,10 @@ + - +
diff --git a/src/application/view/home.phtml b/src/application/view/home.phtml index c909e12..36cce3b 100644 --- a/src/application/view/home.phtml +++ b/src/application/view/home.phtml @@ -24,26 +24,16 @@
- +
- +
- - +
-
-
-
- -
-
- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make -
-
-
+
\ No newline at end of file diff --git a/src/bootstrap.php b/src/bootstrap.php index 6ba1c7c..d45674b 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -12,6 +12,7 @@ require(PROJECT_DIR . '/system/twister.php'); require(PROJECT_DIR . '/system/icon.php'); require(PROJECT_DIR . '/system/helper/filter.php'); require(PROJECT_DIR . '/system/helper/valid.php'); +require(PROJECT_DIR . '/system/helper/localization.php'); // Init libraries $_twister = new Twister( @@ -69,6 +70,12 @@ if (isset($_GET['_route_'])) { case 'api/image': require(PROJECT_DIR . '/application/controller/api/image.php'); break; + case 'api/post/add': + require(PROJECT_DIR . '/application/controller/api/post/add.php'); + break; + case 'api/post/get': + require(PROJECT_DIR . '/application/controller/api/post/get.php'); + break; default: require(PROJECT_DIR . '/application/controller/error/404.php'); } diff --git a/src/config-default.php b/src/config-default.php index e33f4c2..32515e9 100644 --- a/src/config-default.php +++ b/src/config-default.php @@ -24,4 +24,7 @@ define('TWISTER_PASSWORD', ''); // COMMON define('APPLICATION_ALLOW_REGISTRATION', true); -define('APPLICATION_FOLLOW_ON_REGISTRATION', []); \ No newline at end of file +define('APPLICATION_FOLLOW_ON_REGISTRATION', []); + +define('APPLICATION_MAX_POST_SPLIT', 5); +define('APPLICATION_MAX_POST_FEED', 50); \ No newline at end of file diff --git a/src/public/css/user.css b/src/public/css/app.css similarity index 79% rename from src/public/css/user.css rename to src/public/css/app.css index 22cf5c5..6d505b9 100644 --- a/src/public/css/user.css +++ b/src/public/css/app.css @@ -58,7 +58,7 @@ a:active { } .container .post { - margin-bottom: 10px; + margin-bottom: 14px; background: #272E39; border-radius: 3px; overflow: hidden; @@ -96,10 +96,8 @@ a:active { border-radius: 3px; font-family: Roboto-Regular, Sans-Serif, Verdana; font-size: 14px; - /*background: rgba(101, 114, 134, 0.28);*/ - /*background: rgba(255, 255, 255, 0.18);*/ - background: rgb(77, 86, 102); - color: #dfe8f4; + background: rgb(238, 238, 238); + color: #1c1d1e; outline: none; letter-spacing: 0.2px; font-size: 13px; @@ -108,21 +106,20 @@ a:active { .container .post textarea:focus { height: 80px; - background: rgb(87, 98, 117); - /*background: rgb(103, 112, 126);*/ } -.container .post button { +.container .post .button { float: right; - padding: 8px 16px; + padding: 6px 16px; border-radius: 3px; cursor: pointer; background-color: #337ab7; color: #fff; - border: 0 + border: 0; + font-size: 13px; } -.container .post button:hover { +.container .post .button:hover { background-color: #437baa } @@ -134,13 +131,10 @@ a:active { .container .content .item { padding: 16px; - margin-bottom: 8px; - /*background: rgba(101, 114, 134, 0.28);*/ - /*background: rgba(255, 254, 254, 0.04);*/ - /*background: rgba(255, 255, 255, 0.18);*/ - background: rgb(39, 46, 57); + margin-bottom: 2px; + color: #1c1d1e; + background: rgb(238, 238, 238); border-radius: 3px; - color: #a5b2bd; min-height: 84px; } @@ -160,4 +154,23 @@ a:active { letter-spacing: 0.2px; font-size: 13px; padding-right: 8px; +} + +.container .content .item .message .retwist { + border: 1px #ccc solid; + padding: 8px; + border-radius: 3px; + background: #e6e6e6; +} + +.container .item .message .info { + font-weight: bold; + /*border-bottom: 1px #ccc solid;*/ + padding-bottom: 4px; + margin-bottom: 8px; +} + +.container .item .message .info .time { + float: right; + font-weight: normal; } \ No newline at end of file diff --git a/src/public/js/home.js b/src/public/js/home.js new file mode 100644 index 0000000..c64ef9a --- /dev/null +++ b/src/public/js/home.js @@ -0,0 +1,120 @@ +var Home = { + template: { + feed: { + item: { + append: function(feed, userName, time, message, reTwist) { + + if (reTwist === undefined || reTwist.length == 0) { + var rt = false; + } else { + var rt = $( + $('
', { + 'class': 'reTwist' + }).append( + $('
', { + 'class': 'info' + }).append( + reTwist.userName + ).append( + $('', { + 'class': 'time' + }).append( + reTwist.time + ) + ) + ).append(reTwist.message) + ); + } + + $(feed).append( + $('
', { + 'class': 'item' + }).append( + $('
', { + 'class': 'avatar' + }).append( + $('', { + 'src': '/api/image?hash=' + userName, + 'alt': '', + }) + ) + ).append( + $('
', { + 'class': 'message' + }).append( + $('
', { + 'class': 'info' + }).append( + userName + ).append( + $('', { + 'class': 'time' + }).append( + time + ) + ) + ).append(rt).append(message) + ) + ); + } + } + } + }, + post: { + add: function(feed, input) { + $.ajax({ + url: 'api/post/add', + type: 'POST', + data: { + message: $(input).val() + }, + success: function (response) { + + if (response.success) { + + $(input).val(''); + + Home.post.get(feed, true); + + } else { + alert(response.message); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log(textStatus, errorThrown); + } + }); + }, + get: function(feed, reFresh) { + $.ajax({ + url: 'api/post/get', + type: 'POST', + data: {}, + success: function (response) { + if (response.success) { + + if (reFresh) { + $(feed).html(''); + } + + $(response.posts).each(function() { + Home.template.feed.item.append(feed, this.userName, this.time, this.message, this.reTwist); + }); + + } else { + + alert(response.message); + + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log(textStatus, errorThrown); + } + }); + }, + } +} + +$(document).ready(function() { + Home.post.get('#feed', true); +}); \ No newline at end of file diff --git a/src/system/helper/valid.php b/src/system/helper/valid.php index f93eec9..7686808 100644 --- a/src/system/helper/valid.php +++ b/src/system/helper/valid.php @@ -2,6 +2,21 @@ class Valid { + public static function userPost(string $userPost) { + + $length = mb_strlen($userPost); + + if ($length < 1 || $length > 140) { + + return false; + + } else { + + return true; + + } + } + public static function userName(string $userName) { if (preg_match('/[^a-zA-Z0-9_]+/u', $userName)) { diff --git a/src/system/twister.php b/src/system/twister.php index 76e77b8..6a93a34 100644 --- a/src/system/twister.php +++ b/src/system/twister.php @@ -109,7 +109,14 @@ class Twister { return false; } - public function getPosts(string $userNameRecipient, string $userNameSender, int $limit) { + public function getPosts(array $userNames, int $limit) { + + $data = []; + foreach ($userNames as $userName) { + $data[] = [ + 'username' => $userName + ]; + } $this->_curl->prepare( '/', @@ -120,10 +127,7 @@ class Twister { 'method' => 'getposts', 'params' => [ $limit, - [ - ['username' => $userNameRecipient], - ['username' => $userNameSender], - ] + $data ], 'id' => time() + rand() ] @@ -301,4 +305,37 @@ class Twister { return false; } + + public function newPostMessage(string $userName, int $index, string $message) { + + $this->_curl->prepare( + '/', + 'POST', + 30, + [ + 'jsonrpc' => '2.0', + 'method' => 'newpostmsg', + 'params' => [ + $userName, + $index, + $message + ], + 'id' => time() + rand() + ] + ); + + if ($response = $this->_curl->execute()) { + + if ($response['error']) { + + $this->_error = _($response['error']['message']); + + } else { + + return $response['result']; // transaction ID + } + } + + return false; + } } \ No newline at end of file