Merge branch 'dev' of https://codeberg.org/zot/zap into dev

This commit is contained in:
nobody 2022-01-05 08:19:07 +11:00
commit 193a5403a7
35 changed files with 21017 additions and 20826 deletions

View file

@ -2975,8 +2975,10 @@ class Activity
$s['verb'] = self::activity_mapper($act->type); $s['verb'] = self::activity_mapper($act->type);
// Mastodon does not provide update timestamps when updating poll tallies which means race conditions may occur here. // Mastodon does not provide update timestamps when updating poll tallies which means race conditions may occur here.
if ($act->type === 'Update' && $act->obj['type'] === 'Question' && $s['edited'] === $s['created']) { if (in_array($act->type,['Create','Update']) && $act->obj['type'] === 'Question' && $s['edited'] === $s['created']) {
$s['edited'] = datetime_convert(); if (isset($act->obj['votersCount']) && intval($act->obj['votersCount'])) {
$s['edited'] = datetime_convert();
}
} }

View file

@ -317,12 +317,30 @@ class ActivityStreams
return Activity::fetch($url, $channel, $hub); return Activity::fetch($url, $channel, $hub);
} }
public static function is_an_actor($s) /**
* @brief given a type, determine if this object represents an actor
*
* If $type is an array, recurse through each element and return true if any
* of the elements are a known actor type
*
* @param string|array $type
* @return boolean
*/
public static function is_an_actor($type)
{ {
if (!$s) { if (!$type) {
return false; return false;
} }
return (in_array($s, ['Application', 'Group', 'Organization', 'Person', 'Service'])); if (is_array($type)) {
foreach ($type as $x) {
if (self::is_an_actor($x)) {
return true;
}
}
return false;
}
return (in_array($type, ['Application', 'Group', 'Organization', 'Person', 'Service']));
} }
public static function is_response_activity($s) public static function is_response_activity($s)

View file

