| @@ -1,17 +1,17 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Desktop Mode — Content Graph: window + desktop icon registration. | |
| 3 | + * OpenStation — Content Graph: window + desktop icon registration. | |
| 4 | 4 | * |
| 5 | 5 | * Filterable surface (mirrors the my-wordpress module shape): |
| 6 | 6 | * |
| 7 | - * - `desktop_mode_content_graph_window_args` | |
| 8 | - * - `desktop_mode_content_graph_icon_args` | |
| 9 | - * - `desktop_mode_content_graph_user_can_use` | |
| 10 | - * - `desktop_mode_content_graph_post_types` | |
| 11 | - * - `desktop_mode_content_graph_template_html` | |
| 7 | + * - `openstation_content_graph_window_args` | |
| 8 | + * - `openstation_content_graph_icon_args` | |
| 9 | + * - `openstation_content_graph_user_can_use` | |
| 10 | + * - `openstation_content_graph_post_types` | |
| 11 | + * - `openstation_content_graph_template_html` | |
| 12 | 12 | * |
| 13 | - * @package WPDesktopMode | |
| 13 | + * @package OpenStation | |
| 14 | 14 | */ |
| 15 | 15 | |
| 16 | 16 | defined( 'ABSPATH' ) || exit; |
| 17 | 17 | |
| @@ -17,51 +17,53 @@ | ||
| 17 | 17 | |
| 18 | 18 | /** |
| 19 | 19 | * The Corkboard SVG, shared by the window icon and the desktop icon. |
| 20 | 20 | * |
| 21 | - * Dashicons has no corkboard, and the near misses all fail for the | |
| 22 | - * same reason the old "Content Graph" name did: `networking` draws an | |
| 23 | - * org chart, `layout` draws a wireframe — diagrams of the data, not a | |
| 24 | - * thing on a desk. The pushpin is unavailable too, since | |
| 25 | - * `dashicons-admin-post` already owns it for Posts. | |
| 21 | + * The thread is the window's actual subject: the links between pieces | |
| 22 | + * of content. That reading is unchanged and is why this icon exists at | |
| 23 | + * all. What changed is everything drawn around it. | |
| 26 | 24 | * |
| 27 | - * So: a cork board with two notes pinned to it, joined by a length of | |
| 28 | - * thread. The thread is not decoration — it's the window's actual | |
| 29 | - * subject, the links between pieces of content, drawn the way anyone | |
| 30 | - * who has ever seen a detective's board already reads it. Without it | |
| 31 | - * the icon says "pinboard"; with it, "connections". | |
| 25 | + * The previous version framed two pinned notes with the thread arcing | |
| 26 | + * over them. On a 64-unit grid the arc closed the top of the | |
| 27 | + * silhouette, and a closed top over two rectangles is a bag: at 40px | |
| 28 | + * and below the icon read as a shopping bag rather than a board. The | |
| 29 | + * frame was also spending most of the 20px budget on an outline that | |
| 30 | + * carried no meaning, leaving the notes too small to be notes. | |
| 32 | 31 | * |
| 32 | + * So the board and the paper are gone and the graph is the whole mark: | |
| 33 | + * one focused post with related ones fanned around it, which is what | |
| 34 | + * the window itself draws now that nodes are discs rather than post- | |
| 35 | + * type glyphs (see `src/content-graph/satellites.ts`). Sizes are | |
| 36 | + * deliberately unequal, so the hierarchy reads without a caption. | |
| 37 | + * | |
| 38 | + * Pin-led marks are deliberately avoided: `assets/images/pushpin.svg` | |
| 39 | + * belongs to pinned notes, and an icon led by a pin would point at | |
| 40 | + * that feature instead of this one. | |
| 41 | + * | |
| 33 | 42 | * Drawn in `currentColor`, which makes it a silhouette: `renderIcon()` |
| 34 | 43 | * paints it as a CSS mask rather than a background-image, so it takes |
| 35 | 44 | * whatever colour the surface is already using for text. That keeps it |
| 36 | - * legible on the dark dock, on a light title bar, and on hover, with | |
| 37 | - * nothing to configure. Fixed colours could not do that — a background | |
| 38 | - * image has no colour to inherit. | |
| 45 | + * legible on the dark dock, on a light title bar, and under a desktop | |
| 46 | + * theme's icon tint, with nothing to configure. | |
| 39 | 47 | * |
| 40 | - * Hand-placed at 64×64 like the Games icons, the established shape for | |
| 41 | - * custom icons here. Held to five elements because it renders as small | |
| 42 | - * as 20px in the dock: board, two notes, thread, two pin heads. The | |
| 43 | - * thread arcs up through the empty top half rather than running | |
| 44 | - * between the notes, where a 5px gap would swallow it. | |
| 48 | + * Hand-placed at 64×64 like the Games icon, the established shape for | |
| 49 | + * custom icons here, and held to five elements because it renders as | |
| 50 | + * small as 20px in the dock. | |
| 45 | 51 | * |
| 46 | 52 | * @return string Raw `<svg>` markup. |
| 47 | 53 | */ |
| 48 | -function desktop_mode_content_graph_icon_svg() { | |
| 54 | +function openstation_content_graph_icon_svg() { | |
| 49 | 55 | return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">' |
| 50 | - // The board itself — outlined, so it frames rather than fills. | |
| 51 | - . '<rect x="5" y="9" width="54" height="46" rx="4.5" fill="none" stroke="currentColor" stroke-width="4"/>' | |
| 52 | - // Thread first: the pin heads below are drawn over its ends, so | |
| 56 | + // Threads first: the discs below are drawn over their ends, so | |
| 53 | 57 | // the joins stay round instead of showing a stroke cap. |
| 54 | - . '<path d="M20.5 28Q32 16.5 43.5 28" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>' | |
| 55 | - // Notes, each tilted a few degrees — pinned by hand, not laid out. | |
| 56 | - . '<g transform="rotate(-7 20.5 39)">' | |
| 57 | - . '<rect x="12" y="30" width="17" height="18" rx="1.5" fill="currentColor"/></g>' | |
| 58 | - . '<g transform="rotate(7 43.5 39)">' | |
| 59 | - . '<rect x="35" y="30" width="17" height="18" rx="1.5" fill="currentColor"/></g>' | |
| 60 | - // Pin heads, sitting proud of each note's top edge. They are the | |
| 61 | - // cue that separates a pinboard from a picture frame. | |
| 62 | - . '<circle cx="20.5" cy="28" r="3" fill="currentColor"/>' | |
| 63 | - . '<circle cx="43.5" cy="28" r="3" fill="currentColor"/>' | |
| 58 | + . '<path d="M14 16 32 32 52 18M32 32 40 49" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round"/>' | |
| 59 | + // The focused post. | |
| 60 | + . '<circle cx="32" cy="32" r="9" fill="currentColor"/>' | |
| 61 | + // Its satellites, sized just under the hub so the eye lands on | |
| 62 | + // the middle first. | |
| 63 | + . '<circle cx="14" cy="16" r="5.5" fill="currentColor"/>' | |
| 64 | + . '<circle cx="52" cy="18" r="5.5" fill="currentColor"/>' | |
| 65 | + . '<circle cx="40" cy="49" r="5" fill="currentColor"/>' | |
| 64 | 66 | . '</svg>'; |
| 65 | 67 | } |
| 66 | 68 | |
| 67 | 69 | /** |
| @@ -71,9 +73,9 @@ | ||
| 71 | 73 | * the link map of the content they author and maintain. |
| 72 | 74 | * |
| 73 | 75 | * @return bool |
| 74 | 76 | */ |
| 75 | -function desktop_mode_content_graph_user_can_use() { | |
| 77 | +function openstation_content_graph_user_can_use() { | |
| 76 | 78 | $can = current_user_can( 'edit_posts' ); |
| 77 | 79 | |
| 78 | 80 | /** |
| 79 | 81 | * Filter whether the current user can see the Content Graph |
| @@ -80,9 +82,9 @@ | ||
| 80 | 82 | * desktop icon and window. |
| 81 | 83 | * |
| 82 | 84 | * @param bool $can Default: edit_posts capability. |
| 83 | 85 | */ |
| 84 | - return (bool) apply_filters( 'desktop_mode_content_graph_user_can_use', $can ); | |
| 86 | + return (bool) apply_filters( 'openstation_content_graph_user_can_use', $can ); | |
| 85 | 87 | } |
| 86 | 88 | |
| 87 | 89 | /** |
| 88 | 90 | * Build the descriptor list of post types eligible for the graph. |
| @@ -91,9 +93,9 @@ | ||
| 91 | 93 | * of them. |
| 92 | 94 | * |
| 93 | 95 | * @return array[] Each entry: `array( 'slug', 'label', 'icon', 'taxonomies' )`. |
| 94 | 96 | */ |
| 95 | -function desktop_mode_content_graph_post_types() { | |
| 97 | +function openstation_content_graph_post_types() { | |
| 96 | 98 | $types = get_post_types( array( 'public' => true ), 'objects' ); |
| 97 | 99 | $result = array(); |
| 98 | 100 | foreach ( $types as $type ) { |
| 99 | 101 | // `attachment` is public but participates in the graph as media |
| @@ -123,9 +125,9 @@ | ||
| 123 | 125 | * graph entirely. |
| 124 | 126 | * |
| 125 | 127 | * @param array[] $result Default: every public post type except attachment. |
| 126 | 128 | */ |
| 127 | - $filtered = apply_filters( 'desktop_mode_content_graph_post_types', $result ); | |
| 129 | + $filtered = apply_filters( 'openstation_content_graph_post_types', $result ); | |
| 128 | 130 | $filtered = is_array( $filtered ) ? array_values( $filtered ) : $result; |
| 129 | 131 | |
| 130 | 132 | foreach ( $filtered as $i => $entry ) { |
| 131 | 133 | $slug = isset( $entry['slug'] ) ? (string) $entry['slug'] : ''; |
| @@ -139,22 +141,22 @@ | ||
| 139 | 141 | } |
| 140 | 142 | |
| 141 | 143 | /** |
| 142 | 144 | * Render the Content Graph window's static template body. The bundle |
| 143 | - * mounts its UI into `[data-desktop-mode-content-graph-root]`. | |
| 145 | + * mounts its UI into `[data-os-content-graph-root]`. | |
| 144 | 146 | */ |
| 145 | -function desktop_mode_content_graph_render_template() { | |
| 147 | +function openstation_content_graph_render_template() { | |
| 146 | 148 | ob_start(); |
| 147 | 149 | ?> |
| 148 | - <div class="desktop-mode-content-graph" data-desktop-mode-content-graph-root> | |
| 149 | - <header class="desktop-mode-content-graph__toolbar" data-desktop-mode-content-graph-toolbar></header> | |
| 150 | - <div class="desktop-mode-content-graph__body"> | |
| 151 | - <div class="desktop-mode-content-graph__stage" data-desktop-mode-content-graph-stage> | |
| 152 | - <div class="desktop-mode-content-graph__loading" data-desktop-mode-content-graph-loading> | |
| 153 | - <wpd-spinner></wpd-spinner> | |
| 150 | + <div class="desktop-mode-content-graph" data-os-content-graph-root> | |
| 151 | + <header class="os-content-graph__toolbar" data-os-content-graph-toolbar></header> | |
| 152 | + <div class="os-content-graph__body"> | |
| 153 | + <div class="os-content-graph__stage" data-os-content-graph-stage> | |
| 154 | + <div class="os-content-graph__loading" data-os-content-graph-loading> | |
| 155 | + <os-spinner></os-spinner> | |
| 154 | 156 | </div> |
| 155 | 157 | </div> |
| 156 | - <aside class="desktop-mode-content-graph__panel" data-desktop-mode-content-graph-panel hidden></aside> | |
| 158 | + <aside class="os-content-graph__panel" data-os-content-graph-panel hidden></aside> | |
| 157 | 159 | </div> |
| 158 | 160 | </div> |
| 159 | 161 | <?php |
| 160 | 162 | $html = (string) ob_get_clean(); |
| @@ -163,12 +165,12 @@ | ||
| 163 | 165 | * Filter the Content Graph window's template HTML. |
| 164 | 166 | * |
| 165 | 167 | * @param string $html Default template HTML. |
| 166 | 168 | */ |
| 167 | - $filtered = (string) apply_filters( 'desktop_mode_content_graph_template_html', $html ); | |
| 169 | + $filtered = (string) apply_filters( 'openstation_content_graph_template_html', $html ); | |
| 168 | 170 | |
| 169 | - $allowed_html = function_exists( 'desktop_mode_native_window_allowed_html' ) | |
| 170 | - ? desktop_mode_native_window_allowed_html() | |
| 171 | + $allowed_html = function_exists( 'openstation_native_window_allowed_html' ) | |
| 172 | + ? openstation_native_window_allowed_html() | |
| 171 | 173 | : wp_kses_allowed_html( 'post' ); |
| 172 | 174 | |
| 173 | 175 | echo wp_kses( $filtered, $allowed_html ); |
| 174 | 176 | } |
| @@ -176,21 +178,21 @@ | ||
| 176 | 178 | /** |
| 177 | 179 | * Register the native window + the desktop icon on `init` priority 20, |
| 178 | 180 | * matching the my-wordpress + recycle-bin modules. |
| 179 | 181 | */ |
| 180 | -function desktop_mode_content_graph_register_window() { | |
| 181 | - if ( ! desktop_mode_content_graph_user_can_use() ) { | |
| 182 | +function openstation_content_graph_register_window() { | |
| 183 | + if ( ! openstation_content_graph_user_can_use() ) { | |
| 182 | 184 | return; |
| 183 | 185 | } |
| 184 | 186 | |
| 185 | - $icon_uri = 'data:image/svg+xml;base64,' . base64_encode( desktop_mode_content_graph_icon_svg() ); | |
| 187 | + $icon_uri = 'data:image/svg+xml;base64,' . base64_encode( openstation_content_graph_icon_svg() ); | |
| 186 | 188 | |
| 187 | 189 | $window_args = array( |
| 188 | 190 | 'title' => __( 'Corkboard', 'desktop-mode' ), |
| 189 | 191 | 'icon' => $icon_uri, |
| 190 | - 'template' => 'desktop_mode_content_graph_render_template', | |
| 192 | + 'template' => 'openstation_content_graph_render_template', | |
| 191 | 193 | 'script' => 'desktop-mode-content-graph', |
| 192 | - 'style' => 'desktop-mode-content-graph', | |
| 194 | + 'styles' => array( 'desktop-mode-content-graph' ), | |
| 193 | 195 | 'width' => 1080, |
| 194 | 196 | 'height' => 720, |
| 195 | 197 | 'min_width' => 720, |
| 196 | 198 | 'min_height' => 480, |
| @@ -204,11 +206,11 @@ | ||
| 204 | 206 | 'editUserUrl' => esc_url_raw( admin_url( 'user-edit.php' ) ), |
| 205 | 207 | 'editCommentUrl' => esc_url_raw( admin_url( 'comment.php' ) ), |
| 206 | 208 | 'mediaUrl' => esc_url_raw( admin_url( 'upload.php' ) ), |
| 207 | 209 | // Labels the "Open in <site>" action on the detail panel, |
| 208 | - // which hands off to the site folder window. | |
| 209 | - 'siteName' => desktop_mode_site_title(), | |
| 210 | - 'postTypes' => desktop_mode_content_graph_post_types(), | |
| 210 | + // which hands off to the WP Explorer window. | |
| 211 | + 'siteName' => openstation_site_title(), | |
| 212 | + 'postTypes' => openstation_content_graph_post_types(), | |
| 211 | 213 | ), |
| 212 | 214 | ); |
| 213 | 215 | |
| 214 | 216 | /** |
| @@ -213,22 +215,22 @@ | ||
| 213 | 215 | |
| 214 | 216 | /** |
| 215 | 217 | * Filter the args used to register the Content Graph native window. |
| 216 | 218 | * |
| 217 | - * @param array $window_args Args passed to `desktop_mode_register_window()`. | |
| 219 | + * @param array $window_args Args passed to `openstation_register_window()`. | |
| 218 | 220 | */ |
| 219 | - $window_args = (array) apply_filters( 'desktop_mode_content_graph_window_args', $window_args ); | |
| 221 | + $window_args = (array) apply_filters( 'openstation_content_graph_window_args', $window_args ); | |
| 220 | 222 | |
| 221 | - $registered = desktop_mode_register_window( 'desktop-mode-content-graph', $window_args ); | |
| 223 | + $registered = openstation_register_window( 'desktop-mode-content-graph', $window_args ); | |
| 222 | 224 | if ( is_wp_error( $registered ) ) { |
| 223 | 225 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log |
| 224 | - error_log( '[desktop-mode] Content Graph window registration failed: ' . $registered->get_error_message() ); | |
| 226 | + error_log( '[openstation] Content Graph window registration failed: ' . $registered->get_error_message() ); | |
| 225 | 227 | return; |
| 226 | 228 | } |
| 227 | 229 | |
| 228 | 230 | $icon_args = array( |
| 229 | 231 | 'title' => __( 'Corkboard', 'desktop-mode' ), |
| 230 | - 'icon_svg' => desktop_mode_content_graph_icon_svg(), | |
| 232 | + 'icon_svg' => openstation_content_graph_icon_svg(), | |
| 231 | 233 | 'window' => 'desktop-mode-content-graph', |
| 232 | 234 | 'pinned' => false, |
| 233 | 235 | 'position' => 20, |
| 234 | 236 | ); |
| @@ -235,23 +237,11 @@ | ||
| 235 | 237 | |
| 236 | 238 | /** |
| 237 | 239 | * Filter the args used to register the Content Graph desktop icon. |
| 238 | 240 | * |
| 239 | - * @param array $icon_args Args passed to `desktop_mode_register_icon()`. | |
| 241 | + * @param array $icon_args Args passed to `openstation_register_icon()`. | |
| 240 | 242 | */ |
| 241 | - $icon_args = (array) apply_filters( 'desktop_mode_content_graph_icon_args', $icon_args ); | |
| 243 | + $icon_args = (array) apply_filters( 'openstation_content_graph_icon_args', $icon_args ); | |
| 242 | 244 | |
| 243 | - desktop_mode_register_icon( 'desktop-mode-content-graph', $icon_args ); | |
| 245 | + openstation_register_icon( 'desktop-mode-content-graph', $icon_args ); | |
| 244 | 246 | } |
| 245 | -add_action( 'init', 'desktop_mode_content_graph_register_window', 20 ); | |
| 246 | - | |
| 247 | -/** | |
| 248 | - * Enqueue the bundle's CSS in admin context. The script is lazy- | |
| 249 | - * loaded by the native-window sync. | |
| 250 | - */ | |
| 251 | -function desktop_mode_content_graph_enqueue_styles() { | |
| 252 | - if ( ! desktop_mode_content_graph_user_can_use() ) { | |
| 253 | - return; | |
| 254 | - } | |
| 255 | - wp_enqueue_style( 'desktop-mode-content-graph' ); | |
| 256 | -} | |
| 257 | -add_action( 'admin_enqueue_scripts', 'desktop_mode_content_graph_enqueue_styles', 30 ); | |
| 247 | +add_action( 'init', 'openstation_content_graph_register_window', 20 ); | |