Add thread view, quote posts, and GIF picker: full conversation tree modal, quote any beep by URL/ID, Giphy-powered GIF search
This commit is contained in:
@@ -61,6 +61,21 @@ class Beep_Replies {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
if (is_wp_error($post_id)) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
$body = $request->get_json_params();
|
||||
$quote_id = isset($body['quote_id']) ? (int) $body['quote_id'] : 0;
|
||||
if ($quote_id) {
|
||||
Beep_Quotes::create_quote($post_id, $quote_id);
|
||||
}
|
||||
|
||||
$gif_url = isset($body['gif_url']) ? esc_url_raw($body['gif_url']) : '';
|
||||
if ($gif_url) {
|
||||
update_post_meta($post_id, 'beep_gif_url', $gif_url);
|
||||
}
|
||||
|
||||
return rest_ensure_response([
|
||||
'id' => $post_id,
|
||||
'html' => beep_render_post(get_post($post_id)),
|
||||
@@ -173,3 +188,108 @@ class Beep_Replies {
|
||||
return (int) get_comments_number($post_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full conversation/thread for a beep.
|
||||
* Returns the root beep and all nested replies in tree order.
|
||||
*/
|
||||
public static function get_thread($post_id, $depth = 0, $max_depth = 10) {
|
||||
if ($depth > $max_depth) return [];
|
||||
$post = get_post($post_id);
|
||||
if (!$post || $post->post_type !== Beep_CPT::POST_TYPE) return [];
|
||||
$thread = [self::format_beep_reply($post, $depth)];
|
||||
$replies = get_comments([
|
||||
'post_id' => $post_id, 'status' => 'approve', 'order' => 'ASC',
|
||||
'type' => 'comment', 'number' => 100,
|
||||
]);
|
||||
foreach ($replies as $reply) {
|
||||
if ($depth < $max_depth) {
|
||||
$thread = array_merge($thread, self::get_comment_thread($reply->comment_ID, $depth + 1, $max_depth));
|
||||
}
|
||||
}
|
||||
return $thread;
|
||||
}
|
||||
|
||||
private static function get_comment_thread($comment_id, $depth, $max_depth) {
|
||||
if ($depth > $max_depth) return [];
|
||||
$comment = get_comment($comment_id);
|
||||
if (!$comment) return [];
|
||||
$result = [self::format_comment_reply($comment, $depth)];
|
||||
$children = get_comments([
|
||||
'parent' => $comment_id, 'status' => 'approve', 'order' => 'ASC',
|
||||
'type' => 'comment', 'number' => 100,
|
||||
]);
|
||||
foreach ($children as $child) {
|
||||
$result = array_merge($result, self::get_comment_thread($child->comment_ID, $depth + 1, $max_depth));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function format_beep_reply($post, $depth = 0) {
|
||||
$author_id = $post->post_author;
|
||||
$author = get_userdata($author_id);
|
||||
$avatar = get_user_meta($author_id, 'beep_avatar', true);
|
||||
if (!$avatar) {
|
||||
$avatar = 'https://www.gravatar.com/avatar/' . md5(strtolower($author->user_email ?? '')) . '?s=48&d=mp';
|
||||
}
|
||||
return [
|
||||
'id' => $post->ID,
|
||||
'parent_id' => $post->post_parent ?: null,
|
||||
'is_post' => true,
|
||||
'depth' => $depth,
|
||||
'content' => $post->post_content,
|
||||
'time_ago' => self::time_ago(strtotime($post->post_date)),
|
||||
'like_count' => Beep_Likes::get_count($post->ID, 'post'),
|
||||
'reply_count' => self::reply_count($post->ID),
|
||||
'author' => [
|
||||
'id' => $author_id,
|
||||
'name' => $author->display_name ?? 'Unknown',
|
||||
'username' => $author->user_login ?? '',
|
||||
'avatar' => $avatar,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function format_comment_reply($comment, $depth = 0) {
|
||||
$author_id = (int) $comment->user_id;
|
||||
$author = $author_id ? get_userdata($author_id) : null;
|
||||
if ($author_id) {
|
||||
$avatar = get_user_meta($author_id, 'beep_avatar', true);
|
||||
if (!$avatar) {
|
||||
$avatar = 'https://www.gravatar.com/avatar/' . md5(strtolower($author->user_email ?? '')) . '?s=48&d=mp';
|
||||
}
|
||||
$name = $author->display_name ?? 'Unknown';
|
||||
$username = $author->user_login ?? '';
|
||||
} else {
|
||||
$avatar = 'https://www.gravatar.com/avatar/?s=48&d=mp';
|
||||
$name = esc_html($comment->comment_author);
|
||||
$username = '';
|
||||
}
|
||||
return [
|
||||
'id' => $comment->comment_ID,
|
||||
'parent_id' => (int) $comment->comment_parent ?: null,
|
||||
'is_post' => false,
|
||||
'depth' => $depth,
|
||||
'content' => $comment->comment_content,
|
||||
'time_ago' => self::time_ago(strtotime($comment->comment_date)),
|
||||
'like_count' => Beep_Likes::get_count($comment->comment_ID, 'reply'),
|
||||
'reply_count' => 0,
|
||||
'author' => [
|
||||
'id' => $author_id,
|
||||
'name' => $name,
|
||||
'username' => $username,
|
||||
'avatar' => $avatar,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function time_ago($timestamp) {
|
||||
$diff = time() - $timestamp;
|
||||
if ($diff < 0) $diff = 0;
|
||||
if ($diff < 60) return $diff . 's';
|
||||
if ($diff < 3600) return floor($diff / 60) . 'm';
|
||||
if ($diff < 86400) return floor($diff / 3600) . 'h';
|
||||
if ($diff < 604800) return floor($diff / 86400) . 'd';
|
||||
return gmdate('M j', $timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user