Merge branch 'dev' of https://github.com/redmatrix/hubzilla into dev_merge

This commit is contained in:
zotlabs 2017-10-04 19:37:35 -07:00
commit 2862baeee1
19 changed files with 320 additions and 158 deletions

View file

@ -62,6 +62,7 @@ class Site {
$feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0); $feed_contacts = ((x($_POST,'feed_contacts')) ? intval($_POST['feed_contacts']) : 0);
$verify_email = ((x($_POST,'verify_email')) ? 1 : 0); $verify_email = ((x($_POST,'verify_email')) ? 1 : 0);
$techlevel_lock = ((x($_POST,'techlock')) ? intval($_POST['techlock']) : 0); $techlevel_lock = ((x($_POST,'techlock')) ? intval($_POST['techlock']) : 0);
$imagick_path = ((x($_POST,'imagick_path')) ? trim($_POST['imagick_path']) : '');
$techlevel = null; $techlevel = null;
if(array_key_exists('techlevel', $_POST)) if(array_key_exists('techlevel', $_POST))
@ -82,6 +83,7 @@ class Site {
set_config('system', 'reply_address', $reply_address); set_config('system', 'reply_address', $reply_address);
set_config('system', 'from_email', $from_email); set_config('system', 'from_email', $from_email);
set_config('system', 'from_email_name' , $from_email_name); set_config('system', 'from_email_name' , $from_email_name);
set_config('system', 'imagick_convert_path' , $imagick_path);
set_config('system', 'techlevel_lock', $techlevel_lock); set_config('system', 'techlevel_lock', $techlevel_lock);
@ -317,6 +319,7 @@ class Site {
'$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")), '$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")),
'$delivery_batch_count' => array('delivery_batch_count', t('Deliveries per process'),(x(get_config('system','delivery_batch_count'))?get_config('system','delivery_batch_count'):1), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.")), '$delivery_batch_count' => array('delivery_batch_count', t('Deliveries per process'),(x(get_config('system','delivery_batch_count'))?get_config('system','delivery_batch_count'):1), t("Number of deliveries to attempt in a single operating system process. Adjust if necessary to tune system performance. Recommend: 1-5.")),
'$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")), '$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")),
'$imagick_path' => array('imagick_path', t("Path to ImageMagick convert program"), get_config('system','imagick_convert_path'), t("If set, use this program to generate photo thumbnails for huge images ( > 4000 pixels in either dimension), otherwise memory exhaustion may occur. Example: /usr/bin/convert")),
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
'$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')), '$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')),
'$form_security_token' => get_form_security_token("admin_site"), '$form_security_token' => get_form_security_token("admin_site"),

View file

@ -25,7 +25,7 @@ class Common extends \Zotlabs\Web\Controller {
} }
function get() { function get() {
$o = ''; $o = '';
@ -34,38 +34,37 @@ class Common extends \Zotlabs\Web\Controller {
$observer_hash = get_observer_hash(); $observer_hash = get_observer_hash();
if(! perm_is_allowed(\App::$profile['profile_uid'],$observer_hash,'view_contacts')) { if(! perm_is_allowed(\App::$profile['profile_uid'],$observer_hash,'view_contacts')) {
notice( t('Permission denied.') . EOL); notice( t('Permission denied.') . EOL);
return; return;
} }
$o .= '<h2>' . t('Common connections') . '</h2>';
$t = count_common_friends(\App::$profile['profile_uid'],$observer_hash); $t = count_common_friends(\App::$profile['profile_uid'],$observer_hash);
if(! $t) { if(! $t) {
notice( t('No connections in common.') . EOL); notice( t('No connections in common.') . EOL);
return $o; return;
} }
$r = common_friends(\App::$profile['profile_uid'],$observer_hash); $r = common_friends(\App::$profile['profile_uid'],$observer_hash);
if($r) { if($r) {
$tpl = get_markup_template('common_friends.tpl');
foreach($r as $rr) { foreach($r as $rr) {
$o .= replace_macros($tpl,array( $items[] = [
'$url' => $rr['xchan_url'], 'url' => $rr['xchan_url'],
'$name' => $rr['xchan_name'], 'name' => $rr['xchan_name'],
'$photo' => $rr['xchan_photo_m'], 'photo' => $rr['xchan_photo_m'],
'$tags' => '' 'tags' => ''
)); ];
} }
$o .= cleardiv();
} }
$tpl = get_markup_template('common_friends.tpl');
$o = replace_macros($tpl, [
'$title' => t('View Common Connections'),
'$items' => $items
]);
return $o; return $o;
} }

View file

@ -278,20 +278,31 @@ class Import extends \Zotlabs\Web\Controller {
create_table_from_array('xchan',$xchan); create_table_from_array('xchan',$xchan);
require_once('include/photo/photo_driver.php'); require_once('include/photo/photo_driver.php');
$photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
if($photos[4])
$photodate = NULL_DATE;
else
$photodate = $xchan['xchan_photo_date'];
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'", if($xchan['xchan_hash'] === $channel['channel_hash']) {
dbesc($photos[0]), $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' where xchan_hash = '%s'",
dbesc($photos[1]), dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']),
dbesc($photos[2]), dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']),
dbesc($photos[3]), dbesc(z_root() . '/photo/profile/s/' . $channel['channel_id']),
dbesc($photodate), dbesc($xchan['xchan_hash'])
dbesc($xchan['xchan_hash']) );
); }
else {
$photos = import_xchan_photo($xchan['xchan_photo_l'],$xchan['xchan_hash']);
if($photos[4])
$photodate = NULL_DATE;
else
$photodate = $xchan['xchan_photo_date'];
$r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s' where xchan_hash = '%s'",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($photodate),
dbesc($xchan['xchan_hash'])
);
}
} }
logger('import step 7'); logger('import step 7');

