| @@ -1,33 +1,81 @@ | ||
| 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 | |
| 14 | - * @since 0.8.2 | |
| 13 | + * @package OpenStation | |
| 15 | 14 | */ |
| 16 | 15 | |
| 17 | 16 | defined( 'ABSPATH' ) || exit; |
| 18 | 17 | |
| 19 | 18 | /** |
| 19 | + * The Corkboard SVG, shared by the window icon and the desktop icon. | |
| 20 | + * | |
| 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. | |
| 24 | + * | |
| 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. | |
| 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 | + * | |
| 42 | + * Drawn in `currentColor`, which makes it a silhouette: `renderIcon()` | |
| 43 | + * paints it as a CSS mask rather than a background-image, so it takes | |
| 44 | + * whatever colour the surface is already using for text. That keeps it | |
| 45 | + * legible on the dark dock, on a light title bar, and under a desktop | |
| 46 | + * theme's icon tint, with nothing to configure. | |
| 47 | + * | |
| 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. | |
| 51 | + * | |
| 52 | + * @return string Raw `<svg>` markup. | |
| 53 | + */ | |
| 54 | +function openstation_content_graph_icon_svg() { | |
| 55 | + return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">' | |
| 56 | + // Threads first: the discs below are drawn over their ends, so | |
| 57 | + // the joins stay round instead of showing a stroke cap. | |
| 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"/>' | |
| 66 | + . '</svg>'; | |
| 67 | +} | |
| 68 | + | |
| 69 | +/** | |
| 20 | 70 | * Whether the current user should see Content Graph. |
| 21 | 71 | * |
| 22 | 72 | * Mirrors the my-wordpress gate, anyone who can edit posts can view |
| 23 | 73 | * the link map of the content they author and maintain. |
| 24 | 74 | * |
| 25 | - * @since 0.8.2 | |
| 26 | - * | |
| 27 | 75 | * @return bool |
| 28 | 76 | */ |
| 29 | -function desktop_mode_content_graph_user_can_use() { | |
| 77 | +function openstation_content_graph_user_can_use() { | |
| 30 | 78 | $can = current_user_can( 'edit_posts' ); |
| 31 | 79 | |
| 32 | 80 | /** |
| 33 | 81 | * Filter whether the current user can see the Content Graph |
| @@ -32,13 +80,11 @@ | ||
| 32 | 80 | /** |
| 33 | 81 | * Filter whether the current user can see the Content Graph |
| 34 | 82 | * desktop icon and window. |
| 35 | 83 | * |
| 36 | - * @since 0.8.2 | |
| 37 | - * | |
| 38 | 84 | * @param bool $can Default: edit_posts capability. |
| 39 | 85 | */ |
| 40 | - return (bool) apply_filters( 'desktop_mode_content_graph_user_can_use', $can ); | |
| 86 | + return (bool) apply_filters( 'openstation_content_graph_user_can_use', $can ); | |
| 41 | 87 | } |
| 42 | 88 | |
| 43 | 89 | /** |
| 44 | 90 | * Build the descriptor list of post types eligible for the graph. |
| @@ -45,13 +91,11 @@ | ||
| 45 | 91 | * Defaults to every public post type (so CPTs participate by |
| 46 | 92 | * default), matching the user-facing filter bar that ships ON for all |
| 47 | 93 | * of them. |
| 48 | 94 | * |
| 49 | - * @since 0.8.2 | |
| 50 | - * | |
| 51 | 95 | * @return array[] Each entry: `array( 'slug', 'label', 'icon', 'taxonomies' )`. |
| 52 | 96 | */ |
| 53 | -function desktop_mode_content_graph_post_types() { | |
| 97 | +function openstation_content_graph_post_types() { | |
| 54 | 98 | $types = get_post_types( array( 'public' => true ), 'objects' ); |
| 55 | 99 | $result = array(); |
| 56 | 100 | foreach ( $types as $type ) { |
| 57 | 101 | // `attachment` is public but participates in the graph as media |
| @@ -79,13 +123,11 @@ | ||
| 79 | 123 | * `is_object_in_taxonomy()` after filtering. Removing |
| 80 | 124 | * an entry hides it from the filter bar AND excludes it from the |
| 81 | 125 | * graph entirely. |
| 82 | 126 | * |
| 83 | - * @since 0.8.2 | |
| 84 | - * | |
| 85 | 127 | * @param array[] $result Default: every public post type except attachment. |
| 86 | 128 | */ |
| 87 | - $filtered = apply_filters( 'desktop_mode_content_graph_post_types', $result ); | |
| 129 | + $filtered = apply_filters( 'openstation_content_graph_post_types', $result ); | |
| 88 | 130 | $filtered = is_array( $filtered ) ? array_values( $filtered ) : $result; |
| 89 | 131 | |
| 90 | 132 | foreach ( $filtered as $i => $entry ) { |
| 91 | 133 | $slug = isset( $entry['slug'] ) ? (string) $entry['slug'] : ''; |
| @@ -99,24 +141,22 @@ | ||
| 99 | 141 | } |
| 100 | 142 | |
| 101 | 143 | /** |
| 102 | 144 | * Render the Content Graph window's static template body. The bundle |
| 103 | - * mounts its UI into `[data-desktop-mode-content-graph-root]`. | |
| 104 | - * | |
| 105 | - * @since 0.8.2 | |
| 145 | + * mounts its UI into `[data-os-content-graph-root]`. | |
| 106 | 146 | */ |
| 107 | -function desktop_mode_content_graph_render_template() { | |
| 147 | +function openstation_content_graph_render_template() { | |
| 108 | 148 | ob_start(); |
| 109 | 149 | ?> |
| 110 | - <div class="desktop-mode-content-graph" data-desktop-mode-content-graph-root> | |
| 111 | - <header class="desktop-mode-content-graph__toolbar" data-desktop-mode-content-graph-toolbar></header> | |
| 112 | - <div class="desktop-mode-content-graph__body"> | |
| 113 | - <div class="desktop-mode-content-graph__stage" data-desktop-mode-content-graph-stage> | |
| 114 | - <div class="desktop-mode-content-graph__loading" data-desktop-mode-content-graph-loading> | |
| 115 | - <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> | |
| 116 | 156 | </div> |
| 117 | 157 | </div> |
| 118 | - <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> | |
| 119 | 159 | </div> |
| 120 | 160 | </div> |
| 121 | 161 | <?php |
| 122 | 162 | $html = (string) ob_get_clean(); |
| @@ -123,16 +163,14 @@ | ||
| 123 | 163 | |
| 124 | 164 | /** |
| 125 | 165 | * Filter the Content Graph window's template HTML. |
| 126 | 166 | * |
| 127 | - * @since 0.8.2 | |
| 128 | - * | |
| 129 | 167 | * @param string $html Default template HTML. |
| 130 | 168 | */ |
| 131 | - $filtered = (string) apply_filters( 'desktop_mode_content_graph_template_html', $html ); | |
| 169 | + $filtered = (string) apply_filters( 'openstation_content_graph_template_html', $html ); | |
| 132 | 170 | |
| 133 | - $allowed_html = function_exists( 'desktop_mode_native_window_allowed_html' ) | |
| 134 | - ? desktop_mode_native_window_allowed_html() | |
| 171 | + $allowed_html = function_exists( 'openstation_native_window_allowed_html' ) | |
| 172 | + ? openstation_native_window_allowed_html() | |
| 135 | 173 | : wp_kses_allowed_html( 'post' ); |
| 136 | 174 | |
| 137 | 175 | echo wp_kses( $filtered, $allowed_html ); |
| 138 | 176 | } |
| @@ -139,22 +177,22 @@ | ||
| 139 | 177 | |
| 140 | 178 | /** |
| 141 | 179 | * Register the native window + the desktop icon on `init` priority 20, |
| 142 | 180 | * matching the my-wordpress + recycle-bin modules. |
| 143 | - * | |
| 144 | - * @since 0.8.2 | |
| 145 | 181 | */ |
| 146 | -function desktop_mode_content_graph_register_window() { | |
| 147 | - if ( ! desktop_mode_content_graph_user_can_use() ) { | |
| 182 | +function openstation_content_graph_register_window() { | |
| 183 | + if ( ! openstation_content_graph_user_can_use() ) { | |
| 148 | 184 | return; |
| 149 | 185 | } |
| 150 | 186 | |
| 187 | + $icon_uri = 'data:image/svg+xml;base64,' . base64_encode( openstation_content_graph_icon_svg() ); | |
| 188 | + | |
| 151 | 189 | $window_args = array( |
| 152 | - 'title' => __( 'Content Graph', 'desktop-mode' ), | |
| 153 | - 'icon' => 'dashicons-networking', | |
| 154 | - 'template' => 'desktop_mode_content_graph_render_template', | |
| 190 | + 'title' => __( 'Corkboard', 'desktop-mode' ), | |
| 191 | + 'icon' => $icon_uri, | |
| 192 | + 'template' => 'openstation_content_graph_render_template', | |
| 155 | 193 | 'script' => 'desktop-mode-content-graph', |
| 156 | - 'style' => 'desktop-mode-content-graph', | |
| 194 | + 'styles' => array( 'desktop-mode-content-graph' ), | |
| 157 | 195 | 'width' => 1080, |
| 158 | 196 | 'height' => 720, |
| 159 | 197 | 'min_width' => 720, |
| 160 | 198 | 'min_height' => 480, |
| @@ -167,9 +205,12 @@ | ||
| 167 | 205 | 'editTermUrl' => esc_url_raw( admin_url( 'term.php' ) ), |
| 168 | 206 | 'editUserUrl' => esc_url_raw( admin_url( 'user-edit.php' ) ), |
| 169 | 207 | 'editCommentUrl' => esc_url_raw( admin_url( 'comment.php' ) ), |
| 170 | 208 | 'mediaUrl' => esc_url_raw( admin_url( 'upload.php' ) ), |
| 171 | - 'postTypes' => desktop_mode_content_graph_post_types(), | |
| 209 | + // Labels the "Open in <site>" action on the detail panel, | |
| 210 | + // which hands off to the WP Explorer window. | |
| 211 | + 'siteName' => openstation_site_title(), | |
| 212 | + 'postTypes' => openstation_content_graph_post_types(), | |
| 172 | 213 | ), |
| 173 | 214 | ); |
| 174 | 215 | |
| 175 | 216 | /** |
| @@ -174,24 +215,22 @@ | ||
| 174 | 215 | |
| 175 | 216 | /** |
| 176 | 217 | * Filter the args used to register the Content Graph native window. |
| 177 | 218 | * |
| 178 | - * @since 0.8.2 | |
| 179 | - * | |
| 180 | - * @param array $window_args Args passed to `desktop_mode_register_window()`. | |
| 219 | + * @param array $window_args Args passed to `openstation_register_window()`. | |
| 181 | 220 | */ |
| 182 | - $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 ); | |
| 183 | 222 | |
| 184 | - $registered = desktop_mode_register_window( 'desktop-mode-content-graph', $window_args ); | |
| 223 | + $registered = openstation_register_window( 'desktop-mode-content-graph', $window_args ); | |
| 185 | 224 | if ( is_wp_error( $registered ) ) { |
| 186 | 225 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log |
| 187 | - 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() ); | |
| 188 | 227 | return; |
| 189 | 228 | } |
| 190 | 229 | |
| 191 | 230 | $icon_args = array( |
| 192 | - 'title' => __( 'Content Graph', 'desktop-mode' ), | |
| 193 | - 'icon' => 'dashicons-networking', | |
| 231 | + 'title' => __( 'Corkboard', 'desktop-mode' ), | |
| 232 | + 'icon_svg' => openstation_content_graph_icon_svg(), | |
| 194 | 233 | 'window' => 'desktop-mode-content-graph', |
| 195 | 234 | 'pinned' => false, |
| 196 | 235 | 'position' => 20, |
| 197 | 236 | ); |
| @@ -198,27 +237,11 @@ | ||
| 198 | 237 | |
| 199 | 238 | /** |
| 200 | 239 | * Filter the args used to register the Content Graph desktop icon. |
| 201 | 240 | * |
| 202 | - * @since 0.8.2 | |
| 203 | - * | |
| 204 | - * @param array $icon_args Args passed to `desktop_mode_register_icon()`. | |
| 241 | + * @param array $icon_args Args passed to `openstation_register_icon()`. | |
| 205 | 242 | */ |
| 206 | - $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 ); | |
| 207 | 244 | |
| 208 | - desktop_mode_register_icon( 'desktop-mode-content-graph', $icon_args ); | |
| 245 | + openstation_register_icon( 'desktop-mode-content-graph', $icon_args ); | |
| 209 | 246 | } |
| 210 | -add_action( 'init', 'desktop_mode_content_graph_register_window', 20 ); | |
| 211 | - | |
| 212 | -/** | |
| 213 | - * Enqueue the bundle's CSS in admin context. The script is lazy- | |
| 214 | - * loaded by the native-window sync. | |
| 215 | - * | |
| 216 | - * @since 0.8.2 | |
| 217 | - */ | |
| 218 | -function desktop_mode_content_graph_enqueue_styles() { | |
| 219 | - if ( ! desktop_mode_content_graph_user_can_use() ) { | |
| 220 | - return; | |
| 221 | - } | |
| 222 | - wp_enqueue_style( 'desktop-mode-content-graph' ); | |
| 223 | -} | |
| 224 | -add_action( 'admin_enqueue_scripts', 'desktop_mode_content_graph_enqueue_styles', 30 ); | |
| 247 | +add_action( 'init', 'openstation_content_graph_register_window', 20 ); | |