feat(v1.8.0): Twitter-style conversation modal, light theme, major CSS/JS refactor
This commit is contained in:
@@ -45,8 +45,7 @@ class Beep_Shortcode {
|
||||
$html .= beep_render_post($p);
|
||||
}
|
||||
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>';
|
||||
$html = self::empty_state_html();
|
||||
}
|
||||
return rest_ensure_response(['html' => $html, 'sort' => $sort, 'has_more' => $has_more, 'offset' => $offset + count($posts)]);
|
||||
}
|
||||
@@ -84,30 +83,37 @@ class Beep_Shortcode {
|
||||
public static function render_feed($atts) {
|
||||
$atts = shortcode_atts([
|
||||
'limit' => 50,
|
||||
'header' => 'Beep!',
|
||||
'show_wordmark' => true,
|
||||
'header' => 'Messages from',
|
||||
'show_wordmark' => 'yes',
|
||||
'sort' => 'latest',
|
||||
'theme' => 'auto', // auto | dark | light
|
||||
], $atts, 'beep_feed');
|
||||
|
||||
$limit = max(1, (int) $atts['limit']);
|
||||
$sort = ($atts['sort'] === 'top') ? 'top' : 'latest';
|
||||
$theme = in_array($atts['theme'], ['dark', 'light'], true) ? $atts['theme'] : 'auto';
|
||||
$show_wordmark = !in_array(strtolower((string) $atts['show_wordmark']), ['no', 'false', '0'], true);
|
||||
$posts = ($sort === 'top') ? self::get_top_beeps($limit) : self::get_latest_beeps($limit);
|
||||
$has_posts = !empty($posts);
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="beep-feed" data-beep-feed>
|
||||
<div class="beep-embed">
|
||||
<div class="beep-feed-header">
|
||||
<div style="display:flex;align-items:center;justify-content:center;gap:8px;"><strong style="color:#FFFFFF;">Messages from </strong><img src="<?php echo esc_url( BEEP_URL . 'assets/beep-wordmark.png?v=' . BEEP_VERSION ); ?>" alt="Beep!" style="height:30px;width:auto;vertical-align:middle;"></div>
|
||||
</div>
|
||||
<div class="beep-feed beep-embed beep-theme-<?php echo esc_attr($theme); ?>" data-beep-feed>
|
||||
<header class="beep-feed-header">
|
||||
<?php if ($atts['header'] !== '') : ?>
|
||||
<span class="beep-feed-header-title"><?php echo esc_html($atts['header']); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_wordmark) : ?>
|
||||
<img class="beep-feed-wordmark" src="<?php echo esc_url(BEEP_URL . 'assets/beep-wordmark.png?v=' . BEEP_VERSION); ?>" alt="Beep!">
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<?php if ($has_posts) : ?>
|
||||
<div class="beep-tabs" data-beep-tabs role="tablist">
|
||||
<button type="button" class="beep-tab <?php echo $sort === 'latest' ? 'is-active' : ''; ?>"
|
||||
data-beep-sort="latest" role="tab">Latest</button>
|
||||
data-beep-sort="latest" role="tab"><span>Latest</span></button>
|
||||
<button type="button" class="beep-tab <?php echo $sort === 'top' ? 'is-active' : ''; ?>"
|
||||
data-beep-sort="top" role="tab">Top</button>
|
||||
data-beep-sort="top" role="tab"><span>Top</span></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -120,15 +126,23 @@ class Beep_Shortcode {
|
||||
echo beep_render_post($p);
|
||||
}
|
||||
} else {
|
||||
$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>';
|
||||
echo self::empty_state_html();
|
||||
}
|
||||
?>
|
||||
</div><!-- .beep-list -->
|
||||
</div><!-- .beep-embed -->
|
||||
|
||||
<?php echo beep_render_thread_modal() . beep_render_gif_modal(); ?>
|
||||
</div><!-- .beep-feed -->
|
||||
<?php
|
||||
return ob_get_clean() . beep_render_thread_modal() . beep_render_gif_modal();
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty-state markup shared by shortcode and REST.
|
||||
*/
|
||||
public static function empty_state_html() {
|
||||
$empty_bird = beep_bird_svg(['size' => 64]);
|
||||
return '<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>';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,6 +236,29 @@ class Beep_Shortcode {
|
||||
'callback' => [__CLASS__, 'get_thread'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
register_rest_route('beep/v1', '/thread/(?P<post_id>\d+)/html', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [__CLASS__, 'get_thread_html'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* REST endpoint: server-rendered conversation view (root post + replies tree).
|
||||
* Reuses the exact same markup/styles as the feed.
|
||||
*/
|
||||
public static function get_thread_html($request) {
|
||||
$post_id = (int) $request->get_param('post_id');
|
||||
$post = get_post($post_id);
|
||||
if (!$post || $post->post_type !== Beep_CPT::POST_TYPE || $post->post_status !== 'publish') {
|
||||
return new WP_Error('not_found', 'Beep not found.', 404);
|
||||
}
|
||||
$html = beep_render_post($post, ['in_thread' => true, 'show_replies' => true]);
|
||||
return rest_ensure_response([
|
||||
'html' => $html,
|
||||
'id' => $post_id,
|
||||
'reply_count' => Beep_Replies::reply_count($post_id),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function get_thread($request) {
|
||||
|
||||
Reference in New Issue
Block a user