View file

@ -694,7 +694,7 @@ class Item extends \Zotlabs\Web\Controller {
foreach($t as $t1) { foreach($t as $t1) {
$post_tags[] = array( $post_tags[] = array(
'uid' => $profile_uid, 'uid' => $profile_uid,
'ttype' => $t1['type'], 'ttype' => $t1['ttype'],
'otype' => TERM_OBJ_POST, 'otype' => TERM_OBJ_POST,
'term' => $t1['term'], 'term' => $t1['term'],
'url' => $t1['url'], 'url' => $t1['url'],
@ -1105,21 +1105,28 @@ class Item extends \Zotlabs\Web\Controller {
// if this is a different page type or it's just a local delete // if this is a different page type or it's just a local delete
// but not by the item author or owner, do a simple deletion // but not by the item author or owner, do a simple deletion
$complex = false;
if(intval($i[0]['item_type']) || ($local_delete && (! $can_delete))) { if(intval($i[0]['item_type']) || ($local_delete && (! $can_delete))) {
drop_item($i[0]['id']); drop_item($i[0]['id']);
} }
else { else {
// complex deletion that needs to propagate and be performed in phases // complex deletion that needs to propagate and be performed in phases
drop_item($i[0]['id'],true,DROPITEM_PHASE1); drop_item($i[0]['id'],true,DROPITEM_PHASE1);
$r = q("select * from item where id = %d", $complex = true;
intval($i[0]['id']) }
);
if($r) { $r = q("select * from item where id = %d",
xchan_query($r); intval($i[0]['id'])
$sync_item = fetch_post_tags($r); );
build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true)))); if($r) {
} xchan_query($r);
$sync_item = fetch_post_tags($r);
build_sync_packet($i[0]['uid'],array('item' => array(encode_item($sync_item[0],true))));
}
if($complex) {
tag_deliver($i[0]['uid'],$i[0]['id']); tag_deliver($i[0]['uid'],$i[0]['id']);
} }
} }

View file

