Browse Source

implement main feed and post messages features

main
ghost 3 years ago
parent
commit
d4dd0efd13
  1. 47
      src/application/controller/api/post/add.php
  2. 85
      src/application/controller/api/post/get.php
  3. 4
      src/application/controller/following.php
  4. 4
      src/application/controller/home.php
  5. 4
      src/application/controller/login.php
  6. 2
      src/application/controller/logout.php
  7. 2
      src/application/controller/register.php
  8. 1
      src/application/view/common/header/guest.phtml
  9. 3
      src/application/view/common/header/user.phtml
  10. 18
      src/application/view/home.phtml
  11. 7
      src/bootstrap.php
  12. 3
      src/config-default.php
  13. 47
      src/public/css/app.css
  14. 120
      src/public/js/home.js
  15. 15
      src/system/helper/valid.php
  16. 47
      src/system/twister.php

47
src/application/controller/api/post/add.php

@ -0,0 +1,47 @@
<?php
$response = [
'success' => 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);

85
src/application/controller/api/post/get.php

@ -0,0 +1,85 @@
<?php
$response = [
'success' => 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);

4
src/application/controller/following.php

@ -1,6 +1,6 @@
<?php <?php
if (!isset($_SESSION['username'])) { if (!isset($_SESSION['userName'])) {
header('Location: ' . PROJECT_HOST . '/login', true, 302); header('Location: ' . PROJECT_HOST . '/login', true, 302);
} }
@ -10,7 +10,7 @@ $metaTitle = _('Following | Twisterarmy Cloud');
$followingUsersTotal = 0; $followingUsersTotal = 0;
$followingUsers = []; $followingUsers = [];
foreach ((array) $_twister->getFollowing($_SESSION['username']) as $followingUserName) { foreach ((array) $_twister->getFollowing($_SESSION['userName']) as $followingUserName) {
$followingUsers[] = [ $followingUsers[] = [
'name' => $followingUserName 'name' => $followingUserName

4
src/application/controller/home.php

@ -1,6 +1,6 @@
<?php <?php
if (!isset($_SESSION['username'])) { if (!isset($_SESSION['userName'])) {
header('Location: ' . PROJECT_HOST . '/login', true, 302); header('Location: ' . PROJECT_HOST . '/login', true, 302);
} }
@ -8,7 +8,7 @@ if (!isset($_SESSION['username'])) {
$metaTitle = _('Home | Twisterarmy Cloud'); $metaTitle = _('Home | Twisterarmy Cloud');
$followingUsersTotal = 0; $followingUsersTotal = 0;
foreach ((array) $_twister->getFollowing($_SESSION['username']) as $followingUserName) { foreach ((array) $_twister->getFollowing($_SESSION['userName']) as $followingUserName) {
$followingUsersTotal++; $followingUsersTotal++;
} }

4
src/application/controller/login.php

@ -10,7 +10,7 @@ $errorUserPrivateKey = false;
$metaTitle = _('Login | Twisterarmy Cloud'); $metaTitle = _('Login | Twisterarmy Cloud');
// Redirect home when user already logged // Redirect home when user already logged
if (isset($_SESSION['username'])) { if (isset($_SESSION['userName'])) {
header('Location: ' . PROJECT_HOST, true, 302); header('Location: ' . PROJECT_HOST, true, 302);
} }
@ -74,7 +74,7 @@ if (isset($_POST) && $_POST) {
session_start(); session_start();
$_SESSION['username'] = $userName; $_SESSION['userName'] = $userName;
// Redirect // Redirect
header('Location: ' . PROJECT_HOST, true, 302); header('Location: ' . PROJECT_HOST, true, 302);

2
src/application/controller/logout.php

@ -1,7 +1,7 @@
<?php <?php
if (isset($_SESSION['username'])) { if (isset($_SESSION['userName'])) {
session_destroy(); session_destroy();
} }

2
src/application/controller/register.php

@ -1,7 +1,7 @@
<?php <?php
// Redirect to the login page on active session // Redirect to the login page on active session
if (isset($_SESSION['username'])) { if (isset($_SESSION['userName'])) {
header('Location: ' . PROJECT_HOST, true, 302); header('Location: ' . PROJECT_HOST, true, 302);
} }

1
src/application/view/common/header/guest.phtml

@ -7,6 +7,7 @@
<link rel="stylesheet" type="text/css" href="css/font.css" /> <link rel="stylesheet" type="text/css" href="css/font.css" />
<link rel="stylesheet" type="text/css" href="css/bi.css" /> <link rel="stylesheet" type="text/css" href="css/bi.css" />
<link rel="stylesheet" type="text/css" href="css/common.css" /> <link rel="stylesheet" type="text/css" href="css/common.css" />
<link rel="stylesheet" type="text/css" href="css/app.css" />
<link rel="stylesheet" type="text/css" href="css/mobile.css" /> <link rel="stylesheet" type="text/css" href="css/mobile.css" />
<script src="js/jquery.js"></script> <script src="js/jquery.js"></script>
</head> </head>

3
src/application/view/common/header/user.phtml

@ -7,9 +7,10 @@
<link rel="stylesheet" type="text/css" href="css/font.css" /> <link rel="stylesheet" type="text/css" href="css/font.css" />
<link rel="stylesheet" type="text/css" href="css/bi.css" /> <link rel="stylesheet" type="text/css" href="css/bi.css" />
<link rel="stylesheet" type="text/css" href="css/common.css" /> <link rel="stylesheet" type="text/css" href="css/common.css" />
<link rel="stylesheet" type="text/css" href="css/app.css" />
<link rel="stylesheet" type="text/css" href="css/mobile.css" /> <link rel="stylesheet" type="text/css" href="css/mobile.css" />
<link rel="stylesheet" type="text/css" href="css/user.css" />
<script src="js/jquery.js"></script> <script src="js/jquery.js"></script>
<script src="js/home.js"></script>
</head> </head>
<body class="bg-c-1 bg-img-1 c-0"> <body class="bg-c-1 bg-img-1 c-0">
<div class="bg-c-2 bg-img-2 c-1 of-hidden"> <div class="bg-c-2 bg-img-2 c-1 of-hidden">

18
src/application/view/home.phtml

@ -24,26 +24,16 @@
<div class="post"> <div class="post">
<form action="<?php echo PROJECT_HOST ?>" method="POST" name="post"> <form action="<?php echo PROJECT_HOST ?>" method="POST" name="post">
<div class="avatar"> <div class="avatar">
<img src="<?php echo PROJECT_HOST ?>/api/image?hash=<?php echo $_SESSION['username'] ?>" alt="" /> <img src="<?php echo PROJECT_HOST ?>/api/image?hash=<?php echo $_SESSION['userName'] ?>" alt="" />
</div> </div>
<div class="message"> <div class="message">
<textarea name="post" placeholder="<?php echo _('Enter your post...') ?>"></textarea> <textarea name="post" placeholder="<?php echo _('Enter your post...') ?>" id="message"></textarea>
</div> </div>
<div class="action"> <div class="action">
<!--<span>220</span>--> <div class="button" onclick="Home.post.add('#feed', '#message')"><?php echo _('Send') ?></div>
<button><?php echo _('Send') ?></button>
</div> </div>
</form> </form>
</div> </div>
<div class="content"> <div class="content" id="feed"></div>
<div class="item">
<div class="avatar">
<img src="<?php echo PROJECT_HOST ?>/api/image?hash=<?php echo $_SESSION['username'] ?>" alt="" />
</div>
<div class="message">
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
</div>
</div>
</div>
</div> </div>
</div> </div>

7
src/bootstrap.php

@ -12,6 +12,7 @@ require(PROJECT_DIR . '/system/twister.php');
require(PROJECT_DIR . '/system/icon.php'); require(PROJECT_DIR . '/system/icon.php');
require(PROJECT_DIR . '/system/helper/filter.php'); require(PROJECT_DIR . '/system/helper/filter.php');
require(PROJECT_DIR . '/system/helper/valid.php'); require(PROJECT_DIR . '/system/helper/valid.php');
require(PROJECT_DIR . '/system/helper/localization.php');
// Init libraries // Init libraries
$_twister = new Twister( $_twister = new Twister(
@ -69,6 +70,12 @@ if (isset($_GET['_route_'])) {
case 'api/image': case 'api/image':
require(PROJECT_DIR . '/application/controller/api/image.php'); require(PROJECT_DIR . '/application/controller/api/image.php');
break; 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: default:
require(PROJECT_DIR . '/application/controller/error/404.php'); require(PROJECT_DIR . '/application/controller/error/404.php');
} }

3
src/config-default.php

@ -25,3 +25,6 @@ define('TWISTER_PASSWORD', '');
// COMMON // COMMON
define('APPLICATION_ALLOW_REGISTRATION', true); define('APPLICATION_ALLOW_REGISTRATION', true);
define('APPLICATION_FOLLOW_ON_REGISTRATION', []); define('APPLICATION_FOLLOW_ON_REGISTRATION', []);
define('APPLICATION_MAX_POST_SPLIT', 5);
define('APPLICATION_MAX_POST_FEED', 50);

47
src/public/css/user.css → src/public/css/app.css

@ -58,7 +58,7 @@ a:active {
} }
.container .post { .container .post {
margin-bottom: 10px; margin-bottom: 14px;
background: #272E39; background: #272E39;
border-radius: 3px; border-radius: 3px;
overflow: hidden; overflow: hidden;
@ -96,10 +96,8 @@ a:active {
border-radius: 3px; border-radius: 3px;
font-family: Roboto-Regular, Sans-Serif, Verdana; font-family: Roboto-Regular, Sans-Serif, Verdana;
font-size: 14px; font-size: 14px;
/*background: rgba(101, 114, 134, 0.28);*/ background: rgb(238, 238, 238);
/*background: rgba(255, 255, 255, 0.18);*/ color: #1c1d1e;
background: rgb(77, 86, 102);
color: #dfe8f4;
outline: none; outline: none;
letter-spacing: 0.2px; letter-spacing: 0.2px;
font-size: 13px; font-size: 13px;
@ -108,21 +106,20 @@ a:active {
.container .post textarea:focus { .container .post textarea:focus {
height: 80px; height: 80px;
background: rgb(87, 98, 117);
/*background: rgb(103, 112, 126);*/
} }
.container .post button { .container .post .button {
float: right; float: right;
padding: 8px 16px; padding: 6px 16px;
border-radius: 3px; border-radius: 3px;
cursor: pointer; cursor: pointer;
background-color: #337ab7; background-color: #337ab7;
color: #fff; color: #fff;
border: 0 border: 0;
font-size: 13px;
} }
.container .post button:hover { .container .post .button:hover {
background-color: #437baa background-color: #437baa
} }
@ -134,13 +131,10 @@ a:active {
.container .content .item { .container .content .item {
padding: 16px; padding: 16px;
margin-bottom: 8px; margin-bottom: 2px;
/*background: rgba(101, 114, 134, 0.28);*/ color: #1c1d1e;
/*background: rgba(255, 254, 254, 0.04);*/ background: rgb(238, 238, 238);
/*background: rgba(255, 255, 255, 0.18);*/
background: rgb(39, 46, 57);
border-radius: 3px; border-radius: 3px;
color: #a5b2bd;
min-height: 84px; min-height: 84px;
} }
@ -161,3 +155,22 @@ a:active {
font-size: 13px; font-size: 13px;
padding-right: 8px; 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;
}

120
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 = $(
$('<div/>', {
'class': 'reTwist'
}).append(
$('<div/>', {
'class': 'info'
}).append(
reTwist.userName
).append(
$('<span/>', {
'class': 'time'
}).append(
reTwist.time
)
)
).append(reTwist.message)
);
}
$(feed).append(
$('<div/>', {
'class': 'item'
}).append(
$('<div/>', {
'class': 'avatar'
}).append(
$('<img/>', {
'src': '/api/image?hash=' + userName,
'alt': '',
})
)
).append(
$('<div/>', {
'class': 'message'
}).append(
$('<div/>', {
'class': 'info'
}).append(
userName
).append(
$('<span/>', {
'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);
});

15
src/system/helper/valid.php

@ -2,6 +2,21 @@
class Valid { 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) { public static function userName(string $userName) {
if (preg_match('/[^a-zA-Z0-9_]+/u', $userName)) { if (preg_match('/[^a-zA-Z0-9_]+/u', $userName)) {

47
src/system/twister.php

@ -109,7 +109,14 @@ class Twister {
return false; 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( $this->_curl->prepare(
'/', '/',
@ -120,10 +127,7 @@ class Twister {
'method' => 'getposts', 'method' => 'getposts',
'params' => [ 'params' => [
$limit, $limit,
[ $data
['username' => $userNameRecipient],
['username' => $userNameSender],
]
], ],
'id' => time() + rand() 'id' => time() + rand()
] ]
@ -301,4 +305,37 @@ class Twister {
return false; 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;
}
} }
Loading…
Cancel
Save