define ( 'FRIENDICA_CODENAME', 'Asparagus');
define ( 'FRIENDICA_VERSION', '3.5-dev' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
-define ( 'DB_UPDATE_VERSION', 1195 );
+define ( 'DB_UPDATE_VERSION', 1196 );
/**
* @brief Constant with a HTML line break.
return false;
}
-
-function load_contact_links($uid) {
-
- $a = get_app();
-
- $ret = array();
-
- if(! $uid || x($a->contacts,'empty'))
- return;
-
- $r = q("SELECT `id`,`network`,`url`,`thumb`, `rel` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `thumb` != ''",
- intval($uid)
- );
- if(count($r)) {
- foreach($r as $rr){
- $url = normalise_link($rr['url']);
- $ret[$url] = $rr;
- }
- } else
- $ret['empty'] = true;
-
- $a->contacts = $ret;
- return;
-}
-
/**
* @brief Returns querystring as string from a mapped array.
*
-- ------------------------------------------
-- Friendica 3.5-dev (Asparagus)
--- DB_UPDATE_VERSION 1195
+-- DB_UPDATE_VERSION 1196
-- ------------------------------------------
INDEX `extid` (`extid`),
INDEX `uid_id` (`uid`,`id`),
INDEX `uid_created` (`uid`,`created`),
- INDEX `uid_unseen` (`uid`,`unseen`),
+ INDEX `uid_unseen_contactid` (`uid`,`unseen`,`contact-id`),
INDEX `uid_network_received` (`uid`,`network`,`received`),
INDEX `uid_received` (`uid`,`received`),
INDEX `uid_network_commented` (`uid`,`network`,`commented`),
* max_connections_level - The maximum level of connections that are allowed to let the poller start. It is a percentage value. Default value is 75.
* max_contact_queue - Default value is 500.
* max_batch_queue - Default value is 1000.
+* max_processes_backend - Maximum number of concurrent database processes for background tasks. Default value is 5.
+* max_processes_frontend - Maximum number of concurrent database processes for foreground tasks. Default value is 20.
* no_oembed (Boolean) - Don't use OEmbed to fetch more information about a link.
* no_oembed_rich_content (Boolean) - Don't show the rich content (e.g. embedded PDF).
* no_smilies (Boolean) - Don't show smilies.
);
}}
-function get_contact_details_by_url($url, $uid = -1) {
+/**
+ * @brief Get contact data for a given profile link
+ *
+ * The function looks at several places (contact table and gcontact table) for the contact
+ *
+ * @param string $url The profile link
+ * @param int $uid User id
+ * @param array $default If not data was found take this data as default value
+ *
+ * @return array Contact data
+ */
+function get_contact_details_by_url($url, $uid = -1, $default = array()) {
if ($uid == -1)
$uid = local_user();
- $r = q("SELECT `id` AS `gid`, `url`, `name`, `nick`, `addr`, `photo`, `location`, `about`, `keywords`, `gender`, `community`, `network` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
- dbesc(normalise_link($url)));
-
- if ($r) {
- $profile = $r[0];
-
- if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND
- in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
- proc_run('php',"include/update_gcontact.php", $profile["gid"]);
- }
+ // Fetch contact data from the contact table for the user and given network
+ $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
+ `keywords`, `gender`, `photo`, `thumb`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, `self`
+ FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` IN ('%s', '')",
+ dbesc(normalise_link($url)), intval($uid), dbesc($profile["network"]));
- // Fetching further contact data from the contact table
- $r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd`, `self` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` IN ('%s', '')",
- dbesc(normalise_link($url)), intval($uid), dbesc($profile["network"]));
+ // Is the contact present for the user in a different network? (Can happen with OStatus and the "Statusnet" addon)
+ if (!count($r) AND !isset($profile))
+ $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
+ `keywords`, `gender`, `photo`, `thumb`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, `self`
+ FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
+ dbesc(normalise_link($url)), intval($uid));
+ // Fetch the data from the contact table with "uid=0" (which is filled automatically)
if (!count($r) AND !isset($profile))
- $r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd`, `self` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
- dbesc(normalise_link($url)), intval($uid));
+ $r = q("SELECT `id`, 0 AS `cid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
+ `keywords`, `gender`, `photo`, `thumb`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `bd` AS `birthday`, 0 AS `self`
+ FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
+ dbesc(normalise_link($url)));
+ // Fetch the data from the gcontact table
if (!count($r) AND !isset($profile))
- $r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `thumb`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
- dbesc(normalise_link($url)));
+ $r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`,
+ `keywords`, `gender`, `photo`, `photo` AS `thumb`, `community` AS `forum`, 0 AS `prv`, `community`, `birthday`, 0 AS `self`
+ FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
+ dbesc(normalise_link($url)));
if ($r) {
- if (!isset($profile["url"]) AND $r[0]["url"])
- $profile["url"] = $r[0]["url"];
- if (!isset($profile["name"]) AND $r[0]["name"])
- $profile["name"] = $r[0]["name"];
- if (!isset($profile["nick"]) AND $r[0]["nick"])
- $profile["nick"] = $r[0]["nick"];
- if (!isset($profile["addr"]) AND $r[0]["addr"])
- $profile["addr"] = $r[0]["addr"];
- if ((!isset($profile["photo"]) OR $r[0]["self"]) AND $r[0]["photo"])
- $profile["photo"] = $r[0]["photo"];
- if (!isset($profile["location"]) AND $r[0]["location"])
- $profile["location"] = $r[0]["location"];
- if (!isset($profile["about"]) AND $r[0]["about"])
- $profile["about"] = $r[0]["about"];
- if (!isset($profile["keywords"]) AND $r[0]["keywords"])
- $profile["keywords"] = $r[0]["keywords"];
- if (!isset($profile["gender"]) AND $r[0]["gender"])
- $profile["gender"] = $r[0]["gender"];
- if (isset($r[0]["forum"]) OR isset($r[0]["prv"]))
- $profile["community"] = ($r[0]["forum"] OR $r[0]["prv"]);
- if (!isset($profile["network"]) AND $r[0]["network"])
- $profile["network"] = $r[0]["network"];
- if (!isset($profile["addr"]) AND $r[0]["addr"])
- $profile["addr"] = $r[0]["addr"];
- if (!isset($profile["bd"]) AND $r[0]["bd"])
- $profile["bd"] = $r[0]["bd"];
- if (isset($r[0]["thumb"]))
- $profile["thumb"] = $r[0]["thumb"];
- if ($r[0]["uid"] == 0)
- $profile["cid"] = 0;
- else
- $profile["cid"] = $r[0]["id"];
- } else
- $profile["cid"] = 0;
+ $profile = $r[0];
+
+ // "bd" always contains the upcoming birthday of a contact.
+ // "birthday" might contain the birthday including the year of birth.
+ if ($profile["birthday"] != "0000-00-00") {
+ $bd_timestamp = strtotime($profile["birthday"]);
+ $month = date("m", $bd_timestamp);
+ $day = date("d", $bd_timestamp);
+
+ $current_timestamp = time();
+ $current_year = date("Y", $current_timestamp);
+ $current_month = date("m", $current_timestamp);
+ $current_day = date("d", $current_timestamp);
+
+ $profile["bd"] = $current_year."-".$month."-".$day;
+ $current = $current_year."-".$current_month."-".$current_day;
+
+ if ($profile["bd"] < $current)
+ $profile["bd"] = (++$current_year)."-".$month."-".$day;
+ } else
+ $profile["bd"] = "0000-00-00";
+ } else {
+ $profile = $default;
+ if (!isset($profile["thumb"]) AND isset($profile["photo"]))
+ $profile["thumb"] = $profile["photo"];
+ }
+
+ if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND ($profile["gid"] != 0) AND
+ in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
+ proc_run('php',"include/update_gcontact.php", $profile["gid"]);
+ // Show contact details of Diaspora contacts only if connected
if (($profile["cid"] == 0) AND ($profile["network"] == NETWORK_DIASPORA)) {
$profile["location"] = "";
$profile["about"] = "";
+ $profile["gender"] = "";
+ $profile["birthday"] = "0000-00-00";
}
return($profile);
--- /dev/null
+<?php
+
+/**
+ * @file include/PConfig.php
+ * @brief contains the class with methods for the management
+ * of the user configuration
+ */
+
+/**
+ * @brief Management of user configuration
+ */
+class PConfig {
+
+ /**
+ * @brief Loads all configuration values of a user's config family into a cached storage.
+ *
+ * All configuration values of the given user are stored in global cache
+ * which is available under the global variable $a->config[$uid].
+ *
+ * @param string $uid
+ * The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @return void
+ */
+ public static function load($uid,$family) {
+ global $a;
+ $r = q("SELECT `v`,`k` FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
+ dbesc($family),
+ intval($uid)
+ );
+ if(count($r)) {
+ foreach($r as $rr) {
+ $k = $rr['k'];
+ $a->config[$uid][$family][$k] = $rr['v'];
+ }
+ } else if ($family != 'config') {
+ // Negative caching
+ $a->config[$uid][$family] = "!<unset>!";
+ }
+ }
+
+ /**
+ * @brief Get a particular user's config variable given the category name
+ * ($family) and a key.
+ *
+ * Get a particular user's config value from the given category ($family)
+ * and the $key from a cached storage in $a->config[$uid].
+ *
+ * @param string $uid
+ * The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to query
+ * @param boolean $instore
+ * Determines if the key already exists in the DB
+ * @return mixed Stored value or false if it does not exist
+ */
+ public static function get($uid,$family, $key, $instore = false) {
+
+ global $a;
+
+ if(! $instore) {
+ // Looking if the whole family isn't set
+ if(isset($a->config[$uid][$family])) {
+ if($a->config[$uid][$family] === '!<unset>!') {
+ return false;
+ }
+ }
+
+ if(isset($a->config[$uid][$family][$key])) {
+ if($a->config[$uid][$family][$key] === '!<unset>!') {
+ return false;
+ }
+ return $a->config[$uid][$family][$key];
+ }
+ }
+
+ // If APC is enabled then fetch the data from there, else try XCache
+ /*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
+ if (apc_exists($uid."|".$family."|".$key)) {
+ $val = apc_fetch($uid."|".$family."|".$key);
+ $a->config[$uid][$family][$key] = $val;
+
+ if ($val === '!<unset>!')
+ return false;
+ else
+ return $val;
+ }
+ elseif (function_exists("xcache_get") AND function_exists("xcache_isset"))
+ if (xcache_isset($uid."|".$family."|".$key)) {
+ $val = xcache_get($uid."|".$family."|".$key);
+ $a->config[$uid][$family][$key] = $val;
+
+ if ($val === '!<unset>!')
+ return false;
+ else
+ return $val;
+ }*/
+
+
+ $ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
+ intval($uid),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ if(count($ret)) {
+ $val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
+ $a->config[$uid][$family][$key] = $val;
+
+ // If APC is enabled then store the data there, else try XCache
+ /*if (function_exists("apc_store"))
+ apc_store($uid."|".$family."|".$key, $val, 600);
+ elseif (function_exists("xcache_set"))
+ xcache_set($uid."|".$family."|".$key, $val, 600);*/
+
+ return $val;
+ }
+ else {
+ $a->config[$uid][$family][$key] = '!<unset>!';
+
+ // If APC is enabled then store the data there, else try XCache
+ /*if (function_exists("apc_store"))
+ apc_store($uid."|".$family."|".$key, '!<unset>!', 600);
+ elseif (function_exists("xcache_set"))
+ xcache_set($uid."|".$family."|".$key, '!<unset>!', 600);*/
+ }
+ return false;
+ }
+
+ /**
+ * @brief Sets a configuration value for a user
+ *
+ * Stores a config value ($value) in the category ($family) under the key ($key)
+ * for the user_id $uid.
+ *
+ * @note Please do not store booleans - convert to 0/1 integer values!
+ *
+ * @param string $uid
+ * The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to set
+ * @param string $value
+ * The value to store
+ * @return mixed Stored $value or false
+ */
+ public static function set($uid,$family,$key,$value) {
+
+ global $a;
+
+ // manage array value
+ $dbvalue = (is_array($value)?serialize($value):$value);
+
+ if(get_pconfig($uid,$family,$key,true) === false) {
+ $a->config[$uid][$family][$key] = $value;
+ $ret = q("INSERT INTO `pconfig` ( `uid`, `cat`, `k`, `v` ) VALUES ( %d, '%s', '%s', '%s' ) ",
+ intval($uid),
+ dbesc($family),
+ dbesc($key),
+ dbesc($dbvalue)
+ );
+ if($ret)
+ return $value;
+ return $ret;
+ }
+ $ret = q("UPDATE `pconfig` SET `v` = '%s' WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
+ dbesc($dbvalue),
+ intval($uid),
+ dbesc($family),
+ dbesc($key)
+ );
+
+ $a->config[$uid][$family][$key] = $value;
+
+ // If APC is enabled then store the data there, else try XCache
+ /*if (function_exists("apc_store"))
+ apc_store($uid."|".$family."|".$key, $value, 600);
+ elseif (function_exists("xcache_set"))
+ xcache_set($uid."|".$family."|".$key, $value, 600);*/
+
+
+ if($ret)
+ return $value;
+ return $ret;
+ }
+
+ /**
+ * @brief Deletes the given key from the users's configuration.
+ *
+ * Removes the configured value from the stored cache in $a->config[$uid]
+ * and removes it from the database.
+ *
+ * @param string $uid The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to delete
+ * @return mixed
+ */
+ public static function delete($uid,$family,$key) {
+
+ global $a;
+ if(x($a->config[$uid][$family],$key))
+ unset($a->config[$uid][$family][$key]);
+ $ret = q("DELETE FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
+ intval($uid),
+ dbesc($family),
+ dbesc($key)
+ );
+ return $ret;
+ }
+}
$data = Cache::get($url);
- if (is_null($data)) {
- $img_str = fetch_url($url, true, $redirects, 4);
+ // Unserialise to be able to check in the next step if the cached data is alright.
+ if (!is_null($data))
+ $data = unserialize($data);
+ if (is_null($data) OR !$data) {
+ $img_str = fetch_url($url, true, $redirects, 4);
$filesize = strlen($img_str);
if (function_exists("getimagesizefromstring"))
$data["size"] = $filesize;
Cache::set($url, serialize($data));
- } else
- $data = unserialize($data);
+ }
return $data;
}
api_login($a);
}
- load_contact_links(api_user());
-
logger('API call for ' . $a->user['username'] . ': ' . $a->query_string);
logger('API parameters: ' . print_r($_REQUEST,true));
$text .= "<br /><br />".$link;
break;
default:
- $headline = trim($share[1]).'<div class="shared_header">';
+ $headline = trim($share[1])."\n";
+ $headline .= '<div class="shared-wrapper">'."\n";
+ $headline .= '<div class="shared_header">'."\n";
if ($avatar != "")
$headline .= '<img src="'.proxy_url($avatar, false, PROXY_SIZE_MICRO).'" height="32" width="32" >';
$headline .= sprintf(t('<span><a href="%s" target="_blank">%s</a> wrote the following <a href="%s" target="_blank">post</a>'.$reldate.':</span>'), $profile, $author, $link);
- $headline .= "</div>";
- $text = $headline.'<blockquote class="shared_content">'.trim($share[3])."</blockquote>";
+ $headline .= "</div>\n";
+ $text = $headline.'<blockquote class="shared_content">'.trim($share[3])."</blockquote>\n";
+ $text .= "<div>\n";
break;
}
return($text);
$Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
'$1<span class="vcard"><a href="$2" class="url" title="$3"><span class="fn nickname mention">$3</span></a></span>',
$Text);
-
+ elseif (!$simplehtml)
+ $Text = preg_replace("/([@])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
+ '$1<a href="$2" class="userinfo mention" title="$3">$3</a>',
+ $Text);
// Bookmarks in red - will be converted to bookmarks in friendica
$Text = preg_replace("/#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '[bookmark=$1]$1[/bookmark]', $Text);
if ($tryoembed)
$Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text);
+ $Text = preg_replace("/([#])\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",
+ '$1<a href="$2" class="tag" title="$3">$3</a>', $Text);
+
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$1</a>', $Text);
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
//$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
<?php
+require_once("include/PConfig.php");
+
/**
- *
- * Arbitrary configuration storage
+ * @file include/config.php
+ *
+ * @brief Arbitrary configuration storage
* Note:
* Please do not store booleans - convert to 0/1 integer values
* The get_?config() functions return boolean false for keys that are unset,
* configurations need to be fixed as of 10/08/2011.
*/
-
-// retrieve a "family" of config variables from database to cached storage
-
-if(! function_exists('load_config')) {
+/**
+ * @brief Loads all configuration values of family into a cached storage.
+ *
+ * All configuration values of the system are stored in global cache
+ * which is available under the global variable $a->config
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @return void
+ */
function load_config($family) {
global $a;
// Negative caching
$a->config[$family] = "!<unset>!";
}
-}}
-
-// get a particular config variable given the family name
-// and key. Returns false if not set.
-// $instore is only used by the set_config function
-// to determine if the key already exists in the DB
-// If a key is found in the DB but doesn't exist in
-// local config cache, pull it into the cache so we don't have
-// to hit the DB again for this item.
+}
-if(! function_exists('get_config')) {
+/**
+ * @brief Get a particular user's config variable given the category name
+ * ($family) and a key.
+ *
+ * Get a particular config value from the given category ($family)
+ * and the $key from a cached storage in $a->config[$uid].
+ * $instore is only used by the set_config function
+ * to determine if the key already exists in the DB
+ * If a key is found in the DB but doesn't exist in
+ * local config cache, pull it into the cache so we don't have
+ * to hit the DB again for this item.
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to query
+ * @param boolean $instore Determines if the key already exists in the DB
+ * @return mixed Stored value or false if it does not exist
+ */
function get_config($family, $key, $instore = false) {
global $a;
xcache_set($family."|".$key, '!<unset>!', 600);*/
}
return false;
-}}
-
-// Store a config value ($value) in the category ($family)
-// under the key ($key)
-// Return the value, or false if the database update failed
+}
-if(! function_exists('set_config')) {
+/**
+ * @brief Sets a configuration value for system config
+ *
+ * Stores a config value ($value) in the category ($family) under the key ($key)
+ * for the user_id $uid.
+ *
+ * Note: Please do not store booleans - convert to 0/1 integer values!
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to set
+ * @param string $value
+ * The value to store
+ * @return mixed Stored $value or false if the database update failed
+ */
function set_config($family,$key,$value) {
global $a;
if($ret)
return $value;
return $ret;
-}}
-
-
-if(! function_exists('load_pconfig')) {
-function load_pconfig($uid,$family) {
- global $a;
- $r = q("SELECT `v`,`k` FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
- dbesc($family),
- intval($uid)
- );
- if(count($r)) {
- foreach($r as $rr) {
- $k = $rr['k'];
- $a->config[$uid][$family][$k] = $rr['v'];
- }
- } else if ($family != 'config') {
- // Negative caching
- $a->config[$uid][$family] = "!<unset>!";
- }
-}}
-
-
-
-if(! function_exists('get_pconfig')) {
-function get_pconfig($uid,$family, $key, $instore = false) {
-
- global $a;
-
- if(! $instore) {
- // Looking if the whole family isn't set
- if(isset($a->config[$uid][$family])) {
- if($a->config[$uid][$family] === '!<unset>!') {
- return false;
- }
- }
-
- if(isset($a->config[$uid][$family][$key])) {
- if($a->config[$uid][$family][$key] === '!<unset>!') {
- return false;
- }
- return $a->config[$uid][$family][$key];
- }
- }
-
- // If APC is enabled then fetch the data from there, else try XCache
- /*if (function_exists("apc_fetch") AND function_exists("apc_exists"))
- if (apc_exists($uid."|".$family."|".$key)) {
- $val = apc_fetch($uid."|".$family."|".$key);
- $a->config[$uid][$family][$key] = $val;
-
- if ($val === '!<unset>!')
- return false;
- else
- return $val;
- }
- elseif (function_exists("xcache_get") AND function_exists("xcache_isset"))
- if (xcache_isset($uid."|".$family."|".$key)) {
- $val = xcache_get($uid."|".$family."|".$key);
- $a->config[$uid][$family][$key] = $val;
-
- if ($val === '!<unset>!')
- return false;
- else
- return $val;
- }*/
-
-
- $ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
- intval($uid),
- dbesc($family),
- dbesc($key)
- );
-
- if(count($ret)) {
- $val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
- $a->config[$uid][$family][$key] = $val;
+}
- // If APC is enabled then store the data there, else try XCache
- /*if (function_exists("apc_store"))
- apc_store($uid."|".$family."|".$key, $val, 600);
- elseif (function_exists("xcache_set"))
- xcache_set($uid."|".$family."|".$key, $val, 600);*/
-
- return $val;
- }
- else {
- $a->config[$uid][$family][$key] = '!<unset>!';
-
- // If APC is enabled then store the data there, else try XCache
- /*if (function_exists("apc_store"))
- apc_store($uid."|".$family."|".$key, '!<unset>!', 600);
- elseif (function_exists("xcache_set"))
- xcache_set($uid."|".$family."|".$key, '!<unset>!', 600);*/
- }
- return false;
-}}
-
-if(! function_exists('del_config')) {
+/**
+ * @brief Deletes the given key from the system configuration.
+ *
+ * Removes the configured value from the stored cache in $a->config
+ * and removes it from the database.
+ *
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to delete
+ * @return mixed
+ */
function del_config($family,$key) {
global $a;
xcache_unset($family."|".$key);*/
return $ret;
-}}
-
+}
+/**
+ * @brief (Deprecated) Loads all configuration values of a user's config family into a cached storage.
+ *
+ * Note: This function is deprecated. Use PConfig::load() instead.
+ *
+ * @param string $uid
+ * The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @return void
+ */
+function load_pconfig($uid,$family) {
+ return PConfig::load($uid, $family);
+}
-// Same as above functions except these are for personal config storage and take an
-// additional $uid argument.
+/**
+ * @brief (Deprecated) Get a particular user's config variable given the category name
+ * ($family) and a key.
+ *
+ * Note: This function is deprecated. Use PConfig::get() instead.
+ *
+ * @param string $uid
+ * The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to query
+ * @param boolean $instore
+ * Determines if the key already exists in the DB
+ * @return mixed Stored value or false if it does not exist
+ */
+function get_pconfig($uid,$family, $key, $instore = false) {
+ return PConfig::get($uid, $family, $key, $instore);
+}
-if(! function_exists('set_pconfig')) {
+/**
+ * @brief (Deprecated) Sets a configuration value for a user
+ *
+ * Note: This function is deprecated. Use PConfig::set() instead.
+ *
+ * @param string $uid
+ * The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to set
+ * @param string $value
+ * The value to store
+ * @return mixed Stored $value or false
+ */
function set_pconfig($uid,$family,$key,$value) {
+ return PConfig::set($uid, $family, $key, $value);
+}
- global $a;
-
- // manage array value
- $dbvalue = (is_array($value)?serialize($value):$value);
-
- if(get_pconfig($uid,$family,$key,true) === false) {
- $a->config[$uid][$family][$key] = $value;
- $ret = q("INSERT INTO `pconfig` ( `uid`, `cat`, `k`, `v` ) VALUES ( %d, '%s', '%s', '%s' ) ",
- intval($uid),
- dbesc($family),
- dbesc($key),
- dbesc($dbvalue)
- );
- if($ret)
- return $value;
- return $ret;
- }
- $ret = q("UPDATE `pconfig` SET `v` = '%s' WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
- dbesc($dbvalue),
- intval($uid),
- dbesc($family),
- dbesc($key)
- );
-
- $a->config[$uid][$family][$key] = $value;
-
- // If APC is enabled then store the data there, else try XCache
- /*if (function_exists("apc_store"))
- apc_store($uid."|".$family."|".$key, $value, 600);
- elseif (function_exists("xcache_set"))
- xcache_set($uid."|".$family."|".$key, $value, 600);*/
-
-
- if($ret)
- return $value;
- return $ret;
-}}
-
-if(! function_exists('del_pconfig')) {
+/**
+ * @brief (Deprecated) Deletes the given key from the users's configuration.
+ *
+ * Note: This function is deprecated. Use PConfig::delete() instead.
+ *
+ * @param string $uid The user_id
+ * @param string $family
+ * The category of the configuration value
+ * @param string $key
+ * The configuration key to delete
+ * @return mixed
+ */
function del_pconfig($uid,$family,$key) {
-
- global $a;
- if(x($a->config[$uid][$family],$key))
- unset($a->config[$uid][$family][$key]);
- $ret = q("DELETE FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s'",
- intval($uid),
- dbesc($family),
- dbesc($key)
- );
- return $ret;
-}}
+ return PConfig::delete($uid, $family, $key);
+}
function conversation(&$a, $items, $mode, $update, $preview = false) {
require_once('include/bbcode.php');
+ require_once('include/Contact.php');
require_once('mod/proxy.php');
$ssl_state = ((local_user()) ? true : false);
else
$return_url = $_SESSION['return_url'] = $a->query_string;
- load_contact_links(local_user());
-
$cb = array('items' => $items, 'mode' => $mode, 'update' => $update, 'preview' => $preview);
call_hooks('conversation_start',$cb);
else
$profile_link = zrl($profile_link);
- $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
- if(($normalised != 'mailbox') && (x($a->contacts[$normalised])))
- $profile_avatar = $a->contacts[$normalised]['thumb'];
+ // Don't rely on the author-avatar. It is better to use the data from the contact table
+ $author_contact = get_contact_details_by_url($item['author-link'], $profile_owner);
+ if ($author_contact["thumb"])
+ $profile_avatar = $author_contact["thumb"];
else
- $profile_avatar = $a->remove_baseurl(((strlen($item['author-avatar'])) ? $item['author-avatar'] : $item['thumb']));
+ $profile_avatar = $item['author-avatar'];
$locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
call_hooks('render_location',$locate);
'name' => $profile_name_e,
'sparkle' => $sparkle,
'lock' => $lock,
- 'thumb' => proxy_url($profile_avatar, false, PROXY_SIZE_THUMB),
+ 'thumb' => App::remove_baseurl(proxy_url($profile_avatar, false, PROXY_SIZE_THUMB)),
'title' => $item['title_e'],
'body' => $body_e,
'tags' => $tags_e,
$clean_url = normalise_link($item['author-link']);
- if((local_user()) && (local_user() == $item['uid'])) {
- if(isset($a->contacts) && x($a->contacts,$clean_url)) {
- if($a->contacts[$clean_url]['network'] === NETWORK_DFRN) {
- $best_url = 'redir/'.$a->contacts[$clean_url]['id'];
- $sparkle = true;
- } else
- $best_url = $a->contacts[$clean_url]['url'];
- }
- } elseif (local_user()) {
+ if (local_user()) {
$r = q("SELECT `id` FROM `contact` WHERE `network` = '%s' AND `uid` = %d AND `nurl` = '%s' LIMIT 1",
dbesc(NETWORK_DFRN), intval(local_user()), dbesc(normalise_link($clean_url)));
if ($r) {
$ssl_state = false;
- if(local_user()) {
+ if(local_user())
$ssl_state = true;
- if(! count($a->contacts))
- load_contact_links(local_user());
- }
+
$sub_link="";
$poke_link="";
$contact_url="";
$status_link="";
$photos_link="";
$posts_link="";
+ $network = "";
if((local_user()) && local_user() == $item['uid'] && $item['parent'] == $item['id'] && (! $item['self'])) {
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
if($profile_link === 'mailbox')
$profile_link = '';
+ $cid = 0;
+ $network = "";
+ $rel = 0;
+ $r = q("SELECT `id`, `network`, `rel` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' LIMIT 1",
+ intval(local_user()), dbesc(normalise_link($item['author-link'])));
+ if ($r) {
+ $cid = $r[0]["id"];
+ $network = $r[0]["network"];
+ $rel = $r[0]["rel"];
+ }
+
if($sparkle) {
- $cid = intval(basename($profile_link));
- $status_link = $profile_link . "?url=status";
- $photos_link = $profile_link . "?url=photos";
- $profile_link = $profile_link . "?url=profile";
- $pm_url = 'message/new/' . $cid;
+ $status_link = $profile_link."?url=status";
+ $photos_link = $profile_link."?url=photos";
+ $profile_link = $profile_link."?url=profile";
$zurl = '';
- }
- else {
+ } else
$profile_link = zrl($profile_link);
- if(local_user() && local_user() == $item['uid'] && link_compare($item['url'],$item['author-link'])) {
- $cid = $item['contact-id'];
- } else {
- $r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' LIMIT 1",
- intval(local_user()), dbesc(normalise_link($item['author-link'])));
- if ($r) {
- $cid = $r[0]["id"];
-
- if ($r[0]["network"] == NETWORK_DIASPORA)
- $pm_url = 'message/new/' . $cid;
-
- } else
- $cid = 0;
- }
- }
- if(($cid) && (! $item['self'])) {
- $poke_link = 'poke/?f=&c=' . $cid;
- $contact_url = 'contacts/' . $cid;
- $posts_link = 'contacts/' . $cid . '/posts';
- $clean_url = normalise_link($item['author-link']);
-
- if((local_user()) && (local_user() == $item['uid'])) {
- if(isset($a->contacts) && x($a->contacts,$clean_url)) {
- if($a->contacts[$clean_url]['network'] === NETWORK_DIASPORA) {
- $pm_url = 'message/new/' . $cid;
- }
- }
- }
+ if($cid && !$item['self']) {
+ $poke_link = 'poke/?f=&c='.$cid;
+ $contact_url = 'contacts/'.$cid;
+ $posts_link = 'contacts/'.$cid.'/posts';
+ if (in_array($network, array(NETWORK_DFRN, NETWORK_DIASPORA)))
+ $pm_url = 'message/new/'.$cid;
}
if (local_user()) {
t("Send PM") => $pm_url
);
- if ($a->contacts[$clean_url]['network'] === NETWORK_DFRN)
+ if ($network == NETWORK_DFRN)
$menu[t("Poke")] = $poke_link;
- if ((($cid == 0) OR ($a->contacts[$clean_url]['rel'] == CONTACT_IS_FOLLOWER)) AND
+ if ((($cid == 0) OR ($rel == CONTACT_IS_FOLLOWER)) AND
in_array($item['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
$menu[t("Connect/Follow")] = "follow?url=".urlencode($item['author-link']);
} else
--- /dev/null
+<?php
+/**
+ * @brief This class contain functions for the database management
+ *
+ */
+class dbm {
+ /**
+ * @brief Return a list of database processes
+ *
+ * @return array
+ * 'list' => List of processes, separated in their different states
+ * 'amount' => Number of concurrent database processes
+ */
+ public static function processlist() {
+ $r = q("SHOW PROCESSLIST");
+ $s = array();
+
+ $processes = 0;
+ $states = array();
+ foreach ($r AS $process) {
+ $state = trim($process["State"]);
+
+ // Filter out all idle processes
+ if (!in_array($state, array("", "init", "statistics"))) {
+ ++$states[$state];
+ ++$processes;
+ }
+ }
+
+ $statelist = "";
+ foreach ($states AS $state => $usage) {
+ if ($statelist != "")
+ $statelist .= ", ";
+ $statelist .= $state.": ".$usage;
+ }
+ return(array("list" => $statelist, "amount" => $processes));
+ }
+}
+?>
"extid" => array("extid"),
"uid_id" => array("uid","id"),
"uid_created" => array("uid","created"),
- "uid_unseen" => array("uid","unseen"),
+ "uid_unseen_contactid" => array("uid","unseen","contact-id"),
"uid_network_received" => array("uid","network","received"),
"uid_received" => array("uid","received"),
"uid_network_commented" => array("uid","network","commented"),
function groups_count_unseen() {
$r = q("SELECT `group`.`id`, `group`.`name`,
- (SELECT COUNT(*) FROM `item`
+ (SELECT COUNT(*) FROM `item` FORCE INDEX (`uid_unseen_contactid`)
WHERE `uid` = %d AND `unseen` AND
`contact-id` IN (SELECT `contact-id` FROM `group_member`
WHERE `group_member`.`gid` = `group`.`id` AND `group_member`.`uid` = %d)) AS `count`
else
$subscribe_feed = false;
- if(get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()))
+ if (remote_user() OR (get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()))) {
$wallmessage = t('Message');
- else
+ $wallmessage_link = "wallmessage/".$profile["nickname"];
+
+ if (remote_user()) {
+ $r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `id` = '%s' AND `rel` = %d",
+ intval($profile['uid']),
+ intval(remote_user()),
+ intval(CONTACT_IS_FRIEND));
+ } else {
+ $r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND `rel` = %d",
+ intval($profile['uid']),
+ dbesc(normalise_link(get_my_url())),
+ intval(CONTACT_IS_FRIEND));
+ }
+ if ($r) {
+ $remote_url = $r[0]["url"];
+ $message_path = preg_replace("=(.*)/profile/(.*)=ism", "$1/message/new/", $remote_url);
+ $wallmessage_link = $message_path.base64_encode($profile["addr"]);
+ }
+ } else {
$wallmessage = false;
+ $wallmessage_link = false;
+ }
// show edit profile to yourself
if ($profile['uid'] == local_user() && feature_enabled(local_user(),'multi_profiles')) {
? trim(substr($profile['name'],0,strpos($profile['name'],' '))) : $profile['name']);
$lastname = (($firstname === $profile['name']) ? '' : trim(substr($profile['name'],strlen($firstname))));
- $diaspora = array(
- 'guid' => $profile['guid'],
- 'podloc' => $a->get_baseurl(),
- 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ),
- 'nickname' => $profile['nickname'],
- 'fullname' => $profile['name'],
- 'firstname' => $firstname,
- 'lastname' => $lastname,
- 'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg',
- 'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg',
- 'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg',
- );
+ if ($profile['guid'] != "")
+ $diaspora = array(
+ 'guid' => $profile['guid'],
+ 'podloc' => $a->get_baseurl(),
+ 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ),
+ 'nickname' => $profile['nickname'],
+ 'fullname' => $profile['name'],
+ 'firstname' => $firstname,
+ 'lastname' => $lastname,
+ 'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg',
+ 'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg',
+ 'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg',
+ );
+ else
+ $diaspora = false;
if (!$block){
$contact_block = contact_block();
'$remoteconnect' => $remoteconnect,
'$subscribe_feed' => $subscribe_feed,
'$wallmessage' => $wallmessage,
+ '$wallmessage_link' => $wallmessage_link,
'$account_type' => $account_type,
'$location' => $location,
'$gender' => $gender,
'$contact_block' => $contact_block,
));
-
$arr = array('profile' => &$profile, 'entry' => &$o);
call_hooks('profile_sidebar', $arr);
if(in_array($_SESSION['page_flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE))) {
$nav['notifications'] = array('notifications', t('Notifications'), "", t('Notifications'));
$nav['notifications']['all']=array('notifications/system', t('See all notifications'), "", "");
- $nav['notifications']['mark'] = array('', t('Mark all system notifications seen'), '','');
+ $nav['notifications']['mark'] = array('', t('Mark as seen'), '',t('Mark all system notifications seen'));
}
}
$orig_body = $xpath->query('atom:content/text()', $activityobjects)->item(0)->nodeValue;
$orig_created = $xpath->query('atom:published/text()', $activityobjects)->item(0)->nodeValue;
+ $orig_edited = $xpath->query('atom:updated/text()', $activityobjects)->item(0)->nodeValue;
$orig_contact = $contact;
$orig_author = self::fetchauthor($xpath, $activityobjects, $importer, $orig_contact, false);
$item["author-avatar"] = $orig_author["author-avatar"];
$item["body"] = add_page_info_to_body(html2bbcode($orig_body));
$item["created"] = $orig_created;
+ $item["edited"] = $orig_edited;
$item["uri"] = $orig_uri;
$item["plink"] = $orig_link;
if (count($pictures) == 1) {
// Checking, if the link goes to a picture
$data = parseurl_getsiteinfo_cached($pictures[0][1], true);
+
+ // Workaround:
+ // Sometimes photo posts to the own album are not detected at the start.
+ // So we seem to cannot use the cache for these cases. That's strange.
+ if (($data["type"] != "photo") AND strstr($pictures[0][1], "/photos/"))
+ $data = parseurl_getsiteinfo($pictures[0][1], true);
+
if ($data["type"] == "photo") {
$post["type"] = "photo";
if (isset($data["images"][0])) {
}
require_once("boot.php");
+require_once("dbm.php");
function poller_run(&$argv, &$argc){
global $a, $db;
unset($db_host, $db_user, $db_pass, $db_data);
};
+ $max_processes = get_config('system', 'max_processes_backend');
+ if (intval($max_processes) == 0)
+ $max_processes = 5;
+
+ $processlist = dbm::processlist();
+ if ($processlist["list"] != "") {
+ logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG);
+
+ if ($processlist["amount"] > $max_processes) {
+ logger("Processcheck: Maximum number of processes for backend tasks (".$max_processes.") reached.", LOGGER_DEBUG);
+ return;
+ }
+ }
+
if (poller_max_connections_reached())
return;
while ($r = q("SELECT * FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `created` LIMIT 1")) {
+ // Log the type of database processes
+ $processlist = dbm::processlist();
+ if ($processlist["amount"] != "") {
+ logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG);
+
+ if ($processlist["amount"] > $max_processes) {
+ logger("Processcheck: Maximum number of processes for backend tasks (".$max_processes.") reached.", LOGGER_DEBUG);
+ return;
+ }
+ }
+
// Constantly check the number of available database connections to let the frontend be accessible at any time
if (poller_max_connections_reached())
return;
*/
require_once("include/dba.php");
+require_once("include/dbm.php");
if(!$install) {
$db = new dba($db_host, $db_user, $db_pass, $db_data, $install);
- unset($db_host, $db_user, $db_pass, $db_data);
+ unset($db_host, $db_user, $db_pass, $db_data);
/**
* Load configs from db. Overwrite configs from .htconfig.php
load_config('config');
load_config('system');
+ $processlist = dbm::processlist();
+ if ($processlist["list"] != "") {
+
+ logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG);
+
+ $max_processes = get_config('system', 'max_processes_frontend');
+ if (intval($max_processes) == 0)
+ $max_processes = 20;
+
+ if ($processlist["amount"] > $max_processes) {
+ logger("Processcheck: Maximum number of processes for frontend tasks (".$max_processes.") reached.", LOGGER_DEBUG);
+ system_unavailable();
+ }
+ }
+
$maxsysload_frontend = intval(get_config('system','maxloadavg_frontend'));
if($maxsysload_frontend < 1)
$maxsysload_frontend = 50;
$link = 'toggle_mobile?off=1&address=' . curPageURL();
}
$a->page['footer'] = replace_macros(get_markup_template("toggle_mobile_footer.tpl"), array(
- '$toggle_link' => $link,
- '$toggle_text' => t('toggle mobile')
- ));
+ '$toggle_link' => $link,
+ '$toggle_text' => t('toggle mobile')
+ ));
}
/**
/* autocomplete @nicknames */
$(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl");
/* autocomplete bbcode */
- + $(".comment-edit-form textarea").bbco_autocomplete('bbcode');
-
+ $(".comment-edit-form textarea").bbco_autocomplete('bbcode');
+
// setup videos, since VideoJS won't take care of any loaded via AJAX
if(typeof videojs != 'undefined') videojs.autoSetup();
});
foreach($r as $rr) {
//get further details of the contact
- $contact_details = get_contact_details_by_url($rr['url'], $uid);
+ $contact_details = get_contact_details_by_url($rr['url'], $uid, $rr);
$photo_menu = '';
}
else {
$connlnk = $a->get_baseurl() . '/follow/?url=' . $rr['url'];
- $photo_menu = array(array(t("View Profile"), zrl($rr['url'])));
- $photo_menu[] = array(t("Connect/Follow"), $connlnk);
+ $photo_menu = array(
+ 'profile' => array(t("View Profile"), zrl($rr['url'])),
+ 'follow' => array(t("Connect/Follow"), $connlnk)
+ );
}
$entry = array(
'url' => $rr['url'],
'itemurl' => (($contact_details['addr'] != "") ? $contact_details['addr'] : $rr['url']),
- 'name' => htmlentities($rr['name']),
- 'thumb' => proxy_url($rr['photo'], false, PROXY_SIZE_THUMB),
- 'img_hover' => htmlentities($rr['name']),
+ 'name' => htmlentities($contact_details['name']),
+ 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'img_hover' => htmlentities($contact_details['name']),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
$rr[id] = $rr[cid];
$photo_menu = '';
- $photo_menu = contact_photo_menu ($rr);
+ $photo_menu = contact_photo_menu($rr);
$entry = array(
'url' => $rr['url'],
'itemurl' => (($contact_details['addr'] != "") ? $contact_details['addr'] : $rr['url']),
- 'name' => $rr['name'],
- 'thumb' => proxy_url($rr['photo'], false, PROXY_SIZE_THUMB),
- 'img_hover' => htmlentities($rr['name']),
+ 'name' => $contact_details['name'],
+ 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'img_hover' => htmlentities($contact_details['name']),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
else
$profile_link = zrl($profile_link);
- $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
- if(($normalised != 'mailbox') && (x($a->contacts[$normalised])))
- $profile_avatar = $a->contacts[$normalised]['thumb'];
+ // Don't rely on the author-avatar. It is better to use the data from the contact table
+ $author_contact = get_contact_details_by_url($item['author-link'], $profile_owner);
+ if ($author_contact["thumb"])
+ $profile_avatar = $author_contact["thumb"];
else
- $profile_avatar = $a->remove_baseurl(((strlen($item['author-avatar'])) ? $item['author-avatar'] : $item['thumb']));
+ $profile_avatar = $item['author-avatar'];
$locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
call_hooks('render_location',$locate);
else
$profile_link = zrl($profile_link);
- $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
- if(($normalised != 'mailbox') && (x($a->contacts,$normalised)))
- $profile_avatar = $a->contacts[$normalised]['thumb'];
+ // Don't rely on the author-avatar. It is better to use the data from the contact table
+ $author_contact = get_contact_details_by_url($item['author-link'], $profile_owner);
+ if ($author_contact["thumb"])
+ $profile_avatar = $author_contact["thumb"];
else
- $profile_avatar = $a->remove_baseurl(((strlen($item['author-avatar']) && $diff_author) ? $item['author-avatar'] : $thumb));
+ $profile_avatar = $item['author-avatar'];
$like = ((x($alike,$item['uri'])) ? format_like($alike[$item['uri']],$alike[$item['uri'] . '-l'],'like',$item['uri']) : '');
$dislike = ((x($dlike,$item['uri'])) ? format_like($dlike[$item['uri']],$dlike[$item['uri'] . '-l'],'dislike',$item['uri']) : '');
$shiny = "";
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
- $shiny = 'shiny';
+ $shiny = 'shiny';
- //
+ //
localize_item($item);
$location_e = $location;
}
- $photo_menu = array(array(t("View Profile"), zrl($profile_link)));
+ $photo_menu = array(
+ 'profile' => array(t("View Profile"), zrl($profile_link))
+ );
$entry = array(
'id' => $rr['id'],
if (poco_alternate_ostatus_url($result["url"]))
continue;
+ $result = get_contact_details_by_url($result["url"], local_user(), $result);
+
if ($result["name"] == "") {
$urlparts = parse_url($result["url"]);
$result["name"] = end(explode("/", $urlparts["path"]));
} else {
$connlnk = $a->get_baseurl().'/follow/?url='.(($jj->connect) ? $jj->connect : $jj->url);
$conntxt = t('Connect');
- $photo_menu = array(array(t("View Profile"), zrl($jj->url)));
- $photo_menu[] = array(t("Connect/Follow"), $connlnk);
+ $photo_menu = array(
+ 'profile' => array(t("View Profile"), zrl($jj->url)),
+ 'follow' => array(t("Connect/Follow"), $connlnk)
+ );
}
$jj->photo = str_replace("http:///photo/", get_server()."/photo/", $jj->photo);
function display_fetchauthor($a, $item) {
+ require_once("include/Contact.php");
+
$profiledata = array();
$profiledata["uid"] = -1;
$profiledata["nickname"] = $item["author-name"];
$profiledata["about"] = "";
}
- // Don't show details from Diaspora contacts if you don't follow the contact
- $showdetails = ($profiledata["network"] != NETWORK_DIASPORA);
-
- // Fetching further contact data from the contact table
- $r = q("SELECT `uid`, `network`, `name`, `photo`, `nick`, `addr`, `location`, `about`, `gender`, `keywords`
- FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` = '%s' AND `rel` IN (%d, %d)",
- dbesc(normalise_link($profiledata["url"])), intval(local_user()), dbesc($item["network"]),
- intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND));
- if (!count($r))
- $r = q("SELECT `uid`, `network`, `name`, `photo`, `nick`, `addr`, `location`, `about`, `gender`, `keywords`
- FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `rel` IN (%d, %d)",
- dbesc(normalise_link($profiledata["url"])), intval(local_user()),
- intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND));
-
- if (count($r)) {
- $profiledata["name"] = $r[0]["name"];
- $profiledata["photo"] = $r[0]["photo"];
- $profiledata["nickname"] = $r[0]["nick"];
- $profiledata["addr"] = $r[0]["addr"];
- $profiledata["keywords"] = $r[0]["keywords"];
- $profiledata["network"] = $r[0]["network"];
-
- if (local_user() OR $showdetails) {
- $showdetails = true;
- $profiledata["address"] = $r[0]["location"];
- $profiledata["about"] = $r[0]["about"];
- $profiledata["gender"] = $r[0]["gender"];
- }
- }
-
- // Fetching profile data from global contacts
- if ($profiledata["network"] != NETWORK_FEED) {
- $r = q("SELECT `name`, `photo`, `nick`, `addr`, `location`, `about`, `gender`, `keywords`, `network` FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($profiledata["url"])));
- if (count($r)) {
- $profiledata["name"] = $r[0]["name"];
- $profiledata["photo"] = $r[0]["photo"];
- $profiledata["nickname"] = $r[0]["nick"];
- $profiledata["addr"] = $r[0]["addr"];
- $profiledata["network"] = $r[0]["network"];
-
- if ($r[0]["keywords"])
- $profiledata["keywords"] = $r[0]["keywords"];
+ $profiledata = get_contact_details_by_url($profiledata["url"], local_user(), $profiledata);
- if ($showdetails) {
- if ($r[0]["location"])
- $profiledata["address"] = $r[0]["location"];
-
- if ($r[0]["about"])
- $profiledata["about"] = $r[0]["about"];
-
- if ($r[0]["gender"])
- $profiledata["gender"] = $r[0]["gender"];
- }
- }
- }
+ $profiledata["photo"] = App::remove_baseurl($profiledata["photo"]);
if (local_user()) {
if (in_array($profiledata["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
$title = trim(html2plain(bbcode($r[0]["title"], false, false), 0, true));
$author_name = $r[0]["author-name"];
- $image = "";
- if ($image == "")
- $image = $r[0]["thumb"];
+ $image = $a->remove_baseurl($r[0]["thumb"]);
if ($title == "")
$title = $author_name;
--- /dev/null
+<?php
+
+/**
+ * Name: Frio Hovercard
+ * Description: Hovercard addon for the frio theme
+ * Version: 0.1
+ * Author: Rabuzarus <https://github.com/rabuzarus>
+ * License: GNU AFFERO GENERAL PUBLIC LICENSE (Version 3)
+ */
+
+require_once("include/socgraph.php");
+require_once("include/Contact.php");
+
+function hovercard_init(&$a) {
+ // Just for testing purposes
+ $_GET["mode"] = "minimal";
+}
+function hovercard_content() {
+ $profileurl = (x($_REQUEST,'profileurl') ? $_REQUEST['profileurl'] : "");
+ $datatype = (x($_REQUEST,'datatype') ?$_REQUEST['datatype'] : "json");
+
+ // Get out if the system doesn't have public access allowed
+ if(intval(get_config('system','block_public')))
+ http_status_exit(401);
+
+ // Return the raw content of the template. We use this to make templates usable for js functions.
+ // Look at hovercard.js (function getHoverCardTemplate()).
+ // This part should be moved in it's own module. Maybe we could make more templates accessabel.
+ // (We need to discuss possible security lacks before doing this)
+ if ($datatype == "tpl") {
+ $templatecontent = get_template_content("hovercard.tpl");
+ echo $templatecontent;
+ killme();
+ }
+
+ // If a contact is connected the url is internally changed to "redir/CID". We need the pure url to search for
+ // the contact. So we strip out the contact id from the internal url and look in the contact table for
+ // the real url (nurl)
+ if(local_user() && strpos($profileurl, "redir/") === 0) {
+ $cid = intval(substr($profileurl, 6));
+ $r = q("SELECT `nurl`, `self` FROM `contact` WHERE `id` = '%d' LIMIT 1", intval($cid));
+ $profileurl = ($r[0]["nurl"] ? $r[0]["nurl"] : "");
+ $self = ($r[0]["self"] ? $r[0]["self"] : "");
+ }
+
+ // if it's the url containing https it should be converted to http
+ $nurl = normalise_link(clean_contact_url($profileurl));
+ if($nurl) {
+ // Search for contact data
+ $contact = get_contact_details_by_url($nurl);
+ }
+
+ if(!is_array($contact))
+ return;
+
+ // Get the photo_menu - the menu if possible contact actions
+ if(local_user())
+ $actions = contact_photo_menu($contact);
+
+
+ // Move the contact data to the profile array so we can deliver it to
+ //
+ $profile = array(
+ 'name' => $contact["name"],
+ 'nick' => $contact["nick"],
+ 'addr' => (($contact["addr"] != "") ? $contact["addr"] : $contact["url"]),
+ 'thumb' => proxy_url($contact["thumb"], false, PROXY_SIZE_THUMB),
+ 'url' => ($cid ? ("redir/".$cid) : zrl($contact["url"])),
+ 'nurl' => $contact["nurl"], // We additionally store the nurl as identifier
+// 'alias' => $contact["alias"],
+ 'location' => $contact["location"],
+ 'gender' => $contact["gender"],
+ 'about' => $contact["about"],
+ 'network' => format_network_name($contact["network"], $contact["url"]),
+ 'tags' => intval($contact["keywords"]),
+// 'nsfw' => intval($contact["nsfw"]),
+// 'server_url' => $contact["server_url"],
+ 'bd' => (($contact["birthday"] == "0000-00-00") ? "" : $contact["birthday"]),
+// 'generation' => $contact["generation"],
+ 'account_type' => ($contact['community'] ? t("Forum") : ""),
+ 'actions' => $actions,
+ );
+
+ if($datatype == "html") {
+ $t = get_markup_template("hovercard.tpl");
+
+ $o = replace_macros($t, array(
+ '$profile' => $profile,
+ ));
+
+ return $o;
+
+ } else {
+ json_return_and_die($profile);
+ }
+}
+
+/**
+ * @brief Get the raw content of a template file
+ *
+ * @param string $template The name of the template
+ * @param string $root Directory of the template
+ *
+ * @return string|bool Output the raw content if existent, otherwise false
+ */
+function get_template_content($template, $root = "") {
+
+ // We load the whole template system to get the filename.
+ // Maybe we can do it a little bit smarter if I get time.
+ $t = get_markup_template($template, $root);
+ $filename = $t->filename;
+
+ // Get the content of the template file
+ if(file_exists($filename)) {
+ $content = file_get_contents($filename);
+
+ return $content;
+ }
+
+ return false;
+}
if (!count($match)) {
$jj->photo = str_replace("http:///photo/", get_server()."/photo/", $jj->photo);
$connlnk = $a->get_baseurl() . '/follow/?url=' . $jj->url;
- $photo_menu = array(array(t("View Profile"), zrl($jj->url)));
- $photo_menu[] = array(t("Connect/Follow"), $connlnk);
+ $photo_menu = array(
+ 'profile' => array(t("View Profile"), zrl($jj->url)),
+ 'follow' => array(t("Connect/Follow"), $connlnk)
+ );
$contact_details = get_contact_details_by_url($jj->url, local_user());
$prename = $preurl = $preid = '';
if($preselect) {
- $r = q("select name, url, id from contact where uid = %d and id = %d limit 1",
+ $r = q("SELECT `name`, `url`, `id` FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
intval(local_user()),
intval($a->argv[2])
);
+ if(!$r) {
+ $r = q("SELECT `name`, `url`, `id` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' LIMIT 1",
+ intval(local_user()),
+ dbesc(normalise_link(base64_decode($a->argv[2])))
+ );
+ }
+ if(!$r) {
+ $r = q("SELECT `name`, `url`, `id` FROM `contact` WHERE `uid` = %d AND `addr` = '%s' LIMIT 1",
+ intval(local_user()),
+ dbesc(base64_decode($a->argv[2]))
+ );
+ }
if(count($r)) {
$prename = $r[0]['name'];
$preurl = $r[0]['url'];
$preid = $r[0]['id'];
- }
+ $preselect = array($preid);
+ } else
+ $preselect = false;
}
$prefill = (($preselect) ? $prename : '');
'$wait' => t('Please wait'),
'$submit' => t('Submit')
));
-
return $o;
}
if($message['from-url'] == $myprofile) {
$from_url = $myprofile;
$sparkle = '';
- }
- else {
- $from_url = 'redir/' . $message['contact-id'];
+ } elseif ($message['contact-id'] != 0) {
+ $from_url = 'redir/'.$message['contact-id'];
+ $sparkle = ' sparkle';
+ } else {
+ $from_url = $message['from-url']."?zrl=".urlencode($myprofile);
$sparkle = ' sparkle';
}
$subject_e = template_escape($message['title']);
$body_e = template_escape(Smilies::replace(bbcode($message['body'])));
$to_name_e = template_escape($message['name']);
- }
- else {
+ } else {
$from_name_e = $message['from-name'];
$subject_e = $message['title'];
$body_e = Smilies::replace(bbcode($message['body']));
'from_name' => $from_name_e,
'from_url' => $from_url,
'sparkle' => $sparkle,
- 'from_photo' => $message['from-photo'],
+ 'from_photo' => proxy_url($message['from-photo'], false, PROXY_SIZE_THUMB),
'subject' => $subject_e,
'body' => $body_e,
'delete' => t('Delete message'),
if(count($r)) {
foreach($r as $rr) {
- $contact_details = get_contact_details_by_url($rr['url'], local_user());
+ $contact_details = get_contact_details_by_url($rr['url'], local_user(), $rr);
$contacts[] = array(
- 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'),$rr['name'],$rr['url']),
+ 'img_hover' => sprintf(t('Visit %s\'s profile [%s]'), $contact_details['name'], $rr['url']),
'edit_hover' => t('Edit contact'),
'photo_menu' => contact_photo_menu($rr),
'id' => $rr['id'],
'alt_text' => $alt_text,
'dir_icon' => $dir_icon,
- 'thumb' => $rr['thumb'],
- 'name' => $rr['name'],
- 'username' => $rr['name'],
+ 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'name' => $contact_details['name'],
+ 'username' => $contact_details['name'],
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
$r = q("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network`,
`thread`.`uid` AS `contact-uid`
- FROM `thread` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
+ FROM `thread` FORCE INDEX (`uid_created`) INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
$sql_post_table INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
WHERE `thread`.`uid` = %d AND `thread`.`visible` = 1 AND `thread`.`deleted` = 0
$connlnk = $a->get_baseurl() . '/follow/?url=' . (($rr['connect']) ? $rr['connect'] : $rr['url']);
$ignlnk = $a->get_baseurl() . '/suggest?ignore=' . $rr['id'];
- $photo_menu = array(array(t("View Profile"), zrl($rr["url"])));
- $photo_menu[] = array(t("Connect/Follow"), $connlnk);
- $photo_menu[] = array(t('Ignore/Hide'), $ignlnk);
- $contact_details = get_contact_details_by_url($rr["url"], local_user());
+ $photo_menu = array(
+ 'profile' => array(t("View Profile"), zrl($rr["url"])),
+ 'follow' => array(t("Connect/Follow"), $connlnk),
+ 'hide' => array(t('Ignore/Hide'), $ignlnk)
+ );
+
+ $contact_details = get_contact_details_by_url($rr["url"], local_user(), $rr);
$entry = array(
'url' => zrl($rr['url']),
'itemurl' => (($contact_details['addr'] != "") ? $contact_details['addr'] : $rr['url']),
'img_hover' => $rr['url'],
- 'name' => $rr['name'],
- 'thumb' => proxy_url($rr['photo'], false, PROXY_SIZE_THUMB),
+ 'name' => $contact_details['name'],
+ 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
else
$url = zrl($url);
- $contact_details = get_contact_details_by_url($rr['url'], $a->profile['uid']);
+ $contact_details = get_contact_details_by_url($rr['url'], $a->profile['uid'], $rr);
$contacts[] = array(
'id' => $rr['id'],
- 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'), $rr['name'], $rr['url']),
+ 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'), $contact_details['name'], $rr['url']),
'photo_menu' => contact_photo_menu($rr),
- 'thumb' => proxy_url($rr['thumb'], false, PROXY_SIZE_THUMB),
- 'name' => htmlentities(substr($rr['name'],0,20)),
- 'username' => htmlentities($rr['name']),
+ 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'name' => htmlentities(substr($contact_details['name'],0,20)),
+ 'username' => htmlentities($contact_details['name']),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
$body = str_replace("\r\n","\n",$body);
$body = str_replace("\n\n","\n",$body);
-
+
$ret = send_wallmessage($user, $body, $subject, $replyto);
switch($ret){
info( t('Message sent.') . EOL );
}
-// goaway($a->get_baseurl() . '/profile/' . $user['nickname']);
-
+ goaway('profile/'.$user['nickname']);
+
}
else
$profile_link = zrl($profile_link);
- $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
- if(($normalised != 'mailbox') && (x($a->contacts,$normalised)))
- $profile_avatar = $a->contacts[$normalised]['thumb'];
+ // Don't rely on the author-avatar. It is better to use the data from the contact table
+ $author_contact = get_contact_details_by_url($item['author-link'], $profile_owner);
+ if ($author_contact["thumb"])
+ $profile_avatar = $author_contact["thumb"];
else
- $profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $a->remove_baseurl($this->get_data_value('thumb')));
+ $profile_avatar = $item['author-avatar'];
$locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
call_hooks('render_location',$locate);
'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item),
'name' => $name_e,
- 'thumb' => proxy_url($profile_avatar, false, PROXY_SIZE_THUMB),
+ 'thumb' => $a->remove_baseurl(proxy_url($profile_avatar, false, PROXY_SIZE_THUMB)),
'osparkle' => $osparkle,
'sparkle' => $sparkle,
'title' => $title_e,
<?php
-define('UPDATE_VERSION' , 1195);
+define('UPDATE_VERSION' , 1196);
/**
*
.shashape.profile:before{
content: "p";
}
-.shashape.skip:before{
+.shashape.profileneg:before{
content: "q";
}
-.shashape.reload:before{
+.shashape.heard:before{
content: "r";
}
.shashape.search:before{
.shashape.time:before{
content: "t";
}
-.shashape.undo:before{
- content: "u";
-}
.shashape.logout:before,
.shashape.logged-in:before{
content: "v";
.shashape.nolike:before{
content: "C";
}
-/* uppercase D is not defined at the moment
- .shashape.hash:before{
+.shashape.grrrr:before{
content: "D";
-} */
+}
.shashape.arrow7:before{
content: "E";
}
.shashape.follow:before{
content: "F";
}
-.shashape.follower:before{
+.shashape.retweet:before{
content: "G";
}
.shashape.hand:before{
.shashape.arrow-updown:before{
content: "K";
}
-/* uppercase L is not defined at the moment
-.shashape.lock:before{
+.shashape.arrow-sideup:before{
content: "L";
-} */
+}
.shashape.arrow-left:before{
content: "M";
}
content: "#";
}
.shashape.tag:before{
- content: "=";
+ content: "&";
}
.shashape.lock-open:before{
- content: "?";
+ content: "(";
}
.shashape.lock-closed:before{
content: ")";
}
+.shashape.blank:before {
+ content: "_";
+}
+.shashape.ellipsis:before {
+ content: "§";
+}
+.shashape.ok.before,
.shashape.yes:before{
content: "+";
}
.shashape.hmm:before{
- content: ",";
+ content: "%";
}
+.shashape.mark:before,
.shashape.no:before{
content: "-";
}
-.shashape.blank:before{
+.shashape.see:before{
content: ".";
}
-.shashape.see:before{
+.shashape.see2:before{
content: ":";
}
-.shashape.blind:before{
+.shashape.see3:before{
content: ";";
}
+.shashape.blind:before{
+ content: ",";
+}
.shashape.edit:before{
content: "<";
}
.shashape.stamp:before{
content: ">";
}
-.shashape.heart:before{
- content: "_";
+.shashape.comment:before {
+ content: "*";
+}
+.shashape.ask:before {
+ content: "?";
+}
+.shashape.skip:before {
+ content: "{";
+}
+.shashape.reload:before {
+ content: "[";
+}
+.shashape.reloadreverse:before {
+ content: "]";
+}
+.shashape.undo:before {
+ content: "]";
}
-
-
+{{if $diaspora}}
<div style="display:none;">
<dl class="entity_uid">
<dt>Uid</dt>
</dd>
</dl>
</div>
+{{/if}}
--- /dev/null
+<div class="basic-content" >
+ <div class="hover-card-details">
+ <div class="hover-card-header left-align">
+ <div class="hover-card-pic left-align">
+ <span class="image-wrapper medium">
+ <a href="{{$profile.url}}" title="{{$profile.name}}"><img href="" class="left-align thumbnail" src="{{$profile.thumb}}"></a>
+ </span>
+ </div>
+ <div class="hover-card-content">
+ <div class="profile-entry-name">
+ <h4 class="left-align1"><a href="{{$profile.url}}">{{$profile.name}}</a></h4>{{if $profile.account_type}}<span>{{$profile.account_type}}</span>{{/if}}
+ </div>
+ <div class="profile-details">
+ <span class="profile-addr">{{$profile.addr}}</span>
+ {{if $profile.network}}<span class="profile-network"> ({{$profile.network}})</span>{{/if}}
+ </div>
+ {{*{{if $profile.about}}<div class="profile-details profile-about">{{$profile.about}}</div>{{/if}}*}}
+
+ </div>
+ <div class="hover-card-actions right-aligned">
+ {{* here are the differnt actions like privat message, poke, delete and so on *}}
+ {{* @todo we have two different photo menus one for contacts and one for items at the network stream. We currently use the contact photo menu, so the items options are missing We need to move them *}}
+ <div class="hover-card-actions-social">
+ {{if $profile.actions.pm}}<a class="btn btn-labeled btn-primary btn-sm" onclick="addToModal('{{$profile.actions.pm.1}}')" title="{{$profile.actions.pm.0}}"><i class="fa fa-envelope" aria-hidden="true"></i></a>{{/if}}
+ {{if $profile.actions.poke}}<a class="btn btn-labeled btn-primary btn-sm" onclick="addToModal('{{$profile.actions.poke.1}}')" title="{{$profile.actions.poke.0}}"><i class="fa fa-heartbeat" aria-hidden="true"></i></a>{{/if}}
+ </div>
+ <div class="hover-card-actions-connection">
+ {{if $profile.actions.network}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.network.1}}" title="{{$profile.actions.network.0}}"><i class="fa fa-cloud" aria-hidden="true"></i></a>{{/if}}
+ {{if $profile.actions.edit}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.edit.1}}" title="{{$profile.actions.edit.0}}"><i class="fa fa-pencil" aria-hidden="true"></i></a>{{/if}}
+ {{if $profile.actions.follow}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.follow.1}}" title="{{$profile.actions.follow.0}}"><i class="fa fa-user-plus" aria-hidden="true"></i></a>{{/if}}
+ </div>
+ </div>
+ </div>
+
+ <div class="clearfix"></div>
+
+ </div>
+</div>
+{{if $profile.tags}}<div class="hover-card-footer">{{$profile.tags}}</div>{{/if}}
<span id="notify-update" class="nav-ajax-left"></span>
<ul id="nav-notifications-menu" class="menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
{{/if}}
{{/if}}
{{/if}}
{{if $wallmessage}}
- <li><a id="wallmessage-link" href="wallmessage/{{$profile.nickname}}">{{$wallmessage}}</a></li>
+ <li><a id="wallmessage-link" href="{{$wallmessage_link}}">{{$wallmessage}}</a></li>
{{/if}}
{{if $subscribe_feed}}
<li><a id="subscribe-feed-link" href="dfrn_poll/{{$profile.nickname}}">{{$subscribe_feed}}</a></li>
<span id="notify-update" class="nav-ajax-left"></span>
<ul id="nav-notifications-menu" class="menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
{{/if}}
{{*<!--<span id="notify-update" class="nav-ajax-left"></span>
<ul id="nav-notifications-menu" class="notifications-menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>-->*}}
</div>
<li><a id="dfrn-request-link" href="dfrn_request/{{$profile.nickname}}">{{$connect}}</a></li>
{{/if}}
{{if $wallmessage}}
- <li><a id="wallmessage-link" href="wallmessage/{{$profile.nickname}}">{{$wallmessage}}</a></li>
+ <li><a id="wallmessage-link" href="{{$wallmessage_link}}">{{$wallmessage}}</a></li>
{{/if}}
</ul>
</div>
<span class="icon notify">{{$nav.notifications.1}}</span>
<span id="notify-update" class="nav-notify"></span></a>
<ul id="nav-notifications-menu" class="menu-popup">
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
rel="#nav-notifications-menu" title="{{$nav.notifications.1}}">{{$nav.notifications.1}}</a></li>
<ul id="nav-notifications-menu" class="menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
{{/if}}
<span id="notify-update" class="nav-ajax-left"></span>
<ul id="nav-notifications-menu" class="menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
{{/if}}
{{/if}}
{{/if}}
{{if $wallmessage}}
- <li><a id="wallmessage-link" href="wallmessage/{{$profile.nickname}}">{{$wallmessage}}</a></li>
+ <li><a id="wallmessage-link" href="{{$wallmessage_link}}">{{$wallmessage}}</a></li>
{{/if}}
{{if $subscribe_feed}}
<li><a id="subscribe-feed-link" href="dfrn_poll/{{$profile.nickname}}">{{$subscribe_feed}}</a></li>
<span id="notify-update" class="nav-ajax-left"></span>
<ul id="nav-notifications-menu" class="menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
{{/if}}
display: flex;\r
}\r
.hover-card-actions-connection {\r
- margin-left: 30px;\r
+ margin-left: 10px;\r
}\r
.hovercard .hovercard-content .hover-card-actions a.btn {\r
display: inline-block;\r
}
/* The Top Nav Bar user menu */
#topbar-first .account .user-title {
- text-align: right
+ text-align: right;
+ margin-top: 7px;
}
#topbar-first .account .user-title span {
color: $nav_icon_color;
width: 100%;
}
+aside #peoplefind-sidebar input,
+aside #follow-sidebar input {
+ height: 30px;
+ background-position: 10px 5px;
+}
+aside #peoplefind-sidebar .form-group-search .form-button-search,
+aside #follow-sidebar .form-group-search .form-button-search {
+ padding: 2px 8px;
+}
+
+aside #group-sidebar .group-edit-tool {
+ opacity: 0.1;
+ transition: all 0.25s ease-in-out;
+}
+aside #group-sidebar .sidebar-group-li:hover .group-edit-tool {
+ opacity: 0.8;
+ transition: all 0.25s ease-in-out;
+}
+aside #group-sidebar .sidebar-group-li .group-edit-tool:hover {
+ opacity: 1;
+}
+
/* contact block widget */
#contact-block .contact-block-content {
clear: both;
font-weight: 500;
color: #555;
}
-.media .media-body .addional-info a,
-.media .media-body h5.media-heading a {
+.media .media-body .addional-info a, .media .media-body h5.media-heading > a {
display: block;
}
.media .contact-info-comment {
max-height: 480px;
object-fit: contain;
}
-.shared-content-wrapper,
+.wall-item-body > img,
+.wall-item-body > a > img {
+ border-radius: 3px;
+}
+.shared-wrapper,
.vevent {
margin-left: 50px;
margin-right: 50px;
box-shadow: 0 0 0 1.5px rgba(0, 0, 0, .1) inset, 0 1px 1px rgba(0, 0, 0, .05);
}
@media screen and (max-width: 767px) {
- .shared-content-wrapper,
+ .shared-wrapper,
.vevent {
margin-left: 0px;
margin-right: 0px;
}
}
-.shared-content-wrapper:hover,
+.shared-wrapper:hover,
.vevent:hover {
box-shadow: 0 0 0 1.5px rgba(0, 0, 0, .15) inset, 0 1px 1px rgba(0, 0, 0, .05);
}
.wall-item-actions .button-votes,
.wall-item-actions .button-likes {
padding-left: 0px;
- padding-right: 10px;
+ padding-right: 0px;
}
/* wall item hover effects */
.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper,
.directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper,
.events-content-wrapper, .message-content-wrapper, .apps-content-wrapper,
-.notifications-content-wrapper, .admin-content-wrapper {
+.notifications-content-wrapper, .admin-content-wrapper, .group-content-wrapper {
min-height: calc(100vh - 150px);
padding: 15px;
padding-bottom: 20px;
.contact-entry-checkbox {
margin-top: -20px;
}
-.contact-wrapper .media-body .contact-entry-name h4.media-heading {
- font-weight: bold;
- color: #777;
- font-size: 15px;
+.contact-wrapper .media-body .contact-entry-name h4.media-heading a {
+ font-weight: bold !important;
+ color: $link_color;
+ font-size: 15px !important;
+}
+.contact-wrapper .contact-actions {
+ display: flex;
+}
+.contact-wrapper a.contact-action-link {
+ opacity: 0.1;
+ transition: all 0.25s ease-in-out;
+}
+.contact-wrapper a.contact-action-link,
+.contact-wrapper a.contact-action-link:hover,
+.textcomplete-item .contact-wrapper a.contact-action-link {
+ padding-right: 5px;
+ padding-left: 5px;
+ color: #555;
+}
+ul li:hover .contact-wrapper a.contact-action-link {
+ opacity: 0.8;
+ transition: all 0.25s ease-in-out;
+}
+ul li:hover .contact-wrapper a.contact-action-link:hover {
+ opacity: 1;
}
#contacts-search-wrapper,
#directory-search-wrapper{
// Elements with the class "userinfo" will get a hover-card.
// Note that this elements does need a href attribute which links to
// a valid profile url
- $("body").on("mouseover", ".userinfo", function(e) {
+ $("body").on("mouseover", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function(e) {
var timeNow = new Date().getTime();
removeAllhoverCards(e,timeNow);
var hoverCardData = false;
// Take link href attribute as link to the profile
var profileurl = hrefAttr;
// the url to get the contact and template data
- var url = baseurl + "/frio_hovercard";
+ var url = baseurl + "/hovercard";
// store the title in an other data attribute beause bootstrap
// popover destroys the title.attribute. We can restore it later
}
}
}, 500);
- }).on("mouseleave", ".userinfo", function(e) { // action when mouse leaves the hover-card
+ }).on("mouseleave", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function(e) { // action when mouse leaves the hover-card
var timeNow = new Date().getTime();
// copy the original title to the title atribute
var title = $(this).attr("data-orig-title");
if( $("#jot-popup").is(":hidden")) $("#topbar-second > .container > #navbar-button #jotOpen").hide();
}
- // move shared content in it's own DIV (so we can style it better)
- $('.wall-item-body .shared_content').each(function() {
- // create a DIV after ".shared_content" where we will putt in the shared_header
- // and the "shared_content"
- $(this).after('<div class="shared-content-wrapper content-card"></div>');
- // get the shared_header
- var sheader = $(this).prev();
- // get the shared-content-wrapper which we have created above
- var swrapper = $(this).next();
- // move the "shared_header into the new shared_content DIV
- $(swrapper).append(sheader);
- // move the "shared_content" into the new DIV
- $(swrapper).append(this);
- });
-
-
// show bulk deletion button at network page if checkbox is checked
- $('input.item-select').change(function(){
+ $("body").change("input.item-select", function(){
var checked = false;
// We need to get all checked items, so it would close the delete button
animation: true,
html: true,
placement: 'auto',
+ trigger: 'hover',
delay: {
show: 500,
hide: 100
</div>
<div class="media-body">
+ {{* The contact actions like private mail, delete contact, edit contact and so on *}}
+ <div class="contact-actions pull-right nav-pills preferences hidden-xs">
+ {{if $contact.photo_menu.pm}}<a class="contact-action-link" onclick="addToModal('{{$contact.photo_menu.pm.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.pm.0}}"><i class="fa fa-envelope" aria-hidden="true"></i></a>{{/if}}
+ {{if $contact.photo_menu.poke}}<a class="contact-action-link" onclick="addToModal('{{$contact.photo_menu.poke.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.poke.0}}"><i class="fa fa-heartbeat" aria-hidden="true"></i></a>{{/if}}
+ {{if $contact.photo_menu.network}}<a class="contact-action-link" href="{{$contact.photo_menu.network.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.network.0}}"><i class="fa fa-cloud" aria-hidden="true"></i></a>{{/if}}
+ {{if $contact.photo_menu.edit}}<a class="contact-action-link" href="{{$contact.photo_menu.edit.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.edit.0}}"><i class="fa fa-pencil" aria-hidden="true"></i></a>{{/if}}
+ {{if $contact.photo_menu.drop}}<a class="contact-action-link" href="{{$contact.photo_menu.drop.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.drop.0}}"><i class="fa fa-user-times" aria-hidden="true"></i></a>{{/if}}
+ {{if $contact.photo_menu.follow}}<a class="contact-action-link" href="{{$contact.photo_menu.follow.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.follow.0}}"><i class="fa fa-user-plus" aria-hidden="true"></i></a>{{/if}}
+ {{if $contact.photo_menu.hide}}<a class="contact-action-link" href="{{$contact.photo_menu.hide.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.hide.0}}"><i class="fa fa-times" aria-hidden="true"></i></a>{{/if}}
+ </div>
+
{{* The contact description (e.g. Name, Network, kind of connection and so on *}}
<div class="contact-entry-desc">
<div class="contact-entry-name" id="contact-entry-name-{{$contact.id}}" >
- <h4 class="media-heading">{{$contact.name}}
+ <h4 class="media-heading"><a href="{{$contact.url}}">{{$contact.name}}</a>
{{if $contact.account_type}} <small class="contact-entry-details" id="contact-entry-accounttype-{{$contact.id}}">({{$contact.account_type}})</small>{{/if}}
{{if $contact.account_type == 'Forum'}}<i class="fa fa-comments-o" aria-hidden="true"></i>{{/if}}
{{* @todo this needs some changing in core because $contact.account_type contains a translated string which may notbe the same in every language *}}
</div>
- <div class="media-body"> {{* @todo There is a bug with this class - the browser freezes if the screensize is to small - but only fith textcomplete*}}
+ <div class="media-body">
+ {{* The contact actions like private mail, delete contact, edit contact and so on *}}
+ <div class="contact-actions pull-right nav-pills preferences hidden-xs">
+ {if $photo_menu.pm}<a class="contact-action-link" onclick="addToModal('{$photo_menu.pm.1}')" data-toggle="tooltip" title="{$photo_menu.pm.0}"><i class="fa fa-envelope" aria-hidden="true"></i></a>{/if}
+ {if $photo_menu.poke}<a class="contact-action-link" onclick="addToModal('{$photo_menu.poke.1}')" data-toggle="tooltip" title="{$photo_menu.poke.0}"><i class="fa fa-heartbeat" aria-hidden="true"></i></a>{/if}
+ {if $photo_menu.network}<a class="contact-action-link" href="{$photo_menu.network.1}" data-toggle="tooltip" title="{$photo_menu.network.0}"><i class="fa fa-cloud" aria-hidden="true"></i></a>{/if}
+ {if $photo_menu.edit}<a class="contact-action-link" href="{$photo_menu.edit.1}" data-toggle="tooltip" title="{$photo_menu.edit.0}"><i class="fa fa-pencil" aria-hidden="true"></i></a>{/if}
+ {if $photo_menu.drop}<a class="contact-action-link" href="{$photo_menu.drop.1}" data-toggle="tooltip" title="{$photo_menu.drop.0}"><i class="fa fa-user-times" aria-hidden="true"></i></a>{/if}
+ {if $photo_menu.follow}<a class="contact-action-link" href="{$photo_menu.follow.1}" data-toggle="tooltip" title="{$photo_menu.follow.0}"><i class="fa fa-user-plus" aria-hidden="true"></i></a>{/if}
+ </div>
+
{{* The contact description (e.g. Name, Network, kind of connection and so on *}}
<div class="contact-entry-desc">
<div class="contact-entry-name" id="contact-entry-name-{$id}" >
- <h4 class="media-heading">{$name}
+ <h4 class="media-heading"><a href="{url}">{$name}</a>
{if $account_type} <small class="contact-entry-details" id="contact-entry-accounttype-{$id}">({$account_type})</small>{/if}
{if $account_type == 'Forum'}<i class="fa fa-comments-o" aria-hidden="true"></i>{/if}
{{* @todo this needs some changing in core because $contact.account_type contains a translated string which may notbe the same in every language *}}
--- /dev/null
+
+<div id="fileas-sidebar" class="widget">
+ <h3>{{$title}}</h3>
+ <div id="nets-desc">{{$desc}}</div>
+
+ <ul class="fileas-ul">
+ <li class="tool{{if $sel_all}} selected{{/if}}"><a href="{{$base}}" class="fileas-link fileas-all{{if $sel_all}} fileas-selected{{/if}}">{{$all}}</a></li>
+ {{foreach $terms as $term}}
+ <li class="tool{{if $term.selected}} selected{{/if}}"><a href="{{$base}}?f=&file={{$term.name}}" class="fileas-link{{if $term.selected}} fileas-selected{{/if}}">{{$term.name}}</a></li>
+ {{/foreach}}
+ </ul>
+
+</div>
--- /dev/null
+
+<div id="follow-sidebar" class="widget">
+ <h3>{{$connect}}</h3>
+
+ <div id="connect-desc">{{$desc}}</div> {{* The description *}}
+ <form action="follow" method="get" >
+ {{* The input field - For visual consistence we are using a search input field*}}
+ <div class="form-group form-group-search">
+ <input id="side-follow-url" class="search-input form-control form-search" type="text" name="url" value="{{$value|escape:'html'}}" placeholder="{{$hint|escape:'html'}}" data-toggle="tooltip" title="{{$hint|escape:'html'}}" />
+ <button id="side-follow-submit" class="btn btn-default btn-sm form-button-search" type="submit" name="submit" value="{{$follow|escape:'html'}}">{{$follow}}</button>
+ </div>
+ </form>
+</div>
+
--- /dev/null
+<div class="widget" id="group-sidebar">
+ <h3>{{$title}}</h3>
+
+ <div id="sidebar-group-list">
+ {{* The list of available groups *}}
+ <ul role="menu" id="sidebar-group-ul">
+ {{foreach $groups as $group}}
+ <li role="menuitem" class="sidebar-group-li group-{{$group.id}} {{if $group.selected}}selected{{/if}}">
+ {{if ! $newgroup}}<span class="notify badge pull-right"></span>{{/if}}
+ {{if $group.cid}}
+ <div class="checkbox pull-right group-checkbox ">
+ <input type="checkbox"
+ class="{{if $group.selected}}ticked{{else}}unticked {{/if}} action"
+ onclick="contactgroupChangeMember('{{$group.id}}','{{$group.cid}}');return true;"
+ {{if $group.ismember}}checked="checked"{{/if}}
+ />
+ <label for="group-{{$group.id}}"></label>
+ <div class="clearfix"></div>
+ </div>
+ {{/if}}
+ {{if $group.edit}}
+ {{* if the group is editable show a little pencil for editing *}}
+ <a id="edit-sidebar-group-element-{{$group.id}}" class="group-edit-tool pull-right" href="{{$group.edit.href}}" title="{{$edittext}}">
+ <i class="faded-icon fa fa-pencil" aria-hidden="true"></i><span class="sr-only">{{$edittext}}</span>
+ </a>
+ {{/if}}
+ <a id="sidebar-group-element-{{$group.id}}" class="sidebar-group-element" href="{{$group.href}}">{{$group.text}}</a>
+ </li>
+ {{/foreach}}
+ </ul>
+ </div>
+
+ {{if $newgroup}}
+ <div id="sidebar-new-group">
+ {{* show the input field by clicking "new group" *}}
+ <a onclick="javascript:$('#group-new-form').fadeIn('fast');return false;">{{$createtext}}</a>
+ <form id="group-new-form" action="group/new" method="post" style="display:none;">
+ <div class="form-group">
+ <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
+ <input name="groupname" id="id_groupname" class="form-control input-sm" placeholder="{{$creategroup}}">
+ </div>
+ </form>
+ </div>
+ {{else}}
+ <div id="sidebar-edit-groups"><a href="{{$grouppage}}">{{$editgroupstext}}</a></div>
+ {{/if}}
+
+ {{if $ungrouped}}<div id="sidebar-ungrouped"><a href="nogroup">{{$ungrouped}}</a></div>{{/if}}
+</div>
--- /dev/null
+
+<h3 class="heading">{{$messages}}</h3>
+
+{{$tab_content}}
<div class="arrow"></div>
{{$nav.notifications.1}}
<div class="dropdown-header-link">
- <a href="#" onclick="notifyMarkAll(); return false;" data-toggle="tooltip" title="{{$nav.notifications.mark.1}}" class="">Mark as read{{*** @todo Translation ***}}</a>
+ <a href="#" onclick="notifyMarkAll(); return false;" data-toggle="tooltip" title="{{$nav.notifications.mark.3}}" class="">{{$nav.notifications.mark.1}}</a>
</div>
</li>
<form class="navbar-form" role="search" method="get" action="{{$nav.search.0}}">
<!-- <img class="hidden-xs" src="{{$nav.userinfo.icon}}" alt="{{$nav.userinfo.name}}" style="max-width:33px; max-height:33px; min-width:33px; min-height:33px; width:33px; height:33px;"> -->
<div class="form-group form-group-search">
- <input id="nav-search-input-field" class="form-control form-search" type="text" name="search" placeholder="Search">
- <button class="btn btn-default btn-sm form-button-search" type="submit">Search</button>
+ <input id="nav-search-input-field" class="form-control form-search" type="text" name="search" data-toggle="tooltip" title="{{$search_hint}}" placeholder="{{$nav.search.1}}">
+ <button class="btn btn-default btn-sm form-button-search" type="submit">{{$nav.search.1}}</button>
</div>
</form>
</li>
<ul id="nav-user-menu" class="dropdown-menu pull-right menu-popup" role="group" aria-labelledby="main-menu">
{{if $nav.remote}}{{if $nav.sitename}}
<li id="nav-sitename" role="menuitem">{{$nav.sitename}}</li>
- <li role="seperator" class="divider"></li>
+ <li role="separator" class="divider"></li>
{{/if}}{{/if}}
{{foreach $nav.usermenu as $usermenu}}
<li role="menuitem"><a class="{{$usermenu.2}}" href="{{$usermenu.0}}" title="{{$usermenu.3}}">{{$usermenu.1}}</a></li>
{{/foreach}}
- <li role="seperator" class="divider"></li>
- <li role="menuitem"><a href="https://github.com/rabuzarus/frio" target="new" title="frio on GitHub"><i class="fa fa-github"></i> frio on GitHub</a></li>
- <li role="seperator" class="divider"></li>
+ <li role="separator" class="divider"></li>
{{if $nav.notifications}}
<li role="menuitem"><a href="{{$nav.notifications.0}}" title="{{$nav.notifications.1}}"><i class="fa fa-exclamation-circle fa-fw"></i> {{$nav.notifications.1}}</a></li>
{{/if}}
{{if $nav.messages}}
<li role="menuitem"><a class="nav-commlink {{$nav.messages.2}} {{$sel.messages}}" href="{{$nav.messages.0}}" title="{{$nav.messages.3}}" ><i class="fa fa-envelope fa-fw"></i> {{$nav.messages.1}} <span id="mail-update-li" class="nav-mail-badge badge nav-notify"></span></a></li>
{{/if}}
- <li role="seperator" class="divider"></li>
+ <li role="separator" class="divider"></li>
{{if $nav.contacts}}
<li role="menuitem"><a id="nav-contacts-link" class="nav-link {{$nav.contacts.2}}" href="{{$nav.contacts.0}}" title="{{$nav.contacts.3}}"><i class="fa fa-users fa-fw"></i> {{$nav.contacts.1}}</a><span id="intro-update-li" class="nav-intro-badge badge nav-notify"></span></li>
{{/if}}
<li role="menuitem"><a id="nav-manage-link" class="nav-commlink {{$nav.manage.2}} {{$sel.manage}}" href="{{$nav.manage.0}}" title="{{$nav.manage.3}}"><i class="fa fa-flag fa-fw"></i> {{$nav.manage.1}}</a></li>
{{/if}}
<li role="menuitem"><a id="nav-directory-link" class="nav-link {{$nav.directory.2}}" href="{{$nav.directory.0}}" title="{{$nav.directory.3}}"><i class="fa fa-sitemap fa-fw"></i>{{$nav.directory.1}}</a></li>
- <li role="seperator" class="divider"></li>
+ <li role="separator" class="divider"></li>
{{if $nav.apps}}
<li role="menuitem"><a id="nav-apps-link" class="nav-link {{$nav.apps.2}} {{$sel.manage}}" href="{{$nav.apps.0}}" title="{{$nav.apps.3}}" ><i class="fa fa-puzzle-piece fa-fw"></i> {{$nav.apps.1}}</a>
- <li role="seperator" class="divider"></li>
+ <li role="separator" class="divider"></li>
{{/if}}
{{if $nav.help}}
<li role="menuitem"><a id="nav-help-link" class="nav-link {{$nav.help.2}}" target="friendica-help" href="{{$nav.help.0}}" title="{{$nav.help.3}}" ><i class="fa fa-question-circle fa-fw"></i> {{$nav.help.3}}</a></li>
{{if $nav.admin}}
<li role="menuitem"><a id="nav-admin-link" class="nav-link {{$nav.admin.2}}" href="{{$nav.admin.0}}" title="{{$nav.admin.3}}" ><i class="fa fa-user-secret fa-fw"></i> {{$nav.admin.1}}</a></li>
{{/if}}
- <li role="seperator" class="divider"></li>
+ <li role="separator" class="divider"></li>
{{if $nav.logout}}
<li role="menuitem"><a id="nav-logout-link" class="nav-link {{$nav.logout.2}}" href="{{$nav.logout.0}}" title="{{$nav.logout.3}}" ><i class="fa fa fa-sign-out fa-fw"></i> {{$nav.logout.1}}</a></li>
{{else}}
--- /dev/null
+
+<div id="nets-sidebar" class="widget">
+ <h3>{{$title}}</h3>
+ <div id="nets-desc">{{$desc}}</div>
+ <ul role="menu" class="nets-ul">
+ <li role="menuitem" {{if $sel_all}}class="selected"{{/if}}><a href="{{$base}}?nets=all" class="nets-link{{if $sel_all}} nets-selected{{/if}} nets-all">{{$all}}</a></li>
+ {{foreach $nets as $net}}
+ <li role="menuitem" {{if $net.selected}}class="selected"{{/if}}><a href="{{$base}}?nets={{$net.ref}}" class="nets-link{{if $net.selected}} nets-selected{{/if}}">{{$net.name}}</a></li>
+ {{/foreach}}
+ </ul>
+</div>
--- /dev/null
+
+<div id="peoplefind-sidebar" class="widget">
+ <h3>{{$findpeople}}</h3>
+
+ <div id="peoplefind-desc">{{$desc}}</div> {{* The description *}}
+
+ <form action="dirfind" method="get" />
+ {{* The search field *}}
+ <div class="form-group form-group-search">
+ <input id="side-peoplefind-url" class="search-input form-control form-search" type="text" name="search" data-toggle="tooltip" title="{{$hint|escape:'html'}}" />
+ <button id="side-peoplefind-submit" class="btn btn-default btn-sm form-button-search" type="submit" name="submit" value="{{$findthem|escape:'html'}}">{{$findthem}}</button>
+ </div>
+ </form>
+
+ {{* Additional links *}}
+ <div class="side-link" id="side-match-link"><a href="match" >{{$similar}}</a></div>
+ <div class="side-link" id="side-suggest-link"><a href="suggest" >{{$suggest}}</a></div>
+
+ {{if $inv}}
+ <div class="side-link" id="side-invite-link" ><a href="invite" >{{$inv}}</a></div>
+ {{/if}}
+</div>
+
{{/if}}
{{if $wallmessage}}
<div id="wallmessage-link-botton">
- <a id="wallmessage-link" class="btn btn-labeled btn-primary btn-sm" onclick="addToModal('wallmessage/{{$profile.nickname}}')">
+ <a id="wallmessage-link" class="btn btn-labeled btn-primary btn-sm" onclick="addToModal('{{$wallmessage_link}}')">
<span class=""><i class="fa fa-envelope"></i></span>
<span class="">{{$wallmessage}}</span>
</a>
{{* Buttons for like and dislike *}}
{{if $item.vote}}
- <div class="vote-like pull-left">
+ {{if $item.vote.like}}
<a role="button" href="#" class="button-likes" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false;">{{$item.vote.like.0}}</a>
+ {{/if}}
+
+ {{if $item.vote.like AND $item.vote.dislike}}
+ <span role="presentation" class="separator"> • </span>
+ {{/if}}
{{if $item.vote.dislike}}
- <span role="presentation" class="seperator"> • </span>
<a role="button" href="#" class="button-likes" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false;">{{$item.vote.dislike.0}}</a>
{{/if}}
- {{if $item.comment}}<span role="presentation" class="seperator"> • </span>{{/if}}
- </div>
+ {{if ($item.vote.like OR $item.vote.dislike) AND $item.comment}}
+ <span role="presentation" class="separator"> • </span>
+ {{/if}}
{{/if}}
{{* Butten to open the comment text field *}}
{{if $item.comment}}
- <div id="button-reply" class="pull-left">
- <a role="button" class="" id="comment-{{$item.id}}" title="{{$item.switchcomment}}" onclick="openClose('item-comments-{{$item.id}}'); commentExpand({{$item.id}});">{{$item.switchcomment}} </a>
- </div>
+ <a role="button" class="" id="comment-{{$item.id}}" title="{{$item.switchcomment}}" onclick="openClose('item-comments-{{$item.id}}'); commentExpand({{$item.id}});">{{$item.switchcomment}} </a>
{{/if}}
{{* Button for sharing the item *}}
{{if $item.vote}}
+ {{if ($item.vote.like OR $item.vote.dislike OR $item.comment) AND $item.vote.share}}
+ <span role="presentation" class="separator"> • </span>
+ {{/if}}
{{if $item.vote.share}}
- <span role="presentation" class="seperator"> • </span>
<a role="button" href="#" class="" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false;"><i class="fa fa-retweet"></i> {{$item.vote.share.0}}</a>
{{/if}}
{{/if}}
<script>
// jquery color plugin from https://raw.github.com/gist/1891361/17747b50ad87f7a59a14b4e0f38d8f3fb6a18b27/gistfile1.js
- (function(d){d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(f,e){d.fx.step[e]=function(g){if(!g.colorInit){g.start=c(g.elem,e);g.end=b(g.end);g.colorInit=true}g.elem.style[e]="rgb("+[Math.max(Math.min(parseInt((g.pos*(g.end[0]-g.start[0]))+g.start[0]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[1]-g.start[1]))+g.start[1]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[2]-g.start[2]))+g.start[2]),255),0)].join(",")+")"}});function b(f){var e;if(f&&f.constructor==Array&&f.length==3){return f}if(e=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(f)){return[parseInt(e[1]),parseInt(e[2]),parseInt(e[3])]}if(e=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(f)){return[parseFloat(e[1])*2.55,parseFloat(e[2])*2.55,parseFloat(e[3])*2.55]}if(e=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(f)){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}if(e=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(f)){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}if(e=/rgba\(0, 0, 0, 0\)/.exec(f)){return a.transparent}return a[d.trim(f).toLowerCase()]}function c(g,e){var f;do{f=d.css(g,e);if(f!=""&&f!="transparent"||d.nodeName(g,"body")){break}e="backgroundColor"}while(g=g.parentNode);return b(f)}var a={transparent:[255,255,255]}})(jQuery);
+// next line was commented out because it causes a js bug in firefox
+// I leave it here so we can have a look into this later
+// (function(d){d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(f,e){d.fx.step[e]=function(g){if(!g.colorInit){g.start=c(g.elem,e);g.end=b(g.end);g.colorInit=true}g.elem.style[e]="rgb("+[Math.max(Math.min(parseInt((g.pos*(g.end[0]-g.start[0]))+g.start[0]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[1]-g.start[1]))+g.start[1]),255),0),Math.max(Math.min(parseInt((g.pos*(g.end[2]-g.start[2]))+g.start[2]),255),0)].join(",")+")"}});function b(f){var e;if(f&&f.constructor==Array&&f.length==3){return f}if(e=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(f)){return[parseInt(e[1]),parseInt(e[2]),parseInt(e[3])]}if(e=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(f)){return[parseFloat(e[1])*2.55,parseFloat(e[2])*2.55,parseFloat(e[3])*2.55]}if(e=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(f)){return[parseInt(e[1],16),parseInt(e[2],16),parseInt(e[3],16)]}if(e=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(f)){return[parseInt(e[1]+e[1],16),parseInt(e[2]+e[2],16),parseInt(e[3]+e[3],16)]}if(e=/rgba\(0, 0, 0, 0\)/.exec(f)){return a.transparent}return a[d.trim(f).toLowerCase()]}function c(g,e){var f;do{f=d.css(g,e);if(f!=""&&f!="transparent"||d.nodeName(g,"body")){break}e="backgroundColor"}while(g=g.parentNode);return b(f)}var a={transparent:[255,255,255]}})(jQuery);
var colWhite = {backgroundColor:'#EFF0F1'};
var colShiny = {backgroundColor:'#FCE94F'};
</script>
{{* Buttons for like and dislike *}}
{{if $item.vote}}
- <div class="vote-like pull-left">
{{if $item.vote.like}}
<a role="button" class="button-likes" id="like-{{$item.id}}" title="{{$item.vote.like.1}}" onclick="dolike({{$item.id}},'like'); return false;"><i class="fa fa-thumbs-up"></i> {{$item.vote.like.1}}</a>
{{/if}}
+ {{if $item.vote.like AND $item.vote.dislike}}
+ <span role="presentation" class="separator"> • </span>
+ {{/if}}
+
{{if $item.vote.dislike}}
- <!-- <span role="presentation" class="seperator"> • </span> -->
<a role="button" class="button-likes" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.1}}" onclick="dolike({{$item.id}},'dislike'); return false;"><i class="fa fa-thumbs-down"></i> {{$item.vote.dislike.1}}</a>
{{/if}}
- <!-- {{if $item.comment}}<span role="presentation" class="seperator"> • </span>{{/if}} -->
- </div>
+ {{if ($item.vote.like OR $item.vote.dislike) AND $item.comment}}
+ <span role="presentation" class="separator"> • </span>
+ {{/if}}
{{/if}}
{{* Butten to open the comment text field *}}
{{if $item.comment}}
- <div id="button-reply" class="pull-left">
- <a role="button" class="button-comments" id="comment-{{$item.id}}" title="{{$item.switchcomment}}" {{if $item.thread_level != 1}}onclick="openClose('item-comments-{{$item.id}}'); commentExpand({{$item.id}});" {{else}} onclick="showHide('item-comments-{{$item.id}}'); commentExpand({{$item.id}});"{{/if}}><i class="fa fa-commenting"></i> {{$item.switchcomment}}</a>
- </div>
+ <a role="button" class="button-comments" id="comment-{{$item.id}}" title="{{$item.switchcomment}}" {{if $item.thread_level != 1}}onclick="openClose('item-comments-{{$item.id}}'); commentExpand({{$item.id}});" {{else}} onclick="showHide('item-comments-{{$item.id}}'); commentExpand({{$item.id}});"{{/if}}><i class="fa fa-commenting"></i> {{$item.switchcomment}}</a>
{{/if}}
{{* Button for sharing the item *}}
{{if $item.vote}}
+ {{if ($item.vote.like OR $item.vote.dislike OR $item.comment) AND $item.vote.share}}
+ <span role="presentation" class="separator"> • </span>
+ {{/if}}
{{if $item.vote.share}}
- <!-- <span role="presentation" class="seperator"> • </span> -->
<a role="button" class="button-votes" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false;"><i class="fa fa-retweet"></i> {{$item.vote.share.0}}</a>
{{/if}}
{{/if}}
<span id="notify-update" class="nav-ajax-left"></span>
<ul id="nav-notifications-menu" class="notifications-menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
</div>
<li><a id="dfrn-request-link" href="dfrn_request/{{$profile.nickname}}">{{$connect}}</a></li>
{{/if}}
{{if $wallmessage}}
- <li><a id="wallmessage-link" href="wallmessage/{{$profile.nickname}}">{{$wallmessage}}</a></li>
+ <li><a id="wallmessage-link" href="{{$wallmessage_link}}">{{$wallmessage}}</a></li>
{{/if}}
</ul>
</div>
<span id="notify-update" class="nav-ajax-left" rel="#nav-network-notifications-popup"></span>
<ul id="nav-notifications-menu" class="notifications-menu-popup">
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
</div>
<li><a id="dfrn-request-link" href="dfrn_request/{{$profile.nickname}}">{{$connect}}</a></li>
{{/if}}
{{if $wallmessage}}
- <li><a id="wallmessage-link" href="wallmessage/{{$profile.nickname}}">{{$wallmessage}}</a></li>
+ <li><a id="wallmessage-link" href="{{$wallmessage_link}}">{{$wallmessage}}</a></li>
{{/if}}
{{if $subscribe_feed}}
<li><a id="subscribe-feed-link" href="dfrn_poll/{{$profile.nickname}}">{{$subscribe_feed}}</a></li>
<span id="notify-update" class="nav-notify"></span>
<ul id="nav-notifications-menu" class="menu-popup">
<!-- TODO: better icons! -->
- <li id="nav-notifications-mark-all" class="toolbar"><a href="#" onclick="notifyMarkAll(); return false;" title="{{$nav.notifications.mark.1}}"><span class="icon s10 edit"></span></a></a><a href="{{$nav.notifications.all.0}}" title="{{$nav.notifications.all.1}}"><span class="icon s10 plugin"></span></a></li>
+ <li id="nav-notifications-mark-all" class="toolbar"><a href="#" onclick="notifyMarkAll(); return false;" title="{{$nav.notifications.mark.3}}"><span class="icon s10 edit"></span></a></a><a href="{{$nav.notifications.all.0}}" title="{{$nav.notifications.all.1}}"><span class="icon s10 plugin"></span></a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
</li>
{{/if}}
{{/if}}
{{if $wallmessage}}
- <li><a id="wallmessage-link" href="wallmessage/{{$profile.nickname}}">{{$wallmessage}}</a></li>
+ <li><a id="wallmessage-link" href="{{$wallmessage_link}}">{{$wallmessage}}</a></li>
{{/if}}
{{if $subscribe_feed}}
<li><a id="subscribe-feed-link" href="dfrn_poll/{{$profile.nickname}}">{{$subscribe_feed}}</a></li>
{{if $nav.notifications}}<a rel="#nav-notifications-menu" id="notify-update" class="nav-ajax-update" href="{{$nav.notifications.0}}" title="{{$nav.notifications.1}}"></a>{{/if}}
<ul id="nav-notifications-menu" class="menu-popup">
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
{{if $nav.notifications}}<a rel="#nav-notifications-menu" id="notify-update" class="nav-ajax-update" href="{{$nav.notifications.0}}" title="{{$nav.notifications.1}}"></a>{{/if}}
<ul id="nav-notifications-menu" class="menu-popup">
- <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.1}}</a></li>
+ <li id="nav-notifications-mark-all"><a href="#" onclick="notifyMarkAll(); return false;">{{$nav.notifications.mark.3}}</a></li>
<li id="nav-notifications-see-all"><a href="{{$nav.notifications.all.0}}">{{$nav.notifications.all.1}}</a></li>
<li class="empty">{{$emptynotifications}}</li>
</ul>
{{/if}}
{{/if}}
{{if $wallmessage}}
- <li><a id="wallmessage-link" href="wallmessage/{{$profile.nickname}}">{{$wallmessage}}</a></li>
+ <li><a id="wallmessage-link" href="{{$wallmessage_link}}">{{$wallmessage}}</a></li>
{{/if}}
{{if $subscribe_feed}}
<li><a id="subscribe-feed-link" href="dfrn_poll/{{$profile.nickname}}">{{$subscribe_feed}}</a></li>