@ -340,6 +340,30 @@ class Ping extends \Zotlabs\Web\Controller {
killme(); killme();
} }
if((argc() > 1 && (argv(1) === 'register')) && is_site_admin()) {
$result = array();
$r = q("SELECT account_email, account_created from account where (account_flags & %d) > 0",
intval(ACCOUNT_PENDING)
);
if($r) {
foreach($r as $rr) {
$result[] = array(
'notify_link' => z_root() . '/admin/accounts',
'name' => $rr['account_email'],
'url' => '',
'photo' => get_default_profile_photo(48),
'when' => relative_date($rr['account_created']),
'hclass' => ('notify-unseen'),
'message' => t('requires approval')
);
}
}
logger('ping (register): ' . print_r($result, true), LOGGER_DATA);
echo json_encode(array('notify' => $result));
killme();
}
if(argc() > 1 && (argv(1) === 'all_events')) { if(argc() > 1 && (argv(1) === 'all_events')) {
$bd_format = t('g A l F d') ; // 8 AM Friday January 18 $bd_format = t('g A l F d') ; // 8 AM Friday January 18
@ -377,6 +401,39 @@ class Ping extends \Zotlabs\Web\Controller {
killme(); killme();
} }
if(argc() > 1 && (argv(1) === 'files')) {
$result = array();
$r = q("SELECT item.created, xchan.xchan_name, xchan.xchan_url, xchan.xchan_photo_s FROM item
LEFT JOIN xchan on author_xchan = xchan_hash
WHERE item.verb = '%s'
AND item.obj_type = '%s'
AND item.uid = %d
AND item.owner_xchan != '%s'
AND item.item_unseen = 1",
dbesc(ACTIVITY_POST),
dbesc(ACTIVITY_OBJ_FILE),
intval(local_channel()),
dbesc($ob_hash)
);
if($r) {
foreach($r as $rr) {
$result[] = array(
'notify_link' => z_root() . '/sharedwithme',
'name' => $rr['xchan_name'],
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => relative_date($rr['created']),
'hclass' => ('notify-unseen'),
'message' => t('shared a file with you')
);
}
}
logger('ping (files): ' . print_r($result, true), LOGGER_DATA);
echo json_encode(array('notify' => $result));
killme();
}
/** /**
* Normal ping - just the counts, no detail * Normal ping - just the counts, no detail
*/ */
@ -406,7 +463,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result['files'] = intval($files[0]['total']); $result['files'] = intval($files[0]['total']);
} }
$t2 = dba_timer(); $t3 = dba_timer();
if($vnotify & (VNOTIFY_NETWORK|VNOTIFY_CHANNEL)) { if($vnotify & (VNOTIFY_NETWORK|VNOTIFY_CHANNEL)) {
$r = q("SELECT id, item_wall FROM item $r = q("SELECT id, item_wall FROM item

View file

@ -158,6 +158,9 @@ class Profile_photo extends \Zotlabs\Web\Controller {
intval(local_channel()) intval(local_channel())
); );
send_profile_photo_activity($channel,$base_image,$profile); send_profile_photo_activity($channel,$base_image,$profile);
} }
@ -174,12 +177,17 @@ class Profile_photo extends \Zotlabs\Web\Controller {
// We'll set the updated profile-photo timestamp even if it isn't the default profile, // We'll set the updated profile-photo timestamp even if it isn't the default profile,
// so that browsers will do a cache update unconditionally // so that browsers will do a cache update unconditionally
// Also set links back to site-specific profile photo url in case it was
// changed to a generic URL by a clone operation. Otherwise the new photo may
// not get pushed to other sites correctly.
$r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s'
$r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s'
where xchan_hash = '%s'", where xchan_hash = '%s'",
dbesc($im->getType()), dbesc($im->getType()),
dbesc(datetime_convert()), dbesc(datetime_convert()),
dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']),
dbesc(z_root() . '/photo/profile/s/' . $channel['channel_id']),
dbesc($channel['xchan_hash']) dbesc($channel['xchan_hash'])
); );

View file

