PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.2
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.2
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.2, at includes/games/window.php

200 lines 7.1 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 'width' => 900,
130 'height' => 600,
131 'min_width' => 560,
132 'min_height' => 400,
133 // No dock tile from the window registration: the desktop icon
134 // below is this app's one launcher. Registering both used to
135 // mint two entries for one app, each with its own default, and
136 // the dock painted a tile while Preferences said "On the
137 // desktop". The navigation model collapses them either way —
138 // this keeps Games matching how My WordPress and Corkboard
139 // already register.
140 'placement' => 'none',
141 );
142
143 /**
144 * Filter the args used to register the Games native window.
145 *
146 * @param array $window_args Args passed to `openstation_register_window()`.
147 */
148 $window_args = (array) apply_filters( 'openstation_games_window_args', $window_args );
149
150 $registered = openstation_register_window( 'desktop-mode-games', $window_args );
151 if ( is_wp_error( $registered ) ) {
152 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
153 error_log( '[openstation] Games window registration failed: ' . $registered->get_error_message() );
154 return;
155 }
156
157 $icon_args = array(
158 'title' => __( 'Games', 'desktop-mode' ),
159 'icon_svg' => openstation_games_icon_svg(),
160 'window' => 'desktop-mode-games',
161 'position' => 85,
162 );
163
164 /**
165 * Filter the args used to register the Games desktop icon.
166 *
167 * @param array $icon_args Args passed to `openstation_register_icon()`.
168 */
169 $icon_args = (array) apply_filters( 'openstation_games_icon_args', $icon_args );
170
171 openstation_register_icon( 'desktop-mode-games', $icon_args );
172 }
173 add_action( 'init', 'openstation_games_register_window', 20 );
174
175 /**
176 * Localize REST endpoints for the JS bundle.
177 *
178 * The bundle reads its config off `window.openStationGamesConfig`
179 * and never hardcodes URLs.
180 */
181 function openstation_games_localize_config() {
182 if ( ! openstation_games_user_can_use() ) {
183 return;
184 }
185
186 wp_localize_script(
187 'desktop-mode-games',
188 'openStationGamesConfig',
189 array(
190 'restNonce' => wp_create_nonce( 'wp_rest' ),
191 'gamesUrlBase' => esc_url_raw( rest_url( 'desktop-mode/v1/games' ) ),
192 'challengesUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/games/challenges' ) ),
193 'usersSearchUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/games/users/search' ) ),
194 )
195 );
196
197 wp_enqueue_style( 'desktop-mode-games' );
198 }
199 add_action( 'admin_enqueue_scripts', 'openstation_games_localize_config', 30 );
200