PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.11
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.11
1.1.11 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 All 35 releases
desktop-mode / includes / framework / app / class-effects.php

class-effects.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.11, at includes/framework/app/class-effects.php

231 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation App Framework — effects.
4 *
5 * What an action wants the shell to do besides repainting the body:
6 * show a toast, retitle the window, close it, open another one, set
7 * a badge, pop a context menu. An action calls `$os->toast( … )`; the
8 * runtime ships the list to the client, which performs each one
9 * after the morph.
10 *
11 * @package OpenStation
12 */
13
14 namespace OpenStation\App;
15
16 // Direct access, unless a standalone host is booting on bare PHP.
17 if ( ! defined( 'ABSPATH' ) ) {
18 defined( 'OPENSTATION_STANDALONE' ) || exit;
19 }
20
21 /**
22 * Queue of shell effects for one dispatch.
23 */
24 final class Effects {
25
26 /**
27 * @var array<int,array<string,mixed>>
28 */
29 private $items = array();
30
31 /**
32 * Show a toast.
33 *
34 * `$type` is an id from the toast-type registry the shell ships
35 * (`openstation_get_toast_types()`, filterable through
36 * `openstation_toast_types`): `success`, `warning`, `error`,
37 * `shell-error`, or one a plugin registered. The shell maps it to
38 * the tone the toast wears; an empty or unknown id is the plain
39 * toast, so say what happened in the message either way.
40 *
41 * @param string $message Text.
42 * @param string $type Toast-type id, or '' for the plain toast.
43 * @return self
44 */
45 public function toast( $message, $type = '' ) {
46 $effect = array( 'message' => (string) $message );
47 if ( '' !== (string) $type ) {
48 // `type` is the effect kind on the wire; the toast type rides as `toastType`.
49 $effect['toastType'] = (string) $type;
50 }
51 return $this->add( 'toast', $effect );
52 }
53
54 /**
55 * Retitle the window for this session.
56 *
57 * @param string $title New title.
58 * @return self
59 */
60 public function title( $title ) {
61 return $this->add( 'title', array( 'title' => (string) $title ) );
62 }
63
64 /**
65 * Close the window once the response lands.
66 *
67 * @return self
68 */
69 public function close() {
70 return $this->add( 'close', array() );
71 }
72
73 /**
74 * Open (or focus) another registered window.
75 *
76 * @param string $window_id Native window id.
77 * @return self
78 */
79 public function open( $window_id ) {
80 return $this->add( 'open', array( 'window' => (string) $window_id ) );
81 }
82
83 /**
84 * Open an admin URL in an iframe window (an edit screen, a
85 * settings page).
86 *
87 * @param string $url Admin URL.
88 * @param string $title Window title; the page's own title when ''.
89 * @param string $icon Window icon (a Dashicons class or an image
90 * URL); the shell's generic glyph when ''.
91 * @return self
92 */
93 public function open_url( $url, $title = '', $icon = '' ) {
94 return $this->add(
95 'open_url',
96 array(
97 'url' => (string) $url,
98 'title' => (string) $title,
99 'icon' => (string) $icon,
100 )
101 );
102 }
103
104 /**
105 * Set (or clear with 0) the badge on the app's dock tile and
106 * desktop icon.
107 *
108 * @param int $count Count; 0 clears.
109 * @return self
110 */
111 public function badge( $count ) {
112 return $this->add( 'badge', array( 'count' => max( 0, (int) $count ) ) );
113 }
114
115 /**
116 * Swap the art on every rail hosting the app's tile — dock,
117 * taskbar, desktop icon. State-driven icons (the Recycle Bin's
118 * empty/full bin is the canonical case).
119 *
120 * @param string $icon SVG data URI or image URL.
121 * @return self
122 */
123 public function icon( $icon ) {
124 return $this->add( 'icon', array( 'icon' => (string) $icon ) );
125 }
126
127 /**
128 * Announce a content change so every window showing that content
129 * refreshes (`wp.os.announceContentChange`).
130 *
131 * @param string $type Content type, e.g. `post`, `comment`, `user`.
132 * @param string $action `created` | `updated` | `trashed` | `untrashed` | `deleted`.
133 * @param int|int[] $ids Affected ids.
134 * @return self
135 */
136 public function announce( $type, $action, $ids ) {
137 return $this->add(
138 'announce',
139 array(
140 'contentType' => (string) $type,
141 'action' => (string) $action,
142 'ids' => array_values( array_map( 'intval', (array) $ids ) ),
143 )
144 );
145 }
146
147 /**
148 * Pop a context menu at the pointer. Each item dispatches an
149 * action when picked.
150 *
151 * @param array<int,array<string,mixed>> $items Each: `label`, `action` (required), `args`, `icon`, `danger`, `disabled`.
152 * @return self
153 */
154 public function menu( array $items ) {
155 $clean = array();
156 foreach ( $items as $index => $item ) {
157 if ( empty( $item['label'] ) || empty( $item['action'] ) ) {
158 continue;
159 }
160 $clean[] = array(
161 'id' => isset( $item['id'] ) ? (string) $item['id'] : 'item-' . $index,
162 'label' => (string) $item['label'],
163 'action' => (string) $item['action'],
164 'args' => isset( $item['args'] ) && is_array( $item['args'] ) ? $item['args'] : array(),
165 'icon' => isset( $item['icon'] ) ? (string) $item['icon'] : '',
166 'danger' => ! empty( $item['danger'] ),
167 'disabled' => ! empty( $item['disabled'] ),
168 );
169 }
170 return $this->add( 'menu', array( 'items' => $clean ) );
171 }
172
173 /**
174 * Publish on the window's channel bus (`ctx.window.send`), for
175 * peers connected with `wp.os.connect( id )`.
176 *
177 * @param string $channel Channel name.
178 * @param mixed $payload Serialisable payload.
179 * @return self
180 */
181 public function send( $channel, $payload = null ) {
182 return $this->add(
183 'send',
184 array(
185 'channel' => (string) $channel,
186 'payload' => $payload,
187 )
188 );
189 }
190
191 /**
192 * Ask the shell to rebuild its registries from a fresh menu
193 * payload (`wp.os.refreshMenu()`).
194 *
195 * For an action that changed what the SERVER registers — a site
196 * option that gates a whole module, a per-user flag a plugin's
197 * `init` reads. The shell only learns about server registrations
198 * from a payload, and the request that wrote the option decided,
199 * near its own start, what to register: it cannot report the
200 * window it would now add. The refresh is a separate request by
201 * design, which an effect — performed after this response lands —
202 * is exactly.
203 *
204 * @return self
205 */
206 public function refresh_menu() {
207 return $this->add( 'refresh_menu', array() );
208 }
209
210 /**
211 * Queue a custom effect for a runtime extension to handle.
212 *
213 * @param string $type Effect type.
214 * @param array<string,mixed> $data Payload.
215 * @return self
216 */
217 public function add( $type, array $data = array() ) {
218 $this->items[] = array_merge( array( 'type' => (string) $type ), $data );
219 return $this;
220 }
221
222 /**
223 * Everything queued, in order.
224 *
225 * @return array<int,array<string,mixed>>
226 */
227 public function all() {
228 return $this->items;
229 }
230 }
231