We now have a global page for all global entries from the network.

This commit is contained in:
Michael 2018-01-03 13:27:43 +00:00
parent 6925299e5a
commit 3ffea2cd2c
16 changed files with 264 additions and 71 deletions

View file

@ -228,9 +228,10 @@ define('ACCOUNT_TYPE_COMMUNITY', 3);
* Type of the community page
* @{
*/
define('CP_NO_COMMUNITY_PAGE', -1);
define('CP_NO_COMMUNITY_PAGE', -1);
define('CP_USERS_ON_SERVER', 0);
define('CP_GLOBAL_COMMUNITY', 1);
define('CP_USERS_AND_GLOBAL', 2);
/**
* @}
*/

View file

@ -147,10 +147,14 @@ function nav_info(App $a)
if (strlen($gdir)) {
$gdirpath = zrl($gdir, true);
}
} elseif (Config::get('system', 'community_page_style') == CP_USERS_ON_SERVER) {
}
if (in_array(Config::get('system', 'community_page_style'), [CP_USERS_ON_SERVER, CP_USERS_AND_GLOBAL])) {
$nav['community'] = array('community', t('Community'), '', t('Conversations on this site'));
} elseif (Config::get('system', 'community_page_style') == CP_GLOBAL_COMMUNITY) {
$nav['community'] = array('community', t('Community'), '', t('Conversations on the network'));
}
if (in_array(Config::get('system', 'community_page_style'), [CP_GLOBAL_COMMUNITY, CP_USERS_AND_GLOBAL])) {
$nav['global'] = array('global', t('Global Timeline'), '', t('Conversations on the network'));
}
if (local_user()) {
@ -230,6 +234,7 @@ function nav_info(App $a)
function nav_set_selected($item){
$a = get_app();
$a->nav_sel = array(
'global' => null,
'community' => null,
'network' => null,
'home' => null,

View file

@ -253,9 +253,13 @@ if (strlen($a->module)) {
}
// Controller class routing
if (! $a->module_loaded && class_exists('Friendica\\Module\\' . ucfirst($a->module))) {
$a->module_class = 'Friendica\\Module\\' . ucfirst($a->module);
$a->module_loaded = true;
$classes = ['Friendica\\Module\\' . ucfirst($a->module), 'Friendica\\Module\\' . ucfirst($a->module) . 'Module'];
foreach ($classes as $class) {
if (!$a->module_loaded && class_exists($class)) {
$a->module_class = $class;
$a->module_loaded = true;
break;
}
}
/**

View file

@ -1176,7 +1176,8 @@ function admin_page_site(App $a)
$community_page_style_choices = array(
CP_NO_COMMUNITY_PAGE => t("No community page"),
CP_USERS_ON_SERVER => t("Public postings from users of this site"),
CP_GLOBAL_COMMUNITY => t("Global community page")
CP_GLOBAL_COMMUNITY => t("Global community page"),
CP_USERS_AND_GLOBAL => t("Public user postings and global postings")
);
/* OStatus conversation poll choices */

View file

@ -5,7 +5,7 @@ use Friendica\Core\Config;
use Friendica\Database\DBM;
function community_init(App $a) {
if (! local_user()) {
if (!local_user()) {
unset($_SESSION['theme']);
unset($_SESSION['mobile-theme']);
}
@ -14,28 +14,28 @@ function community_init(App $a) {
function community_content(App $a, $update = 0) {
$o = '';
if ((Config::get('system','block_public')) && (! local_user()) && (! remote_user())) {
notice( t('Public access denied.') . EOL);
if (Config::get('system','block_public') && !local_user() && !remote_user()) {
notice(t('Public access denied.') . EOL);
return;
}
if (Config::get('system','community_page_style') == CP_NO_COMMUNITY_PAGE) {
notice( t('Not available.') . EOL);
if (!in_array(Config::get('system','community_page_style'), [CP_USERS_ON_SERVER, CP_USERS_AND_GLOBAL])) {
notice(t('Not available.') . EOL);
return;
}
require_once("include/bbcode.php");
require_once('include/security.php');
require_once('include/conversation.php');
require_once 'include/bbcode.php';
require_once 'include/security.php';
require_once 'include/conversation.php';
if (! $update) {
if (!$update) {
nav_set_selected('community');
}
if (x($a->data,'search')) {
$search = notags(trim($a->data['search']));
} else {
$search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
$search = (x($_GET,'search') ? notags(trim(rawurldecode($_GET['search']))) : '');
}
// Here is the way permissions work in this module...
@ -44,8 +44,8 @@ function community_content(App $a, $update = 0) {
$r = community_getitems($a->pager['start'], $a->pager['itemspage']);
if (! DBM::is_result($r)) {
info( t('No results.') . EOL);
if (!DBM::is_result($r)) {
info(t('No results.') . EOL);
return $o;
}
@ -70,7 +70,7 @@ function community_content(App $a, $update = 0) {
$s[] = $item;
}
}
if ((sizeof($s) < $a->pager['itemspage'])) {
if (sizeof($s) < $a->pager['itemspage']) {
$r = community_getitems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage']);
}
} while ((sizeof($s) < $a->pager['itemspage']) && (++$count < 50) && (sizeof($r) > 0));
@ -87,15 +87,12 @@ function community_content(App $a, $update = 0) {
return replace_macros($t, array(
'$content' => $o,
'$header' => t("Community"),
'$show_global_community_hint' => (Config::get('system', 'community_page_style') == CP_GLOBAL_COMMUNITY && Config::get('system', 'show_global_community_hint')),
'$global_community_hint' => t("This community stream shows all public posts received by this node. They may not reflect the opinions of this nodes users.")
'$show_global_community_hint' => false,
'$global_community_hint' => ''
));
}
function community_getitems($start, $itemspage) {
if (Config::get('system','community_page_style') == CP_GLOBAL_COMMUNITY) {
return(community_getpublicitems($start, $itemspage));
}
$r = dba::p("SELECT ".item_fieldlists()." FROM `thread`
INNER JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
@ -109,39 +106,3 @@ function community_getitems($start, $itemspage) {
return dba::inArray($r);
}
function community_getpublicitems($start, $itemspage) {
$r = dba::p("SELECT ".item_fieldlists()." FROM `thread`
INNER JOIN `item` ON `item`.`id` = `thread`.`iid` ".item_joins().
"WHERE `thread`.`uid` = 0 AND `verb` = ?
ORDER BY `thread`.`commented` DESC LIMIT ".intval($start).", ".intval($itemspage),
ACTIVITY_POST
);
while ($rr = dba::fetch($r)) {
if (!in_array($rr['item_id'], $parents_arr)) {
$parents_arr[] = $rr['item_id'];
}
}
dba::close();
$max_comments = Config::get("system", "max_comments", 100);
$items = array();
foreach ($parents_arr AS $parents) {
$thread_items = dba::p(item_query()." AND `item`.`uid` = 0
AND `item`.`parent` = ?
ORDER BY `item`.`commented` DESC LIMIT ".intval($max_comments + 1),
$parents
);
if (DBM::is_result($thread_items)) {
$items = array_merge($items, dba::inArray($thread_items));
}
}
$items = conv_sort($items, "`commented`");
return $items;
}

164
src/Module/Global.php Normal file
View file

@ -0,0 +1,164 @@
<?php
namespace Friendica\Module;
use Friendica\BaseModule;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use dba;
/**
* Global module
*
* Displays global posts on the server
*
* @author heluecht@pirati.ca
*/
class GlobalModule extends BaseModule {
public static function init() {
if (!local_user()) {
unset($_SESSION['theme']);
unset($_SESSION['mobile-theme']);
}
}
public static function content($update = 0) {
$a = self::getApp();
$o = '';
if (Config::get('system','block_public') && !local_user() && !remote_user()) {
notice(t('Public access denied.') . EOL);
return;
}
if (!in_array(Config::get('system','community_page_style'), [CP_GLOBAL_COMMUNITY, CP_USERS_AND_GLOBAL])) {
notice(t('Not available.') . EOL);
return;
}
require_once 'include/bbcode.php';
require_once 'include/security.php';
require_once 'include/conversation.php';
if (!$update) {
nav_set_selected('global');
}
if (x($a->data,'search')) {
$search = notags(trim($a->data['search']));
} else {
$search = (x($_GET,'search') ? notags(trim(rawurldecode($_GET['search']))) : '');
}
// Here is the way permissions work in this module...
// Only public posts can be shown
// OR your own posts if you are a logged in member
$r = self::getPublicItems($a->pager['start'], $a->pager['itemspage']);
if (!DBM::is_result($r)) {
info(t('No results.') . EOL);
return $o;
}
$maxpostperauthor = Config::get('system','max_author_posts_community_page');
if ($maxpostperauthor != 0) {
$count = 1;
$previousauthor = "";
$numposts = 0;
$s = array();
do {
foreach ($r AS $row=>$item) {
if ($previousauthor == $item["author-link"]) {
++$numposts;
} else {
$numposts = 0;
}
$previousauthor = $item["author-link"];
if (($numposts < $maxpostperauthor) && (sizeof($s) < $a->pager['itemspage'])) {
$s[] = $item;
}
}
if (sizeof($s) < $a->pager['itemspage']) {
$r = self::getPublicItems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage']);
}
} while ((sizeof($s) < $a->pager['itemspage']) && (++$count < 50) && (sizeof($r) > 0));
} else {
$s = $r;
}
// we behave the same in message lists as the search module
$o .= conversation($a, $s, 'community', $update);
$o .= alt_pager($a, count($r));
$t = get_markup_template("community.tpl");
return replace_macros($t, array(
'$content' => $o,
'$header' => t("Global Timeline"),
'$show_global_community_hint' => Config::get('system', 'show_global_community_hint'),
'$global_community_hint' => t("This community stream shows all public posts received by this node. They may not reflect the opinions of this nodes users.")
));
}
private static function getPublicItems($start, $itemspage) {
$r = dba::p("SELECT ".item_fieldlists()." FROM `thread`
INNER JOIN `item` ON `item`.`id` = `thread`.`iid` ".item_joins().
"WHERE `thread`.`uid` = 0 AND `verb` = ?
ORDER BY `thread`.`created` DESC LIMIT ".intval($start).", ".intval($itemspage),
ACTIVITY_POST
);
return dba::inArray($r);
// Currently deactivated
$parents_arr = [];
while ($rr = dba::fetch($r)) {
if (!in_array($rr['item_id'], $parents_arr)) {
$parents_arr[] = $rr['item_id'];
}
}
dba::close($r);
$max_comments = Config::get("system", "max_comments", 100);
$items = array();
foreach ($parents_arr AS $parents) {
$thread_items = dba::p(item_query()." AND `item`.`uid` = 0
AND `item`.`parent` = ?
ORDER BY `item`.`commented` DESC LIMIT ".intval($max_comments + 1),
$parents
);
if (DBM::is_result($thread_items)) {
$items = array_merge($items, dba::inArray($thread_items));
}
}
foreach ($items as $index => $item) {
$items[$index]['writable'] = in_array($item['network'], [NETWORK_DIASPORA, NETWORK_OSTATUS]);
if ($item['network'] == NETWORK_DFRN) {
$fields = ['id', 'writable', 'self'];
$condition = ['nurl' => normalise_link($item['author-link']), 'uid' => local_user()];
$contact = dba::select('contact', $fields, $condition, ['limit' => 1]);
if (DBM::is_result($contact)) {
$items[$index]['contact-id'] = $contact['id'];
$items[$index]['cid'] = $contact['id'];
$items[$index]['writable'] = $contact['writable'];
$items[$index]['self'] = $contact['self'];
}
}
}
$items = conv_sort($items, "`commented`");
return $items;
}
}

View file

@ -322,6 +322,12 @@ class Post extends BaseObject
unset($buttons["like"]);
}
// If a contact isn't writable, we cannot send a like or dislike to it
if (!$item['writable']) {
unset($buttons["like"]);
unset($buttons["dislike"]);
}
$tmp_item = array(
'template' => $this->getTemplate(),
'type' => implode("", array_slice(explode("/", $item['verb']), -1)),

View file

@ -31,6 +31,9 @@
{{if $nav.community}}
<a accesskey="c" id="nav-community-link" class="nav-commlink {{$nav.community.2}} {{$sel.community}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
{{/if}}
{{if $nav.global}}
<a accesskey="g" id="nav-global-link" class="nav-commlink {{$nav.global.2}} {{$sel.global}}" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
{{/if}}
{{if $nav.introductions}}
<a id="nav-notify-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
<span id="intro-update" class="nav-ajax-left"></span>

View file

@ -31,6 +31,9 @@
{{if $nav.community}}
<a accesskey="c" id="nav-community-link" class="nav-commlink {{$nav.community.2}} {{$sel.community}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
{{/if}}
{{if $nav.global}}
<a accesskey="g" id="nav-global-link" class="nav-commlink {{$nav.global.2}} {{$sel.global}}" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
{{/if}}
{{if $nav.introductions}}
<a id="nav-notify-link" class="nav-commlink {{$nav.introductions.2}} {{$sel.introductions}}" href="{{$nav.introductions.0}}" title="{{$nav.introductions.3}}" >{{$nav.introductions.1}}</a>
<span id="intro-update" class="nav-ajax-left"></span>

View file

@ -206,6 +206,19 @@ $(document).ready(function(){
$("#topbar-second > .container > #tabmenu").append(newText);
}
if( $(".global-content-wrapper").length) {
// get the heading element
var heading = $(".global-content-wrapper > h3").first();
// get the text of the heading
var headingContent = heading.text();
// create a new element with the content of the heading
var newText = '<h4 class="heading">'+headingContent+'</h4>';
// remove the old heading element
heading.remove(),
// put the new element to the second nav bar
$("#topbar-second > .container > #tabmenu").append(newText);
}
// Dropdown menus with the class "dropdown-head" will display the active tab
// as button text
$("body").on('click', '.dropdown-head .dropdown-menu li a, .dropdown-head .dropdown-menu li button', function(){

View file

@ -50,6 +50,10 @@
{{if $nav.community}}
<a role="menuitem" class="nav-menu {{$sel.community}}" href="{{$nav.community.0}}" data-toggle="tooltip" title="{{$nav.community.3}}"><i class="fa fa-lg fa-bullseye" aria-hidden="true"></i></a>
{{/if}}
{{if $nav.global}}
<a role="menuitem" class="nav-menu {{$sel.global}}" href="{{$nav.global.0}}" data-toggle="tooltip" title="{{$nav.global.3}}"><i class="fa fa-lg fa-globe" aria-hidden="true"></i></a>
{{/if}}
</li>
<li id="nav-personal" class="nav-segment hidden-xs" role="presentation">

View file

@ -134,6 +134,12 @@
<a id="nav-community-link" class="{{$nav.community.2}} {{$sel.community}} nav-load-page-link" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
</li>
{{/if}}
{{if $nav.global}}
<li>
<a id="nav-global-link" class="{{$nav.global.2}} {{$sel.global}} nav-load-page-link" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
</li>
{{/if}}
</ul>
</div>

View file

@ -130,6 +130,12 @@
<a id="nav-community-link" class="{{$nav.community.2}} {{$sel.community}} nav-load-page-link" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
</li>
{{/if}}
{{if $nav.global}}
<li>
<a id="nav-global-link" class="{{$nav.global.2}} {{$sel.global}} nav-load-page-link" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
</li>
{{/if}}
</ul>
</div>

View file

@ -20,6 +20,12 @@
</li>
{{/if}}
{{if $nav.global}}
<li id="nav-global-link" class="nav-menu {{$sel.global}}">
<a class="{{$nav.global.2}}" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
</li>
{{/if}}
{{if $nav.community}}
<li id="nav-community-link" class="nav-menu {{$sel.community}}">
<a class="{{$nav.community.2}}" href="{{$nav.community.0}}" title="{{$nav.community.3}}" >{{$nav.community.1}}</a>
@ -32,6 +38,7 @@
<span id="net-update" class="nav-notify"></span>
</li>
{{/if}}
{{if $nav.home}}
<li id="nav-home-link" class="nav-menu {{$sel.home}}">
<a accesskey="p" class="{{$nav.home.2}}" href="{{$nav.home.0}}" title="{{$nav.home.3}}" >{{$nav.home.1}}</a>
@ -57,8 +64,6 @@
</li>
{{/if}}
{{if $nav.notifications}}
<li id="nav-notifications-linkmenu" class="nav-menu-icon"><a accesskey="f" href="{{$nav.notifications.0}}" rel="#nav-notifications-menu" title="{{$nav.notifications.1}}"><span class="icon s22 notify">{{$nav.notifications.1}}</span></a>
<span id="notify-update" class="nav-notify"></span>

View file

@ -30,9 +30,13 @@
{{if $nav.network}}<li><a id="nav-network-link" class="nav-commlink {{$nav.network.2}}" href="{{$nav.network.0}}">{{$nav.network.1}}</a></li>{{/if}}
{{if $nav.community}}
<li><a id="nav-community-link" class="nav-commlink {{$nav.community.2}}" href="{{$nav.community.0}}">{{$nav.community.1}}</a></li>
{{/if}}
{{if $nav.community}}
<li><a id="nav-community-link" class="nav-commlink {{$nav.community.2}}" href="{{$nav.community.0}}">{{$nav.community.1}}</a></li>
{{/if}}
{{if $nav.global}}
<li><a id="nav-global-link" class="nav-commlink {{$nav.global.2}}" href="{{$nav.global.0}}">{{$nav.global.1}}</a></li>
{{/if}}
<li><a id="nav-search-link" class="nav-link {{$nav.search.2}}" href="{{$nav.search.0}}">{{$nav.search.1}}</a></li>
<li><a id="nav-directory-link" class="nav-link {{$nav.directory.2}}" href="{{$nav.directory.0}}">{{$nav.directory.1}}</a></li>

View file

@ -39,6 +39,13 @@
</li>
{{/if}}
{{if $nav.global}}
<li role="menuitem" id="nav-global-link" class="nav-menu {{$sel.global}}">
<a accesskey="g" class="{{$nav.global.2}} desktop-view" href="{{$nav.global.0}}" title="{{$nav.global.3}}" >{{$nav.global.1}}</a>
<a class="{{$nav.global.2}} mobile-view" href="{{$nav.global.0}}" title="{{$nav.global.3}}" ><i class="icon s22 icon-bullseye"></i></a>
</li>
{{/if}}
<li role="menu" aria-haspopup="true" id="nav-site-linkmenu" class="nav-menu-icon"><a><span class="icon s22 icon-question"><span class="sr-only">{{$nav.help.3}}</span></span></a>
<ul id="nav-site-menu" class="menu-popup">
{{if $nav.help}} <li role="menuitem"><a class="{{$nav.help.2}}" href="{{$nav.help.0}}" title="{{$nav.help.3}}" >{{$nav.help.1}}</a></li>{{/if}}