| @@ -1,259 +1,203 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Desktop Mode — Recycle Bin: window + icon registration. | |
| 3 | + * OpenStation — Recycle Bin: tile art, gate, shell config. | |
| 4 | 4 | * |
| 5 | - * Native window with id `desktop-mode-recycle-bin`, pinned to the taskbar with a | |
| 6 | - * matching wallpaper icon. Like the code editor, the template body is a | |
| 7 | - * static skeleton that the JS bundle enhances on first open — the table | |
| 8 | - * is populated from the REST list endpoint at render time. | |
| 5 | + * The bin WINDOW is an App Framework app (`apps/trash/trash.os.php`) | |
| 6 | + * that claims the frozen `desktop-mode-recycle-bin` id, so every | |
| 7 | + * shortcut, dock placement and drop target keeps working. This file | |
| 8 | + * keeps what the shell needs regardless of the window: the two bin | |
| 9 | + * drawings (the dock tile's empty/full swap — `icon-state.ts` — and | |
| 10 | + * the app's own `ctx.host.setIcon()` swap read the same pair), the | |
| 11 | + * capability gate, the shell-config seed that makes the tile correct | |
| 12 | + * on the very first paint, and the stylesheet enqueue (the | |
| 13 | + * drag-to-trash drop-target highlight must exist at boot, not at | |
| 14 | + * window-open). | |
| 9 | 15 | * |
| 10 | - * Both registrations are filterable via the standard | |
| 11 | - * `desktop_mode_recycle_bin_window_args` / `desktop_mode_recycle_bin_icon_args` | |
| 12 | - * filters so a plugin can swap the icon, change the dimensions, or | |
| 13 | - * restrict who sees the bin without touching this file. | |
| 14 | - * | |
| 15 | - * @package WPDesktopMode | |
| 16 | - * @since 0.19.0 | |
| 16 | + * @package OpenStation | |
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | 19 | defined( 'ABSPATH' ) || exit; |
| 20 | 20 | |
| 21 | 21 | /** |
| 22 | - * Echoes the recycle bin window's template body. | |
| 22 | + * The bin SVG, used by the app window's icon and its dock tile. | |
| 23 | 23 | * |
| 24 | - * The shell wraps this in `<template id="desktop-mode-native-window-desktop-mode-recycle-bin">` | |
| 25 | - * and clones it into the window body BEFORE the JS render callback runs. | |
| 26 | - * The `data-desktop-mode-recycle-bin-*` hooks below are the contract the JS | |
| 27 | - * relies on — keep them intact (or rename via the filter) when | |
| 28 | - * customizing the layout. | |
| 24 | + * The bin used to be `dashicons-trash`, which worked but wore the | |
| 25 | + * wrong clothes. Dashicons are WP core's icon set: solid fills on a | |
| 26 | + * 20-unit grid, tuned for admin-menu sizes. The shell's own icons are | |
| 27 | + * outlined vessels on a 64-unit grid at stroke 3. Sitting next to | |
| 28 | + * WP Explorer, Corkboard and Games in the dock, the Dashicon was | |
| 29 | + * visibly a guest from another system: heavier, tighter, and drawn to | |
| 30 | + * a different rhythm. | |
| 29 | 31 | * |
| 30 | - * @since 0.19.0 | |
| 32 | + * So this is the same object, redrawn to the house rule the other | |
| 33 | + * three follow: an outlined vessel with solid content, three elements | |
| 34 | + * because it renders as small as 20px in the dock. The lid is the | |
| 35 | + * solid one, which gives the mark a single dense horizontal to be | |
| 36 | + * recognised by when the tapered body below it thins out. | |
| 37 | + * | |
| 38 | + * Drawn in `currentColor`, so `renderIcon()` paints it as a CSS mask | |
| 39 | + * and it takes the surface's own text colour. Dashicons already | |
| 40 | + * inherited colour, being font glyphs; the point of the change is the | |
| 41 | + * drawing, not the theming. | |
| 42 | + * | |
| 43 | + * Note that the row actions inside the bin window, and the "Move to | |
| 44 | + * trash" entries in context menus, stay on `dashicons-trash`. Those | |
| 45 | + * are menu glyphs sitting among other menu glyphs, and they should | |
| 46 | + * match their neighbours rather than this icon. | |
| 47 | + * | |
| 48 | + * The bin has two states. Empty is the vessel on its own; full adds | |
| 49 | + * three crumpled balls inside it and knocks the lid askew. | |
| 50 | + * | |
| 51 | + * @param bool $full Whether to draw the bin holding something. | |
| 52 | + * @return string Raw `<svg>` markup. | |
| 31 | 53 | */ |
| 32 | -function desktop_mode_recycle_bin_render_template() { | |
| 33 | - ob_start(); | |
| 34 | - ?> | |
| 35 | - <div class="desktop-mode-recycle-bin" data-desktop-mode-recycle-bin-root> | |
| 36 | - <header class="desktop-mode-recycle-bin__toolbar" data-desktop-mode-recycle-bin-toolbar> | |
| 37 | - <div class="desktop-mode-recycle-bin__toolbar-left"> | |
| 38 | - <wpd-segmented data-desktop-mode-recycle-bin-filter> | |
| 39 | - <wpd-segment value="" selected><?php esc_html_e( 'All', 'desktop-mode' ); ?></wpd-segment> | |
| 40 | - <wpd-segment value="post"><?php esc_html_e( 'Posts', 'desktop-mode' ); ?></wpd-segment> | |
| 41 | - <wpd-segment value="page"><?php esc_html_e( 'Pages', 'desktop-mode' ); ?></wpd-segment> | |
| 42 | - <?php | |
| 43 | - // The Media segment is only useful when WP itself routes | |
| 44 | - // attachment deletions through Trash. That gate is the | |
| 45 | - // `MEDIA_TRASH` constant — defaults to false in core, can | |
| 46 | - // be flipped to true from `wp-config.php`. Without it, | |
| 47 | - // attachments permanent-delete on first click and the | |
| 48 | - // Trash bin will never have anything in this bucket, so | |
| 49 | - // the tab would always read "0" and confuse users. | |
| 50 | - if ( defined( 'MEDIA_TRASH' ) && MEDIA_TRASH ) : | |
| 51 | - ?> | |
| 52 | - <wpd-segment value="attachment"><?php esc_html_e( 'Media', 'desktop-mode' ); ?></wpd-segment> | |
| 53 | - <?php | |
| 54 | - endif; | |
| 55 | - ?> | |
| 56 | - <wpd-segment value="comment"><?php esc_html_e( 'Comments', 'desktop-mode' ); ?></wpd-segment> | |
| 57 | - <wpd-segment value="desktop"><?php esc_html_e( 'Desktop', 'desktop-mode' ); ?></wpd-segment> | |
| 58 | - </wpd-segmented> | |
| 59 | - <wpd-text-field | |
| 60 | - data-desktop-mode-recycle-bin-search | |
| 61 | - placeholder="<?php esc_attr_e( 'Search trash…', 'desktop-mode' ); ?>" | |
| 62 | - ></wpd-text-field> | |
| 63 | - </div> | |
| 64 | - <div class="desktop-mode-recycle-bin__toolbar-right" data-desktop-mode-recycle-bin-bulk hidden> | |
| 65 | - <span class="desktop-mode-recycle-bin__count" data-desktop-mode-recycle-bin-count></span> | |
| 66 | - <wpd-button variant="secondary" data-desktop-mode-recycle-bin-restore-selected> | |
| 67 | - <span class="dashicons dashicons-image-rotate" aria-hidden="true"></span> | |
| 68 | - <?php esc_html_e( 'Restore', 'desktop-mode' ); ?> | |
| 69 | - </wpd-button> | |
| 70 | - <wpd-button variant="secondary" data-desktop-mode-recycle-bin-pin-to-desktop> | |
| 71 | - <span class="dashicons dashicons-desktop" aria-hidden="true"></span> | |
| 72 | - <?php esc_html_e( 'Pin to desktop', 'desktop-mode' ); ?> | |
| 73 | - </wpd-button> | |
| 74 | - <wpd-button variant="danger" data-desktop-mode-recycle-bin-purge-selected> | |
| 75 | - <span class="dashicons dashicons-trash" aria-hidden="true"></span> | |
| 76 | - <?php esc_html_e( 'Delete forever', 'desktop-mode' ); ?> | |
| 77 | - </wpd-button> | |
| 78 | - </div> | |
| 79 | - <div class="desktop-mode-recycle-bin__toolbar-trailing"> | |
| 80 | - <wpd-button variant="ghost" data-desktop-mode-recycle-bin-refresh title="<?php esc_attr_e( 'Refresh', 'desktop-mode' ); ?>"> | |
| 81 | - <span class="dashicons dashicons-update" aria-hidden="true"></span> | |
| 82 | - </wpd-button> | |
| 83 | - <wpd-button variant="danger" data-desktop-mode-recycle-bin-empty> | |
| 84 | - <span class="dashicons dashicons-trash" aria-hidden="true"></span> | |
| 85 | - <?php esc_html_e( 'Empty bin', 'desktop-mode' ); ?> | |
| 86 | - </wpd-button> | |
| 87 | - </div> | |
| 88 | - </header> | |
| 89 | - <div class="desktop-mode-recycle-bin__body" data-desktop-mode-recycle-bin-body> | |
| 90 | - <wpd-table | |
| 91 | - data-desktop-mode-recycle-bin-table | |
| 92 | - selectable="multi" | |
| 93 | - sticky-header | |
| 94 | - hover | |
| 95 | - striped | |
| 96 | - loading | |
| 97 | - > | |
| 98 | - <div slot="empty" class="desktop-mode-recycle-bin__empty"> | |
| 99 | - <span class="dashicons dashicons-trash" aria-hidden="true"></span> | |
| 100 | - <p><?php esc_html_e( 'The recycle bin is empty.', 'desktop-mode' ); ?></p> | |
| 101 | - <p class="desktop-mode-recycle-bin__empty-hint"> | |
| 102 | - <?php esc_html_e( 'Deleted posts, pages, and media show up here. Restoring puts them back where they were.', 'desktop-mode' ); ?> | |
| 103 | - </p> | |
| 104 | - </div> | |
| 105 | - </wpd-table> | |
| 106 | - </div> | |
| 107 | - </div> | |
| 108 | - <?php | |
| 109 | - $html = (string) ob_get_clean(); | |
| 54 | +function openstation_recycle_bin_icon_svg( $full = false ) { | |
| 55 | + // The lid and the handle travel together. In the full state the | |
| 56 | + // pair is lifted clear of the rim and tipped, hinged at the far | |
| 57 | + // corner, the way a lid sits on a bin that has too much in it. | |
| 58 | + // | |
| 59 | + // It was a 2.5-unit lift at 8 degrees, which on the 20px dock | |
| 60 | + // tile and the 58px home tile was no difference at all: the bin | |
| 61 | + // read as empty while it held things. At 4 units and 12 degrees | |
| 62 | + // (a positive angle turns clockwise about the far corner, so the | |
| 63 | + // near end rises) the lid's near end clears the rim by a fifth | |
| 64 | + // of the body's height and its far end by nine units, and the | |
| 65 | + // wedge of light under it survives every size the mark is drawn. | |
| 66 | + $lid_transform = $full | |
| 67 | + ? ' transform="translate(0 -4) rotate(12 52 21.5)"' | |
| 68 | + : ''; | |
| 110 | 69 | |
| 111 | - /** | |
| 112 | - * Filter the recycle bin window's template HTML. | |
| 113 | - * | |
| 114 | - * Keep the `data-desktop-mode-recycle-bin-*` hooks intact so the JS render | |
| 115 | - * callback can find its mount points, or rename them and update the | |
| 116 | - * matching constants in `src/recycle-bin/index.ts`. | |
| 117 | - * | |
| 118 | - * @since 0.19.0 | |
| 119 | - * | |
| 120 | - * @param string $html Default template HTML. | |
| 121 | - */ | |
| 122 | - $filtered = (string) apply_filters( 'desktop_mode_recycle_bin_template_html', $html ); | |
| 123 | - echo wp_kses( $filtered, desktop_mode_native_window_allowed_html() ); | |
| 70 | + $svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">' | |
| 71 | + . '<g' . $lid_transform . '>' | |
| 72 | + // The handle, outlined so it reads as a loop rather than a tab. | |
| 73 | + . '<path d="M25 19v-2.5a3.5 3.5 0 0 1 3.5-3.5h7a3.5 3.5 0 0 1 3.5 3.5V19" fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>' | |
| 74 | + // The lid: the one solid element, and the widest, so it anchors | |
| 75 | + // the mark at small sizes. | |
| 76 | + . '<rect x="10" y="19" width="44" height="5" rx="2.5" fill="currentColor"/>' | |
| 77 | + . '</g>' | |
| 78 | + // The body, tapered towards the base the way a real bin is, which | |
| 79 | + // is also what separates it from a plain bucket. | |
| 80 | + // | |
| 81 | + // 27 units tall, narrowing to 71% of its top width. It was 24 | |
| 82 | + // tall at 59%, which drew a shallower, more conical tub than a | |
| 83 | + // bin actually is, and left an interior too cramped to hold | |
| 84 | + // anything. Taken further, to a bottom much past 75%, the walls | |
| 85 | + // go vertical and the mark reads as a bucket; this sits at the | |
| 86 | + // edge of that. | |
| 87 | + . '<path d="M15.5 28.5h33l-1.2 24a3.5 3.5 0 0 1-3.5 3H20.2a3.5 3.5 0 0 1-3.5-3z" fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>'; | |
| 88 | + | |
| 89 | + if ( $full ) { | |
| 90 | + // Three crumpled balls, one path with three subpaths so the | |
| 91 | + // mark stays at four elements rather than six. | |
| 92 | + // | |
| 93 | + // Each is a seven-point polygon on a radius jittered between | |
| 94 | + // 0.81 and 1.0, with a same-colour round-joined stroke that | |
| 95 | + // turns the corners into creases instead of points. Seven | |
| 96 | + // points rather than nine because a ball this small needs | |
| 97 | + // deeper, fewer facets to keep any texture at all. | |
| 98 | + // | |
| 99 | + // The layout is staggered deliberately. Two balls at the same | |
| 100 | + // height with a third centred under them reads as a face, and | |
| 101 | + // it cannot be unseen once noticed, so no two share a y (the | |
| 102 | + // top pair are 4.2 units apart) and the third sits below-left | |
| 103 | + // rather than on the centreline. Every gap in the mark clears | |
| 104 | + // 2 units: 5.1 to the left wall, 4.4 to the right, 2.8 to the | |
| 105 | + // rim, 2.5 to the base, and 2.5 to 4.2 between the balls. Those | |
| 106 | + // last three decide how far down the size ladder they stay | |
| 107 | + // three things instead of one. | |
| 108 | + $svg .= '<path d="M29.7 38 27.4 39.5 24.7 39.6 23.6 37.1 24.1 34.4 26.8 34.1 29.2 35.1' | |
| 109 | + . 'ZM39.4 44.1 36.7 43.5 34.8 41.6 35.8 39.1 38.1 37.6 40.2 39.3 41.1 41.8' | |
| 110 | + . 'ZM28.1 50.4 27 47.9 27.4 45.2 30 44.6 32.6 45.6 32.4 48.3 31 50.5Z"' | |
| 111 | + . ' fill="currentColor" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>'; | |
| 112 | + // A fourth, larger sheet rides the rim under the lifted end of | |
| 113 | + // the lid — the one element of the full state that is legible | |
| 114 | + // at 20px, where the balls inside the body are a texture at | |
| 115 | + // best. Same seven-point construction, twice the radius, | |
| 116 | + // straddling the rim (y 28.5) so it reads as spilling out | |
| 117 | + // rather than sitting in. | |
| 118 | + $svg .= '<path d="M30 26 27.3 30 22.7 31.7 19.5 28.2 18.6 23.4 22.8 20.7 27.6 21.6Z"' | |
| 119 | + . ' fill="currentColor" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>'; | |
| 120 | + } | |
| 121 | + | |
| 122 | + return $svg . '</svg>'; | |
| 124 | 123 | } |
| 125 | 124 | |
| 126 | 125 | /** |
| 126 | + * Both bin states as base64 data URIs, ready for `renderIcon()`. | |
| 127 | + * | |
| 128 | + * The client swaps between these as the count crosses zero, so both | |
| 129 | + * have to reach the page on the first paint. Cheap: two string | |
| 130 | + * builds and two base64 encodes, no queries. | |
| 131 | + * | |
| 132 | + * @return array{empty:string,full:string} | |
| 133 | + */ | |
| 134 | +function openstation_recycle_bin_icon_uris() { | |
| 135 | + return array( | |
| 136 | + 'empty' => 'data:image/svg+xml;base64,' . base64_encode( openstation_recycle_bin_icon_svg( false ) ), | |
| 137 | + 'full' => 'data:image/svg+xml;base64,' . base64_encode( openstation_recycle_bin_icon_svg( true ) ), | |
| 138 | + ); | |
| 139 | +} | |
| 140 | + | |
| 141 | +/** | |
| 127 | 142 | * Whether the current user should see the recycle bin at all. |
| 128 | 143 | * |
| 129 | 144 | * Filterable so plugins can hide it from authors/contributors who |
| 130 | 145 | * don't manage trash, or invert the gate to expose it to a custom |
| 131 | - * role. | |
| 146 | + * role. The app's gate (`apps/trash/trash.os.php`) delegates here. | |
| 132 | 147 | * |
| 133 | - * @since 0.19.0 | |
| 134 | - * | |
| 135 | 148 | * @return bool |
| 136 | 149 | */ |
| 137 | -function desktop_mode_recycle_bin_user_can_use() { | |
| 150 | +function openstation_recycle_bin_user_can_use() { | |
| 138 | 151 | $can = current_user_can( 'edit_posts' ); |
| 139 | 152 | |
| 140 | 153 | /** |
| 141 | 154 | * Filter whether the current user can see the recycle bin window. |
| 142 | 155 | * |
| 143 | - * @since 0.19.0 | |
| 144 | - * | |
| 145 | 156 | * @param bool $can Default: edit_posts capability. |
| 146 | 157 | */ |
| 147 | - return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_use', $can ); | |
| 158 | + return (bool) apply_filters( 'openstation_recycle_bin_user_can_use', $can ); | |
| 148 | 159 | } |
| 149 | 160 | |
| 150 | 161 | /** |
| 151 | - * Register the recycle bin window + desktop icon on `init`. | |
| 162 | + * Enqueue the bin stylesheet with the shell. | |
| 152 | 163 | * |
| 153 | - * Hooked at priority 20, after `components.php` has bootstrapped the | |
| 154 | - * native-window registry — same timing as the code editor. | |
| 155 | - * | |
| 156 | - * @since 0.19.0 | |
| 164 | + * Not a window-open companion: the sheet also paints the | |
| 165 | + * drag-to-trash drop-target highlight on the CLOSED bin's dock tile | |
| 166 | + * (`data-os-trash-drop-active`), which must work before the window | |
| 167 | + * has ever opened. | |
| 157 | 168 | */ |
| 158 | -function desktop_mode_recycle_bin_register_window() { | |
| 159 | - if ( ! desktop_mode_recycle_bin_user_can_use() ) { | |
| 169 | +function openstation_recycle_bin_enqueue_style() { | |
| 170 | + if ( ! openstation_recycle_bin_user_can_use() ) { | |
| 160 | 171 | return; |
| 161 | 172 | } |
| 162 | - | |
| 163 | - $window_args = array( | |
| 164 | - 'title' => __( 'Recycle Bin', 'desktop-mode' ), | |
| 165 | - 'icon' => 'dashicons-trash', | |
| 166 | - 'template' => 'desktop_mode_recycle_bin_render_template', | |
| 167 | - 'script' => 'desktop-mode-recycle-bin', | |
| 168 | - 'width' => 880, | |
| 169 | - 'height' => 560, | |
| 170 | - 'min_width' => 520, | |
| 171 | - 'min_height' => 360, | |
| 172 | - 'placement' => 'taskbar', | |
| 173 | - ); | |
| 174 | - | |
| 175 | - /** | |
| 176 | - * Filter the args used to register the recycle bin native window. | |
| 177 | - * | |
| 178 | - * @since 0.19.0 | |
| 179 | - * | |
| 180 | - * @param array $window_args Args passed to `desktop_mode_register_window()`. | |
| 181 | - */ | |
| 182 | - $window_args = (array) apply_filters( 'desktop_mode_recycle_bin_window_args', $window_args ); | |
| 183 | - | |
| 184 | - $registered = desktop_mode_register_window( 'desktop-mode-recycle-bin', $window_args ); | |
| 185 | - if ( is_wp_error( $registered ) ) { | |
| 186 | - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log | |
| 187 | - error_log( '[desktop-mode] Recycle bin window registration failed: ' . $registered->get_error_message() ); | |
| 188 | - return; | |
| 189 | - } | |
| 190 | - | |
| 191 | - $icon_args = array( | |
| 192 | - 'title' => __( 'Recycle Bin', 'desktop-mode' ), | |
| 193 | - 'icon' => 'dashicons-trash', | |
| 194 | - 'window' => 'desktop-mode-recycle-bin', | |
| 195 | - 'position' => 80, | |
| 196 | - ); | |
| 197 | - | |
| 198 | - /** | |
| 199 | - * Filter the args used to register the recycle bin desktop icon. | |
| 200 | - * | |
| 201 | - * @since 0.19.0 | |
| 202 | - * | |
| 203 | - * @param array $icon_args Args passed to `desktop_mode_register_icon()`. | |
| 204 | - */ | |
| 205 | - $icon_args = (array) apply_filters( 'desktop_mode_recycle_bin_icon_args', $icon_args ); | |
| 206 | - | |
| 207 | - desktop_mode_register_icon( 'desktop-mode-recycle-bin', $icon_args ); | |
| 208 | -} | |
| 209 | -add_action( 'init', 'desktop_mode_recycle_bin_register_window', 20 ); | |
| 210 | - | |
| 211 | -/** | |
| 212 | - * Localize REST endpoints for the JS bundle. | |
| 213 | - * | |
| 214 | - * Same pattern as the code editor: the bundle reads its config off | |
| 215 | - * `window.desktopModeRecycleBinConfig` and never hardcodes URLs. | |
| 216 | - * | |
| 217 | - * @since 0.19.0 | |
| 218 | - */ | |
| 219 | -function desktop_mode_recycle_bin_localize_config() { | |
| 220 | - if ( ! desktop_mode_recycle_bin_user_can_use() ) { | |
| 221 | - return; | |
| 222 | - } | |
| 223 | - | |
| 224 | - wp_localize_script( | |
| 225 | - 'desktop-mode-recycle-bin', | |
| 226 | - 'desktopModeRecycleBinConfig', | |
| 227 | - array( | |
| 228 | - 'restNonce' => wp_create_nonce( 'wp_rest' ), | |
| 229 | - 'listUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin' ) ), | |
| 230 | - 'restoreUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/restore' ) ), | |
| 231 | - 'purgeUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/purge' ) ), | |
| 232 | - 'emptyUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/empty' ) ), | |
| 233 | - 'countUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/count' ) ), | |
| 234 | - ) | |
| 235 | - ); | |
| 236 | - | |
| 237 | 173 | wp_enqueue_style( 'desktop-mode-recycle-bin' ); |
| 238 | 174 | } |
| 239 | -add_action( 'admin_enqueue_scripts', 'desktop_mode_recycle_bin_localize_config', 30 ); | |
| 175 | +add_action( 'admin_enqueue_scripts', 'openstation_recycle_bin_enqueue_style', 5 ); | |
| 240 | 176 | |
| 241 | 177 | /** |
| 242 | - * Inject the initial trash count into the shell config so the | |
| 243 | - * dock/taskbar tile + desktop icon can paint a badge on the very | |
| 244 | - * first paint — before the bin window has ever opened. | |
| 178 | + * Inject the initial trash count and both bin drawings into the | |
| 179 | + * shell config, so the dock tile (and any icon a user or plugin has | |
| 180 | + * placed against this window) shows the right one on the very first | |
| 181 | + * paint, before the bin window has ever opened. | |
| 245 | 182 | * |
| 246 | - * @since 0.21.0 | |
| 183 | + * Both drawings travel together rather than the server picking one: | |
| 184 | + * the count changes without a reload, and shipping the pair makes | |
| 185 | + * crossing zero a local swap instead of a round trip. | |
| 247 | 186 | * |
| 248 | 187 | * @param array $config Shell config blob. |
| 249 | 188 | * @return array |
| 250 | 189 | */ |
| 251 | -function desktop_mode_recycle_bin_inject_shell_config( $config ) { | |
| 190 | +function openstation_recycle_bin_inject_shell_config( $config ) { | |
| 252 | 191 | if ( ! is_array( $config ) ) { |
| 253 | 192 | return $config; |
| 254 | 193 | } |
| 255 | - $config['recycleBinCount'] = desktop_mode_recycle_bin_count(); | |
| 256 | - $config['recycleBinCountUrl'] = esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/count' ) ); | |
| 194 | + $icons = openstation_recycle_bin_icon_uris(); | |
| 195 | + | |
| 196 | + $config['recycleBinCount'] = openstation_recycle_bin_count(); | |
| 197 | + $config['recycleBinCountUrl'] = esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/count' ) ); | |
| 198 | + $config['recycleBinPostTypes'] = openstation_recycle_bin_capture_post_types(); | |
| 199 | + $config['recycleBinIconEmpty'] = $icons['empty']; | |
| 200 | + $config['recycleBinIconFull'] = $icons['full']; | |
| 257 | 201 | return $config; |
| 258 | 202 | } |
| 259 | -add_filter( 'desktop_mode_shell_config', 'desktop_mode_recycle_bin_inject_shell_config', 20 ); | |
| 203 | +add_filter( 'openstation_shell_config', 'openstation_recycle_bin_inject_shell_config', 20 ); | |