PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.3
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.3
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
desktop-mode / includes / games / window.php

window.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.3, at includes/games/window.php

208 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — Games: hub window + desktop icon registration.
4 *
5 * Native window with id `desktop-mode-games` — the "Games folder"
6 * fixture on the wallpaper. The template body is a static skeleton
7 * (a game grid + a detail panel, Steam-library style) that the JS
8 * bundle enhances on first open: the grid paints from the games
9 * registry; selecting a game reveals its description, Play +
10 * Challenge actions, its scoreboard, and its challenges below.
11 *
12 * Both registrations are filterable via
13 * `openstation_games_window_args` / `openstation_games_icon_args`,
14 * mirroring the Recycle Bin.
15 *
16 * @package OpenStation
17 */
18
19 defined( 'ABSPATH' ) || exit;
20
21 /**
22 * The shared gamepad SVG used by the window icon and the desktop
23 * icon.
24 *
25 * Drawn in `currentColor`, which is what makes it a silhouette:
26 * `isSilhouetteSvg()` in `src/icon.ts` looks for exactly that token
27 * and, finding it, paints the art as a CSS mask instead of a
28 * background-image, so it takes whatever colour the surface is
29 * already using for text.
30 *
31 * This icon used to be the only fixed-colour one in the shell, in
32 * four hues (`#6c5ce7`, white, `#ffd166`, `#06d6a0`) that belong to
33 * no palette the plugin ships. Two things followed from that. It
34 * could not invert on a light title bar or a light desktop theme,
35 * because a background-image has no colour to inherit. And under a
36 * desktop theme's icon tint it collapsed outright: that path runs
37 * `applyIconMask()`, which keeps only the artwork's alpha, and every
38 * pixel of the old gamepad was opaque, so the d-pad and the buttons
39 * vanished into a featureless blob.
40 *
41 * Redrawn as an outlined body with the controls knocked into it, the
42 * detail is carried by negative space rather than by colour, so it
43 * survives both. Held to five elements because it renders as small as
44 * 20px in the dock: body, two d-pad bars, two buttons.
45 *
46 * @return string Raw `<svg>` markup.
47 */
48 function openstation_games_icon_svg() {
49 return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">'
50 // The body: outlined, so what sits inside it reads as detail
51 // rather than as more fill.
52 . '<path d="M21 21h22a13 13 0 0 1 12.6 9.8l2.8 11.2a7.5 7.5 0 0 1-13.6 5.8L40.5 41h-17l-4.3 6.8A7.5 7.5 0 0 1 5.6 42l2.8-11.2A13 13 0 0 1 21 21z" fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>'
53 // D-pad, two crossed bars sharing a centre.
54 . '<rect x="14" y="28.5" width="14" height="4.6" rx="2.3" fill="currentColor"/>'
55 . '<rect x="18.7" y="23.8" width="4.6" height="14" rx="2.3" fill="currentColor"/>'
56 // Face buttons, offset on the diagonal the way a real pad has
57 // them. Two, not four: four would not separate at 20px.
58 . '<circle cx="40.5" cy="34" r="3.1" fill="currentColor"/>'
59 . '<circle cx="47.5" cy="28.5" r="3.1" fill="currentColor"/>'
60 . '</svg>';
61 }
62
63 /**
64 * Whether the current user can use desktop games.
65 *
66 * @return bool
67 */
68 function openstation_games_user_can_use() {
69 $can = is_user_logged_in() && current_user_can( 'read' );
70
71 /**
72 * Filter whether the current user can see the Games window,
73 * icon, and play games.
74 *
75 * @param bool $can Default: logged-in + `read` capability.
76 */
77 return (bool) apply_filters( 'openstation_games_user_can_use', $can );
78 }
79
80 /**
81 * Echoes the Games window's template body.
82 *
83 * The `data-os-games-*` hooks are the contract the JS
84 * render callback relies on — keep them intact (or rename via the
85 * filter) when customizing the layout.
86 */
87 function openstation_games_render_template() {
88 ob_start();
89 ?>
90 <div class="desktop-mode-games" data-os-games-root>
91 <div class="os-games__library">
92 <div class="os-games__grid" data-os-games-grid role="listbox" aria-label="<?php esc_attr_e( 'Games', 'desktop-mode' ); ?>"></div>
93 <div class="os-games__detail" data-os-games-detail hidden></div>
94 </div>
95 </div>
96 <?php
97 $html = (string) ob_get_clean();
98
99 /**
100 * Filter the Games window's template HTML.
101 *
102 * Keep the `data-os-games-*` hooks intact so the JS
103 * render callback can find its mount points.
104 *
105 * @param string $html Default template HTML.
106 */
107 $filtered = (string) apply_filters( 'openstation_games_template_html', $html );
108 echo wp_kses( $filtered, openstation_native_window_allowed_html() );
109 }
110
111 /**
112 * Register the Games window + desktop icon on `init`.
113 *
114 * Priority 20, after the native-window registry bootstraps — same
115 * timing as the Recycle Bin.
116 */
117 function openstation_games_register_window() {
118 if ( ! openstation_games_user_can_use() ) {
119 return;
120 }
121
122 $icon_uri = 'data:image/svg+xml;base64,' . base64_encode( openstation_games_icon_svg() );
123
124 $window_args = array(
125 'title' => __( 'Games', 'desktop-mode' ),
126 'icon' => $icon_uri,
127 'template' => 'openstation_games_render_template',
128 'script' => 'desktop-mode-games',
129 // Companion styles load with the games bundle on first open.
130 // Every game window (`os-game-<id>`) is opened by
131 // `launchGame()`, which lives in that bundle — so a sheet
132 // riding it here is guaranteed in the tab before any game
133 // paints. Built-in games append their own via the
134 // `openstation_games_window_args` filter below.
135 'styles' => array( 'desktop-mode-games' ),
136 'width' => 900,
137 'height' => 600,
138 'min_width' => 560,
139 'min_height' => 400,
140 // No dock tile from the window registration: the desktop icon
141 // below is this app's one launcher. Registering both used to
142 // mint two entries for one app, each with its own default, and
143 // the dock painted a tile while Preferences said "On the
144 // desktop". The navigation model collapses them either way —
145 // this keeps Games matching how My WordPress and Corkboard
146 // already register.
147 'placement' => 'none',
148 );
149
150 /**
151 * Filter the args used to register the Games native window.
152 *
153 * @param array $window_args Args passed to `openstation_register_window()`.
154 */
155 $window_args = (array) apply_filters( 'openstation_games_window_args', $window_args );
156
157 $registered = openstation_register_window( 'desktop-mode-games', $window_args );
158 if ( is_wp_error( $registered ) ) {
159 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
160 error_log( '[openstation] Games window registration failed: ' . $registered->get_error_message() );
161 return;
162 }
163
164 $icon_args = array(
165 'title' => __( 'Games', 'desktop-mode' ),
166 'icon_svg' => openstation_games_icon_svg(),
167 'window' => 'desktop-mode-games',
168 'position' => 85,
169 );
170
171 /**
172 * Filter the args used to register the Games desktop icon.
173 *
174 * @param array $icon_args Args passed to `openstation_register_icon()`.
175 */
176 $icon_args = (array) apply_filters( 'openstation_games_icon_args', $icon_args );
177
178 openstation_register_icon( 'desktop-mode-games', $icon_args );
179 }
180 add_action( 'init', 'openstation_games_register_window', 20 );
181
182 /**
183 * Localize REST endpoints for the JS bundle.
184 *
185 * The bundle reads its config off `window.openStationGamesConfig`
186 * and never hardcodes URLs.
187 */
188 function openstation_games_localize_config() {
189 if ( ! openstation_games_user_can_use() ) {
190 return;
191 }
192
193 wp_localize_script(
194 'desktop-mode-games',
195 'openStationGamesConfig',
196 array(
197 'restNonce' => wp_create_nonce( 'wp_rest' ),
198 'gamesUrlBase' => esc_url_raw( rest_url( 'desktop-mode/v1/games' ) ),
199 'challengesUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/games/challenges' ) ),
200 'usersSearchUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/games/users/search' ) ),
201 )
202 );
203 }
204 // Priority 5 for the same reason as the recycle bin: the lazy-load payload is
205 // built at priority 10, and localize data attached after that never reaches a
206 // bundle that loads on window open.
207 add_action( 'admin_enqueue_scripts', 'openstation_games_localize_config', 5 );
208