aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Lib/ThreadItem.php40
-rw-r--r--Zotlabs/Module/Channel.php9
-rw-r--r--Zotlabs/Module/Display.php2
-rw-r--r--Zotlabs/Module/Hq.php2
-rw-r--r--Zotlabs/Module/Like.php14
-rw-r--r--Zotlabs/Module/Network.php6
-rw-r--r--Zotlabs/Module/Pubstream.php6
-rw-r--r--Zotlabs/Module/Request.php6
-rw-r--r--include/conversation.php12
-rw-r--r--include/items.php362
-rw-r--r--view/js/main.js5
-rw-r--r--view/tpl/conv_item.tpl5
12 files changed, 234 insertions, 235 deletions
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index 5bb658bba..ee74ffa60 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -206,9 +206,9 @@ class ThreadItem {
}
if (in_array($item['obj_type'], ['Event', ACTIVITY_OBJ_EVENT])) {
- $response_verbs[] = 'attendyes';
- $response_verbs[] = 'attendno';
- $response_verbs[] = 'attendmaybe';
+ $response_verbs[] = 'accept';
+ $response_verbs[] = 'reject';
+ $response_verbs[] = 'tentativeaccept';
if($this->is_commentable() && $observer) {
$isevent = true;
$attend = array( t('I will attend'), t('I will not attend'), t('I might attend'));
@@ -222,7 +222,6 @@ class ThreadItem {
$response_verbs[] = 'comment';
$responses = get_responses($response_verbs, $item);
-
/*
* We should avoid doing this all the time, but it depends on the conversation mode
* And the conv mode may change when we change the conv, or it changes its mode
@@ -231,7 +230,10 @@ class ThreadItem {
$this->check_wall_to_wall();
+ $toplevel_comments_total = 0;
if($this->is_toplevel()) {
+ $toplevel_comments_total = $responses['comment']['count'] ?? 0;
+
if((local_channel() && $conv->get_profile_owner() === local_channel()) || (local_channel() && App::$module === 'pubstream')) {
$star = [
'toggle' => t("Toggle Star Status"),
@@ -243,7 +245,6 @@ class ThreadItem {
$is_comment = true;
}
-
$verified = (intval($item['item_verified']) ? t('Message signature validated') : '');
$forged = ((($item['sig']) && (! intval($item['item_verified']))) ? t('Message signature incorrect') : '');
$unverified = '' ; // (($this->is_wall_to_wall() && (! intval($item['item_verified']))) ? t('Message cannot be verified') : '');
@@ -350,6 +351,17 @@ class ThreadItem {
$contact = App::$contacts[$item['author_xchan']];
}
+ $load_more = '';
+ $load_more_title = '';
+ if ($toplevel_comments_total > $total_children) {
+ if (is_site_admin()) {
+ // provide a load more comments button
+ $load_more = t('Load more');
+ $load_more_title = sprintf(t('Load more of %d replies'), $toplevel_comments_total);
+
+ }
+ }
+
$tmp_item = array(
'template' => $this->get_template(),
'mode' => $mode,
@@ -463,18 +475,20 @@ class ThreadItem {
'reaction_str' => [t('Add yours'), t('Remove yours')],
'is_contained' => $this->is_toplevel() && str_contains($item['tgt_type'], 'Collection'),
'observer_activity' => [
- 'like' => intval($item['observer_liked'] ?? 0),
- 'dislike' => intval($item['observer_disliked'] ?? 0),
- 'announce' => intval($item['observer_announced'] ?? 0),
- 'comment' => intval($item['observer_commented'] ?? 0),
- 'attendyes' => intval($item['observer_accepted'] ?? 0),
- 'attendno' => intval($item['observer_rejected'] ?? 0),
- 'attendmaybe' => intval($item['observer_tentativelyaccepted'] ?? 0)
+ 'like' => intval($item['observer_like_count'] ?? 0),
+ 'dislike' => intval($item['observer_dislike_count'] ?? 0),
+ 'announce' => intval($item['observer_announce_count'] ?? 0),
+ 'comment' => intval($item['observer_comment_count'] ?? 0),
+ 'accept' => intval($item['observer_accept_count'] ?? 0),
+ 'reject' => intval($item['observer_reject_count'] ?? 0),
+ 'tentativeaccept' => intval($item['observer_tentativeaccept_count'] ?? 0)
],
'threaded' => $this->threaded,
'blog_mode' => $this->get_display_mode() === 'list',
'collapse_comments' => t('show less'),
- 'expand_comments' => $this->threaded ? t('show more') : t('show all')
+ 'expand_comments' => $this->threaded ? t('show more') : t('show all'),
+ 'load_more' => $load_more,
+ 'load_more_title' => $load_more_title,
);
$arr = array('item' => $item, 'output' => $tmp_item);
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index 93803da18..27c627e34 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -417,14 +417,7 @@ class Channel extends Controller {
}
}
if ($r) {
- //$parents_str = ids_to_querystr($r, 'item_id');
-
- //$r = items_by_parent_ids($parents_str, permission_sql: $permission_sql, blog_mode: $blog_mode);
- $items = [];
- foreach($r as $parent) {
- $nitems = items_by_parent_id($parent['item_id'], permission_sql: $permission_sql, blog_mode: $blog_mode);
- $items = array_merge($items, $nitems);
- }
+ $items = items_by_parent_ids($r, permission_sql: $permission_sql, blog_mode: $blog_mode);
xchan_query($items);
$items = fetch_post_tags($items, true);
diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php
index d3657149f..094466665 100644
--- a/Zotlabs/Module/Display.php
+++ b/Zotlabs/Module/Display.php
@@ -289,7 +289,7 @@ class Display extends Controller {
if($r) {
$thr_parents = get_recursive_thr_parents($target_item);
- $items = items_by_parent_id($r[0]['item_id'], $thr_parents, $permission_sql);
+ $items = items_by_parent_ids($r, $thr_parents, $permission_sql);
xchan_query($items);
$items = fetch_post_tags($items,true);
diff --git a/Zotlabs/Module/Hq.php b/Zotlabs/Module/Hq.php
index c4f812854..241a5101a 100644
--- a/Zotlabs/Module/Hq.php
+++ b/Zotlabs/Module/Hq.php
@@ -201,7 +201,7 @@ class Hq extends \Zotlabs\Web\Controller {
if($r) {
$thr_parents = get_recursive_thr_parents($target_item);
- $items = items_by_parent_id($r[0]['item_id'], $thr_parents);
+ $items = items_by_parent_ids($r, $thr_parents);
xchan_query($items,true,(($sys_item) ? local_channel() : 0));
$items = fetch_post_tags($items,true);
diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php
index 218d35f1e..e704c397e 100644
--- a/Zotlabs/Module/Like.php
+++ b/Zotlabs/Module/Like.php
@@ -22,9 +22,9 @@ class Like extends Controller {
'like' => 'Like',
'dislike' => 'Dislike',
'announce' => ACTIVITY_SHARE,
- 'attendyes' => 'Accept',
- 'attendno' => 'Reject',
- 'attendmaybe' => 'TentativeAccept'
+ 'accept' => 'Accept',
+ 'reject' => 'Reject',
+ 'tentativeaccept' => 'TentativeAccept'
];
// unlike (etc.) reactions are an undo of positive reactions, rather than a negative action.
@@ -474,11 +474,11 @@ class Like extends Controller {
$bodyverb = t('%1$s likes %2$s\'s %3$s');
if ($verb === 'dislike')
$bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
- if ($verb === 'attendyes')
+ if ($verb === 'accept')
$bodyverb = t('%1$s is attending %2$s\'s %3$s');
- if ($verb === 'attendno')
+ if ($verb === 'reject')
$bodyverb = t('%1$s is not attending %2$s\'s %3$s');
- if ($verb === 'attendmaybe')
+ if ($verb === 'tentativeaccept')
$bodyverb = t('%1$s may attend %2$s\'s %3$s');
if (!isset($bodyverb))
@@ -561,7 +561,7 @@ class Like extends Controller {
call_hooks('post_local_end', $arr);
- if ($is_rsvp && in_array($verb, ['attendyes', 'attendmaybe'])) {
+ if ($is_rsvp && in_array($verb, ['accept', 'tentativeaccept'])) {
event_addtocal($item_id, local_channel());
}
diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php
index 6dd00f13c..f95d92fe2 100644
--- a/Zotlabs/Module/Network.php
+++ b/Zotlabs/Module/Network.php
@@ -507,11 +507,7 @@ class Network extends \Zotlabs\Web\Controller {
// Then fetch all the children of the parents that are on this page
if($r) {
- $items = [];
- foreach($r as $parent) {
- $nitems = items_by_parent_id($parent['item_id'], blog_mode: $blog_mode);
- $items = array_merge($items, $nitems);
- }
+ $items = items_by_parent_ids($r, blog_mode: $blog_mode);
xchan_query($items, true);
$items = fetch_post_tags($items, true);
diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php
index 2944e496a..99b8ab587 100644
--- a/Zotlabs/Module/Pubstream.php
+++ b/Zotlabs/Module/Pubstream.php
@@ -251,11 +251,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
$parents_str = '';
if($r) {
- $items = [];
- foreach($r as $parent) {
- $nitems = items_by_parent_id($parent['item_id']);
- $items = array_merge($items, $nitems);
- }
+ $items = items_by_parent_ids($r);
// use effective_uid param of xchan_query to help sort out comment permission
// for sys_channel owned items.
diff --git a/Zotlabs/Module/Request.php b/Zotlabs/Module/Request.php
index bfd75ad95..0174694b2 100644
--- a/Zotlabs/Module/Request.php
+++ b/Zotlabs/Module/Request.php
@@ -12,9 +12,9 @@ class Request extends Controller
'like' => 'Like',
'dislike' => 'Dislike',
'announce' => 'Announce',
- 'attendyes' => 'Accept',
- 'attendno' => 'Reject',
- 'attendmaybe' => 'TentativeAccept'
+ 'accept' => 'Accept',
+ 'reject' => 'Reject',
+ 'tentativeaccept' => 'TentativeAccept'
];
if (array_key_exists($verb, $verbs)) {
diff --git a/include/conversation.php b/include/conversation.php
index 97a65c27d..bd1b7f863 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -1448,14 +1448,14 @@ function get_response_button_text($v, $count = 0) {
case 'comment':
return ['label' => tt('Reply','Replies',$count,'noun'), 'icon' => 'chat', 'class' => 'comment', 'action' => ''];
break;
- case 'attendyes':
- return ['label' => tt('Attending','Attending',$count,'noun'), 'icon' => 'calendar-check', 'class' => 'attendyes', 'action' => 'dolike'];
+ case 'accept':
+ return ['label' => tt('Attending','Attending',$count,'noun'), 'icon' => 'calendar-check', 'class' => 'accept', 'action' => 'dolike'];
break;
- case 'attendno':
- return ['label' => tt('Not attending','Not attending',$count,'noun'), 'icon' => 'calendar-x', 'class' => 'attendno', 'action' => 'dolike'];
+ case 'reject':
+ return ['label' => tt('Not attending','Not attending',$count,'noun'), 'icon' => 'calendar-x', 'class' => 'reject', 'action' => 'dolike'];
break;
- case 'attendmaybe':
- return ['label' => tt('Undecided','Undecided',$count,'noun'), 'icon' => 'calendar', 'class' => 'attendmaybe', 'action' => 'dolike'];
+ case 'tentativeaccept':
+ return ['label' => tt('Undecided','Undecided',$count,'noun'), 'icon' => 'calendar', 'class' => 'tentativeaccept', 'action' => 'dolike'];
break;
default:
return [];
diff --git a/include/items.php b/include/items.php
index 94e909293..a2c171a64 100644
--- a/include/items.php
+++ b/include/items.php
@@ -5374,16 +5374,16 @@ function item_activity_sql($prefix = 'c') {
if ($observer) {
$sql = <<<SQL
- COUNT(CASE WHEN $prefix.verb = 'Like' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_liked,
- COUNT(CASE WHEN $prefix.verb = 'Dislike' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_disliked,
- COUNT(CASE WHEN $prefix.verb = 'Announce' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_announced,
- COUNT(CASE WHEN $prefix.verb = 'Accept' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_accepted,
- COUNT(CASE WHEN $prefix.verb = 'Reject' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_rejected,
- COUNT(CASE WHEN $prefix.verb = 'TentativeAccept' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_tentativelyaccepted,
+ COUNT(CASE WHEN $prefix.verb = 'Like' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_like_count,
+ COUNT(CASE WHEN $prefix.verb = 'Dislike' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_dislike_count,
+ COUNT(CASE WHEN $prefix.verb = 'Announce' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_announce_count,
+ COUNT(CASE WHEN $prefix.verb = 'Accept' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_accept_count,
+ COUNT(CASE WHEN $prefix.verb = 'Reject' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_reject_count,
+ COUNT(CASE WHEN $prefix.verb = 'TentativeAccept' AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_tentativeaccept_count,
SQL;
if ($thread_allow) {
- $sql .= " COUNT(CASE WHEN $prefix.verb IN ('Create','Update') AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_commented, ";
+ $sql .= " COUNT(CASE WHEN $prefix.verb IN ('Create','Update') AND $prefix.author_xchan = '$observer' THEN 1 END) AS observer_comment_count, ";
}
}
@@ -5396,9 +5396,9 @@ function item_activity_sql($prefix = 'c') {
COUNT(CASE WHEN $prefix.verb = 'Like' THEN 1 END) AS like_count,
COUNT(CASE WHEN $prefix.verb = 'Dislike' THEN 1 END) AS dislike_count,
COUNT(CASE WHEN $prefix.verb = 'Announce' THEN 1 END) AS announce_count,
- COUNT(CASE WHEN $prefix.verb = 'Accept' THEN 1 END) AS attendyes_count,
- COUNT(CASE WHEN $prefix.verb = 'Reject' THEN 1 END) AS attendno_count,
- COUNT(CASE WHEN $prefix.verb = 'TentativeAccept' THEN 1 END) AS attendmaybe_count
+ COUNT(CASE WHEN $prefix.verb = 'Accept' THEN 1 END) AS accept_count,
+ COUNT(CASE WHEN $prefix.verb = 'Reject' THEN 1 END) AS reject_count,
+ COUNT(CASE WHEN $prefix.verb = 'TentativeAccept' THEN 1 END) AS tentativeaccept_count
SQL;
return $sql;
@@ -5443,77 +5443,145 @@ function item_by_item_id(int $id): array
* @brief returns an array of items by ids
* ATTENTION: no permissions for the pa are checked here!!!
* Permissions MUST be checked by the function which returns the ids.
- * @param string $ids - a string with ids separated by comma
- * @param array $thr_parents (optional) - a string with thr_parent mids separated by comma
- * which will be included
+ * @param array $ids
+ * @param array $thr_parents (optional) - thr_parent mids which will be included
* @param string $permission_sql (optional) - SQL provided by item_permission_sql() from the calling module
* @param bool $blog_mode (optional) - if set to yes only the parent items will be returned
*/
-// TODO: improve SQL performance
-function items_by_parent_ids(string $ids, array $thr_parents = [], string $permission_sql = '', bool $blog_mode = false): array
+function items_by_parent_ids(array $parents, array $thr_parents = [], string $permission_sql = '', bool $blog_mode = false): array
{
- if (!$ids) {
+ if (!$parents) {
return [];
}
+ $ids = ids_to_querystr($parents, 'item_id');
$thread_allow = ((local_channel()) ? PConfig::Get(local_channel(), 'system', 'thread_allow', true) : Config::Get('system', 'thread_allow', true));
-
$item_normal_sql = item_normal();
- $activity_sql_cte = item_activity_sql_cte();
- $activity_sql_cte_sub = item_activity_sql_cte('sub');
$thr_parent_sql = (($thread_allow) ? " AND item.thr_parent = item.parent_mid " : '');
-
if ($thr_parents && $thread_allow) {
$thr_parent_str = stringify_array($thr_parents, true);
$thr_parent_sql = " AND item.thr_parent IN (" . protect_sprintf($thr_parent_str) . ") ";
}
+ $reaction = item_reaction_sql($ids, $permission_sql);
+ $reaction_cte_sql = $reaction['cte'];
+ $reaction_select_sql = $reaction['select'];
+
if ($blog_mode) {
- $ret = q("SELECT item.*,
- $activity_sql_cte
- FROM item
- WHERE item.id IN (%s)
- $item_normal_sql
- $permission_sql",
- dbesc($ids)
+ $ret = dbq("WITH
+ parent_items_base AS (
+ SELECT item.*
+ FROM item
+ WHERE item.id IN ($ids)
+ $item_normal_sql
+ $permission_sql
+ ),
+
+ $reaction_cte_sql,
+
+ parent_items AS (
+ SELECT
+ parent_items_base.*,
+ $reaction_select_sql
+
+ FROM parent_items_base
+ LEFT JOIN reaction_like
+ ON reaction_like.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_dislike
+ ON reaction_dislike.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_announce
+ ON reaction_announce.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_accept
+ ON reaction_accept.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_reject
+ ON reaction_reject.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_tentativeaccept
+ ON reaction_tentativeaccept.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_comment
+ ON reaction_comment.thr_parent = parent_items_base.mid
+ )
+
+ SELECT * FROM parent_items"
);
}
else {
- $ret = q("WITH parents AS (
- SELECT item.*,
- 0 AS rn, -- this is required for union (equal amount of coulumns)
- $activity_sql_cte
- FROM item
- WHERE item.id IN (%s)
- $item_normal_sql
- $permission_sql
+ $ret = dbq("WITH
+ parent_items_base AS (
+ SELECT item.*
+ FROM item
+ WHERE item.id IN ($ids)
+ $item_normal_sql
+ $permission_sql
+ ),
+
+ $reaction_cte_sql,
+
+ parent_items AS (
+ SELECT
+ parent_items_base.*,
+ 0 AS rn,
+ $reaction_select_sql
+
+ FROM parent_items_base
+ LEFT JOIN reaction_like
+ ON reaction_like.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_dislike
+ ON reaction_dislike.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_announce
+ ON reaction_announce.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_accept
+ ON reaction_accept.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_reject
+ ON reaction_reject.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_tentativeaccept
+ ON reaction_tentativeaccept.thr_parent = parent_items_base.mid
+ LEFT JOIN reaction_comment
+ ON reaction_comment.thr_parent = parent_items_base.mid
),
- comments AS (
- SELECT sub.*,
- $activity_sql_cte_sub
- FROM (
- SELECT item.*,
- ROW_NUMBER() OVER (PARTITION BY item.parent ORDER BY item.created DESC) AS rn
- FROM item
- WHERE item.parent IN (%s)
- AND item.id != item.parent
- AND (
- item.verb NOT IN ('Like', 'Dislike', 'Announce', 'Accept', 'Reject', 'TentativeAccept')
- OR (item.verb = 'Announce' AND item.item_thread_top = 1)
- )
- $thr_parent_sql
- $item_normal_sql
- $permission_sql
- ) sub
- WHERE rn <= 100 -- number of comments we want to load
+
+ all_comments AS (
+ SELECT item.*,
+ ROW_NUMBER() OVER (PARTITION BY item.parent ORDER BY item.created DESC) AS rn
+ FROM item
+ WHERE item.id != item.parent
+ AND item.parent IN ($ids)
+ AND (
+ item.verb NOT IN ('Like', 'Dislike', 'Announce', 'Accept', 'Reject', 'TentativeAccept')
+ OR (item.verb = 'Announce' AND item.item_thread_top = 1)
+ )
+ $thr_parent_sql
+ $item_normal_sql
+ $permission_sql
+ ),
+
+ last_comments AS (
+ SELECT
+ all_comments.*,
+ $reaction_select_sql
+
+ FROM all_comments
+ LEFT JOIN reaction_like
+ ON reaction_like.thr_parent = all_comments.mid
+ LEFT JOIN reaction_dislike
+ ON reaction_dislike.thr_parent = all_comments.mid
+ LEFT JOIN reaction_announce
+ ON reaction_announce.thr_parent = all_comments.mid
+ LEFT JOIN reaction_accept
+ ON reaction_accept.thr_parent = all_comments.mid
+ LEFT JOIN reaction_reject
+ ON reaction_reject.thr_parent = all_comments.mid
+ LEFT JOIN reaction_tentativeaccept
+ ON reaction_tentativeaccept.thr_parent = all_comments.mid
+ LEFT JOIN reaction_comment
+ ON reaction_comment.thr_parent = all_comments.mid
+
+ WHERE all_comments.rn <= 100
)
- SELECT * FROM parents
+ SELECT * FROM parent_items
UNION ALL
- SELECT * FROM comments",
- dbesc($ids),
- dbesc($ids)
+ SELECT * FROM last_comments"
);
}
@@ -5521,156 +5589,79 @@ function items_by_parent_ids(string $ids, array $thr_parents = [], string $permi
}
/**
- * @brief returns an array of items by ids
+ * @brief prepare reaction sql for items_by_parent_ids()
* ATTENTION: no permissions for the pa are checked here!!!
* Permissions MUST be checked by the function which returns the ids.
- * @param int $id - a parent item id
- * @param array $thr_parents (optional) - a string with thr_parent mids separated by comma
- * which will be included
- * @param string $permission_sql (optional) - SQL provided by item_permission_sql() from the calling module
- * @param bool $blog_mode (optional) - if set to yes only the parent items will be returned
- */
-
-function items_by_parent_id(int $id, array $thr_parents = [], string $permission_sql = '', bool $blog_mode = false): array
-{
- if (!$id) {
- return [];
- }
-
- $item_normal = item_normal();
- $item_normal_c = item_normal(prefix: 'c');
- $activity_sql = item_activity_sql('c');
- $thread_allow = ((local_channel()) ? PConfig::Get(local_channel(), 'system', 'thread_allow', true) : Config::Get('system', 'thread_allow', true));
-
- $blog_mode_sql = (($blog_mode) ? 'item.id' : 'item.parent');
-
- $thr_parent_sql = (($thread_allow) ? " AND item.thr_parent = item.parent_mid " : '');
- if ($thr_parents && $thread_allow) {
- $thr_parent_str = stringify_array($thr_parents, true);
- $thr_parent_sql = " AND item.thr_parent IN (" . protect_sprintf($thr_parent_str) . ") ";
- }
-
- $permission_sql_c = '';
- if ($permission_sql) {
- $permission_sql_c = str_replace('item.', 'c.', $permission_sql);
- }
-
- $thread_limit_sql = '';
- if (!$blog_mode && $thread_allow) {
- // Get the last x replies but make sure the toplevel is included anyway
- $thread_limit_sql = <<<SQL
- ORDER BY
- CASE WHEN item.id = item.parent THEN 0 ELSE 1 END,
- item.created DESC
- LIMIT 101
- SQL;
- }
-
- $ret = q(
- "SELECT item.*,
- $activity_sql
- FROM item
- LEFT JOIN item c
- ON c.parent = item.parent
- AND c.item_thread_top = 0
- AND c.thr_parent = item.mid
- $item_normal_c
- $permission_sql_c
- WHERE $blog_mode_sql = %d
- AND (
- item.verb NOT IN ('Like', 'Dislike', 'Announce')
- OR (item.verb = 'Announce' AND item.item_thread_top = 1)
- )
- $thr_parent_sql
- $item_normal
- $permission_sql
- GROUP BY item.id
- $thread_limit_sql",
- intval($id)
- );
-
- return $ret;
-}
-
-
-
-/**
- * @brief returns SQL which counts activities for an item and
- * if there is an observer also count activities authored by observer.
- * @param string $prefix (optional)
+ * @param string $ids
+ * @param string $permission_sql (optional) - SQL provided by item_permission_sql()
*/
-function item_activity_sql_cte($prefix = 'item'): string
+function item_reaction_sql(string $ids, string $permission_sql = ''): array
{
- $thread_allow = ((local_channel()) ? PConfig::Get(local_channel(), 'system', 'thread_allow', true) : Config::Get('system', 'thread_allow', true));
+ $item_normal_sql = item_normal();
$observer = get_observer_hash();
- $sql = '';
- if ($observer) {
- $observer_verbs = [
- 'Like' => 'observer_liked',
- 'Dislike' => 'observer_disliked',
- 'Announce' => 'observer_announced',
- 'Accept' => 'observer_accepted',
- 'Reject' => 'observer_rejected',
- 'TentativeAccept' => 'observer_tentativelyaccepted'
- ];
+ $verbs = [
+ 'like' => ['Like'],
+ 'dislike' => ['Dislike'],
+ 'announce' => ['Announce'],
+ 'accept' => ['Accept'],
+ 'reject' => ['Reject'],
+ 'tentativeaccept' => ['TentativeAccept'],
+ 'comment' => ['Create', 'Update']
+ ];
- foreach($observer_verbs as $k => $v) {
- if ($sql) {
- $sql .= ",\n";
- }
+ $cte = '';
+ $select = '';
- $sql .= <<<SQL
- (SELECT COUNT(*) FROM item AS reaction
- WHERE reaction.parent = $prefix.parent AND reaction.verb = '$k' AND reaction.author_xchan = '$observer' AND reaction.item_thread_top = 0 AND reaction.thr_parent = $prefix.mid
- ) AS $v
- SQL;
- }
+ foreach($verbs as $k => $v) {
- if ($thread_allow) {
- $sql .= ",\n";
- $sql .= <<<SQL
- (SELECT COUNT(*) FROM item AS reaction
- WHERE reaction.parent = $prefix.parent AND reaction.verb IN ('Create', 'Update') AND reaction.author_xchan = '$observer' AND reaction.item_thread_top = 0 AND reaction.thr_parent = $prefix.mid
- ) AS observer_commented
- SQL;
+ $observer_sql = "0 AS observer_{$k}_count";
+ if ($observer) {
+ $observer_sql = "COUNT(CASE WHEN item.author_xchan = '$observer' THEN 1 END) AS observer_{$k}_count";
}
- }
- $verbs = [
- 'Like' => 'like_count',
- 'Dislike' => 'dislike_count',
- 'Announce' => 'announce_count',
- 'Accept' => 'attendyes_count',
- 'Reject' => 'attendno_count',
- 'TentativeAccept' => 'attendmaybe_count'
- ];
+ $verbs_str = stringify_array($v);
- foreach($verbs as $k => $v) {
- if ($sql) {
- $sql .= ",\n";
+ if ($cte) {
+ $cte .= ",\n";
}
- $sql .= <<<SQL
- (SELECT COUNT(*) FROM item AS reaction
- WHERE reaction.parent = $prefix.parent AND reaction.verb = '$k' AND reaction.item_thread_top = 0 AND reaction.thr_parent = $prefix.mid
- ) AS $v
+ $cte .= <<<SQL
+ reaction_{$k} AS (
+ SELECT
+ item.thr_parent,
+ COUNT(*) AS {$k}_count,
+ $observer_sql
+ FROM item
+ WHERE item.verb IN ($verbs_str)
+ AND item.item_thread_top = 0
+ AND item.parent IN ($ids)
+ $item_normal_sql
+ $permission_sql
+ GROUP BY item.thr_parent
+ )
SQL;
- }
- if ($thread_allow) {
- $sql .= ",\n";
- $sql .= <<<SQL
- (SELECT COUNT(*) FROM item AS reaction
- WHERE reaction.parent = $prefix.parent AND reaction.verb IN ('Create', 'Update') AND reaction.item_thread_top = 0 AND reaction.thr_parent = $prefix.mid
- ) AS comment_count
+ if ($select) {
+ $select .= ",\n";
+ }
+
+ $select .= <<<SQL
+ COALESCE(reaction_{$k}.{$k}_count, 0) AS {$k}_count,
+ COALESCE(reaction_{$k}.observer_{$k}_count, 0) AS observer_{$k}_count
SQL;
+
}
- return $sql;
+ $ret['cte'] = $cte;
+ $ret['select'] = $select;
+
+ return $ret;
}
+
+
/**
* @brief returns an array of items by thr_parent mid of a parent
@@ -5678,6 +5669,7 @@ function item_activity_sql_cte($prefix = 'item'): string
* @param int $parent
*/
+// TODO: streamline logic with items_by_parent_ids() -
function items_by_thr_parent(string $mid, int $parent): array
{
if (!$mid && !$parent) {
diff --git a/view/js/main.js b/view/js/main.js
index 7043c8577..6d79f9092 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -1294,6 +1294,11 @@ function justifyPhotosAjax(id) {
function request(id, mid, verb, parent, uuid) {
+ if (!id) {
+ console.log('load_more');
+ return;
+ }
+
const loading = document.getElementById('like-rotator-' + id);
loading.style.display = 'block';
diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl
index 6d8aa6abc..3bca23df8 100644
--- a/view/tpl/conv_item.tpl
+++ b/view/tpl/conv_item.tpl
@@ -207,9 +207,12 @@
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="dreport/{{$item.dreport_link}}">{{$item.dreport}}</a>
{{/if}}
+ {{if $item.load_more}}
+ <a class="dropdown-item conversation-load-more" title="{{$item.load_more_title}}" href="#" onclick="request(''); return false;">{{$item.load_more}}</a>
+ {{/if}}
{{if $item.settings}}
<div class="dropdown-divider"></div>
- <a class="dropdown-item conversation-settings-link" href="" data-bs-toggle="modal" data-bs-target="#conversation_settings">{{$item.settings}}</a>
+ <a class="dropdown-item conversation-settings-link" href="#" data-bs-toggle="modal" data-bs-target="#conversation_settings">{{$item.settings}}</a>
{{/if}}
</div>
</div>