Merge remote-tracking branch 'upstream/develop' into issue-3326

This commit is contained in:
Michael 2017-04-14 22:30:48 +00:00
commit e7783e2018
40 changed files with 8412 additions and 8405 deletions

View File

@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Asparagus');
define ( 'FRIENDICA_VERSION', '3.5.2-dev' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1216 );
define ( 'DB_UPDATE_VERSION', 1217 );
/**
* @brief Constant with a HTML line break.
@ -382,6 +382,7 @@ define ( 'ACTIVITY_UPDATE', NAMESPACE_ACTIVITY_SCHEMA . 'update' );
define ( 'ACTIVITY_TAG', NAMESPACE_ACTIVITY_SCHEMA . 'tag' );
define ( 'ACTIVITY_FAVORITE', NAMESPACE_ACTIVITY_SCHEMA . 'favorite' );
define ( 'ACTIVITY_SHARE', NAMESPACE_ACTIVITY_SCHEMA . 'share' );
define ( 'ACTIVITY_DELETE', NAMESPACE_ACTIVITY_SCHEMA . 'delete' );
define ( 'ACTIVITY_POKE', NAMESPACE_ZOT . '/activity/poke' );
define ( 'ACTIVITY_MOOD', NAMESPACE_ZOT . '/activity/mood' );

View File

@ -159,7 +159,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`writable` tinyint(1) NOT NULL DEFAULT 0,
`forum` tinyint(1) NOT NULL DEFAULT 0,
`prv` tinyint(1) NOT NULL DEFAULT 0,
`contact-type` int(11) unsigned NOT NULL DEFAULT 0,
`contact-type` int(11) NOT NULL DEFAULT 0,
`hidden` tinyint(1) NOT NULL DEFAULT 0,
`archive` tinyint(1) NOT NULL DEFAULT 0,
`pending` tinyint(1) NOT NULL DEFAULT 1,

10
doc/KeyboardShortcuts.md Normal file
View File

@ -0,0 +1,10 @@
Keyboard shortcuts in Friendica
=======================
* [Home](help)
General
-------
* j: Scroll to next thread
* k: Scroll to previous thread

View File

@ -6,12 +6,10 @@ If you are the admin of a Friendica node, you have access to the so called **Adm
On the front page of the admin panel you will see a summary of information about your node.
These information include the amount of messages currently being processed in the queues.
The first number is the number of messages being actively sent.
This number should decrease quickly.
The second is the messages which could for various reasons not being delivered.
The first number is the number of messages which could not been delivered for various reasons.
They will be resend later.
You can have a quick glance into that second queus in the "Inspect Queue" section of the admin panel.
If you have activated the background workers, there is a third number representing the count of jobs queued for the workers.
The second number represents the current number of jobs for the background workers.
These worker tasks are prioritised and are done accordingly.
Then you get an overview of the accounts on your node, which can be moderated in the "Users" section of the panel.

View File

@ -14,7 +14,6 @@ Database Tables
| [config](help/database/db_config) | main configuration storage |
| [contact](help/database/db_contact) | contact table |
| [conv](help/database/db_conv) | private messages |
| [deliverq](help/database/db_deliverq) | |
| [event](help/database/db_event) | Events |
| [fcontact](help/database/db_fcontact) | friend suggestion stuff |
| [ffinder](help/database/db_ffinder) | friend suggestion stuff |

View File

@ -1,12 +0,0 @@
Table deliverq
==============
| Field | Description | Type | Null | Key | Default | Extra |
|---------|------------------|------------------|------|-----|---------|----------------|
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
| cmd | | varchar(32) | NO | | | |
| item | | int(11) | NO | | 0 | |
| contact | | int(11) | NO | | 0 | |
Return to [database documentation](help/database)

View File

@ -5,14 +5,11 @@
Wenn du der Administrator einer Friendica Instanz bist, hast du Zugriff auf das so genannte **Admin Panel** in dem du die Friendica Instanz konfigurieren kannst,
Auf der Startseite des Admin Panels werden die Informationen zu der Instanz zusammengefasst.
Diese Informationen beinhalten die Anzahl der Nachrichten, die sich aktuell in den Warteschlangen befinden.
Hierbei ist die erste Zahl die Zahl der Nachrichten die gerade aktiv verteilt werden.
Diese Zahl sollte sich relativ schnell sinken.
Die zweite Zahl gibt die Anzahl von Nachrichten an, die nicht zugestellt werden konnten.
Die erste Zahl gibt die Anzahl von Nachrichten an, die nicht zugestellt werden konnten.
Die Zustellung wird zu einem späteren Zeitpunkt noch einmal versucht.
Unter dem Punkt "Warteschlange Inspizieren" kannst du einen schnellen Blick auf die zweite Warteschlange werfen.
Solltest du für die Hintergrundprozesse die Worker aktiviert haben, wird eine dritte Zahl angezeigt.
Diese repräsentiert die Anzahl der Aufgaben, die die Worker noch vor sich haben.
Die zweite Zahl steht für die Anzahl der Aufgaben, die die Worker noch vor sich haben.
Die Worker arbeiten Hintergrundprozesse ab.
Die Aufgaben der Worker sind priorisiert und werden anhand dieser Prioritäten abgearbeitet.
Desweiteren findest du eine Übersicht über die Accounts auf dem Friendica Knoten, die unter dem Punkt "Nutzer" moderiert werden können.

View File

@ -364,9 +364,9 @@ class Probe {
return self::mail($uri, $uid);
}
if ($network == NETWORK_MAIL)
if ($network == NETWORK_MAIL) {
return self::mail($uri, $uid);
}
// Remove "acct:" from the URI
$uri = str_replace('acct:', '', $uri);
@ -391,37 +391,37 @@ class Probe {
/// @todo Do we need the prefix "acct:" or "acct://"?
foreach ($lrdd AS $key => $link) {
if ($webfinger)
if ($webfinger) {
continue;
}
if (!in_array($key, array("lrdd", "lrdd-xml", "lrdd-json"))) {
continue;
}
// At first try it with the given uri
$path = str_replace('{uri}', urlencode($uri), $link);
$webfinger = self::webfinger($path);
if (!in_array($key, array("lrdd", "lrdd-xml", "lrdd-json")))
continue;
// We cannot be sure that the detected address was correct, so we don't use the values
if ($webfinger AND ($uri != $addr)) {
$nick = "";
$addr = "";
}
// Try webfinger with the address (user@domain.tld)
if (!$webfinger) {
$path = str_replace('{uri}', urlencode($addr), $link);
$webfinger = self::webfinger($path);
}
// Mastodon needs to have it with "acct:"
if (!$webfinger) {
$path = str_replace('{uri}', urlencode("acct:".$addr), $link);
$webfinger = self::webfinger($path);
}
// If webfinger wasn't successful then try it with the URL - possibly in the format https://...
if (!$webfinger AND ($uri != $addr)) {
$path = str_replace('{uri}', urlencode($uri), $link);
$webfinger = self::webfinger($path);
// Since the detection with the address wasn't successful, we delete it.
if ($webfinger) {
$nick = "";
$addr = "";
}
}
}
if (!$webfinger)
if (!$webfinger) {
return self::feed($uri);
}
$result = false;

View File

@ -610,12 +610,18 @@ function acl_lookup(App $a, $out_type = 'json') {
$items = array_merge($groups, $contacts);
if ($conv_id) {
/* if $conv_id is set, get unknow contacts in thread */
/* but first get know contacts url to filter them out */
function _contact_link($i){ return dbesc($i['link']); }
$known_contacts = array_map(_contact_link, $contacts);
$unknow_contacts=array();
$r = q("SELECT `author-avatar`,`author-name`,`author-link`
/*
* if $conv_id is set, get unknown contacts in thread
* but first get known contacts url to filter them out
*/
$known_contacts = array_map(
function ($i) {
return dbesc($i['link']);
}
, $contacts);
$unknown_contacts = array();
$r = q("SELECT `author-link`
FROM `item` WHERE `parent` = %d
AND (`author-name` LIKE '%%%s%%' OR `author-link` LIKE '%%%s%%')
AND `author-link` NOT IN ('%s')
@ -629,27 +635,25 @@ function acl_lookup(App $a, $out_type = 'json') {
);
if (dbm::is_result($r)) {
foreach ($r as $row) {
// nickname..
$up = parse_url($row['author-link']);
$nick = explode("/",$up['path']);
$nick = $nick[count($nick)-1];
$nick .= "@".$up['host'];
// /nickname
$unknow_contacts[] = array(
$contact = get_contact_details_by_url($row['author-link']);
if (count($contact) > 0) {
$unknown_contacts[] = array(
'type' => 'c',
'photo' => proxy_url($row['author-avatar'], false, PROXY_SIZE_MICRO),
'name' => htmlentities($row['author-name']),
'id' => '',
'network' => 'unknown',
'link' => $row['author-link'],
'nick' => htmlentities($nick),
'forum' => false
'photo' => proxy_url($contact['micro'], false, PROXY_SIZE_MICRO),
'name' => htmlentities($contact['name']),
'id' => intval($contact['cid']),
'network' => $contact['network'],
'link' => $contact['url'],
'nick' => htmlentities($contact['nick'] ? : $contact['addr']),
'forum' => $contact['forum']
);
}
}
}
$items = array_merge($items, $unknow_contacts);
$tot += count($unknow_contacts);
$items = array_merge($items, $unknown_contacts);
$tot += count($unknown_contacts);
}
$results = array(

View File

@ -698,7 +698,7 @@ function db_definition() {
"writable" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"forum" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"prv" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"contact-type" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
"contact-type" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"archive" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"pending" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),

View File

@ -355,6 +355,14 @@ class ostatus {
$item["body"] = add_page_info_to_body(html2bbcode($xpath->query('atom:content/text()', $entry)->item(0)->nodeValue));
$item["object-type"] = $xpath->query('activity:object-type/text()', $entry)->item(0)->nodeValue;
$item["verb"] = $xpath->query('activity:verb/text()', $entry)->item(0)->nodeValue;
// Mastodon Content Warning
if (($item["verb"] == ACTIVITY_POST) AND $xpath->evaluate('boolean(atom:summary)', $entry)) {
$clear_text = $xpath->query('atom:summary/text()', $entry)->item(0)->nodeValue;
$item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]';
}
if (($item["object-type"] == ACTIVITY_OBJ_BOOKMARK) OR ($item["object-type"] == ACTIVITY_OBJ_EVENT)) {
$item["title"] = $xpath->query('atom:title/text()', $entry)->item(0)->nodeValue;
@ -363,11 +371,10 @@ class ostatus {
$item["title"] = $xpath->query('atom:title/text()', $entry)->item(0)->nodeValue;
}
$item["object"] = $xml;
$item["verb"] = $xpath->query('activity:verb/text()', $entry)->item(0)->nodeValue;
/// @TODO
/// Delete a message
if ($item["verb"] == "qvitter-delete-notice") {
if ($item["verb"] == "qvitter-delete-notice" || $item["verb"] == ACTIVITY_DELETE) {
// ignore "Delete" messages (by now)
logger("Ignore delete message ".print_r($item, true));
continue;
@ -2052,7 +2059,7 @@ class ostatus {
$mentioned = array();
if (($item['parent'] != $item['id']) || ($item['parent-uri'] !== $item['uri']) || (($item['thr-parent'] !== '') && ($item['thr-parent'] !== $item['uri']))) {
if (($item['parent'] != $item['id']) OR ($item['parent-uri'] !== $item['uri']) OR (($item['thr-parent'] !== '') AND ($item['thr-parent'] !== $item['uri']))) {
$parent = q("SELECT `guid`, `author-link`, `owner-link` FROM `item` WHERE `id` = %d", intval($item["parent"]));
$parent_item = (($item['thr-parent']) ? $item['thr-parent'] : $item['parent-uri']);

View File

@ -59,9 +59,8 @@ function photo_albums($uid, $update = false) {
} else {
// This query doesn't do the count and is much faster
$albums = qu("SELECT DISTINCT(`album`), '' AS `total`
FROM `photo`
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra
GROUP BY `album` ORDER BY `created` DESC",
FROM `photo` USE INDEX (`uid_album_scale_created`)
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra",
intval($uid),
dbesc('Contact Photos'),
dbesc(t('Contact Photos'))

View File

@ -2096,7 +2096,7 @@ function update_gcontact($contact) {
fix_alternate_contact_address($contact);
if (!isset($contact["updated"]))
$contact["updated"] = datetime_convert();
$contact["updated"] = dbm::date();
if ($contact["server_url"] == "") {
$server_url = $contact["url"];
@ -2151,7 +2151,7 @@ function update_gcontact($contact) {
dbesc($contact["gender"]), dbesc($contact["keywords"]), intval($contact["hide"]),
intval($contact["nsfw"]), intval($contact["contact-type"]), dbesc($contact["alias"]),
dbesc($contact["notify"]), dbesc($contact["url"]), dbesc($contact["location"]),
dbesc($contact["about"]), intval($contact["generation"]), dbesc($contact["updated"]),
dbesc($contact["about"]), intval($contact["generation"]), dbesc(dbm::date($contact["updated"])),
dbesc($contact["server_url"]), dbesc($contact["connect"]),
dbesc(normalise_link($contact["url"])), intval($contact["generation"]));

View File

@ -223,8 +223,11 @@
var nnm = $("#nav-notifications-menu");
nnm.html(notifications_all + notifications_mark);
var notification_lastitem = parseInt(localStorage.getItem("notification-lastitem"));
var lastItemStorageKey = "notification-lastitem:" + localUser;
var notification_lastitem = parseInt(localStorage.getItem(lastItemStorageKey));
var notification_id = 0;
// Insert notifs into the notifications-menu
$(data.notifications).each(function(key, notif){
var text = notif.message.format('<span class="contactname">' + notif.name + '</span>');
var contact = ('<a href="' + notif.url + '"><span class="contactname">' + notif.name + '</span></a>');
@ -242,9 +245,11 @@
);
nnm.append(html);
});
// Desktop Notifications
$(data.notifications.reverse()).each(function(key, e){
notification_id = parseInt(e.timestamp);
if (notification_lastitem !== null && notification_id > notification_lastitem) {
if (notification_lastitem !== null && notification_id > notification_lastitem && Number(e.seen) === 0) {
if (getNotificationPermission() === "granted") {
var notification = new Notification(document.title, {
body: decodeHtml(e.message.replace('&rarr; ', '').format(e.name)),
@ -259,7 +264,7 @@
});
notification_lastitem = notification_id;
localStorage.setItem("notification-lastitem", notification_lastitem)
localStorage.setItem(lastItemStorageKey, notification_lastitem)
$("img[data-src]", nnm).each(function(i, el){
// Add src attribute for images with a data-src attribute
@ -285,7 +290,7 @@
$.jGrowl(message, {sticky: false, theme: 'info', life: 5000});
});
/* update the js scrollbars */
// Update the js scrollbars
$('#nav-notifications-menu').perfectScrollbar('update');
});
@ -317,6 +322,30 @@
}
});
// Scroll to the next/previous thread when pressing J and K
$(document).keydown(function (event) {
var threads = $('.thread_level_1');
if ((event.keyCode === 74 || event.keyCode === 75) && !$(event.target).is('textarea, input')) {
var scrollTop = $(window).scrollTop();
if (event.keyCode === 75) {
threads = $(threads.get().reverse());
}
threads.each(function(key, item) {
var comparison;
var top = $(item).offset().top - 100;
if (event.keyCode === 74) {
comparison = top > scrollTop + 1;
} else if (event.keyCode === 75) {
comparison = top < scrollTop - 1;
}
if (comparison) {
$('html, body').animate({ scrollTop: top }, 200);
return false;
}
});
}
});
// Set an event listener for infinite scroll
if(typeof infinite_scroll !== 'undefined') {
$(window).scroll(function(e){

View File

@ -1,7 +1,7 @@
<?php
/* ACL selector json backend */
require_once("include/acl_selectors.php");
require_once 'include/acl_selectors.php';
function acl_init(App $a) {
acl_lookup($a);

View File

@ -474,9 +474,6 @@ function admin_page_summary(App $a) {
$r = qu("SELECT COUNT(`id`) AS `count` FROM `register`");
$pending = $r[0]['count'];
$r = qu("SELECT COUNT(*) AS `total` FROM `deliverq` WHERE 1");
$deliverq = (($r) ? $r[0]['total'] : 0);
$r = qu("SELECT COUNT(*) AS `total` FROM `queue` WHERE 1");
$queue = (($r) ? $r[0]['total'] : 0);
@ -485,7 +482,7 @@ function admin_page_summary(App $a) {
// We can do better, but this is a quick queue status
$queues = array('label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue, 'workerq' => $workerqueue);
$queues = array('label' => t('Message queues'), 'queue' => $queue, 'workerq' => $workerqueue);
$t = get_markup_template("admin_summary.tpl");

26
mod/manifest.php Normal file
View File

@ -0,0 +1,26 @@
<?php
use Friendica\Core\Config;
function manifest_content(App $a) {
$tpl = get_markup_template('manifest.tpl');
header('Content-type: application/manifest+json');
$touch_icon = Config::get('system', 'touch_icon', 'images/friendica-128.png');
if ($touch_icon == '') {
$touch_icon = 'images/friendica-128.png';
}
$o = replace_macros($tpl, array(
'$baseurl' => App::get_baseurl(),
'$touch_icon' => $touch_icon,
'$title' => Config::get('config', 'sitename', 'Friendica'),
));
echo $o;
killme();
}
?>

View File

@ -4,6 +4,13 @@ require_once('include/Scrape.php');
function probe_content(App $a) {
if (!local_user()) {
http_status_exit(403,
array("title" => t("Public access denied."),
"description" => t("Only logged in users are permitted to perform a probing.")));
killme();
}
$o .= '<h3>Probe Diagnostic</h3>';
$o .= '<form action="probe" method="get">';

View File

@ -1168,13 +1168,13 @@ function settings_content(App $a) {
$profile_in_dir = '<input type="hidden" name="profile_in_directory" value="1" />';
} else {
$profile_in_dir = replace_macros($opt_tpl, array(
'$field' => array('profile_in_directory', t('Publish your default profile in your local site directory?'), $profile['publish'], '', array(t('No'),t('Yes'))),
'$field' => array('profile_in_directory', t('Publish your default profile in your local site directory?'), $profile['publish'], t("Your profile may be visible in public."), array(t('No'), t('Yes')))
));
}
if (strlen(get_config('system','directory'))) {
$profile_in_net_dir = replace_macros($opt_tpl, array(
'$field' => array('profile_in_netdirectory', t('Publish your default profile in the global social directory?'), $profile['net-publish'], '', array(t('No'),t('Yes'))),
'$field' => array('profile_in_netdirectory', t('Publish your default profile in the global social directory?'), $profile['net-publish'], '', array(t('No'), t('Yes')))
));
} else {
$profile_in_net_dir = '';

View File

@ -3,6 +3,13 @@ require_once("include/Probe.php");
function webfinger_content(App $a) {
if (!local_user()) {
http_status_exit(403,
array("title" => t("Public access denied."),
"description" => t("Only logged in users are permitted to perform a probing.")));
killme();
}
$o .= '<h3>Webfinger Diagnostic</h3>';
$o .= '<form action="webfinger" method="get">';

View File

@ -1,6 +1,6 @@
<?php
define('UPDATE_VERSION' , 1216);
define('UPDATE_VERSION' , 1217);
/**
*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
<dl>
<dt>{{$queues.label}}</dt>
<dd>{{$queues.deliverq}} - <a href="{{$baseurl}}/admin/queue">{{$queues.queue}}</a> - {{$queues.workerq}}</dd>
<dd><a href="{{$baseurl}}/admin/queue">{{$queues.queue}}</a> - {{$queues.workerq}}</dd>
</dl>
<dl>
<dt>{{$pending.0}}</dt>

View File

@ -7,7 +7,7 @@
<link rel="stylesheet" href="library/jgrowl/jquery.jgrowl.css" type="text/css" media="screen" />
<link rel="stylesheet" href="library/datetimepicker/jquery.datetimepicker.css" type="text/css" media="screen" />
<link rel="stylesheet" href="library/perfect-scrollbar/perfect-scrollbar.min.css" type="text/css" media="screen" />
<link rel="stylesheet" href="library/Text_Highlighter/sample.css" type="text/css" media="screen" />
<link rel="stylesheet" href="vendor/pear-pear.php.net/Text_Highlighter/data/Text_Highlighter/Text/sample.css" type="text/css" media="screen" />
<link rel="stylesheet" type="text/css" href="{{$stylesheet}}" media="all" />
@ -19,6 +19,7 @@
<link rel="apple-touch-icon" href="{{$touch_icon}}"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="manifest" href="{{$baseurl}}/manifest" />
<script>
// Prevents links to switch to Safari in a home screen app - see https://gist.github.com/irae/1042167
(function(a,b,c){if(c in b&&b[c]){var d,e=a.location,f=/^(a|html)$/i;a.addEventListener("click",function(a){d=a.target;while(!f.test(d.nodeName))d=d.parentNode;"href"in d&&(chref=d.href).replace(e.href,"").indexOf("#")&&(!/^[a-z\+\.\-]+:/i.test(chref)||chref.indexOf(e.protocol+"//"+e.host)===0)&&(a.preventDefault(),e.href=d.href)},!1)}})(document,window.navigator,"standalone");

View File

@ -26,7 +26,7 @@
</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.edit}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.edit.1}}" title="{{$profile.actions.edit.0}}"><i class="fa fa-user" 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>

View File

@ -0,0 +1,9 @@
{
"name": "{{$title}}",
"start_url": "{{$baseurl}}",
"display": "standalone",
"description": "A Decentralized Social Network",
"icons": [{
"src": "{{$baseurl}}/{{$touch_icon}}"
}]
}

View File

@ -440,7 +440,7 @@ nav.navbar .nav>li>a:focus{
border-radius: 3px;
}
#topbar-first .nav>.account .dropdown-toggle {
padding: 10px 5px 8px;
padding: 10px 5px 0px;
line-height: 1.1em;
text-align: left
}

View File

@ -42,7 +42,6 @@
{{/if}}
</div>
</div>
<div class="media-body">
@ -51,7 +50,7 @@
{{if $contact.photo_menu.pm }}<button type="button" class="contact-action-link btn-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></button>{{/if}}
{{if $contact.photo_menu.poke }}<button type="button" class="contact-action-link btn-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></button>{{/if}}
{{if $contact.photo_menu.network}}<a class="contact-action-link btn-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 btn-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.edit }}<a class="contact-action-link btn-link" href="{{$contact.photo_menu.edit.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.edit.0}}"><i class="fa fa-user" aria-hidden="true"></i></a>{{/if}}
{{if $contact.photo_menu.drop }}<button type="button" class="contact-action-link btn-link" onclick="addToModal('{{$contact.photo_menu.drop.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.drop.0}}"><i class="fa fa-user-times" aria-hidden="true"></i></button>{{/if}}
{{if $contact.photo_menu.follow }}<a class="contact-action-link btn-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 btn-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}}

View File

@ -12,7 +12,7 @@
<link rel="stylesheet" href="library/jgrowl/jquery.jgrowl.css" type="text/css" media="screen" />
<link rel="stylesheet" href="library/datetimepicker/jquery.datetimepicker.css" type="text/css" media="screen" />
<link rel="stylesheet" href="library/perfect-scrollbar/perfect-scrollbar.min.css" type="text/css" media="screen" />
<link rel="stylesheet" href="library/Text_Highlighter/sample.css" type="text/css" media="screen" />
<link rel="stylesheet" href="vendor/pear-pear.php.net/Text_Highlighter/data/Text_Highlighter/Text/sample.css" type="text/css" media="screen" />
<link rel="stylesheet" href="view/theme/frio/frameworks/bootstrap/css/bootstrap.min.css" type="text/css" media="screen"/>
<link rel="stylesheet" href="view/theme/frio/frameworks/bootstrap/css/bootstrap-theme.min.css" type="text/css" media="screen"/>
@ -41,6 +41,7 @@
<link rel="apple-touch-icon" href="{{$touch_icon}}"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="manifest" href="{{$baseurl}}/manifest" />
<script>
// Prevents links to switch to Safari in a home screen app - see https://gist.github.com/irae/1042167
(function(a,b,c){if(c in b&&b[c]){var d,e=a.location,f=/^(a|html)$/i;a.addEventListener("click",function(a){d=a.target;while(!f.test(d.nodeName))d=d.parentNode;"href"in d&&(chref=d.href).replace(e.href,"").indexOf("#")&&(!/^[a-z\+\.\-]+:/i.test(chref)||chref.indexOf(e.protocol+"//"+e.host)===0)&&(a.preventDefault(),e.href=d.href)},!1)}})(document,window.navigator,"standalone");