aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzotlabs <mike@macgirvin.com>2017-11-19 17:39:19 -0800
committerzotlabs <mike@macgirvin.com>2017-11-19 17:39:19 -0800
commit4cd0b745cbc24a035a5e9ba488917ec7beeda888 (patch)
treefaad8cf0e7ef2a720ce002e6b280ae31a77971d0
parentcf4588f16fbe6dc55eabdb590480bc88d560dad3 (diff)
parent88d0bf94d89ac739469528bdab7905d0c00cf8a9 (diff)
downloadvolse-hubzilla-4cd0b745cbc24a035a5e9ba488917ec7beeda888.tar.gz
volse-hubzilla-4cd0b745cbc24a035a5e9ba488917ec7beeda888.tar.bz2
volse-hubzilla-4cd0b745cbc24a035a5e9ba488917ec7beeda888.zip
Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge
-rw-r--r--Zotlabs/Lib/Apps.php45
-rw-r--r--Zotlabs/Module/Appman.php6
-rw-r--r--Zotlabs/Module/Apporder.php16
-rw-r--r--Zotlabs/Module/Hq.php260
-rw-r--r--Zotlabs/Module/Like.php15
-rw-r--r--Zotlabs/Module/Notify.php2
-rw-r--r--Zotlabs/Module/Ping.php14
-rw-r--r--Zotlabs/Module/Pubstream.php5
-rw-r--r--Zotlabs/Storage/Browser.php20
-rw-r--r--Zotlabs/Widget/Appcategories.php1
-rw-r--r--Zotlabs/Widget/Forums.php32
-rwxr-xr-xboot.php4
-rw-r--r--doc/hooklist.bb3
-rw-r--r--include/attach.php12
-rw-r--r--include/channel.php16
-rw-r--r--include/nav.php14
-rw-r--r--include/socgraph.php2
-rw-r--r--include/text.php27
-rw-r--r--install/schema_mysql.sql1
-rw-r--r--install/update.php14
-rw-r--r--view/css/bootstrap-red.css4
-rw-r--r--view/css/mod_hq.css3
-rw-r--r--view/js/main.js16
-rw-r--r--view/js/mod_hq.js145
-rw-r--r--view/pdl/mod_hq.pdl3
-rw-r--r--view/php/default.php2
-rw-r--r--view/theme/redbasic/css/style.css7
-rw-r--r--view/theme/redbasic/js/redbasic.js10
-rw-r--r--view/tpl/app.tpl11
-rw-r--r--view/tpl/app_nav.tpl2
-rw-r--r--view/tpl/apporder.tpl16
-rw-r--r--view/tpl/cloud_directory.tpl2
-rw-r--r--view/tpl/help.tpl1
-rwxr-xr-xview/tpl/navbar_default.tpl18
-rwxr-xr-xview/tpl/navbar_tucson.tpl13
-rw-r--r--view/tpl/notifications_widget.tpl22
36 files changed, 690 insertions, 94 deletions
diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php
index f13fbe362..9271cee85 100644
--- a/Zotlabs/Lib/Apps.php
+++ b/Zotlabs/Lib/Apps.php
@@ -401,11 +401,15 @@ class Apps {
'$undelete' => ((local_channel() && $installed && $mode == 'edit') ? t('Undelete') : ''),
'$deleted' => $papp['deleted'],
'$feature' => (($papp['embed']) ? false : true),
+ '$pin' => (($papp['embed']) ? false : true),
'$featured' => ((strpos($papp['categories'], 'nav_featured_app') === false) ? false : true),
+ '$pinned' => ((strpos($papp['categories'], 'nav_pinned_app') === false) ? false : true),
'$navapps' => (($mode == 'nav') ? true : false),
'$order' => (($mode == 'nav-order') ? true : false),
'$add' => t('Add to app-tray'),
- '$remove' => t('Remove from app-tray')
+ '$remove' => t('Remove from app-tray'),
+ '$add_nav' => t('Pin to navbar'),
+ '$remove_nav' => t('Unpin from navbar')
));
}
@@ -498,25 +502,27 @@ class Apps {
}
}
- static public function app_feature($uid,$app) {
+ static public function app_feature($uid,$app,$term) {
$r = q("select id from app where app_id = '%s' and app_channel = %d limit 1",
dbesc($app['guid']),
intval($uid)
);
- $x = q("select * from term where otype = %d and oid = %d and term = 'nav_featured_app' limit 1",
+ $x = q("select * from term where otype = %d and oid = %d and term = '%s' limit 1",
intval(TERM_OBJ_APP),
- intval($r[0]['id'])
+ intval($r[0]['id']),
+ dbesc($term)
);
if($x) {
- q("delete from term where otype = %d and oid = %d and term = 'nav_featured_app'",
+ q("delete from term where otype = %d and oid = %d and term = '%s'",
intval(TERM_OBJ_APP),
- intval($x[0]['oid'])
+ intval($x[0]['oid']),
+ dbesc($term)
);
}
else {
- store_item_tag($uid,$r[0]['id'],TERM_OBJ_APP,TERM_CATEGORY,'nav_featured_app',escape_tags(z_root() . '/apps/?f=&cat=nav_featured_app'));
+ store_item_tag($uid, $r[0]['id'], TERM_OBJ_APP, TERM_CATEGORY, $term, escape_tags(z_root() . '/apps/?f=&cat=' . $term));
}
}
@@ -531,16 +537,27 @@ class Apps {
}
- static public function app_list($uid, $deleted = false, $cat = '') {
+ static public function app_list($uid, $deleted = false, $cats = []) {
if($deleted)
$sql_extra = "";
else
$sql_extra = " and app_deleted = 0 ";
- if($cat) {
- $r = q("select oid from term where otype = %d and term = '%s'",
- intval(TERM_OBJ_APP),
- dbesc($cat)
+ if($cats) {
+
+ $cat_sql_extra = " and ( ";
+
+ foreach($cats as $cat) {
+ if(strpos($cat_sql_extra, 'term'))
+ $cat_sql_extra .= "or ";
+
+ $cat_sql_extra .= "term = '" . dbesc($cat) . "' ";
+ }
+
+ $cat_sql_extra .= ") ";
+
+ $r = q("select oid from term where otype = %d $cat_sql_extra",
+ intval(TERM_OBJ_APP)
);
if(! $r)
return $r;
@@ -616,7 +633,7 @@ class Apps {
static function moveup($uid,$guid) {
$syslist = array();
- $list = self::app_list($uid, false, 'nav_featured_app');
+ $list = self::app_list($uid, false, ['nav_featured_app', 'nav_pinned_app']);
if($list) {
foreach($list as $li) {
$syslist[] = self::app_encode($li);
@@ -657,7 +674,7 @@ class Apps {
static function movedown($uid,$guid) {
$syslist = array();
- $list = self::app_list($uid, false, 'nav_featured_app');
+ $list = self::app_list($uid, false, ['nav_featured_app', 'nav_pinned_app']);
if($list) {
foreach($list as $li) {
$syslist[] = self::app_encode($li);
diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php
index 5c0667357..64d4628ae 100644
--- a/Zotlabs/Module/Appman.php
+++ b/Zotlabs/Module/Appman.php
@@ -64,7 +64,11 @@ class Appman extends \Zotlabs\Web\Controller {
}
if($_POST['feature']) {
- Zlib\Apps::app_feature(local_channel(),$papp);
+ Zlib\Apps::app_feature(local_channel(), $papp, $_POST['feature']);
+ }
+
+ if($_POST['pin']) {
+ Zlib\Apps::app_feature(local_channel(), $papp, $_POST['pin']);
}
if($_SESSION['return_url'])
diff --git a/Zotlabs/Module/Apporder.php b/Zotlabs/Module/Apporder.php
index 956548d1f..a9f66ba69 100644
--- a/Zotlabs/Module/Apporder.php
+++ b/Zotlabs/Module/Apporder.php
@@ -18,7 +18,7 @@ class Apporder extends \Zotlabs\Web\Controller {
nav_set_selected('Order Apps');
$syslist = array();
- $list = Zlib\Apps::app_list(local_channel(), false, 'nav_featured_app');
+ $list = Zlib\Apps::app_list(local_channel(), false, ['nav_featured_app', 'nav_pinned_app']);
if($list) {
foreach($list as $li) {
$syslist[] = Zlib\Apps::app_encode($li);
@@ -31,14 +31,20 @@ class Apporder extends \Zotlabs\Web\Controller {
$syslist = Zlib\Apps::app_order(local_channel(),$syslist);
foreach($syslist as $app) {
- $nav_apps[] = Zlib\Apps::app_render($app,'nav-order');
+ if(strpos($app['categories'],'nav_pinned_app') !== false) {
+ $navbar_apps[] = Zlib\Apps::app_render($app,'nav-order');
+ }
+ else {
+ $nav_apps[] = Zlib\Apps::app_render($app,'nav-order');
+ }
}
return replace_macros(get_markup_template('apporder.tpl'),
[
- '$header' => t('Change Order of Navigation Apps'),
- '$desc' => t('Use arrows to move the corresponding app up or down in the display list'),
- '$nav_apps' => $nav_apps
+ '$header' => [t('Change Order of Pinned Navbar Apps'), t('Change Order of App Tray Apps')],
+ '$desc' => [t('Use arrows to move the corresponding app left (top) or right (bottom) in the navbar'), t('Use arrows to move the corresponding app up or down in the app tray')],
+ '$nav_apps' => $nav_apps,
+ '$navbar_apps' => $navbar_apps
]
);
}
diff --git a/Zotlabs/Module/Hq.php b/Zotlabs/Module/Hq.php
new file mode 100644
index 000000000..41e9d40ca
--- /dev/null
+++ b/Zotlabs/Module/Hq.php
@@ -0,0 +1,260 @@
+<?php
+namespace Zotlabs\Module;
+
+require_once("include/bbcode.php");
+require_once('include/security.php');
+require_once('include/conversation.php');
+require_once('include/acl_selectors.php');
+require_once('include/items.php');
+
+
+class Hq extends \Zotlabs\Web\Controller {
+
+ function post() {
+
+ if(!local_channel())
+ return;
+
+ if($_REQUEST['notify_id']) {
+ q("update notify set seen = 1 where id = %d and uid = %d",
+ intval($_REQUEST['notify_id']),
+ intval(local_channel())
+ );
+ }
+
+ }
+
+ function get($update = 0, $load = false) {
+
+ if(!local_channel())
+ return;
+
+ if($load)
+ $_SESSION['loadtime'] = datetime_convert();
+
+ if(argc() > 1 && argv(1) !== 'load') {
+ $item_hash = argv(1);
+ }
+
+ if($_REQUEST['mid'])
+ $item_hash = $_REQUEST['mid'];
+
+ $item_normal = item_normal();
+ $item_normal_update = item_normal_update();
+
+ if(! $item_hash) {
+
+ $r = q("SELECT mid FROM item
+ WHERE uid = %d
+ AND mid = parent_mid
+ $item_normal
+ ORDER BY id DESC
+ limit 1",
+ local_channel()
+ );
+ $item_hash = 'b64.' . base64url_encode($r[0]['mid']);
+
+ if(!$item_hash) {
+ \App::$error = 404;
+ notice( t('Item not found.') . EOL);
+ return;
+ }
+ }
+
+ $updateable = false;
+
+ if(! $update) {
+
+ $channel = \App::get_channel();
+
+ $channel_acl = [
+ 'allow_cid' => $channel['channel_allow_cid'],
+ 'allow_gid' => $channel['channel_allow_gid'],
+ 'deny_cid' => $channel['channel_deny_cid'],
+ 'deny_gid' => $channel['channel_deny_gid']
+ ];
+
+ $x = [
+ 'is_owner' => true,
+ 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
+ 'default_location' => $channel['channel_location'],
+ 'nickname' => $channel['channel_address'],
+ 'lockstate' => (($group || $cid || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
+
+ 'acl' => populate_acl($channel_acl),
+ 'permissions' => $channel_acl,
+ 'bang' => '',
+ 'visitor' => true,
+ 'profile_uid' => local_channel(),
+ 'return_path' => 'channel/' . $channel['channel_address'],
+ 'expanded' => true,
+ 'editor_autocomplete' => true,
+ 'bbco_autocomplete' => 'bbcode',
+ 'bbcode' => true,
+ 'jotnets' => true
+ ];
+
+ $o = '<div id="jot-popup">';
+ $o .= status_editor($a,$x);
+ $o .= '</div>';
+ }
+
+ $target_item = null;
+
+ if(strpos($item_hash,'b64.') === 0)
+ $decoded = @base64url_decode(substr($item_hash,4));
+ if($decoded)
+ $item_hash = $decoded;
+
+ $r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1",
+ dbesc($item_hash . '%')
+ );
+
+ if($r) {
+ $target_item = $r[0];
+ }
+
+ //if the item is to be moderated redirect to /moderate
+ if($target_item['item_blocked'] == ITEM_MODERATED) {
+ goaway(z_root() . '/moderate/' . $target_item['id']);
+ }
+
+ $static = ((array_key_exists('static',$_REQUEST)) ? intval($_REQUEST['static']) : 0);
+
+ $simple_update = (($update) ? " AND item_unseen = 1 " : '');
+
+ if($update && $_SESSION['loadtime'])
+ $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
+ if($load)
+ $simple_update = '';
+
+ if($static && $simple_update)
+ $simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
+
+ if(! $update && ! $load) {
+
+ $static = ((local_channel()) ? channel_manual_conv_update(local_channel()) : 1);
+
+ // if the target item is not a post (eg a like) we want to address its thread parent
+
+ $mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
+
+ // if we got a decoded hash we must encode it again before handing to javascript
+ if($decoded)
+ $mid = 'b64.' . base64url_encode($mid);
+
+ $o .= '<div id="live-display"></div>' . "\r\n";
+ $o .= "<script> var profile_uid = " . local_channel()
+ . "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
+
+ \App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),[
+ '$baseurl' => z_root(),
+ '$pgtype' => 'display',
+ '$uid' => '0',
+ '$gid' => '0',
+ '$cid' => '0',
+ '$cmin' => '0',
+ '$cmax' => '99',
+ '$star' => '0',
+ '$liked' => '0',
+ '$conv' => '0',
+ '$spam' => '0',
+ '$fh' => '0',
+ '$nouveau' => '0',
+ '$wall' => '0',
+ '$static' => $static,
+ '$page' => 1,
+ '$list' => ((x($_REQUEST,'list')) ? intval($_REQUEST['list']) : 0),
+ '$search' => '',
+ '$xchan' => '',
+ '$order' => '',
+ '$file' => '',
+ '$cats' => '',
+ '$tags' => '',
+ '$dend' => '',
+ '$dbegin' => '',
+ '$verb' => '',
+ '$net' => '',
+ '$mid' => $mid
+ ]);
+
+ }
+
+ if($load) {
+ $r = null;
+
+ $r = q("SELECT item.id as item_id from item
+ WHERE uid = %d
+ and mid = '%s'
+ $item_normal
+ limit 1",
+ intval(local_channel()),
+ dbesc($target_item['parent_mid'])
+ );
+ if($r) {
+ $updateable = true;
+ }
+
+ }
+
+ elseif($update) {
+ $r = null;
+
+ $r = q("SELECT item.parent AS item_id from item
+ WHERE uid = %d
+ and parent_mid = '%s'
+ $item_normal_update
+ $simple_update
+ limit 1",
+ intval(local_channel()),
+ dbesc($target_item['parent_mid'])
+ );
+ if($r) {
+ $updateable = true;
+ }
+
+ $_SESSION['loadtime'] = datetime_convert();
+ }
+
+ else {
+ $r = [];
+ }
+
+ if($r) {
+ $parents_str = ids_to_querystr($r,'item_id');
+ if($parents_str) {
+ $items = q("SELECT item.*, item.id AS item_id
+ FROM item
+ WHERE parent in ( %s ) $item_normal ",
+ dbesc($parents_str)
+ );
+
+ xchan_query($items);
+ $items = fetch_post_tags($items,true);
+ $items = conv_sort($items,'created');
+ }
+ }
+ else {
+ $items = [];
+ }
+
+ $o .= conversation($items, 'display', $update, 'client');
+
+ if($updateable) {
+ $x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ",
+ intval(local_channel()),
+ intval($r[0]['item_id'])
+ );
+ }
+
+ $o .= '<div id="content-complete"></div>';
+
+ if(($update && $load) && (! $items)) {
+ notice( t('Something went wrong.') . EOL );
+ }
+
+ return $o;
+
+ }
+
+}
diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php
index b104a5f5f..0abf111e0 100644
--- a/Zotlabs/Module/Like.php
+++ b/Zotlabs/Module/Like.php
@@ -12,7 +12,10 @@ class Like extends \Zotlabs\Web\Controller {
function get() {
$o = '';
-
+
+ $sys_channel = get_sys_channel();
+ $sys_channel_id = (($sys_channel) ? $sys_channel['channel_id'] : 0);
+
$observer = \App::get_observer();
$interactive = $_REQUEST['interactive'];
if($interactive) {
@@ -253,20 +256,22 @@ class Like extends \Zotlabs\Web\Controller {
logger('like: verb ' . $verb . ' item ' . $item_id, LOGGER_DEBUG);
// get the item. Allow linked photos (which are normally hidden) to be liked
-
+
$r = q("SELECT * FROM item WHERE id = %d
and (item_type = 0 or item_type = 6) and item_deleted = 0 and item_unpublished = 0
and item_delayed = 0 and item_pending_remove = 0 and item_blocked = 0 LIMIT 1",
intval($item_id)
);
-
+
if(! $item_id || (! $r)) {
logger('like: no item ' . $item_id);
killme();
}
+ // Use the $effective_uid option of xchan_query to sort out comment permission
+ // for public stream items
- xchan_query($r,true,(($r[0]['uid'] == local_channel()) ? 0 : local_channel()));
+ xchan_query($r,true,(($r[0]['uid'] == $sys_channel_id) ? local_channel() : 0));
$item = $r[0];
@@ -464,6 +469,8 @@ class Like extends \Zotlabs\Web\Controller {
$arr['mid'] = $mid;
$arr['aid'] = (($extended_like) ? $ch[0]['channel_account_id'] : $owner_aid);
$arr['uid'] = $owner_uid;
+
+
$arr['item_flags'] = $item_flags;
$arr['item_wall'] = $item_wall;
$arr['parent_mid'] = (($extended_like) ? $mid : $item['mid']);
diff --git a/Zotlabs/Module/Notify.php b/Zotlabs/Module/Notify.php
index 3d6e1c2e7..cffcc8099 100644
--- a/Zotlabs/Module/Notify.php
+++ b/Zotlabs/Module/Notify.php
@@ -34,7 +34,7 @@ class Notify extends \Zotlabs\Web\Controller {
}
- function get() {
+ function get() {
if(! local_channel())
return login();
diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php
index 3c6dda1e9..8644b8326 100644
--- a/Zotlabs/Module/Ping.php
+++ b/Zotlabs/Module/Ping.php
@@ -262,6 +262,16 @@ class Ping extends \Zotlabs\Web\Controller {
if($t) {
foreach($t as $tt) {
+ $message = trim(strip_tags(bbcode($tt['msg'])));
+
+ if(strpos($message, $tt['xname']) === 0)
+ $message = substr($message, strlen($tt['xname']) + 1);
+
+
+ $mid = basename($tt['link']);
+
+ $b64mid = ((strpos($mid, 'b64.' === 0)) ? $mid : 'b64.' . base64url_encode($mid));
+
$notifs[] = array(
'notify_link' => z_root() . '/notify/view/' . $tt['id'],
'name' => $tt['xname'],
@@ -269,7 +279,9 @@ class Ping extends \Zotlabs\Web\Controller {
'photo' => $tt['photo'],
'when' => relative_date($tt['created']),
'hclass' => (($tt['seen']) ? 'notify-seen' : 'notify-unseen'),
- 'message' => strip_tags(bbcode($tt['msg']))
+ 'b64mid' => $b64mid,
+ 'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : ''),
+ 'message' => $message
);
}
}
diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php
index 4224fa3c8..0e6c2360f 100644
--- a/Zotlabs/Module/Pubstream.php
+++ b/Zotlabs/Module/Pubstream.php
@@ -240,7 +240,10 @@ class Pubstream extends \Zotlabs\Web\Controller {
dbesc($parents_str)
);
- xchan_query($items,true,(-1));
+ // use effective_uid param of xchan_query to help sort out comment permission
+ // for sys_channel owned items.
+
+ xchan_query($items,true,(($sys) ? local_channel() : 0));
$items = fetch_post_tags($items,true);
$items = conv_sort($items,$ordering);
}
diff --git a/Zotlabs/Storage/Browser.php b/Zotlabs/Storage/Browser.php
index b5440aacf..17b07ad82 100644
--- a/Zotlabs/Storage/Browser.php
+++ b/Zotlabs/Storage/Browser.php
@@ -197,7 +197,16 @@ class Browser extends DAV\Browser\Plugin {
}
}
+
+ // generate preview icons for tile view.
+ // Currently we only handle images, but this could potentially be extended with plugins
+ // to provide document and video thumbnails. SVG, PDF and office documents have some
+ // security concerns and should only be allowed on single-user sites with tightly controlled
+ // upload access. system.thumbnail_security should be set to 1 if you want to include these
+ // types
+
$photo_icon = '';
+ $preview_style = intval(get_config('system','thumbnail_security',0));
if(strpos($type,'image/') === 0 && $attachHash) {
$r = q("select resource_id, imgscale from photo where resource_id = '%s' and imgscale in ( %d, %d ) order by imgscale asc limit 1",
@@ -206,10 +215,19 @@ class Browser extends DAV\Browser\Plugin {
intval(PHOTO_RES_PROFILE_80)
);
if($r) {
- $photo_icon = $r[0]['resource_id'] . '-' . $r[0]['imgscale'];
+ $photo_icon = 'photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale'];
+ }
+ if($type === 'image/svg+xml' && $preview_style > 0) {
+ $photo_icon = $fullPath;
}
+
}
+ $g = [ 'resource_id' => $attachHash, 'thumbnail' => $photo_icon, 'security' => $preview_style ];
+ call_hooks('file_thumbnail', $g);
+ $photo_icon = $g['photo_icon'];
+
+
$attachIcon = ""; // "<a href=\"attach/".$attachHash."\" title=\"".$displayName."\"><i class=\"fa fa-arrow-circle-o-down\"></i></a>";
// put the array for this file together
diff --git a/Zotlabs/Widget/Appcategories.php b/Zotlabs/Widget/Appcategories.php
index 490ec1abc..8ff14230f 100644
--- a/Zotlabs/Widget/Appcategories.php
+++ b/Zotlabs/Widget/Appcategories.php
@@ -26,6 +26,7 @@ class Appcategories {
and term.uid = app_channel
and term.otype = %d
and term.term != 'nav_featured_app'
+ and term.term != 'nav_pinned_app'
order by term.term asc",
intval(local_channel()),
intval(TERM_OBJ_APP)
diff --git a/Zotlabs/Widget/Forums.php b/Zotlabs/Widget/Forums.php
index 002c0ee21..91b987746 100644
--- a/Zotlabs/Widget/Forums.php
+++ b/Zotlabs/Widget/Forums.php
@@ -29,18 +29,32 @@ class Forums {
);
if($x1) {
$xc = ids_to_querystr($x1,'xchan',true);
+
$x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
intval(local_channel())
);
- if($x2)
+
+ if($x2) {
$xf = ids_to_querystr($x2,'xchan',true);
+
+ // private forums
+ $x3 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'post_wall' and v = '1' and xchan in (" . $xc . ") and not xchan in (" . $xf . ") ",
+ intval(local_channel())
+ );
+ if($x3) {
+ $xf = ids_to_querystr(array_merge($x2,$x3),'xchan',true);
+ }
+ }
}
$sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
- $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d $sql_extra order by xchan_name $limit ",
+
+
+ $r1 = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 $sql_extra order by xchan_name $limit ",
intval(local_channel())
);
+
if(! $r1)
return $o;
@@ -85,9 +99,21 @@ class Forums {
$o .= '<h3>' . t('Forums') . '</h3><ul class="nav nav-pills flex-column">';
foreach($r1 as $rr) {
+
+ $link = 'network?f=&pf=1&cid=' . $rr['abook_id'];
+ if($x3) {
+ foreach($x3 as $xx) {
+ if($rr['xchan_hash'] == $xx['xchan']) {
+ $link = zid($rr['xchan_url']);
+ }
+ }
+ }
+
if($unseen && (! intval($rr['unseen'])))
continue;
- $o .= '<li class="nav-item"><a class="nav-link" href="network?f=&pf=1&cid=' . $rr['abook_id'] . '" ><span class="badge badge-secondary float-right">' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . '</span><img class ="menu-img-1" src="' . $rr['xchan_photo_s'] . '" /> ' . $rr['xchan_name'] . '</a></li>';
+
+
+ $o .= '<li class="nav-item"><a class="nav-link" href="' . $link . '" ><span class="badge badge-secondary float-right">' . ((intval($rr['unseen'])) ? intval($rr['unseen']) : '') . '</span><img class ="menu-img-1" src="' . $rr['xchan_photo_s'] . '" /> ' . $rr['xchan_name'] . '</a></li>';
}
$o .= '</ul></div>';
}
diff --git a/boot.php b/boot.php
index 0ac1d08df..3bf995369 100755
--- a/boot.php
+++ b/boot.php
@@ -50,10 +50,10 @@ require_once('include/hubloc.php');
require_once('include/attach.php');
define ( 'PLATFORM_NAME', 'hubzilla' );
-define ( 'STD_VERSION', '2.9' );
+define ( 'STD_VERSION', '2.9.1' );
define ( 'ZOT_REVISION', '1.3' );
-define ( 'DB_UPDATE_VERSION', 1197 );
+define ( 'DB_UPDATE_VERSION', 1198 );
define ( 'PROJECT_BASE', __DIR__ );
diff --git a/doc/hooklist.bb b/doc/hooklist.bb
index 1192a1506..5b34ef0ca 100644
--- a/doc/hooklist.bb
+++ b/doc/hooklist.bb
@@ -229,6 +229,9 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/feature_settings_post]feature_settings_post[/zrl]
called from settings page when posting from 'addon/feature settings'
+[zrl=[baseurl]/help/hook/file_thumbnail]file_thumbnail[/zrl]
+ called when generating thumbnail images for cloud page in 'view tiles' mode
+
[zrl=[baseurl]/help/hook/follow]follow[/zrl]
called when a follow operation takes place
diff --git a/include/attach.php b/include/attach.php
index 96b9c0b44..0f07fe035 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -31,7 +31,6 @@ function z_mime_content_type($filename) {
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
- 'php' => 'text/html',
'css' => 'text/css',
'md' => 'text/markdown',
'bb' => 'text/bbcode',
@@ -41,8 +40,17 @@ function z_mime_content_type($filename) {
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
'epub' => 'application/epub+zip',
+ 'c' => 'text/plain',
+ 'h' => 'text/plain',
+ 'sh' => 'text/plain',
+ 'py' => 'text/plain',
+ 'php' => 'text/plain',
+ 'rb' => 'text/plain',
+ 'pdl' => 'text/plain',
+
// images
+
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
@@ -73,9 +81,7 @@ function z_mime_content_type($filename) {
'flac' => 'audio/flac',
'opus' => 'audio/ogg',
'webm' => 'video/webm',
-// 'webm' => 'audio/webm',
'mp4' => 'video/mp4',
-// 'mp4' => 'audio/mp4',
'mkv' => 'video/x-matroska',
// adobe
diff --git a/include/channel.php b/include/channel.php
index b12491936..708e74176 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -101,14 +101,14 @@ function create_sys_channel() {
set_config('system', 'prvkey', $hostkey['prvkey']);
}
- create_identity(array(
- 'account_id' => 'xxx', // This will create an identity with an (integer) account_id of 0, but account_id is required
- 'nickname' => 'sys',
- 'name' => 'System',
- 'pageflags' => 0,
- 'publish' => 0,
- 'system' => 1
- ));
+ create_identity([
+ 'account_id' => 'xxx', // Typecast trickery: account_id is required. This will create an identity with an (integer) account_id of 0
+ 'nickname' => 'sys',
+ 'name' => 'System',
+ 'pageflags' => 0,
+ 'publish' => 0,
+ 'system' => 1
+ ]);
}
diff --git a/include/nav.php b/include/nav.php
index 9df50c9fe..2dcf68bc8 100644
--- a/include/nav.php
+++ b/include/nav.php
@@ -253,7 +253,7 @@ EOT;
}
$syslist = array();
- $list = Zlib\Apps::app_list(local_channel(), false, 'nav_featured_app');
+ $list = Zlib\Apps::app_list(local_channel(), false, ['nav_featured_app', 'nav_pinned_app']);
if($list) {
foreach($list as $li) {
$syslist[] = Zlib\Apps::app_encode($li);
@@ -274,16 +274,20 @@ EOT;
$app['active'] = true;
if($is_owner) {
- $nav_apps[] = Zlib\Apps::app_render($app,'nav');
- if(strpos($app['categories'],'navbar_' . $template)) {
+ if(strpos($app['categories'],'nav_pinned_app') !== false) {
$navbar_apps[] = Zlib\Apps::app_render($app,'navbar');
}
+ else {
+ $nav_apps[] = Zlib\Apps::app_render($app,'nav');
+ }
}
elseif(! $is_owner && strpos($app['requires'], 'local_channel') === false) {
- $nav_apps[] = Zlib\Apps::app_render($app,'nav');
- if(strpos($app['categories'],'navbar_' . $template)) {
+ if(strpos($app['categories'],'nav_pinned_app') !== false) {
$navbar_apps[] = Zlib\Apps::app_render($app,'navbar');
}
+ else {
+ $nav_apps[] = Zlib\Apps::app_render($app,'nav');
+ }
}
}
diff --git a/include/socgraph.php b/include/socgraph.php
index a5b5d1378..3c7a893c6 100644
--- a/include/socgraph.php
+++ b/include/socgraph.php
@@ -385,7 +385,7 @@ function poco($a,$extended = false) {
$sql_extra = " and abook_self = 0 ";
if($cid)
- $sql_extra = sprintf(" and abook_id = %d and abook_hidden = 0 ",intval($cid));
+ $sql_extra = sprintf(" and abook_id = %d and abook_hidden = 0 and abook_pending = 0 ",intval($cid));
if($system_mode) {
$r = q("SELECT count(*) as total from abook where abook_self = 1
diff --git a/include/text.php b/include/text.php
index c74e515d2..ee8318d7c 100644
--- a/include/text.php
+++ b/include/text.php
@@ -2710,6 +2710,9 @@ function getIconFromType($type) {
'application/octet-stream' => 'fa-file-o',
//Text
'text/plain' => 'fa-file-text-o',
+ 'text/markdown' => 'fa-file-text-o',
+ 'text/bbcode' => 'fa-file-text-o',
+ 'text/html' => 'fa-file-text-o',
'application/msword' => 'fa-file-word-o',
'application/pdf' => 'fa-file-pdf-o',
'application/vnd.oasis.opendocument.text' => 'fa-file-word-o',
@@ -2739,11 +2742,33 @@ function getIconFromType($type) {
'video/x-matroska' => 'fa-file-video-o'
);
- $iconFromType = 'fa-file-o';
+ $catMap = [
+ 'application' => 'fa-file-code-o',
+ 'multipart' => 'fa-folder',
+ 'audio' => 'fa-file-audio-o',
+ 'video' => 'fa-file-video-o',
+ 'text' => 'fa-file-text-o',
+ 'image' => 'fa=file-picture-o',
+ 'message' => 'fa-file-text-o'
+ ];
+
+
+ $iconFromType = '';
if (array_key_exists($type, $iconMap)) {
$iconFromType = $iconMap[$type];
}
+ else {
+ $parts = explode('/',$type);
+ if($parts[0] && $catMap[$parts[0]]) {
+ $iconFromType = $catMap[$parts[0]];
+ }
+ }
+
+ if(! $iconFromType) {
+ $iconFromType = 'fa-file-o';
+ }
+
return $iconFromType;
}
diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql
index afa3c095d..673e4cd75 100644
--- a/install/schema_mysql.sql
+++ b/install/schema_mysql.sql
@@ -609,7 +609,6 @@ CREATE TABLE IF NOT EXISTS `item` (
`resource_type` char(16) NOT NULL DEFAULT '',
`attach` mediumtext NOT NULL,
`sig` text NOT NULL,
- `diaspora_meta` mediumtext NOT NULL,
`location` char(191) NOT NULL DEFAULT '',
`coord` char(191) NOT NULL DEFAULT '',
`public_policy` char(191) NOT NULL DEFAULT '',
diff --git a/install/update.php b/install/update.php
index 7d59555d3..f7b9b03ed 100644
--- a/install/update.php
+++ b/install/update.php
@@ -1,6 +1,6 @@
<?php
-define( 'UPDATE_VERSION' , 1197 );
+define( 'UPDATE_VERSION' , 1198 );
/**
*
@@ -3059,4 +3059,14 @@ function update_r1196() {
}
return UPDATE_FAILED;
-} \ No newline at end of file
+}
+
+function update_r1197() {
+
+ $r = q("select diaspora_meta from item where true limit 1");
+ if($r) {
+ $r = q("ALTER TABLE item DROP diaspora_meta");
+ }
+
+ return UPDATE_SUCCESS;
+}
diff --git a/view/css/bootstrap-red.css b/view/css/bootstrap-red.css
index 18efd69e4..a0b7c5bba 100644
--- a/view/css/bootstrap-red.css
+++ b/view/css/bootstrap-red.css
@@ -11,7 +11,7 @@ nav .dropdown-menu {
min-width: 16rem;
}
-@media screen and (min-width: 767px) {
+@media screen and (min-width: 992px) {
nav .badge {
top: 0px;
left: 0px;
@@ -19,7 +19,7 @@ nav .dropdown-menu {
}
}
-@media screen and (max-width: 767px) {
+@media screen and (max-width: 992px) {
.navbar {
padding: .5rem 7px;
}
diff --git a/view/css/mod_hq.css b/view/css/mod_hq.css
new file mode 100644
index 000000000..dde242d4e
--- /dev/null
+++ b/view/css/mod_hq.css
@@ -0,0 +1,3 @@
+#jot-popup {
+ display: none;
+}
diff --git a/view/js/main.js b/view/js/main.js
index e231dac60..ddd876689 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -451,20 +451,20 @@ function NavUpdate() {
updateCountsOnly = false;
if(data.network || data.home || data.intros || data.register || data.mail || data.all_events || data.notify || data.files || data.pubs) {
- $('#notifications-btn').css('opacity', 1);
+ $('.notifications-btn').css('opacity', 1);
}
else {
- $('#notifications-btn').css('opacity', 0.5);
+ $('.notifications-btn').css('opacity', 0.5);
$('#navbar-collapse-1').removeClass('show');
}
if(data.home || data.intros || data.register || data.mail || data.notify || data.files) {
- $('#notifications-btn-icon').removeClass('fa-exclamation-circle');
- $('#notifications-btn-icon').addClass('fa-exclamation-triangle');
+ $('.notifications-btn-icon').removeClass('fa-exclamation-circle');
+ $('.notifications-btn-icon').addClass('fa-exclamation-triangle');
}
if(!data.home && !data.intros && !data.register && !data.mail && !data.notify && !data.files) {
- $('#notifications-btn-icon').removeClass('fa-exclamation-triangle');
- $('#notifications-btn-icon').addClass('fa-exclamation-circle');
+ $('.notifications-btn-icon').removeClass('fa-exclamation-triangle');
+ $('.notifications-btn-icon').addClass('fa-exclamation-circle');
}
$.each(data, function(index, item) {
@@ -959,9 +959,9 @@ function notify_popup_loader(notifyType) {
$("." + notifyType + "-update").html(data.notify.length);
$(data.notify).each(function() {
- html = navbar_notifications_tpl.format(this.notify_link,this.photo,this.name,this.message,this.when,this.hclass,this.b64mid);
+ html = navbar_notifications_tpl.format(this.notify_link,this.photo,this.name,this.message,this.when,this.hclass,this.b64mid,this.notify_id);
$("#navbar-" + notifyType + "-menu").append(html);
- html = notifications_tpl.format(this.notify_link,this.photo,this.name,this.message,this.when,this.hclass,this.b64mid);
+ html = notifications_tpl.format(this.notify_link,this.photo,this.name,this.message,this.when,this.hclass,this.b64mid,this.notify_id);
$("#nav-" + notifyType + "-menu").append(html);
});
diff --git a/view/js/mod_hq.js b/view/js/mod_hq.js
new file mode 100644
index 000000000..cf7ec941c
--- /dev/null
+++ b/view/js/mod_hq.js
@@ -0,0 +1,145 @@
+function hqLiveUpdate(notify_id, b64mid) {
+
+ if(typeof profile_uid === 'undefined') profile_uid = false; /* Should probably be unified with channelId defined in head.tpl */
+ if((src === null) || (stopped) || (! profile_uid)) { $('.like-rotator').hide(); return; }
+ if(($('.comment-edit-text.expanded').length) || (in_progress)) {
+ if(livetime) {
+ clearTimeout(livetime);
+ }
+ livetime = setTimeout(liveUpdate, 10000);
+ return;
+ }
+ if(livetime !== null)
+ livetime = null;
+
+ prev = 'live-' + src;
+
+ in_progress = true;
+
+ var update_url;
+ var update_mode;
+
+ if(scroll_next) {
+ bParam_page = next_page;
+ page_load = true;
+ }
+ else {
+ bParam_page = 1;
+ }
+
+ update_url = buildCmd();
+
+ if(page_load) {
+ $("#page-spinner").show();
+ if(bParam_page == 1)
+ update_mode = 'replace';
+ else
+ update_mode = 'append';
+ }
+ else {
+ update_mode = 'update';
+ var orgHeight = $("#region_2").height();
+ }
+
+ var dstart = new Date();
+ console.log('LOADING data...');
+ $.get(update_url, function(data) {
+
+ // on shared hosts occasionally the live update process will be killed
+ // leaving an incomplete HTML structure, which leads to conversations getting
+ // truncated and the page messed up if all the divs aren't closed. We will try
+ // again and give up if we can't get a valid HTML response after 10 tries.
+
+ if((data.indexOf("<html>") != (-1)) && (data.indexOf("</html>") == (-1))) {
+ console.log('Incomplete data. Reloading');
+ in_progress = false;
+ liveRecurse ++;
+ if(liveRecurse < 10) {
+ liveUpdate();
+ }
+ else {
+ console.log('Incomplete data. Too many attempts. Giving up.');
+ }
+ }
+
+ // else data was valid - reset the recursion counter
+ liveRecurse = 0;
+
+ if(notify_id !== 'undefined') {
+ $.post(
+ "hq",
+ {
+ "notify_id" : notify_id
+ },
+ function(data) {
+ if(timer) clearTimeout(timer);
+ timer = setTimeout(NavUpdate,10);
+ }
+ );
+ }
+
+ var dready = new Date();
+ console.log('DATA ready in: ' + (dready - dstart)/1000 + ' seconds.');
+
+ if(update_mode === 'update' || preloadImages) {
+ console.log('LOADING images...');
+
+ $('.wall-item-body, .wall-photo-item',data).imagesLoaded( function() {
+ var iready = new Date();
+ console.log('IMAGES ready in: ' + (iready - dready)/1000 + ' seconds.');
+
+ page_load = false;
+ scroll_next = false;
+ updateConvItems(update_mode,data);
+ $("#page-spinner").hide();
+ $("#profile-jot-text-loading").hide();
+
+ // adjust scroll position if new content was added above viewport
+ if(update_mode === 'update') {
+ $(window).scrollTop($(window).scrollTop() + $("#region_2").height() - orgHeight + contentHeightDiff);
+ }
+
+ in_progress = false;
+
+ // FIXME - the following lines were added so that almost
+ // immediately after we update the posts on the page, we
+ // re-check and update the notification counts.
+ // As it turns out this causes a bit of an inefficiency
+ // as we're pinging twice for every update, once before
+ // and once after. A btter way to do this is to rewrite
+ // NavUpdate and perhaps LiveUpdate so that we check for
+ // post updates first and only call the notification ping
+ // once.
+
+ updateCountsOnly = true;
+ if(timer) clearTimeout(timer);
+ timer = setTimeout(NavUpdate,10);
+
+ });
+ }
+ else {
+ page_load = false;
+ scroll_next = false;
+ updateConvItems(update_mode,data);
+ $("#page-spinner").hide();
+ $("#profile-jot-text-loading").hide();
+
+ in_progress = false;
+
+ // FIXME - the following lines were added so that almost
+ // immediately after we update the posts on the page, we
+ // re-check and update the notification counts.
+ // As it turns out this causes a bit of an inefficiency
+ // as we're pinging twice for every update, once before
+ // and once after. A btter way to do this is to rewrite
+ // NavUpdate and perhaps LiveUpdate so that we check for
+ // post updates first and only call the notification ping
+ // once.
+
+ updateCountsOnly = true;
+ if(timer) clearTimeout(timer);
+ timer = setTimeout(NavUpdate,10);
+
+ }
+ });
+}
diff --git a/view/pdl/mod_hq.pdl b/view/pdl/mod_hq.pdl
new file mode 100644
index 000000000..e657fa88b
--- /dev/null
+++ b/view/pdl/mod_hq.pdl
@@ -0,0 +1,3 @@
+[region=right_aside]
+[widget=notifications][/widget]
+[/region]
diff --git a/view/php/default.php b/view/php/default.php
index b180a6eb8..06cecc56f 100644
--- a/view/php/default.php
+++ b/view/php/default.php
@@ -8,7 +8,7 @@
<body <?php if($page['direction']) echo 'dir="rtl"' ?> >
<?php if(x($page,'banner')) echo $page['banner']; ?>
<header><?php if(x($page,'header')) echo $page['header']; ?></header>
- <nav class="navbar fixed-top navbar-expand-xl navbar-dark bg-dark"><?php if(x($page,'nav')) echo $page['nav']; ?></nav>
+ <nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark"><?php if(x($page,'nav')) echo $page['nav']; ?></nav>
<main>
<aside id="region_1"><div id="left_aside_spacer"><div id="left_aside_wrapper"><?php if(x($page,'aside')) echo $page['aside']; ?></div></div></aside>
<section id="region_2"><?php if(x($page,'content')) echo $page['content']; ?>
diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css
index 6df5a060b..5f31004ff 100644
--- a/view/theme/redbasic/css/style.css
+++ b/view/theme/redbasic/css/style.css
@@ -1484,7 +1484,7 @@ blockquote {
color: $nav_active_icon_colour;
}
-@media screen and (max-width: 767px) {
+@media screen and (max-width: 992px) {
aside#region_1 {
border-right: 1px solid $nav_bd;
@@ -1504,6 +1504,11 @@ blockquote {
flex-basis: 25%;
}
+ #navbar-collapse-2 .navbar-app i {
+ font-size: 1rem;
+ margin-right: 0.5rem;
+ }
+
}
.shareable_element_text {
diff --git a/view/theme/redbasic/js/redbasic.js b/view/theme/redbasic/js/redbasic.js
index ed9ef02aa..41f5eb7ce 100644
--- a/view/theme/redbasic/js/redbasic.js
+++ b/view/theme/redbasic/js/redbasic.js
@@ -8,7 +8,7 @@ $(document).ready(function() {
$('body').append('<div id="css3-calc" style="width: 10px; width: calc(10px + 10px); display: none;"></div>');
if( $('#css3-calc').width() == 10) {
$(window).resize(function() {
- if($(window).width() < 767) {
+ if($(window).width() < 992) {
$('main').css('width', $(window).width() + $('aside').outerWidth() );
} else {
$('main').css('width', '100%' );
@@ -17,7 +17,7 @@ $(document).ready(function() {
}
$('#css3-calc').remove(); // Remove the test element
- if($(window).width() >= 767) {
+ if($(window).width() >= 992) {
$('#left_aside_wrapper').stick_in_parent({
offset_top: parseInt($('aside').css('padding-top')),
parent: 'main',
@@ -25,7 +25,7 @@ $(document).ready(function() {
});
}
- if($(window).width() >= 1200) {
+ if($(window).width() >= 992) {
$('#right_aside_wrapper').stick_in_parent({
offset_top: parseInt($('aside').css('padding-top')),
parent: 'main',
@@ -77,7 +77,9 @@ $(document).ready(function() {
}
});
- $('#notifications-btn').click(function() {
+ $('.notifications-btn').click(function(e) {
+ e.preventDefault();
+ e.stopPropagation();
if($('#navbar-collapse-2').hasClass('show')){
$('#navbar-collapse-2').removeClass('show');
}
diff --git a/view/tpl/app.tpl b/view/tpl/app.tpl
index ac5c18deb..7d2e46c59 100644
--- a/view/tpl/app.tpl
+++ b/view/tpl/app.tpl
@@ -12,13 +12,14 @@
</div>
{{/if}}
{{if $install || $update || $delete || $feature}}
- <div class="app-tools">
+ <div class="text-center app-tools">
<form action="{{$hosturl}}appman" method="post">
<input type="hidden" name="papp" value="{{$app.papp}}" />
- {{if $install}}<button type="submit" name="install" value="{{$install}}" class="btn btn-outline-secondary btn-sm" title="{{$install}}" ><i class="fa fa-arrow-circle-o-down" ></i></button>{{/if}}
- {{if $edit}}<input type="hidden" name="appid" value="{{$app.guid}}" /><button type="submit" name="edit" value="{{$edit}}" class="btn btn-outline-secondary btn-sm" title="{{$edit}}" ><i class="fa fa-pencil" ></i></button>{{/if}}
- {{if $delete}}<button type="submit" name="delete" value="{{if $deleted}}{{$undelete}}{{else}}{{$delete}}{{/if}}" class="btn btn-outline-secondary btn-sm" title="{{if $deleted}}{{$undelete}}{{else}}{{$delete}}{{/if}}" ><i class="fa fa-trash-o drop-icons"></i></button>{{/if}}
- {{if $feature}}<button type="submit" name="feature" value="feature" class="btn btn-outline-secondary btn-sm" title="{{if $featured}}{{$remove}}{{else}}{{$add}}{{/if}}"><i class="fa fa-star"{{if $featured}} style="color: gold"{{/if}}></i></button>{{/if}}
+ {{if $install}}<button type="submit" name="install" value="{{$install}}" class="btn btn-outline-secondary btn-sm" title="{{$install}}" ><i class="fa fa-fw fa-arrow-circle-o-down" ></i></button>{{/if}}
+ {{if $edit}}<input type="hidden" name="appid" value="{{$app.guid}}" /><button type="submit" name="edit" value="{{$edit}}" class="btn btn-outline-secondary btn-sm" title="{{$edit}}" ><i class="fa fa-fw fa-pencil" ></i></button>{{/if}}
+ {{if $delete}}<button type="submit" name="delete" value="{{if $deleted}}{{$undelete}}{{else}}{{$delete}}{{/if}}" class="btn btn-outline-secondary btn-sm" title="{{if $deleted}}{{$undelete}}{{else}}{{$delete}}{{/if}}" ><i class="fa fa-fw fa-trash-o drop-icons"></i></button>{{/if}}
+ {{if $feature}}<button type="submit" name="feature" value="nav_featured_app" class="btn btn-outline-secondary btn-sm" title="{{if $featured}}{{$remove}}{{else}}{{$add}}{{/if}}"><i class="fa fa-fw fa-star{{if $featured}} text-warning{{/if}}"></i></button>{{/if}}
+ {{if $pin}}<button type="submit" name="pin" value="nav_pinned_app" class="btn btn-outline-secondary btn-sm" title="{{if $pinned}}{{$remove_nav}}{{else}}{{$add_nav}}{{/if}}"><i class="fa fa-fw fa-thumb-tack{{if $pinned}} text-success{{/if}}"></i></button>{{/if}}
</form>
</div>
{{/if}}
diff --git a/view/tpl/app_nav.tpl b/view/tpl/app_nav.tpl
index 046cd7237..817c74763 100644
--- a/view/tpl/app_nav.tpl
+++ b/view/tpl/app_nav.tpl
@@ -1 +1 @@
-<a class="navbar-app nav-link{{if $app.active}} active{{/if}}" href="{{$app.url}}" title="{{$app.name}}" >{{if $icon}}<i class="fa fa-fw fa-{{$icon}}"></i>{{else}}<img src="{{$app.photo}}" width="16" height="16" />{{/if}}</a>
+<a class="navbar-app nav-link{{if $app.active}} active{{/if}}" href="{{$app.url}}" title="{{$app.name}}" >{{if $icon}}<i class="fa fa-fw fa-{{$icon}}"></i>{{else}}<img src="{{$app.photo}}" width="16" height="16" />{{/if}}<span class="d-lg-none">{{$app.name}}</span></a>
diff --git a/view/tpl/apporder.tpl b/view/tpl/apporder.tpl
index fdb726131..8a247f11d 100644
--- a/view/tpl/apporder.tpl
+++ b/view/tpl/apporder.tpl
@@ -1,7 +1,15 @@
-<h2>{{$header}}</h2>
-
-<div class="descriptive-text">{{$desc}}</div>
-<br><br><br>
+{{if $navbar_apps}}
+<h2>{{$header.0}}</h2>
+<div class="descriptive-text">{{$desc.0}}</div>
+<br><br>
+{{foreach $navbar_apps as $navbar_app}}
+{{$navbar_app}}
+{{/foreach}}
+<br><br>
+{{/if}}
+<h2>{{$header.1}}</h2>
+<div class="descriptive-text">{{$desc.1}}</div>
+<br><br>
{{foreach $nav_apps as $nav_app}}
{{$nav_app}}
{{/foreach}}
diff --git a/view/tpl/cloud_directory.tpl b/view/tpl/cloud_directory.tpl
index 40278661f..3ae8cbf35 100644
--- a/view/tpl/cloud_directory.tpl
+++ b/view/tpl/cloud_directory.tpl
@@ -16,7 +16,7 @@
<div class="cloud-container">
<div class="cloud-icon"><a href="{{$item.fullPath}}">
{{if $item.photo_icon}}
- <img src="photo/{{$item.photo_icon}}" title="{{$item.type}}" >
+ <img src="{{$item.photo_icon}}" title="{{$item.type}}" >
{{else}}
<i class="fa fa-fw {{$item.iconFromType}}" title="{{$item.type}}"></i>
{{/if}}
diff --git a/view/tpl/help.tpl b/view/tpl/help.tpl
index d36494123..c523c4115 100644
--- a/view/tpl/help.tpl
+++ b/view/tpl/help.tpl
@@ -9,6 +9,7 @@
<a class="dropdown-item lang-choice" href="/help">de</a>
<a class="dropdown-item lang-choice" href="/help">en</a>
<a class="dropdown-item lang-choice" href="/help">es</a>
+ <a class="dropdown-item lang-choice" href="/help">fr</a>
</div>
</div>
</div>
diff --git a/view/tpl/navbar_default.tpl b/view/tpl/navbar_default.tpl
index 426d32047..c4f5af1dc 100755
--- a/view/tpl/navbar_default.tpl
+++ b/view/tpl/navbar_default.tpl
@@ -1,5 +1,5 @@
{{if $nav.login && !$userinfo}}
-<div class="d-xl-none pt-1 pb-1">
+<div class="d-lg-none pt-1 pb-1">
{{if $nav.loginmenu.1.4}}
<a class="btn btn-primary btn-sm text-white" href="#" title="{{$nav.loginmenu.1.3}}" id="{{$nav.loginmenu.1.4}}_collapse" data-toggle="modal" data-target="#nav-login">
{{$nav.loginmenu.1.1}}
@@ -76,12 +76,12 @@
<i class="fa fa-question-circle"></i>
</button>
{{/if}}
- <button id="expand-aside" type="button" class="d-md-none navbar-toggler border-0" data-toggle="offcanvas" data-target="#region_1">
+ <button id="expand-aside" type="button" class="d-lg-none navbar-toggler border-0" data-toggle="offcanvas" data-target="#region_1">
<i class="fa fa-arrow-circle-right" id="expand-aside-icon"></i>
</button>
{{if $localuser || $nav.pubs}}
- <button id="notifications-btn" type="button" class="navbar-toggler border-0 text-white">
- <i id="notifications-btn-icon" class="fa fa-exclamation-circle"></i>
+ <button id="notifications-btn-1" type="button" class="navbar-toggler border-0 text-white notifications-btn">
+ <i id="notifications-btn-icon-1" class="fa fa-exclamation-circle notifications-btn-icon"></i>
</button>
{{/if}}
<button id="menu-btn" class="navbar-toggler border-0" type="button" data-toggle="collapse" data-target="#navbar-collapse-2">
@@ -134,6 +134,11 @@
<a class="nav-link {{$nav.help.2}}" target="hubzilla-help" href="{{$nav.help.0}}" title="{{$nav.help.3}}" id="{{$nav.help.4}}" onclick="contextualHelp(); return false;"><i class="fa fa-fw fa-question-circle"></i></a>
</li>
{{/if}}
+ {{if $localuser || $nav.pubs}}
+ <li id="notifications-btn" class="nav-item d-xl-none">
+ <a class="nav-link text-white notifications-btn" href="#"><i id="notifications-btn-icon" class="fa fa-exclamation-circle notifications-btn-icon"></i></a>
+ </li>
+ {{/if}}
{{if $channel_menu && $channel_apps.0}}
<li class="nav-item dropdown" id="channel-menu">
<a class="nav-link" href="#" data-toggle="dropdown"><img src="{{$channel_thumb}}" style="height:14px; width:14px;position:relative; top:-2px;" /></a>
@@ -179,7 +184,7 @@
</li>
</ul>
</div>
-<div class="collapse d-xl-none" id="navbar-collapse-2">
+<div class="collapse d-lg-none" id="navbar-collapse-2">
<div class="navbar-nav mr-auto">
{{if $channel_apps.0}}
{{foreach $channel_apps as $channel_app}}
@@ -190,6 +195,9 @@
</div>
<div id="sys-apps-collapsed" style="display:none;">
{{/if}}
+ {{foreach $navbar_apps as $navbar_app}}
+ {{$navbar_app}}
+ {{/foreach}}
{{foreach $nav_apps as $nav_app}}
{{$nav_app|replace:'dropdown-item':'nav-link'}}
{{/foreach}}
diff --git a/view/tpl/navbar_tucson.tpl b/view/tpl/navbar_tucson.tpl
index faf8b5b4a..4e045571f 100755
--- a/view/tpl/navbar_tucson.tpl
+++ b/view/tpl/navbar_tucson.tpl
@@ -1,5 +1,5 @@
{{if $nav.login && !$userinfo}}
-<div class="d-xl-none pt-1 pb-1">
+<div class="d-lg-none pt-1 pb-1">
{{if $nav.loginmenu.1.4}}
<a class="btn btn-primary btn-sm text-white" href="#" title="{{$nav.loginmenu.1.3}}" id="{{$nav.loginmenu.1.4}}_collapse" data-toggle="modal" data-target="#nav-login">
{{$nav.loginmenu.1.1}}
@@ -87,8 +87,8 @@
</button>
{{if $localuser || $nav.pubs}}
- <button id="notifications-btn" type="button" class="navbar-toggler border-0 text-white" data-toggle="collapse" data-target="#navbar-collapse-1">
- <i id="notifications-btn-icon" class="fa fa-exclamation"></i>
+ <button id="notifications-btn-1" type="button" class="navbar-toggler border-0 text-white notifications-btn" data-toggle="collapse" data-target="#navbar-collapse-1">
+ <i id="notifications-btn-icon-1" class="fa fa-exclamation notifications-btn-icon"></i>
</button>
{{/if}}
@@ -231,6 +231,11 @@
<a class="nav-link {{$nav.help.2}}" target="hubzilla-help" href="{{$nav.help.0}}" title="{{$nav.help.3}}" id="{{$nav.help.4}}" onclick="contextualHelp(); return false;"><i class="fa fa-fw fa-question-circle"></i></a>
</li>
{{/if}}
+ {{if $localuser || $nav.pubs}}
+ <li id="notifications-btn" class="nav-item d-xl-none">
+ <a class="nav-link text-white notifications-btn" href="#"><i id="notifications-btn-icon" class="fa fa-exclamation-circle notifications-btn-icon"></i></a>
+ </li>
+ {{/if}}
{{if $channel_apps.0}}
<li class="nav-item dropdown" id="channel-menu">
<a class="nav-link" href="#" data-toggle="dropdown"><img src="{{$channel_thumb}}" style="height:14px; width:14px;position:relative; top:-2px;" /></a>
@@ -258,7 +263,7 @@
</div>
-<div class="collapse d-xl-none" id="navbar-collapse-2">
+<div class="collapse d-lg-none" id="navbar-collapse-2">
<div class="navbar-nav mr-auto">
{{if $channel_apps.0}}
{{foreach $channel_apps as $channel_app}}
diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl
index 3ef7bff7d..8168866ad 100644
--- a/view/tpl/notifications_widget.tpl
+++ b/view/tpl/notifications_widget.tpl
@@ -2,7 +2,7 @@
var notifications_parent;
$(document).ready(function() {
notifications_parent = $('#notifications_wrapper')[0].parentElement.id;
- $('#notifications-btn').click(function() {
+ $('.notifications-btn').click(function() {
if($('#notifications_wrapper').hasClass('fs'))
$('#notifications_wrapper').prependTo('#' + notifications_parent);
else
@@ -15,21 +15,35 @@
});
});
- {{if $module == 'display'}}
+ {{if $module == 'display' || $module == 'hq'}}
$(document).on('click', '.notification', function(e) {
var b64mid = $(this).data('b64mid');
+ var notify_id = $(this).data('notify_id');
var path = $(this)[0].pathname.substr(1,7);
+ console.log(path);
+
+ {{if $module == 'hq'}}
+ if(b64mid !== 'undefined' && path !== 'pubstre') {
+ {{else}}
if(path === 'display' && b64mid) {
+ {{/if}}
e.preventDefault();
e.stopPropagation();
$('.thread-wrapper').remove();
- $(this).fadeOut();
+
+ if(! page_load)
+ $(this).fadeOut();
+
bParam_mid = b64mid;
mode = 'replace';
page_load = true;
+ {{if $module == 'hq'}}
+ hqLiveUpdate(notify_id);
+ {{else}}
liveUpdate();
+ {{/if}}
if($('#notifications_wrapper').hasClass('fs'))
$('#notifications_wrapper').prependTo('#' + notifications_parent).removeClass('fs');
@@ -43,7 +57,7 @@
<div id="notifications_wrapper">
<div id="notifications" class="navbar-nav" data-children=".nav-item">
<div id="nav-notifications-template" rel="template">
- <a class="list-group-item clearfix notification {5}" href="{0}" title="{2} {3}" data-b64mid="{6}">
+ <a class="list-group-item clearfix notification {5}" href="{0}" title="{2} {3}" data-b64mid="{6}" data-notify_id="{7}">
<img class="menu-img-3" data-src="{1}">
<span class="contactname">{2}</span>
<span class="dropdown-sub-text">{3}<br>{4}</span>