v1.7.0: sync live — shortcode-only, wordmark, fixed fatal, no auto-inject

This commit is contained in:
2026-06-07 17:49:23 -07:00
parent 2788dc8d96
commit 79e124f282
25 changed files with 1024 additions and 1300 deletions
+25 -51
View File
@@ -21,6 +21,7 @@ class Beep_Shortcode {
'args' => [
'sort' => ['default' => 'latest'],
'limit' => ['default' => 50, 'validate_callback' => function ($v) { return is_numeric($v); }],
'offset' => ['default' => 0, 'validate_callback' => function ($v) { return is_numeric($v); }],
],
]);
}
@@ -29,32 +30,39 @@ class Beep_Shortcode {
* REST endpoint: re-render the feed list with the given sort.
*/
public static function fetch_feed($request) {
$sort = $request->get_param('sort') === 'top' ? 'top' : 'latest';
$limit = max(1, (int) $request->get_param('limit'));
$posts = ($sort === 'top') ? self::get_top_beeps($limit) : self::get_latest_beeps($limit);
$sort = $request->get_param('sort') === 'top' ? 'top' : 'latest';
$limit = max(1, (int) $request->get_param('limit'));
$offset = max(0, (int) $request->get_param('offset'));
$posts = ($sort === 'top') ? self::get_top_beeps($limit + 1, $offset) : self::get_latest_beeps($limit + 1, $offset);
$has_more = count($posts) > $limit;
if ($has_more) {
$posts = array_slice($posts, 0, $limit);
}
$html = '';
foreach ($posts as $p) {
$html .= beep_render_post($p);
}
if ($html === '') {
$html = '<div class="beep-empty">No beeps yet.</div>';
if ($html === '' && $offset === 0) {
$empty_bird = beep_bird_svg( ['size' => 64, 'fill' => '#4a90c4'] );
$html = '<div class="beep-empty"><div class="beep-empty-icon">' . $empty_bird . '</div><p>No beeps yet.</p><span>Be the first to share something!</span></div>';
}
return rest_ensure_response(['html' => $html, 'sort' => $sort]);
return rest_ensure_response(['html' => $html, 'sort' => $sort, 'has_more' => $has_more, 'offset' => $offset + count($posts)]);
}
public static function get_latest_beeps($limit) {
public static function get_latest_beeps($limit, $offset = 0) {
global $wpdb;
return $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->posts}
WHERE post_type = %s AND post_status = 'publish'
ORDER BY post_date DESC
LIMIT %d",
Beep_CPT::POST_TYPE, $limit
LIMIT %d OFFSET %d",
Beep_CPT::POST_TYPE, $limit, $offset
));
}
public static function get_top_beeps($limit) {
public static function get_top_beeps($limit, $offset = 0) {
global $wpdb;
$likes = Beep_Likes::table_name();
return $wpdb->get_results($wpdb->prepare(
@@ -68,8 +76,8 @@ class Beep_Shortcode {
) l ON l.post_id = p.ID
WHERE p.post_type = %s AND p.post_status = 'publish'
ORDER BY COALESCE(l.cnt, 0) DESC, p.post_date DESC
LIMIT %d",
Beep_CPT::POST_TYPE, $limit
LIMIT %d OFFSET %d",
Beep_CPT::POST_TYPE, $limit, $offset
));
}
@@ -86,21 +94,12 @@ class Beep_Shortcode {
$posts = ($sort === 'top') ? self::get_top_beeps($limit) : self::get_latest_beeps($limit);
$has_posts = !empty($posts);
// Show magic login form if not logged in
if (!is_user_logged_in()) {
return Beep_Magic_Links::render_login_form() . beep_render_public_feed($posts, $atts);
}
ob_start();
?>
<div class="beep-feed" data-beep-feed>
<div class="beep-embed">
<div class="beep-feed-header">
<?php if (!empty($atts['show_wordmark'])): ?>
<?php echo beep_logo_svg(); ?>
<?php else: ?>
<span class="beep-feed-header-text"><?php echo esc_html($atts['header']); ?></span>
<?php endif; ?>
<div style="display:flex;align-items:center;justify-content:center;gap:8px;"><strong style="color:#FFFFFF;">Messages from </strong><img src="https://sami-ahmed.net/wp-content/plugins/beep/assets/beep-wordmark.png" alt="Beep!" style="height:22px;width:auto;vertical-align:middle;"></div>
</div>
<?php if ($has_posts) : ?>
@@ -112,21 +111,7 @@ class Beep_Shortcode {
</div>
<?php endif; ?>
<?php if (is_user_logged_in() && !beep_user_is_banned(get_current_user_id())) : ?>
<?php echo beep_render_composer(); ?>
<?php elseif (is_user_logged_in()) : ?>
<div class="beep-notice beep-notice-banned">
Your account has been suspended from beeping.
</div>
<?php else : ?>
<div class="beep-notice beep-notice-login">
<p><strong>Join in.</strong> Sign in to like and reply.</p>
<a class="beep-button" href="<?php echo esc_url(wp_login_url(get_permalink())); ?>">Log in</a>
<?php if (get_option('users_can_register')) : ?>
<a class="beep-button beep-button-secondary" href="<?php echo esc_url(wp_registration_url()); ?>">Sign up</a>
<?php endif; ?>
</div>
<?php endif; ?>
<?php echo beep_render_composer(); ?>
<div class="beep-list" data-beep-list>
<?php
@@ -135,26 +120,15 @@ class Beep_Shortcode {
echo beep_render_post($p);
}
} else {
echo '<div class="beep-empty">No beeps yet.</div>';
$empty_bird = beep_bird_svg( ['size' => 64, 'fill' => '#4a90c4'] );
echo '<div class="beep-empty"><div class="beep-empty-icon">' . $empty_bird . '</div><p>No beeps yet.</p><span>Be the first to share something!</span></div>';
}
?>
</div><!-- .beep-list -->
</div><!-- .beep-embed -->
</div><!-- .beep-feed -->
<?php
// Output BeepConfig and beep.js inline since wp_enqueue_scripts isn't working
$beep_config = sprintf(
'<script>var BeepConfig=%s;</script>',
json_encode([
'restUrl' => esc_url_raw(rest_url('beep/v1/')),
'nonce' => wp_create_nonce('wp_rest'),
'charLimit' => BEEP_CHAR_LIMIT,
'loginUrl' => esc_url_raw(wp_login_url(is_singular() ? get_permalink() : home_url('/'))),
'isLoggedIn' => is_user_logged_in(),
])
);
$beep_script = '<script src="' . esc_url(BEEP_URL . 'assets/beep.js?ver=' . BEEP_VERSION) . '" defer></script>';
return ob_get_clean() . $beep_config . $beep_script . beep_render_thread_modal() . beep_render_gif_modal();
return ob_get_clean() . beep_render_thread_modal() . beep_render_gif_modal();
}
/**