From 191298ec93968c8c5804c021d320c536dac32c12 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 3 May 2016 20:37:05 -0700 Subject: [PATCH 1/7] more background work for app management - give every member a copy of all the system apps so that they can edit and delete them to taste/preference. This needs further work to pick up changes in system apps (additions, edits, deletions, etc.). Currently this is done once and never attempted again. --- Zotlabs/Module/Apps.php | 7 +++- include/apps.php | 73 +++++++++++++++++++++++++++++++++-------- include/widgets.php | 4 +-- view/tpl/app_select.tpl | 4 +-- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/Zotlabs/Module/Apps.php b/Zotlabs/Module/Apps.php index 4066966ca..ea6ab1913 100644 --- a/Zotlabs/Module/Apps.php +++ b/Zotlabs/Module/Apps.php @@ -17,16 +17,21 @@ class Apps extends \Zotlabs\Web\Controller { $apps = array(); - $syslist = get_system_apps(); if(local_channel()) { + import_system_apps(); + $syslist = array(); $list = app_list(local_channel()); if($list) { foreach($list as $x) { $syslist[] = app_encode($x); } } + translate_system_apps($syslist); } + else + $syslist = get_system_apps(true); + usort($syslist,'app_name_compare'); // logger('apps: ' . print_r($syslist,true)); diff --git a/include/apps.php b/include/apps.php index dca49a3c6..cab851b66 100644 --- a/include/apps.php +++ b/include/apps.php @@ -8,7 +8,7 @@ require_once('include/plugin.php'); require_once('include/identity.php'); -function get_system_apps() { +function get_system_apps($translate = true) { $ret = array(); if(is_dir('apps')) @@ -17,7 +17,7 @@ function get_system_apps() { $files = glob('app/*.apd'); if($files) { foreach($files as $f) { - $x = parse_app_description($f); + $x = parse_app_description($f,$translate); if($x) { $ret[] = $x; } @@ -28,7 +28,7 @@ function get_system_apps() { foreach($files as $f) { $n = basename($f,'.apd'); if(plugin_is_installed($n)) { - $x = parse_app_description($f); + $x = parse_app_description($f,$translate); if($x) { $ret[] = $x; } @@ -40,11 +40,36 @@ function get_system_apps() { } + +function import_system_apps() { + if(! local_channel()) + return; + + // Eventually we want to look at modification dates and update system apps. + + $installed = get_pconfig(local_channel(),'system','apps_installed'); + if($installed) + return; + $apps = get_system_apps(false); + if($apps) { + foreach($apps as $app) { + $app['uid'] = local_channel(); + $app['guid'] = hash('whirlpool',$app['name']); + $app['system'] = 1; + app_install(local_channel(),$app); + } + } + set_pconfig(local_channel(),'system','apps_installed',1); +} + + + + function app_name_compare($a,$b) { return strcmp($a['name'],$b['name']); } -function parse_app_description($f) { +function parse_app_description($f,$translate = true) { $ret = array(); $baseurl = z_root(); @@ -116,7 +141,8 @@ function parse_app_description($f) { } } if($ret) { - translate_system_apps($ret); + if($translate) + translate_system_apps($ret); return $ret; } return false; @@ -293,11 +319,18 @@ function app_destroy($uid,$app) { ); $x[0]['app_deleted'] = 1; - - $r = q("delete from app where app_id = '%s' and app_channel = %d", - dbesc($app['guid']), - intval($uid) - ); + if($x[0]['app_system']) { + $r = q("update app set app_deleted = 1 where app_id = '%s' and app_channel = %d", + dbesc($app['guid']), + intval($uid) + ); + } + else { + $r = q("delete from app where app_id = '%s' and app_channel = %d", + dbesc($app['guid']), + intval($uid) + ); + } build_sync_packet($uid,array('app' => $x)); } @@ -370,10 +403,12 @@ function app_store($arr) { $darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : ''); $darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : ''); $darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : ''); + $darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0); + $darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0); $created = datetime_convert(); - $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )", + $r = q("insert into app ( app_id, app_sig, app_author, app_name, app_desc, app_url, app_photo, app_version, app_channel, app_addr, app_price, app_page, app_requires, app_created, app_edited, app_system, app_deleted ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )", dbesc($darray['app_id']), dbesc($darray['app_sig']), dbesc($darray['app_author']), @@ -388,7 +423,9 @@ function app_store($arr) { dbesc($darray['app_page']), dbesc($darray['app_requires']), dbesc($created), - dbesc($created) + dbesc($created), + intval($darray['app_system']), + intval($darray['app_deleted']) ); if($r) { $ret['success'] = true; @@ -425,10 +462,12 @@ function app_update($arr) { $darray['app_price'] = ((x($arr,'price')) ? escape_tags($arr['price']) : ''); $darray['app_page'] = ((x($arr,'page')) ? escape_tags($arr['page']) : ''); $darray['app_requires'] = ((x($arr,'requires')) ? escape_tags($arr['requires']) : ''); + $darray['app_system'] = ((x($arr,'system')) ? intval($arr['system']) : 0); + $darray['app_deleted'] = ((x($arr,'deleted')) ? intval($arr['deleted']) : 0); $edited = datetime_convert(); - $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s' where app_id = '%s' and app_channel = %d", + $r = q("update app set app_sig = '%s', app_author = '%s', app_name = '%s', app_desc = '%s', app_url = '%s', app_photo = '%s', app_version = '%s', app_addr = '%s', app_price = '%s', app_page = '%s', app_requires = '%s', app_edited = '%s', app_system = %d, app_deleted = %d where app_id = '%s' and app_channel = %d", dbesc($darray['app_sig']), dbesc($darray['app_author']), dbesc($darray['app_name']), @@ -441,6 +480,8 @@ function app_update($arr) { dbesc($darray['app_page']), dbesc($darray['app_requires']), dbesc($edited), + intval($darray['app_system']), + intval($darray['app_deleted']), dbesc($darray['app_id']), intval($darray['app_channel']) ); @@ -499,6 +540,12 @@ function app_encode($app,$embed = false) { if($app['app_requires']) $ret['requires'] = $app['app_requires']; + if($app['app_system']) + $ret['system'] = $app['app_system']; + + if($app['app_deleted']) + $ret['deleted'] = $app['app_deleted']; + if(! $embed) return $ret; diff --git a/include/widgets.php b/include/widgets.php index fa92901ae..1b9d3c07a 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -103,8 +103,8 @@ function widget_appselect($arr) { '$system' => t('System'), '$authed' => ((local_channel()) ? true : false), '$personal' => t('Personal'), - '$new' => t('Create Personal App'), - '$edit' => t('Edit Personal App') + '$new' => t('New App'), + '$edit' => t('Edit App') )); } diff --git a/view/tpl/app_select.tpl b/view/tpl/app_select.tpl index 527d01eae..93049d522 100644 --- a/view/tpl/app_select.tpl +++ b/view/tpl/app_select.tpl @@ -2,8 +2,8 @@

{{$title}}

{{/if}} From 1685548a4cff333b2f923960f33a7f87394afcc5 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 3 May 2016 21:59:26 -0700 Subject: [PATCH 2/7] ensure that important system fields are passed through the appman editor --- Zotlabs/Module/Appman.php | 6 +++++- view/tpl/app_create.tpl | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Zotlabs/Module/Appman.php b/Zotlabs/Module/Appman.php index 96e4cdd87..b0dd887f4 100644 --- a/Zotlabs/Module/Appman.php +++ b/Zotlabs/Module/Appman.php @@ -23,6 +23,8 @@ class Appman extends \Zotlabs\Web\Controller { 'photo' => escape_tags($_REQUEST['photo']), 'version' => escape_tags($_REQUEST['version']), 'price' => escape_tags($_REQUEST['price']), + 'requires' => escape_tags($_REQUEST['requires']), + 'system' => intval($_REQUEST['system']), 'sig' => escape_tags($_REQUEST['sig']) ); @@ -64,7 +66,7 @@ class Appman extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(! local_channel()) { notice( t('Permission denied.') . EOL); @@ -99,6 +101,8 @@ class Appman extends \Zotlabs\Web\Controller { '$version' => array('version', t('Version ID'),(($app) ? $app['app_version'] : ''), ''), '$price' => array('price', t('Price of app'),(($app) ? $app['app_price'] : ''), ''), '$page' => array('page', t('Location (URL) to purchase app'),(($app) ? $app['app_page'] : ''), ''), + '$system' => (($app) ? intval($app['app_system']) : 0), + '$requires' => (($app) ? $app['app_requires'] : ''), '$embed' => $embed, '$submit' => t('Submit') )); diff --git a/view/tpl/app_create.tpl b/view/tpl/app_create.tpl index ff28e0598..0590e7031 100644 --- a/view/tpl/app_create.tpl +++ b/view/tpl/app_create.tpl @@ -12,6 +12,10 @@ {{/if}} + + + + {{include file="field_input.tpl" field=$name}} {{include file="field_input.tpl" field=$url}} {{include file="field_textarea.tpl" field=$desc}} From 7c57da3a28ceda8eb5622ffedd0a20bba742e96a Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 3 May 2016 22:12:09 -0700 Subject: [PATCH 3/7] Sync the current list of system apps with the built-in name translation table. Some of the names were changed in the past without the translation table being updated to reflect it. --- app/bookmarks.apd | 2 +- app/chat.apd | 2 +- app/probe.apd | 2 +- app/profile.apd | 2 +- app/suggest.apd | 2 +- include/apps.php | 11 ++++++++--- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/bookmarks.apd b/app/bookmarks.apd index 9581a220c..2a04d9bf3 100644 --- a/app/bookmarks.apd +++ b/app/bookmarks.apd @@ -1,4 +1,4 @@ url: $baseurl/bookmarks requires: local_channel -name: View bookmarks +name: View Bookmarks photo: $baseurl/app/bookmarks.png diff --git a/app/chat.apd b/app/chat.apd index d4879c0b7..7ba1cd2c8 100644 --- a/app/chat.apd +++ b/app/chat.apd @@ -1,4 +1,4 @@ url: $baseurl/chat/$nick requires: local_channel -name: My chatrooms +name: My Chatrooms photo: $baseurl/app/chat.png diff --git a/app/probe.apd b/app/probe.apd index e1ab5fc43..910e628ba 100644 --- a/app/probe.apd +++ b/app/probe.apd @@ -1,4 +1,4 @@ url: $baseurl/probe requires: local_channel -name: Remote diagnostics +name: Remote Diagnostics photo: $baseurl/app/probe.png diff --git a/app/profile.apd b/app/profile.apd index d353d5742..48e5d5814 100644 --- a/app/profile.apd +++ b/app/profile.apd @@ -1,4 +1,4 @@ url: $baseurl/profile/$nick requires: local_channel -name: View profile +name: View Profile photo: $baseurl/app/profile.png diff --git a/app/suggest.apd b/app/suggest.apd index f3d17e0ea..cd94a6d1f 100644 --- a/app/suggest.apd +++ b/app/suggest.apd @@ -1,4 +1,4 @@ url: $baseurl/suggest requires: local_channel -name: Suggest channels +name: Suggest Channels photo: $baseurl/app/suggest.png diff --git a/include/apps.php b/include/apps.php index cab851b66..30fed361d 100644 --- a/include/apps.php +++ b/include/apps.php @@ -152,8 +152,13 @@ function parse_app_description($f,$translate = true) { function translate_system_apps(&$arr) { $apps = array( 'Site Admin' => t('Site Admin'), - 'Bookmarks' => t('Bookmarks'), - 'Address Book' => t('Address Book'), + 'Bug Report' => t('Bug Report'), + 'View Bookmarks' => t('View Bookmarks'), + 'My Chatrooms' => t('My Chatrooms'), + 'Connections' => t('Connections'), + 'Firefox Share' => t('Firefox Share'), + 'Remote Diagnostics' => t('Remote Diagnostics'), + 'Suggest Channels' => t('Suggest Channels'), 'Login' => t('Login'), 'Channel Manager' => t('Channel Manager'), 'Grid' => t('Grid'), @@ -161,7 +166,7 @@ function translate_system_apps(&$arr) { 'Files' => t('Files'), 'Webpages' => t('Webpages'), 'Channel Home' => t('Channel Home'), - 'Profile' => t('Profile'), + 'View Profile' => t('View Profile'), 'Photos' => t('Photos'), 'Events' => t('Events'), 'Directory' => t('Directory'), From 0db8d3f6c6dcf72aa90a9cbf45708882c90e0402 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 4 May 2016 11:49:29 +0200 Subject: [PATCH 4/7] whitespace --- Zotlabs/Module/Editblock.php | 74 +++++++++++++++++------------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index 2821b3fe0..b13ab22f3 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -4,46 +4,43 @@ namespace Zotlabs\Module; require_once('include/identity.php'); require_once('include/acl_selectors.php'); - class Editblock extends \Zotlabs\Web\Controller { function init() { - + if(argc() > 1 && argv(1) === 'sys' && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { \App::$is_sys = true; } } - + if(argc() > 1) $which = argv(1); else return; - + profile_load($a,$which); - + } - - - - function get() { - + + function get() { + if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); \App::$error = 404; return; } - + $which = argv(1); - + $uid = local_channel(); $owner = 0; $channel = null; $observer = \App::get_observer(); - + $channel = \App::get_channel(); - + if(\App::$is_sys && is_site_admin()) { $sys = get_sys_channel(); if($sys && intval($sys['channel_id'])) { @@ -52,7 +49,7 @@ class Editblock extends \Zotlabs\Web\Controller { $observer = $sys; } } - + if(! $owner) { // Figure out who the page owner is. $r = q("select channel_id from channel where channel_address = '%s'", @@ -62,27 +59,26 @@ class Editblock extends \Zotlabs\Web\Controller { $owner = intval($r[0]['channel_id']); } } - + $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - + if(! perm_is_allowed($owner,$ob_hash,'write_pages')) { notice( t('Permission denied.') . EOL); return; } - + $is_owner = (($uid && $uid == $owner) ? true : false); - + $o = ''; - + // Figure out which post we're editing $post_id = ((argc() > 2) ? intval(argv(2)) : 0); - - + if(! ($post_id && $owner)) { notice( t('Item not found') . EOL); return; } - + $itm = q("SELECT * FROM `item` WHERE `id` = %d and uid = %s LIMIT 1", intval($post_id), intval($owner) @@ -98,20 +94,20 @@ class Editblock extends \Zotlabs\Web\Controller { notice( t('Item not found') . EOL); return; } - + $plaintext = true; - + $mimeselect = ''; $mimetype = $itm[0]['mimetype']; - + if($mimetype != 'text/bbcode') $plaintext = true; - + if(get_config('system','page_mimetype')) $mimeselect = ''; else $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); - + \App::$page['htmlhead'] .= replace_macros(get_markup_template('jot-header.tpl'), array( '$baseurl' => z_root(), '$editselect' => (($plaintext) ? 'none' : '/(profile-jot-text|prvmail-text)/'), @@ -122,17 +118,17 @@ class Editblock extends \Zotlabs\Web\Controller { '$confirmdelete' => t('Delete block?'), '$bbco_autocomplete'=> (($mimetype == 'text/bbcode') ? 'bbcode' : 'comanche-block') )); - + $tpl = get_markup_template("jot.tpl"); - + $jotplugins = ''; $jotnets = ''; - + call_hooks('jot_tool', $jotplugins); call_hooks('jot_networks', $jotnets); - + $rp = 'blocks/' . $channel['channel_address']; - + $editor = replace_macros($tpl,array( '$return_path' => $rp, '$action' => 'item', @@ -174,18 +170,16 @@ class Editblock extends \Zotlabs\Web\Controller { '$defexpire' => '', '$bbcode' => (($mimetype == 'text/bbcode') ? true : false) )); - + $o .= replace_macros(get_markup_template('edpost_head.tpl'), array( '$title' => t('Edit Block'), '$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false), '$id' => $itm[0]['id'], '$editor' => $editor )); - + return $o; - + } - - - -} + +} \ No newline at end of file From 9fe33bb67df2f9cea25e3815ddfe503dfabb3fd6 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 4 May 2016 11:53:38 +0200 Subject: [PATCH 5/7] whitespace --- Zotlabs/Module/Editblock.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php index b13ab22f3..0204d0994 100644 --- a/Zotlabs/Module/Editblock.php +++ b/Zotlabs/Module/Editblock.php @@ -24,7 +24,7 @@ class Editblock extends \Zotlabs\Web\Controller { } - function get() { + function get() { if(! \App::$profile) { notice( t('Requested profile is not available.') . EOL ); @@ -104,7 +104,7 @@ class Editblock extends \Zotlabs\Web\Controller { $plaintext = true; if(get_config('system','page_mimetype')) - $mimeselect = ''; + $mimeselect = ''; else $mimeselect = mimetype_select($itm[0]['uid'],$mimetype); @@ -182,4 +182,4 @@ class Editblock extends \Zotlabs\Web\Controller { } -} \ No newline at end of file +} From 33a8d845c12a9a6394a5fb8fa8edd851126e19e2 Mon Sep 17 00:00:00 2001 From: Treer Date: Wed, 4 May 2016 23:55:32 +1000 Subject: [PATCH 6/7] Refine permissions dialog UI --- Zotlabs/Module/Channel.php | 10 +++++- Zotlabs/Module/Network.php | 12 +++++-- include/acl_selectors.php | 27 ++++++++++++--- view/js/acl.js | 37 ++++++++++++++++---- view/theme/redbasic/css/style.css | 57 +++++++++++++++++++++++++++---- view/tpl/acl_selector.tpl | 27 ++++++++++++--- 6 files changed, 145 insertions(+), 25 deletions(-) diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index 36f13e775..ee7140475 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -126,13 +126,21 @@ function get($update = 0, $load = false) { if($perms['post_wall']) { + // I'm trying to make two points in this description text - warn about finality of wall + // post permissions, and try to clear up confusion that these permissions set who is + // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking + // the "Show" button on a group does not post it to the feed of people in that group, it + // mearly allows those people to view the post if they are viewing/following this channel. + $aclDesc = t('Post permissions cannot be changed after a post is sent.
These permissions set who is allowed to view the post.'); + $aclContextHelpCmd = ''; + $x = array( 'is_owner' => $is_owner, 'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false), 'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''), 'nickname' => \App::$profile['channel_address'], 'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'), - 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')) : ''), + 'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd) : ''), 'showacl' => (($is_owner) ? 'yes' : ''), 'bang' => '', 'visitor' => (($is_owner || $observer) ? true : false), diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 77353da05..a6b36ad3c 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -154,6 +154,14 @@ class Network extends \Zotlabs\Web\Controller { } nav_set_selected('network'); + + // I'm trying to make two points in this description text - warn about finality of wall + // post permissions, and try to clear up confusion that these permissions set who is + // *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking + // the "Show" button on a group does not post it to the feed of people in that group, it + // mearly allows those people to view the post if they are viewing/following this channel. + $aclDesc = t('Post permissions cannot be changed after a post is sent.
These permissions set who is allowed to view the post.'); + $aclContextHelpCmd = ''; $channel_acl = array( 'allow_cid' => $channel['channel_allow_cid'], @@ -161,7 +169,7 @@ class Network extends \Zotlabs\Web\Controller { 'deny_cid' => $channel['channel_deny_cid'], 'deny_gid' => $channel['channel_deny_gid'] ); - + $private_editing = ((($group || $cid) && (! intval($_GET['pf']))) ? true : false); $x = array( @@ -170,7 +178,7 @@ class Network extends \Zotlabs\Web\Controller { 'default_location' => $channel['channel_location'], 'nickname' => $channel['channel_address'], 'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'), - 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')), + 'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd), 'bang' => (($private_editing) ? '!' : ''), 'visitor' => true, 'profile_uid' => local_channel(), diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 92f9436a2..c22055848 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -210,12 +210,24 @@ function fixacl(&$item) { $item = str_replace(array('<','>'),array('',''),$item); } -function populate_acl($defaults = null,$show_jotnets = true, $showall = '') { +/** +* Builds a modal dialog for editing permissions, using acl_selector.tpl as the template. +* +* @param array $default Optional access control list for the initial state of the dialog. +* @param boolean $show_jotnets Whether plugins for federated networks should be included in the permissions dialog +* @param string $showall_caption An optional caption to describe the scope of an unrestricted post. e.g. "Public" +* @param string $dialog_description Optional message to include at the top of the dialog. E.g. "Warning: Post permissions cannot be changed once sent". +* @param string $context_help Allows the dialog to present a context sensitive help icon. E.g. "photos/permissions" +* @param boolean $readonly Not implemented yet. When implemented, the dialog will use acl_readonly.tpl instead, so that permissions may be viewed for posts that can no longer have their permissions changed. +* +* @return string html modal dialog build from acl_selector.tpl +*/ +function populate_acl($defaults = null,$show_jotnets = true, $showall_caption = '', $dialog_description = '', $context_help = '', $readonly = false) { $allow_cid = $allow_gid = $deny_cid = $deny_gid = false; - if(! $showall) - $showall = t('Visible to your default audience'); + if(! $showall_caption) + $showall_caption = t('Visible to your default audience'); if(is_array($defaults)) { $allow_cid = ((strlen($defaults['allow_cid'])) @@ -239,9 +251,12 @@ function populate_acl($defaults = null,$show_jotnets = true, $showall = '') { $tpl = get_markup_template("acl_selector.tpl"); $o = replace_macros($tpl, array( - '$showall' => $showall, + '$showall' => $showall_caption, + '$showlimited' => t("Limit access:"), + '$showlimitedDesc' => t('Select "Show" to allow access. "Don\'t show" lets you override and limit the scope of "Show".'), '$show' => t("Show"), '$hide' => t("Don't show"), + '$search' => t("Search"), '$allowcid' => json_encode($allow_cid), '$allowgid' => json_encode($allow_gid), '$denycid' => json_encode($deny_cid), @@ -249,7 +264,9 @@ function populate_acl($defaults = null,$show_jotnets = true, $showall = '') { '$jnetModalTitle' => t('Other networks and post services'), '$jotnets' => $jotnets, '$aclModalTitle' => t('Permissions'), - '$aclModalDismiss' => t('Close') + '$aclModalDesc' => $dialog_description, + '$aclModalDismiss' => t('Close'), + '$helpUrl' => (($context_help == '') ? '' : (z_root() . '/help?f=&cmd=' . $context_help)) )); return $o; diff --git a/view/js/acl.js b/view/js/acl.js index be215fc91..162ada764 100644 --- a/view/js/acl.js +++ b/view/js/acl.js @@ -14,8 +14,9 @@ function ACL(backend_url, preset) { that.nw = 4; //items per row. should be calulated from #acl-list.width that.list_content = $("#acl-list-content"); - that.item_tpl = unescape($(".acl-list-item[rel=acl-template]").html()); - that.showall = $("#acl-showall"); + that.item_tpl = unescape($(".acl-list-item[rel=acl-template]").html()); + that.showall = $("#acl-showall"); + that.showlimited = $("#acl-showlimited"); // set the initial ACL lists in case the enclosing form gets submitted before the ajax loader completes. that.on_submit(); @@ -26,6 +27,7 @@ function ACL(backend_url, preset) { $(document).ready(function() { that.showall.click(that.on_showall); + that.showlimited.click(that.on_showlimited); $(document).on('click','.acl-button-show',that.on_button_show); $(document).on('click','.acl-button-hide',that.on_button_hide); $("#acl-search").keypress(that.on_search); @@ -71,7 +73,8 @@ ACL.prototype.on_search = function(event) { }; ACL.prototype.on_showall = function(event) { - event.preventDefault(); + + // preventDefault() isn't called here as we want state changes from update_view() to be applied to the radiobutton event.stopPropagation(); if (that.showall.hasClass("btn-warning")) { @@ -87,9 +90,17 @@ ACL.prototype.on_showall = function(event) { that.update_view(); that.on_submit(); - return false; + return true; // return true so that state changes from update_view() will be applied }; +ACL.prototype.on_showlimited = function(event) { + // Prevent the radiobutton from being selected, as the showlimited radiobutton + // option is selected only by selecting show or hide options on channels or groups. + event.preventDefault(); + event.stopPropagation(); + return false; +} + ACL.prototype.on_selectall = function(event) { event.preventDefault(); event.stopPropagation(); @@ -188,18 +199,32 @@ ACL.prototype.set_deny = function(itemid) { that.update_view(); }; +ACL.prototype.update_radiobuttons = function(isPublic) { + + that.showall.prop('checked', isPublic); + that.showlimited.prop('checked', !isPublic); + that.showlimited.prop('disabled', isPublic); +}; + ACL.prototype.update_view = function() { if (that.allow_gid.length === 0 && that.allow_cid.length === 0 && that.deny_gid.length === 0 && that.deny_cid.length === 0) { + // btn-warning indicates that the permissions are public, it was chosen because + // that.showall used to be a normal button, which btn-warning is a bootstrap style for. that.showall.removeClass("btn-default").addClass("btn-warning"); + that.update_radiobuttons(true); + /* jot acl */ - $('#jot-perms-icon').removeClass('fa-lock').addClass('fa-unlock'); + $('#jot-perms-icon, #dialog-perms-icon').removeClass('fa-lock').addClass('fa-unlock'); $('#jot-public').show(); $('.profile-jot-net input').attr('disabled', false); + } else { that.showall.removeClass("btn-warning").addClass("btn-default"); + that.update_radiobuttons(false); + /* jot acl */ - $('#jot-perms-icon').removeClass('fa-unlock').addClass('fa-lock'); + $('#jot-perms-icon, #dialog-perms-icon').removeClass('fa-unlock').addClass('fa-lock'); $('#jot-public').hide(); $('.profile-jot-net input').attr('disabled', 'disabled'); diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index 58f216029..4dd3488e5 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -912,19 +912,43 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover { clear: both; } +.modal-header .contextual-help-tool { + /* Mostly duplicating ".modal-header .close" and ".close" layout settings from bootstrap */ + float: right; + font-size: 21px; + padding: 0; + margin-top: -4px; + margin-right: 15px; + line-height: 1; +} + #acl-search { - margin-top: 20px; - padding: 8px; + padding: 4px; border: 1px solid #ccc; - width: 100%; + width: 90%; /* fallback if browser does not support calc() */ + width: calc(100% - 10px); + margin: 0px 0px 10px 10px; } #acl-search::-webkit-input-placeholder { - font-family: FontAwesome; + /* non-fontawesome fonts set a fallback for text parts of the placeholder*/ + font-family: FontAwesome, sans-serif, arial, freesans; } #acl-search::-moz-placeholder { - font-family: FontAwesome; + /* non-fontawesome fonts set a fallback for text parts of the placeholder*/ + font-family: FontAwesome, sans-serif, arial, freesans; +} + +#acl-dialog-description { + font-size: 90%; + color: #888; +} +#acl-showlimited-description { + font-size: 90%; + color: #888; + margin-left: 10px; + margin-bottom: 4px; } #acl-list { @@ -933,11 +957,11 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover { overflow: auto; clear: both; min-height: 62px; - margin-top: 20px; padding: 10px 10px 0px 0px; -webkit-border-radius: $radiuspx ; -moz-border-radius: $radiuspx; border-radius: $radiuspx; + background-color: rgb(238,238,238); } #jotnets-wrapper, #jotnets-collapse { @@ -957,6 +981,7 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover { -webkit-border-radius: $radiuspx ; -moz-border-radius: $radiuspx; border-radius: $radiuspx; + background-color: white; } .acl-list-item.grouphide { @@ -995,6 +1020,26 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover { margin-left: 5px; } +#acl-showlimited-caption, +#acl-showall-caption { + font-size: 115%; +} + +#acl-radiowrapper-showall { + margin-bottom: 20px; +} +#acl-radiowrapper-showlimited { + margin-bottom: 0; +} + +#acl-showall + i { + font-size: 140%; +} + +#acl-showall-caption { + margin-left: 0.35em; +} + .contact-block-content { margin-top: 10px; } diff --git a/view/tpl/acl_selector.tpl b/view/tpl/acl_selector.tpl index e57fdba12..49d90cd3e 100755 --- a/view/tpl/acl_selector.tpl +++ b/view/tpl/acl_selector.tpl @@ -3,9 +3,13 @@