| @@ -256,8 +256,60 @@ | ||
| 256 | 256 | return openstation_files_normalize_share_row( $row ); |
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | /** |
| 260 | + * The cheap "is this folder shared" summary the desktop paints tiles | |
| 261 | + * from, so a tile never has to load the full share roster to decide | |
| 262 | + * whether to wear a badge. | |
| 263 | + * | |
| 264 | + * `shared` is deliberately viewer-agnostic — a recipient needs to | |
| 265 | + * see the badge on a folder someone shared with them just as much as | |
| 266 | + * the owner does. `recipientCount` is not: the full roster is | |
| 267 | + * owner-internal, so only a viewer who can manage the folder's | |
| 268 | + * shares gets a real number. Everyone else gets `0`, which keeps the | |
| 269 | + * wire shape stable rather than making the key conditional. | |
| 270 | + * | |
| 271 | + * Lives here rather than inline in the two callers because both the | |
| 272 | + * folder response shape and the `folder` file type serialize it, and | |
| 273 | + * a badge that appeared on one path but not the other is exactly the | |
| 274 | + * bug this consolidates away. | |
| 275 | + * | |
| 276 | + * @param array|null $folder_row Normalized folder row. | |
| 277 | + * @param int|null $viewer_id Viewer; defaults to the current user. | |
| 278 | + * @return array{shared: bool, recipientCount: int} | |
| 279 | + */ | |
| 280 | +function openstation_files_folder_share_summary( $folder_row, $viewer_id = null ) { | |
| 281 | + $summary = array( | |
| 282 | + 'shared' => false, | |
| 283 | + 'recipientCount' => 0, | |
| 284 | + ); | |
| 285 | + if ( ! is_array( $folder_row ) || ! isset( $folder_row['id'] ) ) { | |
| 286 | + return $summary; | |
| 287 | + } | |
| 288 | + | |
| 289 | + $folder_id = (int) $folder_row['id']; | |
| 290 | + $viewer_id = null === $viewer_id ? get_current_user_id() : (int) $viewer_id; | |
| 291 | + $has_all = 'all' === (string) ( isset( $folder_row['share_mode'] ) ? $folder_row['share_mode'] : '' ); | |
| 292 | + | |
| 293 | + $accepted = 0; | |
| 294 | + foreach ( openstation_files_get_folder_shares( $folder_id ) as $share ) { | |
| 295 | + if ( 'accepted' === $share['state'] ) { | |
| 296 | + ++$accepted; | |
| 297 | + } | |
| 298 | + } | |
| 299 | + | |
| 300 | + $summary['shared'] = $has_all || $accepted > 0; | |
| 301 | + // The manage check costs a folder read of its own, and an | |
| 302 | + // unshared folder counts zero recipients for everyone anyway — | |
| 303 | + // so only pay for it when there is something to count. Every | |
| 304 | + // folder tile on the desktop serializes through here. | |
| 305 | + if ( $summary['shared'] && openstation_files_share_can_manage( $folder_id, $viewer_id ) ) { | |
| 306 | + $summary['recipientCount'] = $accepted + ( $has_all ? 1 : 0 ); | |
| 307 | + } | |
| 308 | + return $summary; | |
| 309 | +} | |
| 310 | + | |
| 311 | +/** | |
| 260 | 312 | * Every share row for a folder. Owner-internal view. |
| 261 | 313 | * |
| 262 | 314 | * @param int $folder_id Folder id. |
| 263 | 315 | * @return array[] |
| @@ -1503,9 +1555,9 @@ | ||
| 1503 | 1555 | if ( $folder ) { |
| 1504 | 1556 | $shape['folderName'] = (string) $folder['name']; |
| 1505 | 1557 | $shape['ownerId'] = (int) $folder['owner_id']; |
| 1506 | 1558 | $owner_user = get_userdata( (int) $folder['owner_id'] ); |
| 1507 | - $shape['ownerName'] = $owner_user ? $owner_user->display_name : ''; | |
| 1559 | + $shape['ownerName'] = $owner_user ? openstation_plain_text_title( $owner_user->display_name ) : ''; | |
| 1508 | 1560 | $shape['ownerAvatar'] = $owner_user ? get_avatar_url( $owner_user->ID, array( 'size' => 48 ) ) : ''; |
| 1509 | 1561 | } |
| 1510 | 1562 | $pending[] = $shape; |
| 1511 | 1563 | } |
| @@ -1516,13 +1568,16 @@ | ||
| 1516 | 1568 | } |
| 1517 | 1569 | add_filter( 'openstation_shell_config', 'openstation_files_share_inject_shell_config', 20 ); |
| 1518 | 1570 | |
| 1519 | 1571 | /** |
| 1520 | - * Place an icon at the next free row-major slot in a user's view | |
| 1521 | - * of `$parent_id`. Internal helper used by share-accept and | |
| 1522 | - * fan-out. Mirrors the grid math in `src/desktop-files/grid.ts` | |
| 1523 | - * (padding 16 + col 96 + row 110). | |
| 1572 | + * Place an icon at the next free slot in a user's view of | |
| 1573 | + * `$parent_id`. Internal helper used by share-accept and fan-out. | |
| 1524 | 1574 | * |
| 1575 | + * "Next free" follows the destination's own reading order — columns | |
| 1576 | + * on the desktop, rows in a folder — so a shared thing arriving | |
| 1577 | + * unannounced lands where the next tile the user created would have. | |
| 1578 | + * Grid math lives in `includes/desktop-files/grid.php`. | |
| 1579 | + * | |
| 1525 | 1580 | * @param int $user_id Viewer. |
| 1526 | 1581 | * @param int $parent_id Folder id (0 = desktop root). |
| 1527 | 1582 | * @param string $type File-type slug. |
| 1528 | 1583 | * @param string $ref Entity reference. |
| @@ -1544,26 +1599,14 @@ | ||
| 1544 | 1599 | $parent_id |
| 1545 | 1600 | ), |
| 1546 | 1601 | ARRAY_A |
| 1547 | 1602 | ); |
| 1548 | - $occupied = array(); | |
| 1549 | - foreach ( (array) $existing as $row ) { | |
| 1550 | - $col = max( 0, (int) round( ( (int) $row['x'] - 16 ) / 96 ) ); | |
| 1551 | - $r = max( 0, (int) round( ( (int) $row['y'] - 16 ) / 110 ) ); | |
| 1552 | - $occupied[ "$col,$r" ] = true; | |
| 1553 | - } | |
| 1603 | + $occupied = openstation_files_grid_occupied( $existing ); | |
| 1554 | 1604 | |
| 1555 | - $pick_col = 0; | |
| 1556 | - $pick_row = 0; | |
| 1557 | - for ( $r = 0; $r < 999; $r++ ) { | |
| 1558 | - for ( $col = 0; $col < 999; $col++ ) { | |
| 1559 | - if ( ! isset( $occupied[ "$col,$r" ] ) ) { | |
| 1560 | - $pick_col = $col; | |
| 1561 | - $pick_row = $r; | |
| 1562 | - break 2; | |
| 1563 | - } | |
| 1564 | - } | |
| 1565 | - } | |
| 1605 | + list( $pick_col, $pick_row ) = openstation_files_grid_next_free( | |
| 1606 | + $occupied, | |
| 1607 | + openstation_files_grid_order( $parent_id ) | |
| 1608 | + ); | |
| 1566 | 1609 | |
| 1567 | 1610 | return openstation_files_place( |
| 1568 | 1611 | $user_id, |
| 1569 | 1612 | $parent_id, |
| @@ -1568,10 +1611,7 @@ | ||
| 1568 | 1611 | $user_id, |
| 1569 | 1612 | $parent_id, |
| 1570 | 1613 | $type, |
| 1571 | 1614 | $ref, |
| 1572 | - array( | |
| 1573 | - 'x' => 16 + $pick_col * 96, | |
| 1574 | - 'y' => 16 + $pick_row * 110, | |
| 1575 | - ) | |
| 1615 | + openstation_files_grid_cell_to_point( $pick_col, $pick_row ) | |
| 1576 | 1616 | ); |
| 1577 | 1617 | } |