diff --git a/src/application/controller/api/user/profile.php b/src/application/controller/api/user/profile.php
index 13c1a6e..ead5216 100644
--- a/src/application/controller/api/user/profile.php
+++ b/src/application/controller/api/user/profile.php
@@ -47,12 +47,12 @@ if (isset($_SESSION['userName'])) {
}
}
-
// Get latest version available
if ($profileInfo = $_modelProfile->get($userId)) {
$profile = [
'userName' => $userName,
+ 'seq' => $profileInfo['seq'],
'fullName' => $profileInfo['fullName'],
'location' => $profileInfo['location'],
'url' => $profileInfo['url'],
diff --git a/src/application/controller/common/module/settings.php b/src/application/controller/common/module/settings.php
new file mode 100644
index 0000000..9225e84
--- /dev/null
+++ b/src/application/controller/common/module/settings.php
@@ -0,0 +1,3 @@
+getThisBlock();
+
+ // Save revision to DHT
+ $userProfileVersions = $_twister->putDHT( $_SESSION['userName'],
+ 'profile',
+ 's',
+ [
+ 'fullname' => $fullName,
+ 'location' => $location,
+ 'url' => $url,
+ 'bitmessage' => $bitMessage,
+ 'tox' => $tox,
+ 'bio' => $bio,
+ ],
+ $_SESSION['userName'],
+ $seq);
+
+ // Save revision to DB
+ if (!$_modelProfile->versionExists($_SESSION['userId'],
+ $blockId,
+ $seq)) {
+
+ $_modelProfile->add($_SESSION['userId'],
+ $blockId,
+ $seq,
+ time(),
+ $fullName,
+ $bio,
+ $location,
+ $url,
+ $bitMessage,
+ $tox);
+ }
+
+ $_memcache->replace('api.user.profile.' . $_SESSION['userName'],
+ [
+ 'userName' => $_SESSION['userName'],
+ 'seq' => $seq,
+ 'fullName' => $fullName,
+ 'location' => $location,
+ 'url' => $url,
+ 'bitMessage' => $bitMessage,
+ 'tox' => $tox,
+ 'bio' => $bio,
+ ],
+ MEMCACHE_COMPRESS,
+ MEMCACHE_DHT_PROFILE_TIMEOUT);
+
+}
+
+// Get profile details
+if ($profile = $_memcache->get('api.user.profile.' . $_SESSION['userName'])) {
+
+ $seq = $profile['seq'];
+ $fullName = $profile['fullName'];
+ $location = $profile['location'];
+ $url = $profile['url'];
+ $bitMessage = $profile['bitMessage'];
+ $tox = $profile['tox'];
+ $bio = $profile['bio'];
+
+} else if ($userProfileVersions = $_twister->getDHT($_SESSION['userName'], 'profile', 's')) {
+
+ // Check user exists
+ if ($userId = $_modelUser->getUserId($_SESSION['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($_SESSION['userId'])) {
+
+ $profile = [
+ 'userName' => $_SESSION['userName'],
+ 'seq' => $profileInfo['seq'],
+ 'fullName' => $profileInfo['fullName'],
+ 'location' => $profileInfo['location'],
+ 'url' => $profileInfo['url'],
+ 'bitMessage' => $profileInfo['bitMessage'],
+ 'tox' => $profileInfo['tox'],
+ 'bio' => $profileInfo['bio'],
+ ];
+
+ $seq = $profile['seq'];
+ $fullName = $profile['fullName'];
+ $location = $profile['location'];
+ $url = $profile['url'];
+ $bitMessage = $profile['bitMessage'];
+ $tox = $profile['tox'];
+ $bio = $profile['bio'];
+
+ $_memcache->set('api.user.profile.' . $_SESSION['userName'], $profile, MEMCACHE_COMPRESS, MEMCACHE_DHT_PROFILE_TIMEOUT);
+
+ }
+}
+
+require(PROJECT_DIR . '/application/view/settings/profile.phtml');
\ No newline at end of file
diff --git a/src/application/model/block.php b/src/application/model/block.php
index c8df5d3..b896bf7 100644
--- a/src/application/model/block.php
+++ b/src/application/model/block.php
@@ -17,6 +17,21 @@ class ModelBlock extends Model {
}
}
+ public function getThisBlock() {
+
+ try {
+
+ $query = $this->_db->query("SELECT MAX(`blockId`) AS `blockId` FROM `block`");
+
+ return $query->fetch()['blockId'];
+
+ } catch (PDOException $e) {
+
+ trigger_error($e->getMessage());
+ return false;
+ }
+ }
+
public function getNextBlock() {
try {
diff --git a/src/application/view/common/module/menu.phtml b/src/application/view/common/module/menu.phtml
index 87134d2..d11b734 100644
--- a/src/application/view/common/module/menu.phtml
+++ b/src/application/view/common/module/menu.phtml
@@ -13,7 +13,7 @@
-
+
\ No newline at end of file
diff --git a/src/application/view/common/module/settings.phtml b/src/application/view/common/module/settings.phtml
new file mode 100644
index 0000000..8ea4d5e
--- /dev/null
+++ b/src/application/view/common/module/settings.phtml
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/src/application/view/settings/profile.phtml b/src/application/view/settings/profile.phtml
new file mode 100644
index 0000000..b765760
--- /dev/null
+++ b/src/application/view/settings/profile.phtml
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/src/bootstrap.php b/src/bootstrap.php
index 2159015..53465da 100644
--- a/src/bootstrap.php
+++ b/src/bootstrap.php
@@ -87,6 +87,9 @@ if (isset($_GET['_route_'])) {
case 'register':
require(PROJECT_DIR . '/application/controller/register.php');
break;
+ case 'settings':
+ require(PROJECT_DIR . '/application/controller/settings/profile.php');
+ break;
// API calls
case 'api/image':
diff --git a/src/public/css/template/default/app.css b/src/public/css/template/default/app.css
index bde0284..328535d 100644
--- a/src/public/css/template/default/app.css
+++ b/src/public/css/template/default/app.css
@@ -6,12 +6,23 @@
transition: all .5s ease-in; */
}
+:focus {outline:none;}
+::-moz-focus-inner {border:0;}
+
a,
a:visited,
a:active {
color: #fff
}
+input[type="text"],
+textarea {
+ padding: 9px 16px;
+ width: 100%;
+ border-radius: 3px;
+ background: rgb(238, 238, 238);
+}
+
.container {
max-width: 1024px;
margin: 16px auto;
diff --git a/src/public/css/template/default/module/following.css b/src/public/css/template/default/module/following.css
index e2d56bb..625d755 100644
--- a/src/public/css/template/default/module/following.css
+++ b/src/public/css/template/default/module/following.css
@@ -60,11 +60,11 @@
font-size: 13px;
}
-.moduleFollowing .item .info .username {
+.moduleFollowing .item .info .userName {
margin-bottom: 8px;
}
-.moduleFollowing .item .info .username a {
+.moduleFollowing .item .info .userName a {
font-weight: bold;
}
@@ -86,10 +86,11 @@
.moduleFollowing .item .info .tox,
.moduleFollowing .item .info .bitMessage {
display: inline-block;
- margin-right: 4px;
- margin-top: 4px;
+ margin: 2px 4px;
+ font-size: 10px;
}
.moduleFollowing .item .info .tox {
- font-size: 10px
+ font-size: 10px;
+ margin: 2px 4px;
}
\ No newline at end of file
diff --git a/src/public/css/template/default/module/menu.css b/src/public/css/template/default/module/menu.css
index 0a2c349..77b6200 100644
--- a/src/public/css/template/default/module/menu.css
+++ b/src/public/css/template/default/module/menu.css
@@ -9,8 +9,10 @@
border-radius: 3px;
cursor: pointer;
text-align: center;
- padding: 8px 16px;
+ padding: 0 16px;
margin: 0 2px 2px 2px;
+ height: 36px;
+ line-height: 36px;
}
.moduleMenu .item.active,
diff --git a/src/public/css/template/default/module/settings.css b/src/public/css/template/default/module/settings.css
new file mode 100644
index 0000000..e4f7749
--- /dev/null
+++ b/src/public/css/template/default/module/settings.css
@@ -0,0 +1,13 @@
+
+.moduleSettings .item {
+ display: block;
+ background: rgba(39, 46, 57, 0.28);
+ border-radius: 3px;
+ padding: 8px 16px;
+ margin: 0 2px 2px 2px;
+}
+
+.moduleSettings .item.active,
+.moduleSettings .item:hover {
+ background: #272E39;
+}
\ No newline at end of file
diff --git a/src/public/css/template/default/settings/profile.css b/src/public/css/template/default/settings/profile.css
new file mode 100644
index 0000000..b96c3a0
--- /dev/null
+++ b/src/public/css/template/default/settings/profile.css
@@ -0,0 +1,57 @@
+.settingsProfile form {
+ background: rgba(39, 46, 57, 0.28);
+ padding: 16px;
+ border-radius: 3px;
+}
+
+.settingsProfile form label {
+ color: #ccc;
+ display: block;
+ margin-bottom: 4px;
+}
+
+.settingsProfile form input {
+ background: transparent;
+ margin-bottom: 16px;
+ width: 360px;
+ font-size: 15px;
+ color: #fff
+}
+
+.settingsProfile form input:focus {
+ background: rgb(238, 238, 238);
+ color: #1c1d1e
+}
+
+.settingsProfile form textarea {
+ background: transparent;
+ margin-bottom: 8px;
+ min-height: 80px;
+ font-size: 14px;
+ color: #fff
+}
+
+.settingsProfile form textarea:focus {
+ background: rgb(238, 238, 238);
+ color: #1c1d1e
+}
+
+.settingsProfile form button {
+ float: right;
+ padding: 10px 16px;
+ border-radius: 3px;
+ cursor: pointer;
+ background-color: #337ab7;
+ color: #fff;
+ border: 0;
+ width: 100%;
+}
+
+.settingsProfile form button:hover {
+ background-color: #437baa;
+}
+
+.settingsProfile form .actions {
+ text-align: right;
+ overflow: hidden;
+}
\ No newline at end of file
diff --git a/src/public/js/module/following.js b/src/public/js/module/following.js
index 3994165..f05fe32 100644
--- a/src/public/js/module/following.js
+++ b/src/public/js/module/following.js
@@ -25,7 +25,7 @@ var ModuleFollowing = {
'class': 'info'
}).append(
$('', {
- 'class': 'username'
+ 'class': 'userName'
}).append(
$('', {
'href': 'people/' + userName
@@ -49,7 +49,7 @@ var ModuleFollowing = {
})
).append(
$('', {
- 'class': 'bitmessage'
+ 'class': 'bitMessage'
})
)
).append(
@@ -79,7 +79,7 @@ var ModuleFollowing = {
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 + '"] .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(response.profile.url == '' ? '' : $('',{'href':response.profile.url,'class':'bi bi-link','target':'_blank','title':'Website'}));
$(list).find('div[data-username="' + userName + '"] .bio').html(response.profile.bio);
diff --git a/src/public/js/module/settings.js b/src/public/js/module/settings.js
new file mode 100644
index 0000000..9cd0fe3
--- /dev/null
+++ b/src/public/js/module/settings.js
@@ -0,0 +1,7 @@
+var ModuleSettings = {
+ init: function(href) {
+
+ $('#moduleSettings a[href="' + href + '"]').addClass('active');
+
+ }
+}
\ No newline at end of file
diff --git a/src/public/js/settings/profile.js b/src/public/js/settings/profile.js
new file mode 100644
index 0000000..bb17164
--- /dev/null
+++ b/src/public/js/settings/profile.js
@@ -0,0 +1,7 @@
+$(document).ready(function() {
+
+ // Init modules
+ ModuleMenu.init('settings');
+ ModuleSettings.init('settings');
+
+});
\ No newline at end of file
diff --git a/src/system/twister.php b/src/system/twister.php
index 7f5c91b..cd3844e 100644
--- a/src/system/twister.php
+++ b/src/system/twister.php
@@ -276,6 +276,47 @@ class Twister {
return false;
}
+ public function putDHT(string $peerAlias,
+ string $command,
+ string $flag, // s(ingle)/m(ulti)
+ mixed $value,
+ string $sig_user,
+ int $seq) {
+
+ $this->_curl->prepare(
+ '/',
+ 'POST',
+ 30,
+ [
+ 'jsonrpc' => '2.0',
+ 'method' => 'dhtput',
+ 'params' => [
+ $peerAlias,
+ $command,
+ $flag,
+ $value,
+ $sig_user,
+ $seq,
+ ],
+ 'id' => time() + rand()
+ ]
+ );
+
+ if ($response = $this->_curl->execute()) {
+
+ if ($response['error']) {
+
+ $this->_error = _($response['error']['message']);
+
+ } else {
+
+ return $response['result']; // Array
+ }
+ }
+
+ return false;
+ }
+
public function createWalletUser(string $userName) {
$this->_curl->prepare(