@ -143,7 +143,7 @@ function cardcategories_widget($baseurl,$selected = '') {
function common_friends_visitor_widget($profile_uid,$cnt = 10) { function common_friends_visitor_widget($profile_uid,$cnt = 25) {
if(local_channel() == $profile_uid) if(local_channel() == $profile_uid)
return; return;
@ -161,14 +161,14 @@ function common_friends_visitor_widget($profile_uid,$cnt = 10) {
return; return;
$r = common_friends($profile_uid,$observer_hash,0,$cnt,true); $r = common_friends($profile_uid,$observer_hash,0,$cnt,true);
return replace_macros(get_markup_template('remote_friends_common.tpl'), array( return replace_macros(get_markup_template('remote_friends_common.tpl'), array(
'$desc' => sprintf( t('Common connections: %d'), $t), '$desc' => t('Common Connections'),
'$base' => z_root(), '$base' => z_root(),
'$uid' => $profile_uid, '$uid' => $profile_uid,
'$cid' => $observer, '$cid' => $observer,
'$linkmore' => (($t > $cnt) ? 'true' : ''), '$linkmore' => (($t > $cnt) ? 'true' : ''),
'$more' => t('show more'), '$more' => sprintf( t('View all %d common connections'), $t),
'$items' => $r '$items' => $r
)); ));

View file

@ -180,6 +180,8 @@ EOT;
$nav['intros'] = array('connections/ifpending', t('Connections'), "", t('Connections'),'connections_nav_btn'); $nav['intros'] = array('connections/ifpending', t('Connections'), "", t('Connections'),'connections_nav_btn');
if(is_site_admin())
$nav['registrations'] = array('admin/accounts', t('Registrations'), "", t('Registrations'),'registrations_nav_btn');
$nav['notifications'] = array('notifications/system', t('Notices'), "", t('Notifications'),'notifications_nav_btn'); $nav['notifications'] = array('notifications/system', t('Notices'), "", t('Notifications'),'notifications_nav_btn');

View file

@ -66,7 +66,19 @@ function photo_upload($channel, $observer, $args) {
$os_storage = 0; $os_storage = 0;
if($args['os_syspath'] && $args['getimagesize']) { if($args['os_syspath'] && $args['getimagesize']) {
$imagedata = @file_get_contents($args['os_syspath']); if($args['getimagesize'][0] > 1600 || $args['getimagesize'][1] > 1600) {
$imagick_path = get_config('system','imagick_convert_path');
if($imagick_path && @file_exists($imagick_path)) {
$tmp_name = $args['os_syspath'] . '-001';
$newsize = photo_calculate_1600_scale($args['getimagesize']);
exec($imagick_path . ' ' . $args['os_syspath'] . ' -resize ' . $newsize . '^ ' . $tmp_name);
$imagedata = @file_get_contents($tmp_name);
@unlink($tmp_name);
}
}
else {
$imagedata = @file_get_contents($args['os_syspath']);
}
$filename = $args['filename']; $filename = $args['filename'];
$filesize = strlen($imagedata); $filesize = strlen($imagedata);
// this is going to be deleted if it exists // this is going to be deleted if it exists
@ -122,7 +134,6 @@ function photo_upload($channel, $observer, $args) {
} }
logger('photo_upload: loading the contents of ' . $src , LOGGER_DEBUG); logger('photo_upload: loading the contents of ' . $src , LOGGER_DEBUG);
$imagedata = @file_get_contents($src); $imagedata = @file_get_contents($src);
} }
@ -428,6 +439,70 @@ function photo_upload($channel, $observer, $args) {
return $ret; return $ret;
} }
function photo_calculate_1600_scale($arr) {
$max = 1600;
$width = $arr[0];
$height = $arr[1];
$dest_width = $dest_height = 0;
if((! $width)|| (! $height))
return FALSE;
if($width > $max && $height > $max) {
// very tall image (greater than 16:9)
// constrain the width - let the height float.
if((($height * 9) / 16) > $width) {
$dest_width = $max;
$dest_height = intval(( $height * $max ) / $width);
}
// else constrain both dimensions
elseif($width > $height) {
$dest_width = $max;
$dest_height = intval(( $height * $max ) / $width);
}
else {
$dest_width = intval(( $width * $max ) / $height);
$dest_height = $max;
}
}
else {
if( $width > $max ) {
$dest_width = $max;
$dest_height = intval(( $height * $max ) / $width);
}
else {
if( $height > $max ) {
// very tall image (greater than 16:9)
// but width is OK - don't do anything
if((($height * 9) / 16) > $width) {
$dest_width = $width;
$dest_height = $height;
}
else {
$dest_width = intval(( $width * $max ) / $height);
$dest_height = $max;
}
}
else {
$dest_width = $width;
$dest_height = $height;
}
}
}
return $dest_width . 'x' . $dest_height;
}
/** /**
* @brief Returns a list with all photo albums observer is allowed to see. * @brief Returns a list with all photo albums observer is allowed to see.
* *

View file

@ -7,14 +7,14 @@ such as XAMPP and WAMP are not officially supported at this time - however
we welcome patches if you manage to get it working. we welcome patches if you manage to get it working.
Be aware that this software is more than a simple web application. It is a Be aware that this software is more than a simple web application. It is a
complex communications system which more closely resembles an email server complex communications and content management system which more closely
than a web server. For reliability and performance, messages are delivered in resembles an email server than a web server. For reliability and performance,
the background and are queued for later delivery when sites are down. This messages are delivered in the background and are queued for later delivery
kind of functionality requires a bit more of the host system than the typical when sites are down. This kind of functionality requires a bit more of the
blog. Not every PHP/MySQL hosting provider will be able to support the host system than the typical blog. Not every PHP/MySQL hosting provider will
Hubzilla. Many will - but please review the requirements and confirm these be able to support Hubzilla. Many will - but please review the requirements
with your hosting provider prior to installation. (And preferably before and confirm these with your hosting provider prior to installation. (And
entering into a long-term contract.) preferably before entering into a long-term contract.)
If you encounter installation issues, please let us know via the Github issue If you encounter installation issues, please let us know via the Github issue
tracker where you downloaded the software. Please be as clear as tracker where you downloaded the software. Please be as clear as
@ -75,27 +75,6 @@ location may prevent some of these services from working correctly. This
should not be a problem with Apache, but may be an issue with nginx or other should not be a problem with Apache, but may be an issue with nginx or other
web server platforms. web server platforms.
**Server Roles**
During installation you will be asked to choose a server role. Your choices are
1. Basic
2. Standard
3. Pro
Basic is highly simplified, with almost all the advanced functionality and
complexity removed or permanently disabled.
Standard is typically used for federated network use, when you wish to interact
with other networks using other protocols. Not all the built in features and
functionality work correctly when other networks are involved. All advanced
and complex features are available to all members by default.
Pro is for sites that wish to make full use of the built-in abilities and
features, but **not** to interact with other networks. Advanced features are
enabled according to a per-account 'techlevel' which reduces complexity
initially and allows members to adjust the software complexity to match their
technical abilities.
**Installation** **Installation**
1. Requirements 1. Requirements
@ -173,7 +152,8 @@ technical abilities.
cd mywebsite cd mywebsite
util/update_addon_repo hzaddons util/update_addon_repo hzaddons
- Create searchable representations of the online documentation. You may do this any time - Once the software is configured and the database installed, create searchable
representations of the online documentation. You may do this any time
that the documentation is updated. that the documentation is updated.
cd mywebsite cd mywebsite

View file

@ -7,6 +7,10 @@ nav .badge {
font-size: 0.75rem; font-size: 0.75rem;
} }
nav .dropdown-menu {
min-width: 16rem;
}
@media screen and (min-width: 767px) { @media screen and (min-width: 767px) {
nav .badge { nav .badge {
top: 0px; top: 0px;

View file

@ -444,7 +444,7 @@ function NavUpdate() {
updateCountsOnly = false; updateCountsOnly = false;
if(data.network || data.home || data.intros || data.mail || data.all_events || data.notify || data.files || data.pubs) { 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 { else {
@ -490,7 +490,7 @@ function NavUpdate() {
if(data.notify == 0) { data.notify = ''; $('.notify-update, .notify-button').hide(); } else { $('.notify-update, .notify-button').show(); } if(data.notify == 0) { data.notify = ''; $('.notify-update, .notify-button').hide(); } else { $('.notify-update, .notify-button').show(); }
$('.notify-update').html(data.notify); $('.notify-update').html(data.notify);
if(data.register == 0) { data.register = ''; $('.register-update').removeClass('show'); } else { $('.register-update').addClass('show'); } if(data.register == 0) { data.register = ''; $('.register-update, .register-button').hide(); } else { $('.register-update, .register-button').show(); }
$('.register-update').html(data.register); $('.register-update').html(data.register);
if(data.events == 0) { data.events = ''; $('.events-update, .events-button').hide(); } else { $('.events-update, .events-button').show(); } if(data.events == 0) { data.events = ''; $('.events-update, .events-button').hide(); } else { $('.events-update, .events-button').show(); }

View file

@ -3,12 +3,9 @@
[/region] [/region]
[region=aside] [region=aside]
[widget=fullprofile][/widget] [widget=fullprofile][/widget]
[widget=common_friends][/widget]
[widget=archive][var=wall]1[/var][/widget] [widget=archive][var=wall]1[/var][/widget]
[widget=categories][/widget] [widget=categories][/widget]
[widget=tagcloud_wall][var=limit]24[/var][/widget] [widget=tagcloud_wall][var=limit]24[/var][/widget]
[/region] [/region]
[region=content]
[widget=common_friends][/widget]
$content
[/region]

View file

@ -82,6 +82,7 @@
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div> <div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
<h3>{{$advanced}}</h3> <h3>{{$advanced}}</h3>
{{include file="field_input.tpl" field=$imagick_path}}
{{include file="field_input.tpl" field=$proxy}} {{include file="field_input.tpl" field=$proxy}}
{{include file="field_input.tpl" field=$proxyuser}} {{include file="field_input.tpl" field=$proxyuser}}
{{include file="field_input.tpl" field=$timeout}} {{include file="field_input.tpl" field=$timeout}}

View file

@ -1,15 +1,17 @@
<div class="generic-content-wrapper"> <div class="generic-content-wrapper">
<div class="profile-match-photo"> <div class="section-title-wrapper">
<a href="{{$url}}"> <h2>{{$title}}</h2>
<img src="{{$photo}}" alt="{{$name}}" width="80" height="80" title="{{$name}} [{{$url}}]" />
</a>
</div> </div>
<div class="profile-match-break"></div> <div class="section-content-wrapper clearfix">
<div class="profile-match-name"> {{foreach $items as $item}}
<a href="{{$url}}" title="{{$name}}[{{$tags}}]">{{$name}}</a> <div class="float-left mr-4">
<a href="{{$item.url}}">
<img class="contact-block-img" src="{{$item.photo}}" alt="{{$item.name}}" title="{{$item.name}} [{{$item.url}}]" />
</a>
<div>
{{$item.name}}
</div>
</div>
{{/foreach}}
</div> </div>
{{if $note}}
<div class="profile-match-note">{{$note}}</div>
{{/if}}
<div class="profile-match-end"></div>
</div> </div>

View file

@ -8,7 +8,8 @@
aside_padding_top = parseInt($('aside').css('padding-top')); aside_padding_top = parseInt($('aside').css('padding-top'));
section_padding_top = parseInt($('section').css('padding-top')); section_padding_top = parseInt($('section').css('padding-top'));
$(document).on('click', slideUpCover); $('#cover-photo').on('click', slideUpCover);
$('#cover-photo').on('keyup', slideUpCover);
if($('#cover-photo').length && $(window).width() > 755) { if($('#cover-photo').length && $(window).width() > 755) {
if($(window).scrollTop() < $('#cover-photo').height()) { if($(window).scrollTop() < $('#cover-photo').height()) {

View file

@ -128,7 +128,7 @@
{{/if}} {{/if}}
{{if $nav.intros}} {{if $nav.intros}}
<li class="nav-item dropdown intro-button" style="display: none;"> <li class="nav-item dropdown intro-button" style="display: none;">
<a class="nav-link" href="{{$nav.intros.0}}" title="{{$nav.intros.3}}" id="{{$nav.intros.4}}" data-toggle="dropdown" rel="#nav-intros-menu"> <a class="nav-link" href="#" title="{{$nav.intros.3}}" id="{{$nav.intros.4}}" data-toggle="dropdown" rel="#nav-intros-menu">
<i class="fa fa-fw fa-users"></i> <i class="fa fa-fw fa-users"></i>
<span class="badge badge-pill badge-danger intro-update"></span> <span class="badge badge-pill badge-danger intro-update"></span>
</a> </a>
@ -138,9 +138,20 @@
</div> </div>
</li> </li>
{{/if}} {{/if}}
{{if $nav.registrations}}
<li class="nav-item dropdown register-button" style="display: none;">
<a class="nav-link" href="#" title="{{$nav.registrations.3}}" id="{{$nav.registrations.4}}" data-toggle="dropdown" rel="#nav-register-menu">
<i class="fa fa-fw fa-user-o"></i>
<span class="badge badge-pill badge-danger register-update"></span>
</a>
<div id="nav-register-menu" class="dropdown-menu" rel="register">
{{$emptynotifications}}
</div>
</li>
{{/if}}
{{if $nav.notifications}} {{if $nav.notifications}}
<li class="nav-item dropdown notify-button" style="display: none;"> <li class="nav-item dropdown notify-button" style="display: none;">
<a class="nav-link" href="{{$nav.notifications.0}}" title="{{$nav.notifications.1}}" id="{{$nav.notifications.4}}" data-toggle="dropdown" rel="#nav-notify-menu"> <a class="nav-link" href="#" title="{{$nav.notifications.1}}" id="{{$nav.notifications.4}}" data-toggle="dropdown" rel="#nav-notify-menu">
<i class="fa fa-fw fa-exclamation"></i> <i class="fa fa-fw fa-exclamation"></i>
<span class="badge badge-pill badge-danger notify-update"></span> <span class="badge badge-pill badge-danger notify-update"></span>
</a> </a>
@ -151,6 +162,17 @@
</div> </div>
</li> </li>
{{/if}} {{/if}}
{{if $nav.files}}
<li class="nav-item dropdown files-button" style="display: none;">
<a class="nav-link" href="#" title="{{$nav.files.3}}" id="{{$nav.files.4}}" data-toggle="dropdown" rel="#nav-files-menu">
<i class="fa fa-fw fa-folder"></i>
<span class="badge badge-pill badge-danger files-update"></span>
</a>
<div id="nav-files-menu" class="dropdown-menu" rel="files">
{{$emptynotifications}}
</div>
</li>
{{/if}}
{{if $nav.login && !$userinfo}} {{if $nav.login && !$userinfo}}
<li class="nav-item d-none d-md-flex"> <li class="nav-item d-none d-md-flex">
<a class="nav-link" href="#" title="{{$nav.loginmenu.1.3}}" id="{{$nav.loginmenu.1.4}}" data-toggle="modal" data-target="#nav-login">{{$nav.loginmenu.1.1}}</a> <a class="nav-link" href="#" title="{{$nav.loginmenu.1.3}}" id="{{$nav.loginmenu.1.4}}" data-toggle="modal" data-target="#nav-login">{{$nav.loginmenu.1.1}}</a>
@ -166,14 +188,7 @@
<a class="nav-link" href="{{$nav.alogout.0}}" title="{{$nav.alogout.3}}" id="{{$nav.alogout.4}}">{{$nav.alogout.1}}</a> <a class="nav-link" href="{{$nav.alogout.0}}" title="{{$nav.alogout.3}}" id="{{$nav.alogout.4}}">{{$nav.alogout.1}}</a>
</li> </li>
{{/if}} {{/if}}
{{if $nav.files}}
<li class="nav-item dropdown files-button" style="display: none;">
<a class="nav-link" href="{{$nav.files.0}}" title="{{$nav.files.3}}" id="{{$nav.files.4}}" rel="#nav-files-menu">
<i class="fa fa-fw fa-folder"></i>
<span class="badge badge-pill badge-primary files-update"></span>
</a>
</li>
{{/if}}
{{if $nav.pubs}} {{if $nav.pubs}}
<li class="nav-item dropdown pubs-button" style="display: none;"> <li class="nav-item dropdown pubs-button" style="display: none;">
<a class="nav-link" href="{{$nav.pubs.0}}" title="{{$nav.pubs.3}}" id="{{$nav.pubs.4}}" rel="#nav-pubs-menu"> <a class="nav-link" href="{{$nav.pubs.0}}" title="{{$nav.pubs.3}}" id="{{$nav.pubs.4}}" rel="#nav-pubs-menu">

View file

@ -1,28 +1,16 @@
<div class="widget"> <div class="widget">
<div class="panel"> <h3>{{$desc}}</h3>
<div class="section-subtitle-wrapper" role="tab" id="common-friends-visitor"> {{if $linkmore}}
<h3><a data-toggle="collapse" href="#common-friends-collapse">{{$desc}}</a></h3> <a class="allcontact-link" href="{{$base}}/common/{{$uid}}">{{$more}}</a>
</div> {{/if}}
<div id="common-friends-collapse" class="collapse" role="tabpanel" aria-labelledby="common-friends-visitor"> {{if $items}}
{{if $items}} <div class="contact-block-content">
{{foreach $items as $item}} {{foreach $items as $item}}
<div class="profile-match-wrapper"> <div class="contact-block-div">
<div class="profile-match-photo"> <a class="contact-block-link mpfriend" href="{{$base}}/chanview?f=&url={{$item.xchan_url}}"><img class="contact-block-img mpfriend" src="{{$item.xchan_photo_s}}"alt="{{$item.xchan_name}}" title="{{$item.xchan_name}} [{{$item.xchan_addr}}]" /></a>
<a href="{{$base}}/chanview?f=&url={{$item.xchan_url}}">
<img src="{{$item.xchan_photo_m}}" width="80" height="80" alt="{{$item.xchan_name}}" title="{{$item.xchan_name}}" />
</a>
</div>
<div class="profile-match-break"></div>
<div class="profile-match-name">
<a href="{{$base}}/chanview?f=&url={{$item.xchan_url}}" title="{{$item.xchan_name}}">{{$item.xchan_name}}</a>
</div>
<div class="profile-match-end"></div>
</div>
{{/foreach}}
{{/if}}
<div id="rfic-end" class="clear"></div>
{{if $linkmore}}<button class="btn btn-default"><a href="{{$base}}/common/{{$uid}}">{{$more}}</a></button>{{/if}}
</div> </div>
{{/foreach}}
</div> </div>
</div> {{/if}}
<div>

View file

@ -1,7 +1,7 @@
<div class="generic-content-wrapper" {{if $hideEditor}}style="display: none;"{{/if}}> <div class="generic-content-wrapper">
<div class="section-title-wrapper"> <div class="section-title-wrapper">
<div class="pull-right"> <div class="pull-right">
<span class="wiki-typename">[{{$typename}}]&nbsp;</span> <span class="text-muted wiki-typename">[{{$typename}}]&nbsp;</span>
{{if $showPageControls}} {{if $showPageControls}}
<div id="page-tools" class="btn-group" style="display: none;"> <div id="page-tools" class="btn-group" style="display: none;">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown"> <button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown">
@ -53,18 +53,6 @@
<textarea id="editor">{{$content}}</textarea> <textarea id="editor">{{$content}}</textarea>
</div> </div>
{{/if}} {{/if}}
{{if $showPageControls}}
<div>
<div id="id_{{$commitMsg.0}}_wrapper" class="field input">
<div class="input-group">
<input class="form-control form-control-sm" name="{{$commitMsg.0}}" id="id_{{$commitMsg.0}}" type="text" value="{{$commitMsg.2}}"{{if $commitMsg.5}} {{$commitMsg.5}}{{/if}}>
<div class="input-group-btn">
<button id="save-page" type="button" class="btn btn-primary disabled">Save</button>
</div>
</div>
</div>
</div>
{{/if}}
</div> </div>
<div id="preview-pane" class="tab-pane active"> <div id="preview-pane" class="tab-pane active">
<div id="wiki-preview"> <div id="wiki-preview">
@ -74,6 +62,16 @@
<div id="page-history-pane" class="tab-pane"> <div id="page-history-pane" class="tab-pane">
<div id="page-history-list"></div> <div id="page-history-list"></div>
</div> </div>
{{if $showPageControls}}
<div id="id_{{$commitMsg.0}}_wrapper" class="field input" style="display: none">
<div class="input-group">
<input class="form-control form-control-sm" name="{{$commitMsg.0}}" id="id_{{$commitMsg.0}}" type="text" value="{{$commitMsg.2}}"{{if $commitMsg.5}} {{$commitMsg.5}}{{/if}}>
<div class="input-group-btn">
<button id="save-page" type="button" class="btn btn-primary disabled">Save</button>
</div>
</div>
</div>
{{/if}}
</div> </div>
</div> </div>
</div> </div>
@ -106,6 +104,7 @@
window.wiki_page_name = '{{$page}}'; window.wiki_page_name = '{{$page}}';
window.wiki_page_content = '{{$content|escape:'javascript'}}'; window.wiki_page_content = '{{$content|escape:'javascript'}}';
window.wiki_page_commit = '{{$commit}}'; window.wiki_page_commit = '{{$commit}}';
window.saved = true;
$("#generic-modal-ok-{{$wikiModalID}}").removeClass('btn-primary'); $("#generic-modal-ok-{{$wikiModalID}}").removeClass('btn-primary');
$("#generic-modal-ok-{{$wikiModalID}}").addClass('btn-danger'); $("#generic-modal-ok-{{$wikiModalID}}").addClass('btn-danger');
@ -174,10 +173,16 @@
adjustInlineEditorHeight(); adjustInlineEditorHeight();
} }
}, 500); // Return the focus to the editor allowing immediate text entry }, 500); // Return the focus to the editor allowing immediate text entry
$('#page-tools').show(); $('#page-tools, #id_{{$commitMsg.0}}_wrapper').show();
}); });
$('#wiki-get-preview').click(function (ev) { $('#wiki-get-preview').click(function (ev) {
if(window.saved) {
$('#page-tools, #id_{{$commitMsg.0}}_wrapper').hide();
}
else {
$('#page-tools').hide();
}
$.post("wiki/{{$channel_address}}/preview", { $.post("wiki/{{$channel_address}}/preview", {
{{if !$mimeType || $mimeType == 'text/markdown'}} {{if !$mimeType || $mimeType == 'text/markdown'}}
content: editor.getValue(), content: editor.getValue(),
@ -188,30 +193,34 @@
mimetype: '{{$mimeType}}' mimetype: '{{$mimeType}}'
}, },
function (data) { function (data) {
if (data.success) { if (data.success) {
$('#wiki-preview').html(data.html); $('#wiki-preview').html(data.html);
{{if !$mimeType || $mimeType == 'text/markdown'}} {{if !$mimeType || $mimeType == 'text/markdown'}}
$("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"}); $("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"});
{{/if}} {{/if}}
$('#page-tools').hide(); } else {
} else { window.console.log('Error previewing page.');
window.console.log('Error previewing page.'); }
}
}, 'json'); }, 'json');
ev.preventDefault(); ev.preventDefault();
}); });
$('#wiki-get-history').click(function (ev) { $('#wiki-get-history').click(function (ev) {
if(window.saved) {
$('#page-tools, #id_{{$commitMsg.0}}_wrapper').hide();
}
else {
$('#page-tools').hide();
}
$.post("wiki/{{$channel_address}}/history/page", {name: window.wiki_page_name, resource_id: window.wiki_resource_id}, function (data) { $.post("wiki/{{$channel_address}}/history/page", {name: window.wiki_page_name, resource_id: window.wiki_resource_id}, function (data) {
if (data.success) { if (data.success) {
$('#page-history-list').html(data.historyHTML); $('#page-history-list').html(data.historyHTML);
$('#page-tools').hide();
} else { } else {
window.console.log('Error getting page history.'); window.console.log('Error getting page history.');
} }
}, 'json'); }, 'json');
ev.preventDefault(); ev.preventDefault();
}); });
function wiki_refresh_page_list() { function wiki_refresh_page_list() {
if (window.wiki_resource_id === '') { if (window.wiki_resource_id === '') {
@ -254,6 +263,7 @@
}, },
function (data) { function (data) {
if (data.success) { if (data.success) {
window.saved = true;
window.console.log('Page saved successfully.'); window.console.log('Page saved successfully.');
window.wiki_page_content = currentContent; window.wiki_page_content = currentContent;
$('#id_commitMsg').val(''); // Clear the commit message box $('#id_commitMsg').val(''); // Clear the commit message box
@ -446,6 +456,7 @@
{{if !$mimeType || $mimeType == 'text/markdown'}} {{if !$mimeType || $mimeType == 'text/markdown'}}
$("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"}); $("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"});
window.editor.on("input", function() { window.editor.on("input", function() {
window.saved = false;
if(window.editor.getSession().getUndoManager().isClean()) { if(window.editor.getSession().getUndoManager().isClean()) {
$('#save-page').addClass('disabled'); $('#save-page').addClass('disabled');
} else { } else {
@ -454,6 +465,7 @@
}); });
{{else}} {{else}}
window.editor.on("input", function() { window.editor.on("input", function() {
window.saved = false;
$('#save-page').removeClass('disabled'); $('#save-page').removeClass('disabled');
}); });
{{if $mimeType == 'text/bbcode'}} {{if $mimeType == 'text/bbcode'}}