Merge pull request #1 from friendica/develop

Develop
This commit is contained in:
gerhard6380 2016-08-09 16:48:18 +02:00 committed by GitHub
commit 0f2e5a4684
23 changed files with 1091 additions and 601 deletions

View file

@ -392,9 +392,11 @@ define ( 'GRAVITY_COMMENT', 6);
* Process priority for the worker * Process priority for the worker
* @{ * @{
*/ */
define('PRIORITY_HIGH', 1); define('PRIORITY_UNDEFINED', 0);
define('PRIORITY_MEDIUM', 2); define('PRIORITY_SYSTEM', 10);
define('PRIORITY_LOW', 3); define('PRIORITY_HIGH', 20);
define('PRIORITY_MEDIUM', 30);
define('PRIORITY_LOW', 40);
/* @}*/ /* @}*/
@ -571,6 +573,7 @@ class App {
$this->performance["start"] = microtime(true); $this->performance["start"] = microtime(true);
$this->performance["database"] = 0; $this->performance["database"] = 0;
$this->performance["database_write"] = 0;
$this->performance["network"] = 0; $this->performance["network"] = 0;
$this->performance["file"] = 0; $this->performance["file"] = 0;
$this->performance["rendering"] = 0; $this->performance["rendering"] = 0;
@ -1263,7 +1266,7 @@ class App {
function proc_run($args) { function proc_run($args) {
// Add the php path if it is a php call // Add the php path if it is a php call
if (count($args) && $args[0] === 'php') if (count($args) && ($args[0] === 'php' OR is_int($args[0])))
$args[0] = ((x($this->config,'php_path')) && (strlen($this->config['php_path'])) ? $this->config['php_path'] : 'php'); $args[0] = ((x($this->config,'php_path')) && (strlen($this->config['php_path'])) ? $this->config['php_path'] : 'php');
// add baseurl to args. cli scripts can't construct it // add baseurl to args. cli scripts can't construct it
@ -1395,7 +1398,7 @@ function check_db() {
$build = DB_UPDATE_VERSION; $build = DB_UPDATE_VERSION;
} }
if($build != DB_UPDATE_VERSION) if($build != DB_UPDATE_VERSION)
proc_run(PRIORITY_HIGH, 'include/dbupdate.php'); proc_run(PRIORITY_SYSTEM, 'include/dbupdate.php');
} }

View file

@ -1,21 +1,24 @@
<?php <?php
/** /**
* @file include/NotificationsManager.php * @file include/NotificationsManager.php
* @brief Methods for read and write notifications from/to database
* or for formatting notifications
*/ */
require_once('include/html2plain.php'); require_once('include/html2plain.php');
require_once("include/datetime.php"); require_once("include/datetime.php");
require_once("include/bbcode.php"); require_once("include/bbcode.php");
/** /**
* @brief Read and write notifications from/to database * @brief Methods for read and write notifications from/to database
* or for formatting notifications
*/ */
class NotificationsManager { class NotificationsManager {
private $a; private $a;
public function __construct() { public function __construct() {
$this->a = get_app(); $this->a = get_app();
} }
/** /**
* @brief set some extra note properties * @brief set some extra note properties
* *
@ -28,109 +31,780 @@ class NotificationsManager {
* - msg_html: message as html string * - msg_html: message as html string
* - msg_plain: message as plain text string * - msg_plain: message as plain text string
*/ */
private function _set_extra($notes) { private function _set_extra($notes) {
$rets = array(); $rets = array();
foreach($notes as $n) { foreach($notes as $n) {
$local_time = datetime_convert('UTC',date_default_timezone_get(),$n['date']); $local_time = datetime_convert('UTC',date_default_timezone_get(),$n['date']);
$n['timestamp'] = strtotime($local_time); $n['timestamp'] = strtotime($local_time);
$n['date_rel'] = relative_date($n['date']); $n['date_rel'] = relative_date($n['date']);
$n['msg_html'] = bbcode($n['msg'], false, false, false, false); $n['msg_html'] = bbcode($n['msg'], false, false, false, false);
$n['msg_plain'] = explode("\n",trim(html2plain($n['msg_html'], 0)))[0]; $n['msg_plain'] = explode("\n",trim(html2plain($n['msg_html'], 0)))[0];
$rets[] = $n; $rets[] = $n;
} }
return $rets; return $rets;
} }
/** /**
* @brief get all notifications for local_user() * @brief Get all notifications for local_user()
* *
* @param array $filter optional Array "column name"=>value: filter query by columns values * @param array $filter optional Array "column name"=>value: filter query by columns values
* @param string $order optional Space separated list of column to sort by. prepend name with "+" to sort ASC, "-" to sort DESC. Default to "-date" * @param string $order optional Space separated list of column to sort by. prepend name with "+" to sort ASC, "-" to sort DESC. Default to "-date"
* @param string $limit optional Query limits * @param string $limit optional Query limits
* *
* @return array of results or false on errors * @return array of results or false on errors
*/ */
public function getAll($filter = array(), $order="-date", $limit="") { public function getAll($filter = array(), $order="-date", $limit="") {
$filter_str = array(); $filter_str = array();
$filter_sql = ""; $filter_sql = "";
foreach($filter as $column => $value) { foreach($filter as $column => $value) {
$filter_str[] = sprintf("`%s` = '%s'", $column, dbesc($value)); $filter_str[] = sprintf("`%s` = '%s'", $column, dbesc($value));
} }
if (count($filter_str)>0) { if (count($filter_str)>0) {
$filter_sql = "AND ".implode(" AND ", $filter_str); $filter_sql = "AND ".implode(" AND ", $filter_str);
} }
$aOrder = explode(" ", $order); $aOrder = explode(" ", $order);
$asOrder = array(); $asOrder = array();
foreach($aOrder as $o) { foreach($aOrder as $o) {
$dir = "asc"; $dir = "asc";
if ($o[0]==="-") { if ($o[0]==="-") {
$dir = "desc"; $dir = "desc";
$o = substr($o,1); $o = substr($o,1);
} }
if ($o[0]==="+") { if ($o[0]==="+") {
$dir = "asc"; $dir = "asc";
$o = substr($o,1); $o = substr($o,1);
} }
$asOrder[] = "$o $dir"; $asOrder[] = "$o $dir";
} }
$order_sql = implode(", ", $asOrder); $order_sql = implode(", ", $asOrder);
if ($limit!="") $limit = " LIMIT ".$limit; if($limit!="")
$limit = " LIMIT ".$limit;
$r = q("SELECT * FROM `notify` WHERE `uid` = %d $filter_sql ORDER BY $order_sql $limit",
$r = q("SELECT * FROM `notify` WHERE `uid` = %d $filter_sql ORDER BY $order_sql $limit",
intval(local_user())
);
if(dbm::is_result($r))
return $this->_set_extra($r);
return false;
}
/**
* @brief Get one note for local_user() by $id value
*
* @param int $id
* @return array note values or null if not found
*/
public function getByID($id) {
$r = q("SELECT * FROM `notify` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($id),
intval(local_user()) intval(local_user())
); );
if ($r!==false && count($r)>0) return $this->_set_extra($r); if(dbm::is_result($r)) {
return false; return $this->_set_extra($r)[0];
} }
return null;
/** }
* @brief get one note for local_user() by $id value
* /**
* @param int $id * @brief set seen state of $note of local_user()
* @return array note values or null if not found *
*/ * @param array $note
public function getByID($id) { * @param bool $seen optional true or false, default true
$r = q("SELECT * FROM `notify` WHERE `id` = %d AND `uid` = %d LIMIT 1", * @return bool true on success, false on errors
intval($id), */
intval(local_user()) public function setSeen($note, $seen = true) {
); return q("UPDATE `notify` SET `seen` = %d WHERE ( `link` = '%s' OR ( `parent` != 0 AND `parent` = %d AND `otype` = '%s' )) AND `uid` = %d",
if($r!==false && count($r)>0) { intval($seen),
return $this->_set_extra($r)[0]; dbesc($note['link']),
} intval($note['parent']),
return null; dbesc($note['otype']),
}
/**
* @brief set seen state of $note of local_user()
*
* @param array $note
* @param bool $seen optional true or false, default true
* @return bool true on success, false on errors
*/
public function setSeen($note, $seen = true) {
return q("UPDATE `notify` SET `seen` = %d WHERE ( `link` = '%s' OR ( `parent` != 0 AND `parent` = %d AND `otype` = '%s' )) AND `uid` = %d",
intval($seen),
dbesc($note['link']),
intval($note['parent']),
dbesc($note['otype']),
intval(local_user())
);
}
/**
* @brief set seen state of all notifications of local_user()
*
* @param bool $seen optional true or false. default true
* @return bool true on success, false on error
*/
public function setAllSeen($seen = true) {
return q("UPDATE `notify` SET `seen` = %d WHERE `uid` = %d",
intval($seen),
intval(local_user()) intval(local_user())
); );
} }
/**
* @brief set seen state of all notifications of local_user()
*
* @param bool $seen optional true or false. default true
* @return bool true on success, false on error
*/
public function setAllSeen($seen = true) {
return q("UPDATE `notify` SET `seen` = %d WHERE `uid` = %d",
intval($seen),
intval(local_user())
);
}
/**
* @brief List of pages for the Notifications TabBar
*
* @param app $a The
* @return array with with notifications TabBar data
*/
public function getTabs() {
$tabs = array(
array(
'label' => t('System'),
'url'=>'notifications/system',
'sel'=> (($this->a->argv[1] == 'system') ? 'active' : ''),
'id' => 'system-tab',
'accesskey' => 'y',
),
array(
'label' => t('Network'),
'url'=>'notifications/network',
'sel'=> (($this->a->argv[1] == 'network') ? 'active' : ''),
'id' => 'network-tab',
'accesskey' => 'w',
),
array(
'label' => t('Personal'),
'url'=>'notifications/personal',
'sel'=> (($this->a->argv[1] == 'personal') ? 'active' : ''),
'id' => 'personal-tab',
'accesskey' => 'r',
),
array(
'label' => t('Home'),
'url' => 'notifications/home',
'sel'=> (($this->a->argv[1] == 'home') ? 'active' : ''),
'id' => 'home-tab',
'accesskey' => 'h',
),
array(
'label' => t('Introductions'),
'url' => 'notifications/intros',
'sel'=> (($this->a->argv[1] == 'intros') ? 'active' : ''),
'id' => 'intro-tab',
'accesskey' => 'i',
),
);
return $tabs;
}
/**
* @brief Format the notification query in an usable array
*
* @param array $notifs The array from the db query
* @param string $ident The notifications identifier (e.g. network)
* @return array
* string 'label' => The type of the notification
* string 'link' => URL to the source
* string 'image' => The avatar image
* string 'text' => The notification text
* string 'when' => Relative date of the notification
* bool 'seen' => Is the notification marked as "seen"
*/
private function formatNotifs($notifs, $ident = "") {
$notif = array();
$arr = array();
if (dbm::is_result($notifs)) {
foreach ($notifs as $it) {
// Because we use different db tables for the notification query
// we have sometimes $it['unseen'] and sometimes $it['seen].
// So we will have to transform $it['unseen']
if($it['unseen'])
$it['seen'] = ($it['unseen'] > 0 ? false : true);
// Depending on the identifier of the notification we need to use different defaults
switch ($ident) {
case 'system':
$default_item_label = 'notify';
$default_item_link = $this->a->get_baseurl(true).'/notify/view/'. $it['id'];
$default_item_image = proxy_url($it['photo'], false, PROXY_SIZE_MICRO);
$default_item_text = strip_tags(bbcode($it['msg']));
$default_item_when = relative_date($it['date']);
$default_tpl = $tpl_notify;
break;
case 'home':
$default_item_label = 'comment';
$default_item_link = $this->a->get_baseurl(true).'/display/'.$it['pguid'];
$default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
$default_item_text = sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']);
$default_item_when = relative_date($it['created']);
$default_tpl = $tpl_item_comments;
break;
default:
$default_item_label = (($it['id'] == $it['parent']) ? 'post' : 'comment');
$default_item_link = $this->a->get_baseurl(true).'/display/'.$it['pguid'];
$default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
$default_item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$default_item_when = relative_date($it['created']);
$default_tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
}
// Transform the different types of notification in an usable array
switch($it['verb']){
case ACTIVITY_LIKE:
$notif = array(
'label' => 'like',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'$image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_DISLIKE:
$notif = array(
'label' => 'dislike',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_ATTEND:
$notif = array(
'label' => 'attend',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s is attending %s's event"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_ATTENDNO:
$notif = array(
'label' => 'attendno',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s is not attending %s's event"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_ATTENDMAYBE:
$notif = array(
'label' => 'attendmaybe',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s may attend %s's event"), $it['author-name'], $it['pname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif = array(
'label' => 'friend',
'link' => $this->a->get_baseurl(true).'/display/'.$it['pguid'],
'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'when' => relative_date($it['created']),
'seen' => $it['seen']
);
break;
default:
$notif = array(
'label' => $default_item_label,
'link' => $default_item_link,
'image' => $default_item_image,
'text' => $default_item_text,
'when' => $default_item_when,
'seen' => $it['seen']
);
}
$arr[] = $notif;
}
}
return $arr;
}
/**
* @brief Total number of network notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of network notifications
*/
private function networkTotal($seen = 0) {
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT COUNT(*) AS `total`
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
$sql_seen",
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get network notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available network notifications
* array 'notifications' => Network notifications
*/
public function networkNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'network';
$total = $this->networkTotal($seen);
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` AS `object`,
`pitem`.`author-name` AS `pname`, `pitem`.`author-link` AS `plink`, `pitem`.`guid` AS `pguid`
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
$sql_seen
ORDER BY `item`.`created` DESC LIMIT %d, %d ",
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Total number of system notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of system notifications
*/
private function systemTotal($seen = 0) {
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `seen` = 0 ";
$r = q("SELECT COUNT(*) AS `total` FROM `notify` WHERE `uid` = %d $sql_seen",
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get system notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available system notifications
* array 'notifications' => System notifications
*/
public function systemNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'system';
$total = $this->systemTotal($seen);
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `seen` = 0 ";
$r = q("SELECT `id`, `photo`, `msg`, `date`, `seen` FROM `notify`
WHERE `uid` = %d $sql_seen ORDER BY `date` DESC LIMIT %d, %d ",
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Addional SQL query string for the personal notifications
*
* @return string The additional sql query
*/
private function _personal_sql_extra() {
$myurl = $this->a->get_baseurl(true) . '/profile/'. $this->a->user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/profile/','/u/',$myurl);
$sql_extra = sprintf(" AND ( `item`.`author-link` regexp '%s' or `item`.`tag` regexp '%s' or `item`.`tag` regexp '%s' ) ",
dbesc($myurl . '$'),
dbesc($myurl . '\\]'),
dbesc($diasp_url . '\\]')
);
return $sql_extra;
}
/**
* @brief Total number of personal notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of personal notifications
*/
private function personalTotal($seen = 0) {
$sql_seen = "";
$sql_extra = $this->_personal_sql_extra();
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT COUNT(*) AS `total`
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1
$sql_extra
$sql_seen
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 " ,
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get personal notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available personal notifications
* array 'notifications' => Personal notifications
*/
public function personalNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'personal';
$total = $this->personalTotal($seen);
$sql_extra = $this->_personal_sql_extra();
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` AS `object`,
`pitem`.`author-name` AS `pname`, `pitem`.`author-link` AS `plink`, `pitem`.`guid` AS `pguid`,
FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1
$sql_extra
$sql_seen
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0
ORDER BY `item`.`created` DESC LIMIT %d, %d " ,
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Total number of home notifications
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @return int Number of home notifications
*/
private function homeTotal($seen = 0) {
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT COUNT(*) AS `total` FROM `item`
WHERE `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1
$sql_seen",
intval(local_user())
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get home notifications
*
* @param int|string $seen
* If 0 only include notifications into the query
* which aren't marked as "seen"
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available home notifications
* array 'notifications' => Home notifications
*/
public function homeNotifs($seen = 0, $start = 0, $limit = 80) {
$ident = 'home';
$total = $this->homeTotal($seen);
$notifs = array();
$sql_seen = "";
if($seen === 0)
$sql_seen = " AND `item`.`unseen` = 1 ";
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, `item`.`unseen`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1
$sql_seen
ORDER BY `item`.`created` DESC LIMIT %d, %d ",
intval(local_user()),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatNotifs($r, $ident);
$arr = array (
'notifications' => $notifs,
'ident' => $ident,
'total' => $total,
);
return $arr;
}
/**
* @brief Total number of introductions
* @param bool $all
* If false only include introductions into the query
* which aren't marked as ignored
* @return int Number of introductions
*/
private function introTotal($all = false) {
$sql_extra = "";
if(!$all)
$sql_extra = " AND `ignore` = 0 ";
$r = q("SELECT COUNT(*) AS `total` FROM `intro`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid'])
);
if(dbm::is_result($r))
return $r[0]['total'];
return 0;
}
/**
* @brief Get introductions
*
* @param bool $all
* If false only include introductions into the query
* which aren't marked as ignored
* @param int $start Start the query at this point
* @param int $limit Maximum number of query results
*
* @return array with
* string 'ident' => Notification identifier
* int 'total' => Total number of available introductions
* array 'notifications' => Introductions
*/
public function introNotifs($all = false, $start = 0, $limit = 80) {
$ident = 'introductions';
$total = $this->introTotal($seen);
$notifs = array();
$sql_extra = "";
if(!$all)
$sql_extra = " AND `ignore` = 0 ";
/// @todo Fetch contact details by "get_contact_details_by_url" instead of queries to contact, fcontact and gcontact
$r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest`,
`gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
`gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
`gcontact`.`network` AS `gnetwork`
FROM `intro`
LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0
LIMIT %d, %d",
intval($_SESSION['uid']),
intval($start),
intval($limit)
);
if(dbm::is_result($r))
$notifs = $this->formatIntros($r);
$arr = array (
'ident' => $ident,
'total' => $total,
'notifications' => $notifs,
);
return $arr;
}
/**
* @brief Format the notification query in an usable array
*
* @param array $intros The array from the db query
* @return array with the introductions
*/
private function formatIntros($intros) {
$knowyou = '';
foreach($intros as $it) {
// There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
// We have to distinguish between these two because they use different data.
// Contact suggestions
if($it['fid']) {
$return_addr = bin2hex($this->a->user['nickname'] . '@' . $this->a->get_hostname() . (($this->a->path) ? '/' . $this->a->path : ''));
$intro = array(
'label' => 'friend_suggestion',
'notify_type' => t('Friend Suggestion'),
'intro_id' => $it['intro_id'],
'madeby' => $it['name'],
'contact_id' => $it['contact-id'],
'photo' => ((x($it,'fphoto')) ? proxy_url($it['fphoto'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'name' => $it['fname'],
'url' => zrl($it['furl']),
'hidden' => $it['hidden'] == 1,
'post_newfriend' => (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0),
'knowyou' => $knowyou,
'note' => $it['note'],
'request' => $it['frequest'] . '?addr=' . $return_addr,
);
// Normal connection requests
} else {
// Probe the contact url to get missing data
$ret = probe_url($it["url"]);
if ($it['gnetwork'] == "")
$it['gnetwork'] = $ret["network"];
// Don't show these data until you are connected. Diaspora is doing the same.
if($it['gnetwork'] === NETWORK_DIASPORA) {
$it['glocation'] = "";
$it['gabout'] = "";
$it['ggender'] = "";
}
$intro = array(
'label' => (($it['network'] !== NETWORK_OSTATUS) ? 'friend_request' : 'follower'),
'notify_type' => (($it['network'] !== NETWORK_OSTATUS) ? t('Friend/Connect Request') : t('New Follower')),
'dfrn_id' => $it['issued-id'],
'uid' => $_SESSION['uid'],
'intro_id' => $it['intro_id'],
'contact_id' => $it['contact-id'],
'photo' => ((x($it,'photo')) ? proxy_url($it['photo'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'name' => $it['name'],
'location' => bbcode($it['glocation'], false, false),
'about' => bbcode($it['gabout'], false, false),
'keywords' => $it['gkeywords'],
'gender' => $it['ggender'],
'hidden' => $it['hidden'] == 1,
'post_newfriend' => (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0),
'url' => $it['url'],
'zrl' => zrl($it['url']),
'addr' => $ret['addr'],
'network' => $it['gnetwork'],
'knowyou' => $it['knowyou'],
'note' => $it['note'],
);
}
$arr[] = $intro;
}
return $arr;
}
} }

View file

@ -107,6 +107,9 @@ class dba {
$a->save_timestamp($stamp1, "database"); $a->save_timestamp($stamp1, "database");
if (strtolower(substr($sql, 0, 6)) != "select")
$a->save_timestamp($stamp1, "database_write");
if(x($a->config,'system') && x($a->config['system'],'db_log')) { if(x($a->config,'system') && x($a->config['system'],'db_log')) {
if (($duration > $a->config["system"]["db_loglimit"])) { if (($duration > $a->config["system"]["db_loglimit"])) {
$duration = round($duration, 3); $duration = round($duration, 3);

View file

@ -217,7 +217,7 @@ function poller_max_connections_reached() {
* *
*/ */
function poller_kill_stale_workers() { function poller_kill_stale_workers() {
$r = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'"); $r = q("SELECT `pid`, `executed`, `priority`, `parameter` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
if (!dbm::is_result($r)) { if (!dbm::is_result($r)) {
// No processing here needed // No processing here needed
@ -230,9 +230,19 @@ function poller_kill_stale_workers() {
intval($pid["pid"])); intval($pid["pid"]));
else { else {
// Kill long running processes // Kill long running processes
// Check if the priority is in a valid range
if (!in_array($pid["priority"], array(PRIORITY_SYSTEM, PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORITY_LOW)))
$pid["priority"] = PRIORITY_MEDIUM;
// Define the maximum durations
$max_duration_defaults = array(PRIORITY_SYSTEM => 360, PRIORITY_HIGH => 10, PRIORITY_MEDIUM => 60, PRIORITY_LOW => 180);
$max_duration = $max_duration_defaults[$pid["priority"]];
// How long is the process already running?
$duration = (time() - strtotime($pid["executed"])) / 60; $duration = (time() - strtotime($pid["executed"])) / 60;
if ($duration > 180) { if ($duration > $max_duration) {
logger("Worker process ".$pid["pid"]." took more than 3 hours. It will be killed now."); logger("Worker process ".$pid["pid"]." (".$pid["parameter"].") took more than ".$max_duration." minutes. It will be killed now.");
posix_kill($pid["pid"], SIGTERM); posix_kill($pid["pid"], SIGTERM);
// We killed the stale process. // We killed the stale process.
@ -244,7 +254,7 @@ function poller_kill_stale_workers() {
intval(PRIORITY_LOW), intval(PRIORITY_LOW),
intval($pid["pid"])); intval($pid["pid"]));
} else } else
logger("Worker process ".$pid["pid"]." now runs for ".round($duration)." minutes. That's okay.", LOGGER_DEBUG); logger("Worker process ".$pid["pid"]." now runs for ".round($duration)." of ".$max_duration." allowed minutes. That's okay.", LOGGER_DEBUG);
} }
} }
@ -286,7 +296,7 @@ function poller_too_much_workers() {
$high_running = $s[0]["total"]; $high_running = $s[0]["total"];
/// @todo define maximum number of fastlanes /// @todo define maximum number of fastlanes
if (($high_running == 0) AND ($top_priority >= PRIORITY_HIGH) AND ($top_priority < PRIORITY_LOW)) { if (($high_running == 0) AND ($top_priority != PRIORITY_UNDEFINED) AND ($top_priority < PRIORITY_LOW)) {
logger("There are jobs with priority ".$top_priority." waiting but none is executed. Open a fastlane.", LOGGER_DEBUG); logger("There are jobs with priority ".$top_priority." waiting but none is executed. Open a fastlane.", LOGGER_DEBUG);
$queues = $active + 1; $queues = $active + 1;
} }

View file

@ -418,6 +418,7 @@ function check_funcs(&$checks) {
check_add($ck_funcs, t('mb_string PHP module'), true, true, ""); check_add($ck_funcs, t('mb_string PHP module'), true, true, "");
check_add($ck_funcs, t('mcrypt PHP module'), true, true, ""); check_add($ck_funcs, t('mcrypt PHP module'), true, true, "");
check_add($ck_funcs, t('XML PHP module'), true, true, ""); check_add($ck_funcs, t('XML PHP module'), true, true, "");
check_add($ck_funcs, t('iconv module'), true, true, "");
if(function_exists('apache_get_modules')){ if(function_exists('apache_get_modules')){
if (! in_array('mod_rewrite',apache_get_modules())) { if (! in_array('mod_rewrite',apache_get_modules())) {
@ -451,6 +452,10 @@ function check_funcs(&$checks) {
$ck_funcs[5]['status']= false; $ck_funcs[5]['status']= false;
$ck_funcs[5]['help']= t('Error: mcrypt PHP module required but not installed.'); $ck_funcs[5]['help']= t('Error: mcrypt PHP module required but not installed.');
} }
if(! function_exists('iconv_strlen')){
$ck_funcs[7]['status']= false;
$ck_funcs[7]['help']= t('Error: iconv PHP module required but not installed.');
}
$checks = array_merge($checks, $ck_funcs); $checks = array_merge($checks, $ck_funcs);

View file

@ -1,7 +1,13 @@
<?php <?php
include_once("include/bbcode.php");
include_once("include/contact_selectors.php"); /**
include_once("include/Scrape.php"); * @file mod/notifications.php
* @brief The notifications module
*/
require_once("include/NotificationsManager.php");
require_once("include/contact_selectors.php");
require_once("include/network.php");
function notifications_post(&$a) { function notifications_post(&$a) {
@ -66,499 +72,248 @@ function notifications_content(&$a) {
return; return;
} }
$page = (x($_REQUEST,'page') ? $_REQUEST['page'] : 1);
$show = (x($_REQUEST,'show') ? $_REQUEST['show'] : 0);
nav_set_selected('notifications'); nav_set_selected('notifications');
$json = (($a->argc > 1 && $a->argv[$a->argc - 1] === 'json') ? true : false); $json = (($a->argc > 1 && $a->argv[$a->argc - 1] === 'json') ? true : false);
$nm = new NotificationsManager();
$o = ''; $o = '';
// get the nav tabs for the notification pages // Get the nav tabs for the notification pages
$tabs = notifications_tabs($a); $tabs = $nm->getTabs();
$notif_content = array(); $notif_content = array();
// Notification results per page
$perpage = 20;
$startrec = ($page * $perpage) - $perpage;
// Get introductions
if( (($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) { if( (($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) {
nav_set_selected('introductions'); nav_set_selected('introductions');
if(($a->argc > 2) && ($a->argv[2] == 'all'))
$sql_extra = '';
else
$sql_extra = " AND `ignore` = 0 ";
$notif_header = t('Notifications'); $notif_header = t('Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$notif_ignored_lnk .= '<a href="' . ((strlen($sql_extra)) ? 'notifications/intros/all' : 'notifications/intros' ) . '" id="notifications-show-hide-link" >' $all = (($a->argc > 2) && ($a->argv[2] == 'all'));
. ((strlen($sql_extra)) ? t('Show Ignored Requests') : t('Hide Ignored Requests')) . '</a></div>' . "\r\n";
$r = q("SELECT COUNT(*) AS `total` FROM `intro` $notifs = $nm->introNotifs($all, $startrec, $perpage);
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid']) // Get the network notifications
} else if (($a->argc > 1) && ($a->argv[1] == 'network')) {
$notif_header = t('Network Notifications');
$notifs = $nm->networkNotifs($show, $startrec, $perpage);
// Get the system notifications
} else if (($a->argc > 1) && ($a->argv[1] == 'system')) {
$notif_header = t('System Notifications');
$notifs = $nm->systemNotifs($show, $startrec, $perpage);
// Get the personal notifications
} else if (($a->argc > 1) && ($a->argv[1] == 'personal')) {
$notif_header = t('Personal Notifications');
$notifs = $nm->personalNotifs($show, $startrec, $perpage);
// Get the home notifications
} else if (($a->argc > 1) && ($a->argv[1] == 'home')) {
$notif_header = t('Home Notifications');
$notifs = $nm->homeNotifs($show, $startrec, $perpage);
}
// Set the pager
$a->set_pager_total($notifs['total']);
$a->set_pager_itemspage($perpage);
// Add additional informations (needed for json output)
$notifs['items_page'] = $a->pager['itemspage'];
$notifs['page'] = $a->pager['page'];
// Json output
if(intval($json) === 1)
json_return_and_die($notifs);
$notif_tpl = get_markup_template('notifications.tpl');
// Process the data for template creation
if($notifs['ident'] === 'introductions') {
$sugg = get_markup_template('suggestions.tpl');
$tpl = get_markup_template("intros.tpl");
// The link to switch between ignored and normal connection requests
$notif_show_lnk = array(
'href' => (!$all ? 'notifications/intros/all' : 'notifications/intros' ),
'text' => (!$all ? t('Show Ignored Requests') : t('Hide Ignored Requests'))
); );
if($r && count($r)) {
$a->set_pager_total($r[0]['total']);
$a->set_pager_itemspage(20);
}
/// @todo Fetch contact details by "get_contact_details_by_url" instead of queries to contact, fcontact and gcontact // Loop through all introduction notifications.This creates an array with the output html for each
// introduction
$r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest`, foreach ($notifs['notifications'] as $it) {
`gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
`gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
`gcontact`.`network` AS `gnetwork`
FROM `intro`
LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid']));
if(($r !== false) && (count($r))) {
$sugg = get_markup_template('suggestions.tpl');
$tpl = get_markup_template("intros.tpl");
foreach($r as $rr) {
if($rr['fid']) {
$return_addr = bin2hex($a->user['nickname'] . '@' . $a->get_hostname() . (($a->path) ? '/' . $a->path : ''));
// There are two kind of introduction. Contacts suggested by other contacts and normal connection requests.
// We have to distinguish between these two because they use different data.
switch ($it['label']) {
case 'friend_suggestion':
$notif_content[] = replace_macros($sugg, array( $notif_content[] = replace_macros($sugg, array(
'$str_notifytype' => t('Notification type: '), '$str_notifytype' => t('Notification type: '),
'$notify_type' => t('Friend Suggestion'), '$notify_type' => $it['notify_type'],
'$intro_id' => $rr['intro_id'], '$intro_id' => $it['intro_id'],
'$madeby' => sprintf( t('suggested by %s'),$rr['name']), '$madeby' => sprintf( t('suggested by %s'),$it['madeby']),
'$contact_id' => $rr['contact-id'], '$contact_id' => $it['contact-id'],
'$photo' => ((x($rr,'fphoto')) ? proxy_url($rr['fphoto'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"), '$photo' => $it['photo'],
'$fullname' => $rr['fname'], '$fullname' => $it['name'],
'$url' => zrl($rr['furl']), '$url' => $it['url'],
'$hidden' => array('hidden', t('Hide this contact from others'), ($rr['hidden'] == 1), ''), '$hidden' => array('hidden', t('Hide this contact from others'), ($it['hidden'] == 1), ''),
'$activity' => array('activity', t('Post a new friend activity'), (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0), t('if applicable')), '$activity' => array('activity', t('Post a new friend activity'), $it['post_newfriend'], t('if applicable')),
'$knowyou' => $knowyou, '$knowyou' => $it['knowyou'],
'$approve' => t('Approve'), '$approve' => t('Approve'),
'$note' => $rr['note'], '$note' => $it['note'],
'$request' => $rr['frequest'] . '?addr=' . $return_addr, '$request' => $it['request'],
'$ignore' => t('Ignore'), '$ignore' => t('Ignore'),
'$discard' => t('Discard'), '$discard' => t('Discard'),
)); ));
break;
continue; // Normal connection requests
default:
$friend_selected = (($it['network'] !== NETWORK_OSTATUS) ? ' checked="checked" ' : ' disabled ');
$fan_selected = (($it['network'] === NETWORK_OSTATUS) ? ' checked="checked" disabled ' : '');
$dfrn_tpl = get_markup_template('netfriend.tpl');
} $knowyou = '';
$friend_selected = (($rr['network'] !== NETWORK_OSTATUS) ? ' checked="checked" ' : ' disabled '); $dfrn_text = '';
$fan_selected = (($rr['network'] === NETWORK_OSTATUS) ? ' checked="checked" disabled ' : '');
$dfrn_tpl = get_markup_template('netfriend.tpl');
$knowyou = ''; if($it['network'] === NETWORK_DFRN || $it['network'] === NETWORK_DIASPORA) {
$dfrn_text = ''; if($it['network'] === NETWORK_DFRN) {
$lbl_knowyou = t('Claims to be known to you: ');
if($rr['network'] === NETWORK_DFRN || $rr['network'] === NETWORK_DIASPORA) { $knowyou = (($it['knowyou']) ? t('yes') : t('no'));
if($rr['network'] === NETWORK_DFRN) { $helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Fan/Admirer" means that you allow to read but you do not want to read theirs. Approve as: ');
$lbl_knowyou = t('Claims to be known to you: '); } else {
$knowyou = (($rr['knowyou']) ? t('yes') : t('no')); $knowyou = '';
$helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Fan/Admirer" means that you allow to read but you do not want to read theirs. Approve as: '); $helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Sharer" means that you allow to read but you do not want to read theirs. Approve as: ');
} else { }
$knowyou = '';
$helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Sharer" means that you allow to read but you do not want to read theirs. Approve as: ');
} }
$dfrn_text = replace_macros($dfrn_tpl,array( $dfrn_text = replace_macros($dfrn_tpl,array(
'$intro_id' => $rr['intro_id'], '$intro_id' => $it['intro_id'],
'$friend_selected' => $friend_selected, '$friend_selected' => $friend_selected,
'$fan_selected' => $fan_selected, '$fan_selected' => $fan_selected,
'$approve_as' => $helptext, '$approve_as' => $helptext,
'$as_friend' => t('Friend'), '$as_friend' => t('Friend'),
'$as_fan' => (($rr['network'] == NETWORK_DIASPORA) ? t('Sharer') : t('Fan/Admirer')) '$as_fan' => (($it['network'] == NETWORK_DIASPORA) ? t('Sharer') : t('Fan/Admirer'))
)); ));
}
$header = $rr["name"]; $header = $it["name"];
$ret = probe_url($rr["url"]); if ($it["addr"] != "")
$header .= " <".$it["addr"].">";
if ($rr['gnetwork'] == "") $header .= " (".network_to_name($it['network'], $it['url']).")";
$rr['gnetwork'] = $ret["network"];
if ($ret["addr"] != "") $notif_content[] = replace_macros($tpl, array(
$header .= " <".$ret["addr"].">"; '$header' => htmlentities($header),
'$str_notifytype' => t('Notification type: '),
'$notify_type' => $it['notify_type'],
'$dfrn_text' => $dfrn_text,
'$dfrn_id' => $it['dfrn_id'],
'$uid' => $it['uid'],
'$intro_id' => $it['intro_id'],
'$contact_id' => $it['contact_id'],
'$photo' => $it['photo'],
'$fullname' => $it['name'],
'$location' => $it['location'],
'$lbl_location' => t('Location:'),
'$about' => $it['about'],
'$lbl_about' => t('About:'),
'$keywords' => $it['keywords'],
'$lbl_keywords' => t('Tags:'),
'$gender' => $it['gender'],
'$lbl_gender' => t('Gender:'),
'$hidden' => array('hidden', t('Hide this contact from others'), ($it['hidden'] == 1), ''),
'$activity' => array('activity', t('Post a new friend activity'), $it['post_newfriend'], t('if applicable')),
'$url' => $it['url'],
'$zrl' => $it['zrl'],
'$lbl_url' => t('Profile URL'),
'$addr' => $it['addr'],
'$lbl_knowyou' => $lbl_knowyou,
'$lbl_network' => t('Network:'),
'$network' => network_to_name($it['network'], $it['url']),
'$knowyou' => $knowyou,
'$approve' => t('Approve'),
'$note' => $it['note'],
'$ignore' => t('Ignore'),
'$discard' => t('Discard'),
$header .= " (".network_to_name($rr['gnetwork'], $rr['url']).")"; ));
break;
// Don't show these data until you are connected. Diaspora is doing the same.
if($rr['gnetwork'] === NETWORK_DIASPORA) {
$rr['glocation'] = "";
$rr['gabout'] = "";
$rr['ggender'] = "";
}
$notif_content[] = replace_macros($tpl, array(
'$header' => htmlentities($header),
'$str_notifytype' => t('Notification type: '),
'$notify_type' => (($rr['network'] !== NETWORK_OSTATUS) ? t('Friend/Connect Request') : t('New Follower')),
'$dfrn_text' => $dfrn_text,
'$dfrn_id' => $rr['issued-id'],
'$uid' => $_SESSION['uid'],
'$intro_id' => $rr['intro_id'],
'$contact_id' => $rr['contact-id'],
'$photo' => ((x($rr,'photo')) ? proxy_url($rr['photo'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'$fullname' => $rr['name'],
'$location' => bbcode($rr['glocation'], false, false),
'$lbl_location' => t('Location:'),
'$about' => bbcode($rr['gabout'], false, false),
'$lbl_about' => t('About:'),
'$keywords' => $rr['gkeywords'],
'$lbl_keywords' => t('Tags:'),
'$gender' => $rr['ggender'],
'$lbl_gender' => t('Gender:'),
'$hidden' => array('hidden', t('Hide this contact from others'), ($rr['hidden'] == 1), ''),
'$activity' => array('activity', t('Post a new friend activity'), (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0), t('if applicable')),
'$url' => $rr['url'],
'$zrl' => zrl($rr['url']),
'$lbl_url' => t('Profile URL'),
'$addr' => $rr['addr'],
'$lbl_knowyou' => $lbl_knowyou,
'$lbl_network' => t('Network:'),
'$network' => network_to_name($rr['gnetwork'], $rr['url']),
'$knowyou' => $knowyou,
'$approve' => t('Approve'),
'$note' => $rr['note'],
'$ignore' => t('Ignore'),
'$discard' => t('Discard'),
));
} }
} }
else
if($notifs['total'] == 0)
info( t('No introductions.') . EOL); info( t('No introductions.') . EOL);
} else if (($a->argc > 1) && ($a->argv[1] == 'network')) { // Normal notifications (no introductions)
} else {
$notif_header = t('Network Notifications'); // The template files we need in different cases for formatting the content
$notif_tpl = get_markup_template('notifications.tpl'); $tpl_item_like = 'notifications_likes_item.tpl';
$tpl_item_dislike = 'notifications_dislikes_item.tpl';
$tpl_item_attend = 'notifications_attend_item.tpl';
$tpl_item_attendno = 'notifications_attend_item.tpl';
$tpl_item_attendmaybe = 'notifications_attend_item.tpl';
$tpl_item_friend = 'notifications_friends_item.tpl';
$tpl_item_comment = 'notifications_comments_item.tpl';
$tpl_item_post = 'notifications_posts_item.tpl';
$tpl_item_notify = 'notify.tpl';
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`, // Loop trough ever notification This creates an array with the output html for each
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`, // notification and apply the correct template according to the notificationtype (label).
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid` foreach ($notifs['notifications'] as $it) {
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 ORDER BY `item`.`created` DESC" ,
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl'); // We use the notification label to get the correct template file
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl'); $tpl_var_name = 'tpl_item_'.$it['label'];
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl'); $tpl_notif = get_markup_template($$tpl_var_name);
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
$tpl_item_posts = get_markup_template('notifications_posts_item.tpl');
if ($r) { $notif_content[] = replace_macros($tpl_notif,array(
'$item_label' => $it['label'],
foreach ($r as $it) { '$item_link' => $it['link'],
switch($it['verb']){ '$item_image' => $it['image'],
case ACTIVITY_LIKE: '$item_text' => $it['text'],
$notif_content[] = replace_macros($tpl_item_likes,array( '$item_when' => $it['when'],
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'], '$item_seen' => $it['seen'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'], ));
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content[] = replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content[] = replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
$notif_content[] = replace_macros($tpl,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => $item_text,
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_nocontent = t('No more network notifications.');
} }
} else if (($a->argc > 1) && ($a->argv[1] == 'system')) { // It doesn't make sense to show the Show unread / Show all link visible if the user is on the
// "Show all" page and there are no notifications. So we will hide it.
$notif_header = t('System Notifications'); if($show == 0 || intval($show) && $notifs['total'] > 0) {
$notif_tpl = get_markup_template('notifications.tpl'); $notif_show_lnk = array(
'href' => ($show ? 'notifications/'.$notifs['ident'] : 'notifications/'.$notifs['ident'].'?show=all' ),
$not_tpl = get_markup_template('notify.tpl'); 'text' => ($show ? t('Show unread') : t('Show all')),
require_once('include/bbcode.php'); );
$r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc",
intval(local_user())
);
if (count($r) > 0) {
foreach ($r as $it) {
$notif_content[] = replace_macros($not_tpl,array(
'$item_link' => $a->get_baseurl(true).'/notify/view/'. $it['id'],
'$item_image' => proxy_url($it['photo'], false, PROXY_SIZE_MICRO),
'$item_text' => strip_tags(bbcode($it['msg'])),
'$item_when' => relative_date($it['date'])
));
}
} else {
$notif_nocontent = t('No more system notifications.');
}
} else if (($a->argc > 1) && ($a->argv[1] == 'personal')) {
$notif_header = t('Personal Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$myurl = $a->get_baseurl(true) . '/profile/'. $a->user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/profile/','/u/',$myurl);
$sql_extra .= sprintf(" AND ( `item`.`author-link` regexp '%s' or `item`.`tag` regexp '%s' or `item`.`tag` regexp '%s' ) ",
dbesc($myurl . '$'),
dbesc($myurl . '\\]'),
dbesc($diasp_url . '\\]')
);
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1
$sql_extra
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 ORDER BY `item`.`created` DESC" ,
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
$tpl_item_posts = get_markup_template('notifications_posts_item.tpl');
if (count($r) > 0) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content[] = replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content[] = replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content[] = replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
$notif_content[] = replace_macros($tpl,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => $item_text,
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_nocontent = t('No more personal notifications.');
}
} else if (($a->argc > 1) && ($a->argv[1] == 'home')) {
$notif_header = t('Home Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1 ORDER BY `item`.`created` DESC",
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
if (count($r) > 0) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content[] = replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content[] = replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content[] = replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$notif_content[] = replace_macros($tpl_item_comments,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_nocontent = t('No more home notifications.');
} }
// Output if there aren't any notifications available
if($notifs['total'] == 0)
$notif_nocontent = sprintf( t('No more %s notifications.'), $notifs['ident']);
} }
$o .= replace_macros($notif_tpl, array( $o .= replace_macros($notif_tpl, array(
'$notif_header' => $notif_header, '$notif_header' => $notif_header,
'$tabs' => $tabs, '$tabs' => $tabs,
'$notif_content' => $notif_content, '$notif_content' => $notif_content,
'$notif_nocontent' => $notif_nocontent, '$notif_nocontent' => $notif_nocontent,
'$notif_ignored_lnk' => $notif_ignored_lnk, '$notif_show_lnk' => $notif_show_lnk,
'$notif_paginate' => paginate($a)
)); ));
$o .= paginate($a);
return $o; return $o;
} }
/**
* @brief List of pages for the Notifications TabBar
*
* @param app $a The
* @return array with with notifications TabBar data
*/
function notifications_tabs($a) {
$tabs = array(
array(
'label' => t('System'),
'url'=>'notifications/system',
'sel'=> (($a->argv[1] == 'system') ? 'active' : ''),
'accesskey' => 'y',
),
array(
'label' => t('Network'),
'url'=>'notifications/network',
'sel'=> (($a->argv[1] == 'network') ? 'active' : ''),
'accesskey' => 'w',
),
array(
'label' => t('Personal'),
'url'=>'notifications/personal',
'sel'=> (($a->argv[1] == 'personal') ? 'active' : ''),
'accesskey' => 'r',
),
array(
'label' => t('Home'),
'url' => 'notifications/home',
'sel'=> (($a->argv[1] == 'home') ? 'active' : ''),
'accesskey' => 'h',
),
array(
'label' => t('Introductions'),
'url' => 'notifications/intros',
'sel'=> (($a->argv[1] == 'intros') ? 'active' : ''),
'accesskey' => 'i',
),
/*array(
'label' => t('Messages'),
'url' => 'message',
'sel'=> '',
),*/ /*while I can have notifications for messages, this tablist is not place for message page link */
);
return $tabs;
}

View file

@ -79,7 +79,7 @@ $a->config['system']['rino_encrypt'] = {{$rino}};
// default system theme // default system theme
$a->config['system']['theme'] = 'duepuntozero'; $a->config['system']['theme'] = 'vier';
// By default allow pseudonyms // By default allow pseudonyms

View file

@ -6,7 +6,7 @@
<div class="notif-network-wrapper"> <div class="notif-network-wrapper">
{{* The "show ignored" link *}} {{* The "show ignored" link *}}
{{if $notif_ignored_lnk}}{{$notif_ignored_lnk}}{{/if}} {{if $notif_show_lnk}}<a href="{{$notif_show_lnk.href}}" id="notifications-show-hide-link">{{$notif_show_lnk.text}}</a>{{/if}}
{{* The notifications *}} {{* The notifications *}}
{{if $notif_content}} {{if $notif_content}}
@ -19,4 +19,7 @@
{{if $notif_nocontent}} {{if $notif_nocontent}}
<div class="notif_nocontent">{{$notif_nocontent}}</div> <div class="notif_nocontent">{{$notif_nocontent}}</div>
{{/if}} {{/if}}
{{* The pager *}}
{{$notif_paginate}}
</div> </div>

View file

@ -0,0 +1,4 @@
<div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notification"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div>

View file

@ -1,4 +1,4 @@
<div class="notif-item"> <div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a> <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="notif-item"> <div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a> <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="notif-item"> <div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a> <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="notif-item"> <div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notification"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a> <a href="{{$item_link}}" target="friendica-notification"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="notif-item"> <div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a> <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="notif-item"> <div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a> <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="notif-item"> <div class="notif-item {{if !$item_seen}}unseen{{/if}}">
<a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a> <a href="{{$item_link}}" target="friendica-notifications"><img src="{{$item_image}}" class="notif-image">{{$item_text}} <span class="notif-when">{{$item_when}}</span></a>
</div> </div>

View file

@ -1,6 +1,6 @@
# frio # frio
### A bootstrap based theme for friendica ### A bootstrap based theme for friendica
This Theme was started as Experiment to give the user a good looking and modern theme for friendica. This Theme was started as an experiment to give the user a good looking and modern theme for friendica.
I conentrated on 3 topics: I conentrated on 3 topics:
@ -10,14 +10,12 @@ I conentrated on 3 topics:
**Installation Requirements:** **Installation Requirements:**
* modern Browser with JS enabled (Chrome/Chromium is recommended) * modern Browser with JS enabled (Chrome/Chromium is recommended)
* enabled frio_hovercard addon
* if you update the theme you should disable and enable the theme again from the admin panel (to apply possible new hooks) * if you update the theme you should disable and enable the theme again from the admin panel (to apply possible new hooks)
**Note:** **Note:**
This theme is far from beeing stable and ready for productive use. Many parts are missing and will be never added. This theme is marked as experimental. While it is doing its job very well in the most cases there still much work to do to get it marked as stable. So some important templates are still missing and will be added in future versions.
Because of the heavy use of the bootstrap framework nearly every friendica theme template may have to be overwritten. It would be a lot of work and after that it would be hard to maintain the theme.
So why I am doing this? Some insights into my motivation for starting coding this theme:
This theme should be the start of a discussion in the friendica community (users and developers) about UI/UX in friendica. This theme should be the start of a discussion in the friendica community (users and developers) about UI/UX in friendica.
What frameworks do we want to use? How should default friendica look like? And how do we want to use friendica? What do we need in the core code (At the present time some stuff in this is done with ugly javascript hacks and own php code)? What frameworks do we want to use? How should default friendica look like? And how do we want to use friendica? What do we need in the core code (At the present time some stuff in this is done with ugly javascript hacks and own php code)?
@ -59,6 +57,6 @@ Michael Vogel (Vier Theme) - <https://github.com/annando>
StefOfficiel (Friendiboot Theme) - <https://github.com/StefOfficiel/Friendiboot> StefOfficiel (Friendiboot Theme) - <https://github.com/StefOfficiel/Friendiboot>
#### License: #### License:
<https://github.com/rabuzarus/frio/blob/master/LICENSE> <https://raw.githubusercontent.com/friendica/friendica/develop/view/theme/frio/LICENSE>
[original commit history](https://github.com/rabuzarus/frio/commits/master) [original commit history](https://github.com/rabuzarus/frio/commits/master)

View file

@ -108,6 +108,10 @@ a#item-delete-selected {
display: none; display: none;
} }
#toggle_mobile_link {
display: none;
}
/* /*
* Overwriting and Extend Bootstrap * Overwriting and Extend Bootstrap
*/ */
@ -510,6 +514,9 @@ nav.navbar a {
#topbar-first .btn-enter:hover { #topbar-first .btn-enter:hover {
background-color: #89a2b0 background-color: #89a2b0
} }
.navbar-fixed-top ul.nav.navbar-nav.navbar-right {
display: flex;
}
/* Notification Menu */ /* Notification Menu */
@ -1791,15 +1798,18 @@ ul.dropdown-menu li:hover {
-moz-box-shadow: 0 0 3px #dadada; -moz-box-shadow: 0 0 3px #dadada;
} }
/* PAGES */ /* *******
* PAGES
*********/
/* Profile-page */ .generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper,
.generic-page-wrapper ,#profile-page, .profile_photo-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper,
.suggest-content-wrapper, .common-content-wrapper,
.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper,
.directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper, .directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper,
.message-content-wrapper, .apps-content-wrapper, .message-content-wrapper, .apps-content-wrapper, .photos-content-wrapper,
.admin-content-wrapper, .group-content-wrapper, .viewcontacts-content-wrapper { .admin-content-wrapper, .group-content-wrapper, .viewcontacts-content-wrapper,
.dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper,
.nogroup-content-wrapper, .profperm-content-wrapper {
min-height: calc(100vh - 150px); min-height: calc(100vh - 150px);
padding: 15px; padding: 15px;
padding-bottom: 20px; padding-bottom: 20px;
@ -1815,6 +1825,8 @@ ul.dropdown-menu li:hover {
-webkit-box-shadow: 0 0 3px #dadada; -webkit-box-shadow: 0 0 3px #dadada;
-moz-box-shadow: 0 0 3px #dadada; -moz-box-shadow: 0 0 3px #dadada;
} }
/* Profile-page */
#profile-content-standard, #profile-content-standard,
#profile-content-advanced { #profile-content-advanced {
overflow: hidden; overflow: hidden;
@ -2174,12 +2186,17 @@ ul.notif-network-list > li {
padding-left: 15px; padding-left: 15px;
padding-right: 15px; padding-right: 15px;
} }
ul.notif-network-list li.unseen {
border-left: 3px solid #f3fcfd;
background-color: #f3fcfd;
}
.intro-wrapper.media { .intro-wrapper.media {
overflow: visible; overflow: visible;
word-wrap: break-word; word-wrap: break-word;
margin-top: 0; margin-top: 0;
} }
.intro-photo-wrapper img.intro-photo { .intro-photo-wrapper img.intro-photo,
.notif-item img.notif-image {
height:80px; height:80px;
width: 80px; width: 80px;
border-radius: 4px; border-radius: 4px;
@ -2231,6 +2248,31 @@ ul.notif-network-list > li:hover .intro-action-buttons {
display: block; display: block;
margin-top: 5px margin-top: 5px
} }
/* Search Page */
/* This is a little bit hacky. Since the search page is used for diferent
content types we can't apply the generic-page-wrapper class.
So we apply the css of the generic-page-wrapper class to the ul element with some
little modifications to emulate a standard page template */
.search-content-wrapper > ul.viewcontact_wrapper {
min-height: calc(100vh - 150px);
padding-top: 15px;
padding-bottom: 20px;
margin: 0;
margin-bottom: 20px;
border: none;
/*background-color: #fff;*/
background-color: rgba(255,255,255,$contentbg_transp);
border-radius: 4px;
position: relative;
/*overflow: hidden;*/
color: #555;
box-shadow: 0 0 3px #dadada;
-webkit-box-shadow: 0 0 3px #dadada;
-moz-box-shadow: 0 0 3px #dadada;
}
/* /*
* Overwriting for transparency and other colors * Overwriting for transparency and other colors
*/ */

View file

@ -73,16 +73,6 @@ else
"; if(x($page,'right_aside')) echo $page['right_aside']; echo" "; if(x($page,'right_aside')) echo $page['right_aside']; echo"
</aside> </aside>
<!-- The following paragraph can maybe deleted because we don't need it anymore -->
<div id=\"NavAside\" class=\"navmenu navmenu-default navmenu-fixed-left offcanvas hidden-lg hidden-md\">
<div class=\"nav-container\">
<div class=\"list-group\">
"; if(x($page,'aside')) echo $page['aside']; echo"
"; if(x($page,'right_aside')) echo $page['right_aside']; echo"
</div>
</div>
</div><!--/.sidebar-offcanvas-->
<div class=\"col-lg-7 col-md-7 col-sm-12 col-xs-12\" id=\"content\"> <div class=\"col-lg-7 col-md-7 col-sm-12 col-xs-12\" id=\"content\">
<section class=\"sectiontop "; echo $a->argv[0]; echo "-content-wrapper\">"; <section class=\"sectiontop "; echo $a->argv[0]; echo "-content-wrapper\">";
if(x($page,'content')) echo $page['content']; echo" if(x($page,'content')) echo $page['content']; echo"

View file

@ -42,16 +42,6 @@
"; include('includes/photo_side.php'); echo" "; include('includes/photo_side.php'); echo"
</aside> </aside>
<div id=\"NavAside\" class=\"navmenu navmenu-default navmenu-fixed-left offcanvas hidden-lg hidden-md\">
<div class=\"nav-container\">
<div class=\"list-group\">
"; if(x($page,'aside')) echo $page['aside']; echo"
"; if(x($page,'right_aside')) echo $page['right_aside']; echo"
"; include('includes/photo_side.php'); echo"
</div>
</div>
</div><!--/.sidebar-offcanvas-->
<div class=\"col-lg-8 col-md-8 col-sm-12 col-xs-12\" id=\"content\"> <div class=\"col-lg-8 col-md-8 col-sm-12 col-xs-12\" id=\"content\">
<section class=\"sectiontop\"> <section class=\"sectiontop\">
<div class=\"panel "; echo $a->argv[0]; echo "-content-wrapper\"> <div class=\"panel "; echo $a->argv[0]; echo "-content-wrapper\">

View file

@ -231,13 +231,13 @@
{{if $nav.userinfo == ''}} {{if $nav.userinfo == ''}}
<nav class="navbar navbar-fixed-top"> <nav class="navbar navbar-fixed-top">
<div class="container"> <div class="container">
<div class="navbar-header"> <div class="navbar-header pull-left">
<a class="navbar-brand" href="#"><div id="navbrand-container"> <a class="navbar-brand" href="#"><div id="navbrand-container">
<div id="logo-img"></div> <div id="logo-img"></div>
<div id="navbar-brand-text"> Friendica</div></div> <div id="navbar-brand-text"> Friendica</div></div>
</a> </a>
</div> </div>
<div class="hidden-sm hidden-xs"> <div class="pull-right">
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li><a href="register" data-toggle="tooltip" title="{{$register.title}}"><i class="fa fa-street-view fa-fw"></i> {{$register.desc}}</a></li> <li><a href="register" data-toggle="tooltip" title="{{$register.title}}"><i class="fa fa-street-view fa-fw"></i> {{$register.desc}}</a></li>
<li> <li>

View file

@ -6,7 +6,7 @@
<div class="notif-network-wrapper"> <div class="notif-network-wrapper">
{{* The "show ignored" link *}} {{* The "show ignored" link *}}
{{if $notif_ignored_lnk}}{{$notif_ignored_lnk}}{{/if}} {{if $notif_show_lnk}}<a href="{{$notif_show_lnk.href}}" id="notifications-show-hide-link">{{$notif_show_lnk.text}}</a>{{/if}}
{{* The notifications *}} {{* The notifications *}}
{{if $notif_content}} {{if $notif_content}}
@ -22,4 +22,17 @@
<div class="notif_nocontent">{{$notif_nocontent}}</div> <div class="notif_nocontent">{{$notif_nocontent}}</div>
{{/if}} {{/if}}
</div> </div>
{{* The pager *}}
{{$notif_paginate}}
</div> </div>
{{* Since only the DIV's inside the notification-list are marked with the class "unseen",
we need some js to transfer this class to the parent li list-elements *}}
<script>
$(document).ready(function(){
if( $(".notif-item").hasClass("unseen")) {
$(".notif-item.unseen").parent("li").addClass("unseen");
}
});
</script>

View file

@ -2,7 +2,7 @@
/* /*
* Name: frio * Name: frio
* Description: Bootstrap V3 theme. The theme is currently under construction, so it is far from finished. For further information have a look at the <a href="https://github.com/friendica/friendica/tree/develop/view/theme/frio/README.md">ReadMe</a>. * Description: Bootstrap V3 theme. The theme is currently under construction, so it is far from finished. For further information have a look at the <a href="https://github.com/friendica/friendica/tree/develop/view/theme/frio/README.md">ReadMe</a>.
* Version: V.0.2 Alpha * Version: V.0.7
* Author: Rabuzarus <https://friendica.kommune4.de/profile/rabuzarus> * Author: Rabuzarus <https://friendica.kommune4.de/profile/rabuzarus>
* *
*/ */