| 1 |
<?php |
| 2 |
/** |
| 3 |
* Comments — the moderation window, as an OpenStation app. |
| 4 |
* |
| 5 |
* Claims the frozen id `desktop-mode-comments` (see AGENTS.md), so the |
| 6 |
* URL remap, the dock tile, the saved sessions and every window-links |
| 7 |
* identity key on it. A two-pane conversation view: the rail of |
| 8 |
* conversations on the left, the nested thread with its actions and |
| 9 |
* composer on the right, painted by the client view (`comments.os.ts`) |
| 10 |
* from the `data()` below. |
| 11 |
* |
| 12 |
* (Header kept short on purpose: Plugin Check's direct-access scan |
| 13 |
* reads only the first 50 raw lines, and the guard below must land |
| 14 |
* inside that window.) |
| 15 |
* |
| 16 |
* @package OpenStation |
| 17 |
*/ |
| 18 |
|
| 19 |
namespace OpenStation\Apps\Comments; |
| 20 |
|
| 21 |
use OpenStation\App; |
| 22 |
use OpenStation\App\Os; |
| 23 |
use OpenStation\App\State; |
| 24 |
|
| 25 |
// Direct access, unless a standalone host is booting on bare PHP. |
| 26 |
if ( ! defined( 'ABSPATH' ) ) { |
| 27 |
defined( 'OPENSTATION_STANDALONE' ) || exit; |
| 28 |
} |
| 29 |
|
| 30 |
require_once __DIR__ . '/parts/permissions.php'; |
| 31 |
require_once __DIR__ . '/parts/spam-score.php'; |
| 32 |
require_once __DIR__ . '/parts/ai-moderation.php'; |
| 33 |
require_once __DIR__ . '/parts/fields.php'; |
| 34 |
require_once __DIR__ . '/parts/rest.php'; |
| 35 |
require_once __DIR__ . '/parts/app.php'; |
| 36 |
|
| 37 |
return App::define( 'desktop-mode-comments' ) |
| 38 |
->title( __( 'Comments', 'desktop-mode' ) ) |
| 39 |
->icon( 'dashicons-admin-comments' ) |
| 40 |
->size( 1180, 760 ) |
| 41 |
->min_size( 760, 480 ) |
| 42 |
// No dock or wallpaper tile from this registration: the Comments |
| 43 |
// dock tile lives in WordPress's `$menu`, and the shell's URL remap |
| 44 |
// routes its click here when the opt-in is on. |
| 45 |
->placement( 'none' ) |
| 46 |
->can( |
| 47 |
static function () { |
| 48 |
return \openstation_comments_window_user_can_register(); |
| 49 |
} |
| 50 |
) |
| 51 |
// Static facts the view reads on every paint — shipped once with |
| 52 |
// the window config, never riding a response. Resolved when the |
| 53 |
// manifest is built, for the acting user. UI-side gating is |
| 54 |
// polish: every action re-checks the cap server-side. |
| 55 |
->config( |
| 56 |
static function () { |
| 57 |
return array( |
| 58 |
'currentUserId' => (int) get_current_user_id(), |
| 59 |
'canModerate' => current_user_can( 'moderate_comments' ), |
| 60 |
'canEditComments' => current_user_can( 'edit_posts' ), |
| 61 |
); |
| 62 |
} |
| 63 |
) |
| 64 |
->state( |
| 65 |
array( |
| 66 |
'tab' => 'pending', |
| 67 |
'search' => '', |
| 68 |
'page' => 1, |
| 69 |
// The `edit-comments.php?p=<id>` scope; 0 is every post. |
| 70 |
'post' => 0, |
| 71 |
// The conversation on screen; 0 is the placeholder. |
| 72 |
'selected' => 0, |
| 73 |
// Bumped by every mutation that moves rows between views, so |
| 74 |
// the client's page accumulation starts clean from page 1. |
| 75 |
'gen' => 0, |
| 76 |
) |
| 77 |
) |
| 78 |
->mount( __NAMESPACE__ . '\mount' ) |
| 79 |
->action( 'reopen', __NAMESPACE__ . '\reopen_action' ) |
| 80 |
->action( 'filter', __NAMESPACE__ . '\filter_action' ) |
| 81 |
->action( 'page', __NAMESPACE__ . '\page_action' ) |
| 82 |
->action( 'select', __NAMESPACE__ . '\select_action' ) |
| 83 |
->action( 'moderate', __NAMESPACE__ . '\moderate_action' ) |
| 84 |
->action( 'reply', __NAMESPACE__ . '\reply_action' ) |
| 85 |
->action( 'edit', __NAMESPACE__ . '\edit_action' ) |
| 86 |
// A comment changing anywhere on the desktop repaints the window. |
| 87 |
->watch( 'comment' ) |
| 88 |
->data( __NAMESPACE__ . '\data' ); |
| 89 |
|