@ -446,6 +446,9 @@ class Apps
* nav: render apps for app-bin * nav: render apps for app-bin
*/ */
$channel_id = local_channel();
$sys_channel = is_sys_channel($channel_id);
$installed = false; $installed = false;
if (!$papp) { if (!$papp) {
@ -469,7 +472,7 @@ class Apps
if (strpos($papp['url'], '$baseurl') !== false || strpos($papp['url'], '$nick') !== false || strpos($papp['photo'], '$baseurl') !== false || strpos($papp['photo'], '$nick') !== false) { if (strpos($papp['url'], '$baseurl') !== false || strpos($papp['url'], '$nick') !== false || strpos($papp['photo'], '$baseurl') !== false || strpos($papp['photo'], '$nick') !== false) {
$view_channel = local_channel(); $view_channel = $channel_id;
if (!$view_channel) { if (!$view_channel) {
$sys = get_sys_channel(); $sys = get_sys_channel();
$view_channel = $sys['channel_id']; $view_channel = $sys['channel_id'];
@ -490,7 +493,7 @@ class Apps
foreach ($papp as $k => $v) { foreach ($papp as $k => $v) {
if (strpos($v, 'http') === 0 && $k != 'papp') { if (strpos($v, 'http') === 0 && $k != 'papp') {
if (!(local_channel() && strpos($v, z_root()) === 0)) { if (!($channel_id && strpos($v, z_root()) === 0)) {
$papp[$k] = zid($v); $papp[$k] = zid($v);
} }
} }
@ -513,17 +516,17 @@ class Apps
switch ($require) { switch ($require) {
case 'nologin': case 'nologin':
if (local_channel()) { if ($channel_id) {
return ''; return '';
} }
break; break;
case 'admin': case 'admin':
if (!is_site_admin()) { if (!(is_site_admin() || $sys_channel)) {
return ''; return '';
} }
break; break;
case 'local_channel': case 'local_channel':
if (!local_channel()) { if (!$channel_id) {
return ''; return '';
} }
break; break;
@ -538,7 +541,7 @@ class Apps
} }
break; break;
case 'custom_role': case 'custom_role':
if (get_pconfig(local_channel(), 'system', 'permissions_role') != 'custom') { if (get_pconfig($channel_id, 'system', 'permissions_role') != 'custom') {
return ''; return '';
} }
break; break;
@ -552,7 +555,7 @@ class Apps
if ($config) { if ($config) {
$unset = ((get_config('system', $require[0]) === $require[1]) ? false : true); $unset = ((get_config('system', $require[0]) === $require[1]) ? false : true);
} else { } else {
$unset = ((local_channel() && feature_enabled(local_channel(), $require)) ? false : true); $unset = (($channel_id && feature_enabled($channnel_id, $require)) ? false : true);
} }
if ($unset) { if ($unset) {
return ''; return '';
@ -565,14 +568,13 @@ class Apps
$hosturl = ''; $hosturl = '';
if (local_channel()) { if ($channel_id || $sys_channel) {
if (self::app_installed(local_channel(), $papp) && (!(isset($papp['deleted']) && intval($papp['deleted'])))) { if (self::app_installed(($sys_channel) ? 0 : $channel_id, $papp)) {
$installed = true; $installed = true;
if ($mode === 'install') { if ($mode === 'install') {
return ''; return '';
} }
} }
$hosturl = z_root() . '/'; $hosturl = z_root() . '/';
} elseif (remote_channel()) { } elseif (remote_channel()) {
$observer = App::get_observer(); $observer = App::get_observer();
@ -612,10 +614,10 @@ class Apps
'$purchase' => ((isset($papp['page']) && $papp['page'] && (!$installed)) ? t('Purchase') : ''), '$purchase' => ((isset($papp['page']) && $papp['page'] && (!$installed)) ? t('Purchase') : ''),
'$installed' => $installed, '$installed' => $installed,
'$action_label' => (($hosturl && in_array($mode, ['view', 'install'])) ? $install_action : ''), '$action_label' => (($hosturl && in_array($mode, ['view', 'install'])) ? $install_action : ''),
'$edit' => ((local_channel() && $installed && $mode === 'edit') ? t('Edit') : ''), '$edit' => (($channel_id && $installed && $mode === 'edit') ? t('Edit') : ''),
'$delete' => ((local_channel() && $installed && $mode === 'edit') ? t('Delete') : ''), '$delete' => (($channel_id && $installed && $mode === 'edit') ? t('Delete') : ''),
'$undelete' => ((local_channel() && $installed && $mode === 'edit') ? t('Undelete') : ''), '$undelete' => (($channel_id && $installed && $mode === 'edit') ? t('Undelete') : ''),
'$settings_url' => ((local_channel() && $installed && $mode === 'list' && isset($papp['settings_url'])) ? $papp['settings_url'] : ''), '$settings_url' => (($channel_id && $installed && $mode === 'list' && isset($papp['settings_url'])) ? $papp['settings_url'] : ''),
'$deleted' => ((isset($papp['deleted'])) ? intval($papp['deleted']) : false), '$deleted' => ((isset($papp['deleted'])) ? intval($papp['deleted']) : false),
'$feature' => (((isset($papp['embed']) && $papp['embed']) || $mode === 'edit') ? false : true), '$feature' => (((isset($papp['embed']) && $papp['embed']) || $mode === 'edit') ? false : true),
'$pin' => (((isset($papp['embed']) && $papp['embed']) || $mode === 'edit') ? false : true), '$pin' => (((isset($papp['embed']) && $papp['embed']) || $mode === 'edit') ? false : true),
@ -649,6 +651,16 @@ class Apps
$app['uid'] = $uid; $app['uid'] = $uid;
if (self::app_installed($uid, $app, true)) { if (self::app_installed($uid, $app, true)) {
// preserve the existing deleted status across app updates
if (isset($app['guid'])) {
$check = q("select * from app where app_id = '%s' and app_channel = %d",
dbesc($app['guid']),
intval($uid)
);
if ($check) {
$app['deleted'] = intval($check[0]['app_deleted']);
}
}
$x = self::app_update($app); $x = self::app_update($app);
} else { } else {
$x = self::app_store($app); $x = self::app_store($app);
@ -684,6 +696,8 @@ class Apps
public static function can_delete($uid, $app) public static function can_delete($uid, $app)
{ {
// $uid 0 cannot delete, only archive
if (!$uid) { if (!$uid) {
return false; return false;
} }
@ -703,11 +717,11 @@ class Apps
public static function app_destroy($uid, $app) public static function app_destroy($uid, $app)
{ {
if ($uid && $app['guid']) { if ($app['guid']) {
$x = q( $x = q(
"select * from app where app_id = '%s' and app_channel = %d limit 1", "select * from app where app_id = '%s' and app_channel = %d limit 1",
dbesc($app['guid']), dbesc($app['guid']),
intval($uid) intval($target_uid)
); );
if ($x) { if ($x) {
if (!intval($x[0]['app_deleted'])) { if (!intval($x[0]['app_deleted'])) {
@ -728,14 +742,16 @@ class Apps
$r = q( $r = q(
"update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", "update app set app_deleted = 1 where app_id = '%s' and app_channel = %d",
dbesc($app['guid']), dbesc($app['guid']),
intval($uid) intval($target_uid)
); );
} }
if (intval($x[0]['app_system'])) { if ($uid) {
Libsync::build_sync_packet($uid, array('sysapp' => $x)); if (intval($x[0]['app_system'])) {
} else { Libsync::build_sync_packet($uid, array('sysapp' => $x));
Libsync::build_sync_packet($uid, array('app' => $x)); } else {
} Libsync::build_sync_packet($uid, array('app' => $x));
}
}
} else { } else {
self::app_undestroy($uid, $app); self::app_undestroy($uid, $app);
} }
@ -748,7 +764,7 @@ class Apps
// undelete a system app // undelete a system app
if ($uid && $app['guid']) { if ($app['guid']) {
$x = q( $x = q(
"select * from app where app_id = '%s' and app_channel = %d limit 1", "select * from app where app_id = '%s' and app_channel = %d limit 1",
dbesc($app['guid']), dbesc($app['guid']),
@ -795,7 +811,6 @@ class Apps
public static function app_installed($uid, $app, $bypass_filter = false) public static function app_installed($uid, $app, $bypass_filter = false)
{ {
$r = q( $r = q(
"select id from app where app_id = '%s' and app_channel = %d limit 1", "select id from app where app_id = '%s' and app_channel = %d limit 1",
dbesc((array_key_exists('guid', $app)) ? $app['guid'] : ''), dbesc((array_key_exists('guid', $app)) ? $app['guid'] : ''),

View file

@ -280,6 +280,23 @@ class Libprofile
*/ */
call_hooks('profile_sidebar_enter', $profile); call_hooks('profile_sidebar_enter', $profile);
$profdm = EMPTY_STR;
$profdm_url = EMPTY_STR;
$can_dm = perm_is_allowed($profile['uid'], (is_array($observer)) ? $observer['xchan_hash'] : EMPTY_STR, 'post_mail') && intval($observer['xchan_type']) !== XCHAN_TYPE_GROUP ;
if ($can_dm) {
$dm_path = Libzot::get_rpost_path($observer);
if ($dm_path) {
$profdm = t('Direct Message');
$profdm_url = $dm_path
. '&to='
. urlencode($profile['channel_hash'])
. '&body='
. urlencode('@!{' . $profile['channel_address'] . '@' . App::get_hostname() . '}');
}
}
if ($show_connect) { if ($show_connect) {
// This will return an empty string if we're already connected. // This will return an empty string if we're already connected.
@ -364,7 +381,9 @@ class Libprofile
'$profile' => $profile, '$profile' => $profile,
'$connect' => $connect, '$connect' => $connect,
'$connect_url' => $connect_url, '$connect_url' => $connect_url,
'$location' => $location, '$profdm' => $profdm,
'$profdm_url' => $profdm_url,
'$location' => $location,
'$gender' => $gender, '$gender' => $gender,
'$pronouns' => $pronouns, '$pronouns' => $pronouns,
'$pdesc' => $pdesc, '$pdesc' => $pdesc,

View file

@ -801,13 +801,14 @@ class Libzot
$deleted_changed = 1; $deleted_changed = 1;
} }
if ($arr['channel_type'] === 'collection') { $px = 0;
$px = 2; if (isset($arr['channel_type'])) {
} elseif ($arr['channel_type'] === 'group') { if ($arr['channel_type'] === 'collection') {
$px = 1; $px = 2;
} else { } elseif ($arr['channel_type'] === 'group') {
$px = 0; $px = 1;
} }
}
if (array_key_exists('public_forum', $arr) && intval($arr['public_forum'])) { if (array_key_exists('public_forum', $arr) && intval($arr['public_forum'])) {
$px = 1; $px = 1;
} }
@ -1451,17 +1452,16 @@ class Libzot
$arr['item_verified'] = true; $arr['item_verified'] = true;
if (!array_key_exists('comment_policy', $arr)) { if (!array_key_exists('comment_policy', $arr)) {
// set comment policy depending on source hub. Unknown or osada is ActivityPub. // set comment policy based on type of site.
// Anything else we'll say is zot - which could have a range of project names
$s = q( $s = q(
"select site_project from site where site_url = '%s' limit 1", "select site_type from site where site_url = '%s' limit 1",
dbesc($r[0]['hubloc_url']) dbesc($r[0]['hubloc_url'])
); );
if ((!$s) || (in_array($s[0]['site_project'], ['', 'osada']))) { if ($s && intval($s[0]['site_type']) === SITE_TYPE_ZOT) {
$arr['comment_policy'] = 'authenticated';
} else {
$arr['comment_policy'] = 'contacts'; $arr['comment_policy'] = 'contacts';
} else {
$arr['comment_policy'] = 'authenticated';
} }
} }
} }
@ -3020,9 +3020,11 @@ class Libzot
return EMPTY_STR; return EMPTY_STR;
} }
$parsed = parse_url($observer['xchan_url']); if ($observer['xchan_network'] === 'zot6') {
$parsed = parse_url($observer['xchan_url']);
return $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '') . '/rpost?f='; return $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '') . '/rpost?f=';
}
return EMPTY_STR;
} }
/** /**
@ -3587,7 +3589,7 @@ class Libzot
public static function is_zot_request() public static function is_zot_request()
{ {
$x = getBestSupportedMimeType(['application/x-zot+json', 'application/x-nomad']); $x = getBestSupportedMimeType(['application/x-zot+json', 'application/x-nomad+json']);
return (($x) ? true : false); return (($x) ? true : false);
} }

View file

@ -297,7 +297,11 @@ class Libzotdir
$arr = []; $arr = [];
$arr['xprof_hash'] = $hash; $arr['xprof_hash'] = $hash;
$arr['xprof_dob'] = ((isset($profile['birthday']) && $profile['birthday'] === '0000-00-00') ? $profile['birthday'] : datetime_convert('', '', $profile['birthday'], 'Y-m-d')); // !!!! check this for 0000 year if (isset($profile['birthday'])) {
$arr['xprof_dob'] = (($profile['birthday'] === '0000-00-00')
? $profile['birthday']
: datetime_convert('', '', $profile['birthday'], 'Y-m-d')); // !!!! check this for 0000 year
}
$arr['xprof_age'] = (isset($profile['age']) ? intval($profile['age']) : 0); $arr['xprof_age'] = (isset($profile['age']) ? intval($profile['age']) : 0);
$arr['xprof_desc'] = ((isset($profile['description']) && $profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT, 'UTF-8', false) : ''); $arr['xprof_desc'] = ((isset($profile['description']) && $profile['description']) ? htmlspecialchars($profile['description'], ENT_COMPAT, 'UTF-8', false) : '');
$arr['xprof_gender'] = ((isset($profile['gender']) && $profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT, 'UTF-8', false) : ''); $arr['xprof_gender'] = ((isset($profile['gender']) && $profile['gender']) ? htmlspecialchars($profile['gender'], ENT_COMPAT, 'UTF-8', false) : '');

View file

@ -113,12 +113,15 @@ class ThreadItem
$conv = $this->get_conversation(); $conv = $this->get_conversation();
$observer = $conv->get_observer(); $observer = $conv->get_observer();
$lock = (((intval($item['item_private'])) || (($item['uid'] == local_channel()) && (strlen($item['allow_cid']) || strlen($item['allow_gid']) $lock = t('Public visibility');
|| strlen($item['deny_cid']) || strlen($item['deny_gid'])))) if (intval($item['item_private']) === 2) {
? t('Private Message') $lock = t('Direct message (private mail)');
: false); }
if (intval($item['item_private']) === 1) {
$lock = t('Restricted visibility');
}
$locktype = $item['item_private']; $locktype = intval($item['item_private']);
$shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && (! intval($item['item_private']))) ? true : false); $shareable = ((($conv->get_profile_owner() == local_channel() && local_channel()) && (! intval($item['item_private']))) ? true : false);

View file

@ -12,9 +12,13 @@ class Appman extends Controller
public function post() public function post()
{ {
if (!local_channel()) { $channel_id = local_channel();
if (! $channel_id) {
return; return;
} }
if (is_sys_channel($channel_id)) {
$channel_id = 0;
}
if ($_POST['url']) { if ($_POST['url']) {
$arr = [ $arr = [
@ -36,9 +40,9 @@ class Appman extends Controller
'categories' => escape_tags($_REQUEST['categories']) 'categories' => escape_tags($_REQUEST['categories'])
]; ];
$_REQUEST['appid'] = Apps::app_install(local_channel(), $arr); $_REQUEST['appid'] = Apps::app_install($channel_id, $arr);
if (Apps::app_installed(local_channel(), $arr)) { if (Apps::app_installed($channel_id, $arr)) {
info(t('App installed.') . EOL); info(t('App installed.') . EOL);
} }
@ -54,14 +58,14 @@ class Appman extends Controller
} }
if ($_POST['install']) { if ($_POST['install']) {
Apps::app_install(local_channel(), $papp); Apps::app_install($channel_id, $papp);
if (Apps::app_installed(local_channel(), $papp)) { if (Apps::app_installed($channel_id, $papp)) {
info(t('App installed.') . EOL); info(t('App installed.') . EOL);
} }
} }
if ($_POST['delete']) { if ($_POST['delete']) {
Apps::app_destroy(local_channel(), $papp); Apps::app_destroy($channel_id, $papp);
} }
if ($_POST['edit']) { if ($_POST['edit']) {
@ -69,11 +73,11 @@ class Appman extends Controller
} }
if ($_POST['feature']) { if ($_POST['feature']) {
Apps::app_feature(local_channel(), $papp, $_POST['feature']); Apps::app_feature($channel_id, $papp, $_POST['feature']);
} }
if ($_POST['pin']) { if ($_POST['pin']) {
Apps::app_feature(local_channel(), $papp, $_POST['pin']); Apps::app_feature($channel_id, $papp, $_POST['pin']);
} }
if ($_SESSION['return_url']) { if ($_SESSION['return_url']) {
@ -87,19 +91,25 @@ class Appman extends Controller
public function get() public function get()
{ {
if (!local_channel()) { $channel_id = local_channel();
if (!$channel_id) {
notice(t('Permission denied.') . EOL); notice(t('Permission denied.') . EOL);
return; return;
} }
if (is_sys_channel($channel_id)) {
$channel_id = 0;
}
$channel = App::get_channel(); $channel = App::get_channel();
if (argc() > 3) { if (argc() > 3) {
if (argv(2) === 'moveup') { if (argv(2) === 'moveup') {
Apps::moveup(local_channel(), argv(1), argv(3)); Apps::moveup($channel_id, argv(1), argv(3));
} }
if (argv(2) === 'movedown') { if (argv(2) === 'movedown') {
Apps::movedown(local_channel(), argv(1), argv(3)); Apps::movedown($channel_id, argv(1), argv(3));
} }
goaway(z_root() . '/apporder'); goaway(z_root() . '/apporder');
} }
@ -110,7 +120,7 @@ class Appman extends Controller
$r = q( $r = q(
"select * from app where app_id = '%s' and app_channel = %d limit 1", "select * from app where app_id = '%s' and app_channel = %d limit 1",
dbesc($_REQUEST['appid']), dbesc($_REQUEST['appid']),
dbesc(local_channel()) dbesc($channel_id)
); );
if ($r) { if ($r) {
$app = $r[0]; $app = $r[0];
@ -119,7 +129,7 @@ class Appman extends Controller
"select * from term where otype = %d and oid = %d and uid = %d", "select * from term where otype = %d and oid = %d and uid = %d",
intval(TERM_OBJ_APP), intval(TERM_OBJ_APP),
intval($r[0]['id']), intval($r[0]['id']),
intval(local_channel()) intval($channel_id)
); );
if ($term) { if ($term) {
$app['categories'] = array_elm_to_str($term, 'term'); $app['categories'] = array_elm_to_str($term, 'term');

View file

@ -30,7 +30,7 @@ class Apps extends Controller
Zlib\Apps::import_system_apps(); Zlib\Apps::import_system_apps();
$syslist = []; $syslist = [];
$cat = ((array_key_exists('cat', $_GET) && $_GET['cat']) ? [escape_tags($_GET['cat'])] : ''); $cat = ((array_key_exists('cat', $_GET) && $_GET['cat']) ? [escape_tags($_GET['cat'])] : '');
$list = Zlib\Apps::app_list((($available) ? 0 : local_channel()), (($mode == 'edit') ? true : false), $cat); $list = Zlib\Apps::app_list(($available || is_sys_channel(local_channel()) ? 0 : local_channel()), (($mode == 'edit') ? true : false), $cat);
if ($list) { if ($list) {
foreach ($list as $x) { foreach ($list as $x) {
$syslist[] = Zlib\Apps::app_encode($x); $syslist[] = Zlib\Apps::app_encode($x);
@ -48,7 +48,7 @@ class Apps extends Controller
foreach ($syslist as $app) { foreach ($syslist as $app) {
$apps[] = Zlib\Apps::app_render($app, (($available) ? 'install' : $mode)); $apps[] = Zlib\Apps::app_render($app, (($available) ? 'install' : $mode));
} }
return replace_macros(get_markup_template('myapps.tpl'), array( return replace_macros(get_markup_template('myapps.tpl'), array(
'$sitename' => get_config('system', 'sitename'), '$sitename' => get_config('system', 'sitename'),
'$cat' => $cat, '$cat' => $cat,

View file

@ -185,7 +185,7 @@ class Directory extends Controller
$directory_admin = false; $directory_admin = false;
$url = z_root() . '/dirsearch'; $url = z_root() . '/dirsearch';
if (is_site_admin()) { if (is_sys_channel(local_channel())) {
$directory_admin = true; $directory_admin = true;
} }

View file

@ -13,7 +13,8 @@ use Zotlabs\Lib\Libprofile;
class Followers extends Controller class Followers extends Controller
{ {
private $results = [];
public function init() public function init()
{ {
@ -30,10 +31,6 @@ class Followers extends Controller
http_status_exit(404, 'Not found'); http_status_exit(404, 'Not found');
} }
// if (intval($channel['channel_system'])) {
// http_status_exit(403,'Permission denied');
// }
Libprofile::load(argv(1)); Libprofile::load(argv(1));
$observer_hash = get_observer_hash(); $observer_hash = get_observer_hash();
@ -69,11 +66,26 @@ class Followers extends Controller
dbesc($channel['channel_hash']) dbesc($channel['channel_hash'])
); );
$ret = Activity::encode_follow_collection($r, App::$query_string, 'OrderedCollection', $t[0]['total']); $this->results = $r;
$ret = Activity::encode_follow_collection($r, App::$query_string, 'OrderedCollection', $t[0]['total']);
} }
if (ActivityStreams::is_as_request()) { if (ActivityStreams::is_as_request()) {
as_return_and_die($ret, $channel); as_return_and_die($ret, $channel);
} }
} }
function get() {
if ($this->results) {
foreach ($this->results as $member) {
$members[] = micropro($member, true, 'mpgroup', 'card');
}
}
$o = replace_macros(get_markup_template('listmembers.tpl'), [
'$title' => t('List members'),
'$members' => $members
]);
return $o;
}
} }

View file

@ -13,6 +13,8 @@ use Zotlabs\Lib\Libprofile;
class Following extends Controller class Following extends Controller
{ {
private $results = [];
public function init() public function init()
{ {
@ -29,10 +31,6 @@ class Following extends Controller
http_status_exit(404, 'Not found'); http_status_exit(404, 'Not found');
} }
// if (intval($channel['channel_system'])) {
// http_status_exit(403,'Permission denied');
// }
Libprofile::load(argv(1)); Libprofile::load(argv(1));
$observer_hash = get_observer_hash(); $observer_hash = get_observer_hash();
@ -69,6 +67,8 @@ class Following extends Controller
dbesc($channel['channel_hash']) dbesc($channel['channel_hash'])
); );
$this->results = $r;
$ret = Activity::encode_follow_collection($r, App::$query_string, 'OrderedCollection', $t[0]['total']); $ret = Activity::encode_follow_collection($r, App::$query_string, 'OrderedCollection', $t[0]['total']);
} }
@ -76,4 +76,19 @@ class Following extends Controller
as_return_and_die($ret, $channel); as_return_and_die($ret, $channel);
} }
} }
function get() {
if ($this->results) {
foreach ($this->results as $member) {
$members[] = micropro($member, true, 'mpgroup', 'card');
}
}
$o = replace_macros(get_markup_template('listmembers.tpl'), [
'$title' => t('List members'),
'$members' => $members
]);
return $o;
}
} }

View file

@ -1369,6 +1369,12 @@ class Item extends Controller
$datarray['obj']['id'] = $mid; $datarray['obj']['id'] = $mid;
} }
if ($private && !$parent) {
if ( intval($private) === 1 && (!$str_group_allow)) {
$private = 2;
}
}
$datarray['aid'] = $channel['channel_account_id']; $datarray['aid'] = $channel['channel_account_id'];
$datarray['uid'] = $profile_uid; $datarray['uid'] = $profile_uid;
$datarray['uuid'] = $uuid; $datarray['uuid'] = $uuid;

View file

@ -158,57 +158,18 @@ class Lists extends Controller
$change = false; $change = false;
logger('mod_lists: ' . App::$cmd, LOGGER_DEBUG); // logger('mod_lists: ' . App::$cmd, LOGGER_DEBUG);
if (argc() > 2 && argv(1) === 'view') {
$grp = argv(2);
if ($grp) {
$r = q(
"select * from pgrp where hash = '%s' and deleted = 0",
dbesc($grp)
);
if ($r) {
$uid = $r[0]['uid'];
if (local_channel() && local_channel() == $uid) {
goaway(z_root() . '/lists/' . $r[0]['id']);
}
if (!($r[0]['visible'] && perm_is_allowed($uid, get_observer_hash(), 'view_contacts'))) {
notice(t('Permission denied') . EOL);
return;
}
$members = [];
$memberlist = AccessList::members($uid, $r[0]['id']);
if ($memberlist) {
foreach ($memberlist as $member) {
$members[] = micropro($member, true, 'mpgroup', 'card');
}
}
$o = replace_macros(get_markup_template('listmembers.tpl'), [
'$title' => t('List members'),
'$members' => $members
]);
return $o;
} else {
notice(t('List not found') . EOL);
return;
}
}
}
if (!local_channel()) {
notice(t('Permission denied') . EOL);
return;
}
// Switch to text mode interface if we have more than 'n' contacts or group members, else loading avatars will lead to poor interactivity // Switch to text mode interface if we have more than 'n' contacts or group members, else loading avatars will lead to poor interactivity
$switchtotext = get_pconfig(local_channel(), 'system', 'listedit_image_limit', get_config('system', 'listedit_image_limit', 1000)); $switchtotext = get_pconfig(local_channel(), 'system', 'listedit_image_limit', get_config('system', 'listedit_image_limit', 1000));
if ((argc() == 1) || ((argc() == 2) && (argv(1) === 'new'))) { if ((argc() == 1) || ((argc() == 2) && (argv(1) === 'new'))) {
if (!local_channel()) {
notice(t('Permission denied') . EOL);
return;
}
$new = (((argc() == 2) && (argv(1) === 'new')) ? true : false); $new = (((argc() == 2) && (argv(1) === 'new')) ? true : false);
$groups = q( $groups = q(
@ -250,7 +211,13 @@ class Lists extends Controller
$tpl = get_markup_template('group_edit.tpl'); $tpl = get_markup_template('group_edit.tpl');
if ((argc() == 3) && (argv(1) === 'drop')) { if ((argc() == 3) && (argv(1) === 'drop')) {
check_form_security_token_redirectOnErr('/lists', 'group_drop', 't'); if (!local_channel()) {
notice(t('Permission denied') . EOL);
return;
}
check_form_security_token_redirectOnErr('/lists', 'group_drop', 't');
if (intval(argv(2))) { if (intval(argv(2))) {
$r = q( $r = q(
@ -273,6 +240,11 @@ class Lists extends Controller
if ((argc() > 2) && intval(argv(1)) && argv(2)) { if ((argc() > 2) && intval(argv(1)) && argv(2)) {
if (!local_channel()) {
notice(t('Permission denied') . EOL);
return;
}
check_form_security_token_ForbiddenOnErr('group_member_change', 't'); check_form_security_token_ForbiddenOnErr('group_member_change', 't');
$r = q( $r = q(
@ -290,31 +262,45 @@ class Lists extends Controller
if (strlen(argv(1)) <= 11 && intval(argv(1))) { if (strlen(argv(1)) <= 11 && intval(argv(1))) {
$r = q( $r = q(
"SELECT * FROM pgrp WHERE id = %d AND uid = %d AND deleted = 0 LIMIT 1", "SELECT * FROM pgrp WHERE id = %d AND deleted = 0 LIMIT 1",
intval(argv(1)), intval(argv(1))
intval(local_channel())
); );
} else { } else {
$r = q( $r = q(
"SELECT * FROM pgrp WHERE hash = '%s' AND uid = %d AND deleted = 0 LIMIT 1", "SELECT * FROM pgrp WHERE hash = '%s' AND deleted = 0 LIMIT 1",
dbesc(argv(1)), dbesc(argv(1))
intval(local_channel())
); );
} }
if (!$r) { if (! $r) {
$r = q( notice(t('Access list not found.') . EOL);
"SELECT * FROM pgrp WHERE id = %d AND deleted = 0 LIMIT 1", return;
intval(argv(1)), }
);
if ($r) { $group = array_shift($r);
notice(t('Permission denied.') . EOL); $uid = $group['uid'];
} else { $owner = (local_channel() && intval(local_channel()) === intval($group['uid']));
notice(t('Access list not found.') . EOL);
if (!$owner) {
// public view of group members if permitted
if (!($group['visible'] && perm_is_allowed($uid, get_observer_hash(), 'view_contacts'))) {
notice(t('Permission denied') . EOL);
return;
} }
goaway(z_root() . '/connections'); $members = [];
} $memberlist = AccessList::members($uid, $group['id']);
$group = $r[0];
if ($memberlist) {
foreach ($memberlist as $member) {
$members[] = micropro($member, true, 'mpgroup', 'card');
}
}
$o = replace_macros(get_markup_template('listmembers.tpl'), [
'$title' => t('List members'),
'$members' => $members
]);
return $o;
}
$members = AccessList::members(local_channel(), $group['id']); $members = AccessList::members(local_channel(), $group['id']);

View file

@ -98,11 +98,13 @@ class Lockview extends Controller
$l = array_merge($l, $recips['cc']); $l = array_merge($l, $recips['cc']);
} }
for ($x = 0; $x < count($l); $x++) { for ($x = 0; $x < count($l); $x++) {
if ($l[$x] !== ACTIVITY_PUBLIC_INBOX) { if ($l[$x] === ACTIVITY_PUBLIC_INBOX) {
$l[$x] = '<strong><em>' . t('Everybody') . '</em></strong>';
} else {
$l[$x] = '<a href="' . $l[$x] . '">' . $l[$x] . '</a>'; $l[$x] = '<a href="' . $l[$x] . '">' . $l[$x] . '</a>';
} }
} }
echo $o . implode(', ', $l); echo $o . implode('<br>', $l);
killme(); killme();
} }
} }

View file

@ -349,7 +349,7 @@ class Ping extends Controller
"SELECT * FROM item "SELECT * FROM item
WHERE uid = %d WHERE uid = %d
AND author_xchan != '%s' AND author_xchan != '%s'
AND changed > '%s' AND edited > '%s'
$seenstr $seenstr
$item_normal_moderate $item_normal_moderate
$sql_extra $sql_extra
@ -386,7 +386,7 @@ class Ping extends Controller
"SELECT * FROM item "SELECT * FROM item
WHERE uid = %d WHERE uid = %d
AND author_xchan != '%s' AND author_xchan != '%s'
AND changed > '%s' AND edited > '%s'
$seenstr $seenstr
$item_normal_moderate $item_normal_moderate
$sql_extra $sql_extra
@ -600,7 +600,7 @@ class Ping extends Controller
$loadtime = get_loadtime('stream'); $loadtime = get_loadtime('stream');
$r = q( $r = q(
"SELECT id, author_xchan FROM item "SELECT id, author_xchan FROM item
WHERE uid = %d and changed > '%s' WHERE uid = %d and edited > '%s'
$seenstr $seenstr
$item_normal $item_normal
$sql_extra ", $sql_extra ",
@ -629,7 +629,7 @@ class Ping extends Controller
$loadtime = get_loadtime('channel'); $loadtime = get_loadtime('channel');
$r = q( $r = q(
"SELECT id, author_xchan FROM item "SELECT id, author_xchan FROM item
WHERE item_wall = 1 and uid = %d and changed > '%s' WHERE item_wall = 1 and uid = %d and edited > '%s'
$seenstr $seenstr
$item_normal $item_normal
$sql_extra ", $sql_extra ",

View file

@ -42,10 +42,6 @@ class Rpost extends Controller
if (!local_channel()) { if (!local_channel()) {
if (remote_channel()) { if (remote_channel()) {
// redirect to your own site. // redirect to your own site.
// We can only do this with a GET request so you'll need to keep the text short or risk getting truncated
// by the wretched beast called 'suhosin'. All the browsers now allow long GET requests, but suhosin
// blocks them.
$url = Libzot::get_rpost_path(App::get_observer()); $url = Libzot::get_rpost_path(App::get_observer());
// make sure we're not looping to our own hub // make sure we're not looping to our own hub
if (($url) && (!stristr($url, App::get_hostname()))) { if (($url) && (!stristr($url, App::get_hostname()))) {
@ -198,6 +194,15 @@ class Rpost extends Controller
'allow_gid' => EMPTY_STR, 'allow_gid' => EMPTY_STR,
'deny_cid' => EMPTY_STR, 'deny_cid' => EMPTY_STR,
'deny_gid' => EMPTY_STR]); 'deny_gid' => EMPTY_STR]);
if (! (isset($_REQUEST['body']) && $_REQUEST['body'])) {
$xchan = q("select * from xchan where xchan_hash = '%s'",
dbesc($_REQUEST['to'])
);
if ($xchan) {
$_REQUEST['body'] .= '@!{' . (($xchan[0]['xchan_addr']) ? $xchan[0]['xchan_addr'] : $xchan[0]['xchan_url']) . '} ' ;
}
}
} }
$channel_acl = $acl->get(); $channel_acl = $acl->get();

View file

@ -724,7 +724,7 @@ class Channel
'$desktop_notifications_request' => t('Grant permission'), '$desktop_notifications_request' => t('Grant permission'),
'$mailhost' => ['mailhost', t('Email notifications sent from (hostname)'), get_pconfig(local_channel(), 'system', 'email_notify_host', App::get_hostname()), sprintf(t('If your channel is mirrored to multiple locations, set this to your preferred location. This will prevent duplicate email notifications. Example: %s'), App::get_hostname())], '$mailhost' => ['mailhost', t('Email notifications sent from (hostname)'), get_pconfig(local_channel(), 'system', 'email_notify_host', App::get_hostname()), sprintf(t('If your channel is mirrored to multiple locations, set this to your preferred location. This will prevent duplicate email notifications. Example: %s'), App::get_hostname())],
'$always_show_in_notices' => array('always_show_in_notices', t('Show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no), '$always_show_in_notices' => array('always_show_in_notices', t('Show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no),
'$permit_all_mentions' => ['permit_all_mentions', t('Accept messages from strangers which mention me'), get_pconfig(local_channel(), 'system', 'permit_all_mentions'), t('This setting bypasses normal permissions'), $yes_no], '$permit_all_mentions' => ['permit_all_mentions', t('Accept messages from strangers which mention you'), get_pconfig(local_channel(), 'system', 'permit_all_mentions'), t('This setting bypasses normal permissions'), $yes_no],
'$followed_tags' => ['followed_tags', t('Accept messages from strangers which include any of the following hashtags'), $followed, t('comma separated, do not include the #')], '$followed_tags' => ['followed_tags', t('Accept messages from strangers which include any of the following hashtags'), $followed, t('comma separated, do not include the #')],
'$evdays' => array('evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')), '$evdays' => array('evdays', t('Notify me of events this many days in advance'), $evdays, t('Must be greater than 0')),
'$basic_addon' => $plugin['basic'], '$basic_addon' => $plugin['basic'],

View file

@ -27,7 +27,7 @@ class Tasks extends Controller
$x['html'] = ''; $x['html'] = '';
if (isset($x['tasks']) && is_array($x['tasks'])) { if (isset($x['tasks']) && is_array($x['tasks'])) {
foreach ($x['tasks'] as $y) { foreach ($x['tasks'] as $y) {
$x['html'] .= '<div class="tasklist-item"><input type="checkbox" onchange="taskComplete(' . $y['id'] . ') return false;" /> ' . $y['summary'] . '</div>'; $x['html'] .= '<div class="tasklist-item"><input type="checkbox" onchange="taskComplete(' . $y['id'] . '); return false;" /> ' . $y['summary'] . '</div>';
} }
} }
json_return_and_die($x); json_return_and_die($x);

View file

@ -891,11 +891,11 @@ class App {
// normally self::$hostname (also scheme and port) will be filled in during startup. // normally self::$hostname (also scheme and port) will be filled in during startup.
// Set it manually from $_SERVER variables only if it wasn't. // Set it manually from $_SERVER variables only if it wasn't.
if (! self::$hostname) { if (! self::$hostname) {
self::$hostname = punify(get_host()); self::$hostname = punify(get_host());
self::$scheme = 'http'; self::$scheme = 'http';
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) { if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) {
self::$scheme = 'https'; self::$scheme = 'https';
} }
@ -920,7 +920,7 @@ class App {
// Rewrite rules on the server will convert incoming paths to a request parameter. // Rewrite rules on the server will convert incoming paths to a request parameter.
// Strip this path information from our stored copy of the query_string, in case // Strip this path information from our stored copy of the query_string, in case
// we need to re-use the rest of the original query. // we need to re-use the rest of the original query.
if (isset($_SERVER['QUERY_STRING']) && substr($_SERVER['QUERY_STRING'], 0, 4) === "req=") { if (isset($_SERVER['QUERY_STRING']) && substr($_SERVER['QUERY_STRING'], 0, 4) === "req=") {
self::$query_string = str_replace(['<','>'],['&lt;','&gt;'],substr($_SERVER['QUERY_STRING'], 4)); self::$query_string = str_replace(['<','>'],['&lt;','&gt;'],substr($_SERVER['QUERY_STRING'], 4));
// removing leading '/' - maybe a nginx problem // removing leading '/' - maybe a nginx problem
@ -934,7 +934,7 @@ class App {
// Here is where start breaking out the URL path information to both route the // Here is where start breaking out the URL path information to both route the
// web request based on the leading path component, and also to use remaining // web request based on the leading path component, and also to use remaining
// path components as C-style arguments to our individual controller modules. // path components as C-style arguments to our individual controller modules.
if (isset($_GET['req'])) { if (isset($_GET['req'])) {
self::$cmd = escape_tags(trim($_GET['req'],'/\\')); self::$cmd = escape_tags(trim($_GET['req'],'/\\'));
} }
@ -1416,8 +1416,9 @@ function z_root() {
* @return string * @return string
*/ */
function absurl($path) { function absurl($path) {
if (strpos($path, '/') === 0) if (strpos($path, '/') === 0) {
return z_path() . $path; return z_path() . $path;
}
return $path; return $path;
} }
@ -2069,7 +2070,7 @@ function load_contact_links($uid) {
// logger('load_contact_links'); // logger('load_contact_links');
$r = q("SELECT abook_id, abook_flags, abook_self, abook_incl, abook_excl, abook_my_perms, abook_their_perms, xchan_hash, xchan_photo_m, xchan_name, xchan_url, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d ", $r = q("SELECT abook_id, abook_flags, abook_self, abook_incl, abook_excl, abook_my_perms, abook_their_perms, xchan_hash, xchan_photo_m, xchan_name, xchan_url, xchan_addr, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d ",
intval($uid) intval($uid)
); );
if($r) { if($r) {

View file

@ -123,7 +123,7 @@ Let's go ahead and add some code to implement our post_local hook handler.
$cities = []; $cities = [];
$zones = timezone_identifiers_list(); $zones = timezone_identifiers_list();
foreach ($zones as $zone) { foreach ($zones as $zone) {
if ((strpos($zone,'/')) &amp;&amp; (! stristr($zone,'US/')) &amp;&amp; (! stristr($zone,'Etc/'))) { if ((strpos($zone,'/')) &amp;&amp; (stristr($zone,'US/') === false) &amp;&amp; (stristr($zone,'Etc/') === false)) {
$cities[] = str_replace('_', ' ',substr($zone,strrpos($zone,'/') + 1)); $cities[] = str_replace('_', ' ',substr($zone,strrpos($zone,'/') + 1));
} }
} }

View file

@ -163,12 +163,36 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '')
: $xchan['xchan_url'] : $xchan['xchan_url']
); );
$profdm = EMPTY_STR;
$profdm_url = EMPTY_STR;
if (local_channel()) {
$can_dm = their_perms_contains(local_channel(),$xchan['xchan_hash'],'post_mail') && $xchan['xchan_type'] !== XCHAN_TYPE_GROUP;
if ($can_dm) {
$profdm = t('Direct Message');
$profdm_url = z_root() . '/rpost?f='
. '&to='
. urlencode($xchan['xchan_hash'])
. '&body='
. urlencode('@!{' . $xchan['xchan_addr'] ? $xchan['xchan_addr'] : $xchan['xchan_url'] . '}');
}
}
return replace_macros(get_markup_template('xchan_vcard.tpl'), [ return replace_macros(get_markup_template('xchan_vcard.tpl'), [
'$name' => $xchan['xchan_name'], '$name' => $xchan['xchan_name'],
'$photo' => ((is_array(App::$profile) && array_key_exists('photo', App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']), '$photo' => ((is_array(App::$profile) && array_key_exists('photo', App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']),
'$follow' => urlencode(($xchan['xchan_addr']) ? $xchan['xchan_addr'] : $xchan['xchan_url']), '$follow' => urlencode(($xchan['xchan_addr']) ? $xchan['xchan_addr'] : $xchan['xchan_url']),
'$link' => zid($xchan['xchan_url']), '$link' => zid($xchan['xchan_url']),
'$connect' => $connect, '$connect' => $connect,
'$profdm' => $profdm,
'$profdm_url' => $profdm_url,
'$newwin' => (($mode === 'chanview') ? t('New window') : EMPTY_STR), '$newwin' => (($mode === 'chanview') ? t('New window') : EMPTY_STR),
'$newtit' => t('Open the selected location in a different window or browser tab'), '$newtit' => t('Open the selected location in a different window or browser tab'),
'$url' => $url, '$url' => $url,
@ -1007,6 +1031,6 @@ function micropro($contact, $redirect = false, $class = '', $mode = false)
'$name' => $contact['xchan_name'], '$name' => $contact['xchan_name'],
'$addr' => $contact['xchan_addr'], '$addr' => $contact['xchan_addr'],
'$title' => $contact['xchan_name'] . ' [' . $contact['xchan_addr'] . ']', '$title' => $contact['xchan_name'] . ' [' . $contact['xchan_addr'] . ']',
'$network' => sprintf(t('Network: %s'), $contact['xchan_network']) '$network' => sprintf(t('Network: %s'), network_to_name($contact['xchan_network']))
)); ));
} }

View file

@ -605,10 +605,15 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
'isstarred' => ((intval($item['item_starred'])) ? true : false), 'isstarred' => ((intval($item['item_starred'])) ? true : false),
); );
$lock = (($item['item_private'] || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) $lock = t('Public visibility');
? t('Private Message') if (intval($item['item_private']) === 2) {
: false $lock = t('Direct message (private mail)');
); }
if (intval($item['item_private']) === 1) {
$lock = t('Restricted visibility');
}
$locktype = intval($item['item_private']);
$likebuttons = false; $likebuttons = false;
$shareable = false; $shareable = false;
@ -656,6 +661,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
'name' => $profile_name, 'name' => $profile_name,
'sparkle' => $sparkle, 'sparkle' => $sparkle,
'lock' => $lock, 'lock' => $lock,
'locktype' => $locktype,
'thumb' => $profile_avatar, 'thumb' => $profile_avatar,
'title' => $item['title'], 'title' => $item['title'],
'body' => $body['html'], 'body' => $body['html'],
@ -931,13 +937,15 @@ function thread_author_menu($item, $mode = '')
$can_dm = false; $can_dm = false;
if ($local_channel && $contact) { if ($local_channel && $contact) {
$can_dm = perm_is_allowed($local_channel, $item['author_xchan'], 'send_stream'); $can_dm = perm_is_allowed($local_channel, $item['author_xchan'], 'post_mail') && intval($contact['xchan_type']) !== XCHAN_TYPE_GROUP ;
} elseif ($item['author']['xchan_network'] === 'activitypub') { } elseif ($item['author']['xchan_network'] === 'activitypub') {
$can_dm = true; $can_dm = true;
} }
// if ($can_dm) { if ($can_dm) {
// $pm_url = z_root() . '/rpost?to=' . urlencode($item['author_xchan']); $pm_url = z_root()
// } . '/rpost?to='
. urlencode($item['author_xchan']);
}
if ($profile_link) { if ($profile_link) {
$menu[] = [ $menu[] = [

View file

@ -2996,7 +2996,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
} }
// is the link already in str_tags? // is the link already in str_tags?
if (! stristr($str_tags, $newtag)) { if (is_string($newtag) && ! stristr($str_tags, $newtag)) {
// append or set str_tags // append or set str_tags
if (strlen($str_tags)) { if (strlen($str_tags)) {
$str_tags .= ','; $str_tags .= ',';

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,2 @@
<?php <?php
define ( 'STD_VERSION', '21.12.04' ); define ( 'STD_VERSION', '22.01.02' );

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -454,7 +454,7 @@ footer {
margin-bottom: 0px; margin-bottom: 0px;
} }
.connect-btn-wrapper { .connect-btn-wrapper, .profdm-btn-wrapper {
margin-bottom: 10px; margin-bottom: 10px;
} }
@ -908,6 +908,12 @@ div.jGrowl div.jGrowl-notification {
} }
.dimmer {
opacity: 0.5;
filter:alpha(opacity=50);
}
.profile-match-connect { margin-top: 5px; } .profile-match-connect { margin-top: 5px; }
.reshared-content { margin-left: 20px; } .reshared-content { margin-left: 20px; }
@ -1517,6 +1523,7 @@ blockquote {
.wall-item-lock .dropdown-menu { .wall-item-lock .dropdown-menu {
min-width: 20rem; min-width: 20rem;
padding: 5px;
} }

View file

@ -56,12 +56,10 @@
{{/if}} {{/if}}
</div> </div>
</div> </div>
{{if $item.lock}}
<div class="wall-item-lock dropdown"> <div class="wall-item-lock dropdown">
<i class="fa {{if $item.locktype == 2}}fa-envelope{{else}}fa-lock{{/if}} lockview{{if $item.privacy_warning}} text-warning{{/if}}" data-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i>&nbsp; <i class="fa {{if $item.locktype == 2}}fa-envelope{{elseif $item.locktype == 1}}fa-lock dimmer{{else}}fa-globe dimmer{{/if}} lockview{{if $item.privacy_warning}} text-warning{{/if}}" data-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i>&nbsp;
<div id="panel-{{$item.id}}" class="dropdown-menu"></div> <div id="panel-{{$item.id}}" class="dropdown-menu"></div>
</div> </div>
{{/if}}
<div class="wall-item-author"> <div class="wall-item-author">
{{if $item.previewing}}<span class="preview-indicator"><i class="fa fa-eye" title="{{$item.preview_lbl}}"></i></span>&nbsp;{{/if}} {{if $item.previewing}}<span class="preview-indicator"><i class="fa fa-eye" title="{{$item.preview_lbl}}"></i></span>&nbsp;{{/if}}
<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link u-url"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" >{{$item.name}}</span></a>{{if $item.owner_url}}&nbsp;{{$item.via}}&nbsp;<a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}} <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link u-url"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" >{{$item.name}}</span></a>{{if $item.owner_url}}&nbsp;{{$item.via}}&nbsp;<a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}}

View file

@ -5,6 +5,9 @@
{{if $connect}} {{if $connect}}
<div class="connect-btn-wrapper"><a href="{{$connect_url}}" class="btn btn-block btn-success btn-sm"><i class="fa fa-plus"></i> {{$connect}}</a></div> <div class="connect-btn-wrapper"><a href="{{$connect_url}}" class="btn btn-block btn-success btn-sm"><i class="fa fa-plus"></i> {{$connect}}</a></div>
{{/if}} {{/if}}
{{if $profdm}}
<div class="profdm-btn-wrapper"><a href="{{$profdm_url}}" class="btn btn-block btn-success btn-sm"><i class="fa fa-envelope"></i> {{$profdm}}</a></div>
{{/if}}
{{if ! $zcard}} {{if ! $zcard}}
{{if $editmenu.multi}} {{if $editmenu.multi}}
<div class="dropdown float-right"> <div class="dropdown float-right">

View file

@ -37,11 +37,10 @@
{{/if}} {{/if}}
</div> </div>
</div> </div>
{{if $item.lock}}
<div class="wall-item-lock dropdown"> <div class="wall-item-lock dropdown">
<i class="fa fa-lock lockview" data-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i><ul id="panel-{{$item.id}}" class="lockview-panel dropdown-menu"></ul>&nbsp; <i class="fa {{if $item.locktype == 2}}fa-envelope{{elseif $item.locktype == 1}}fa-lock dimmer{{else}}fa-globe dimmer{{/if}} lockview{{if $item.privacy_warning}} text-warning{{/if}}" data-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i>&nbsp;
<div id="panel-{{$item.id}}" class="dropdown-menu"></div>
</div> </div>
{{/if}}
<div class="wall-item-author"> <div class="wall-item-author">
{{if $item.previewing}}<span class="preview-indicator"><i class="fa fa-eye" title="{{$item.preview_lbl}}"></i></span>&nbsp;{{/if}} {{if $item.previewing}}<span class="preview-indicator"><i class="fa fa-eye" title="{{$item.preview_lbl}}"></i></span>&nbsp;{{/if}}
<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" >{{$item.name}}</span></a>{{if $item.owner_url}}&nbsp;{{$item.via}}&nbsp;<a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}} <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" >{{$item.name}}</span></a>{{if $item.owner_url}}&nbsp;{{$item.via}}&nbsp;<a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}}

View file

@ -3,6 +3,10 @@
{{if $connect}} {{if $connect}}
<div class="connect-btn-wrapper"><a href="follow?f=&url={{$follow}}" rel="nofollow noopener" class="btn btn-block btn-success btn-sm"><i class="fa fa-plus"></i> {{$connect}}</a></div> <div class="connect-btn-wrapper"><a href="follow?f=&url={{$follow}}" rel="nofollow noopener" class="btn btn-block btn-success btn-sm"><i class="fa fa-plus"></i> {{$connect}}</a></div>
{{/if}} {{/if}}
{{if $profdm}}
<div class="profdm-btn-wrapper"><a href="{{$profdm_url}}" class="btn btn-block btn-success btn-sm"><i class="fa fa-envelope"></i> {{$profdm}}</a></div>
{{/if}}
<div class="fn p-name">{{$name}}</div> <div class="fn p-name">{{$name}}</div>
</div> </div>