Skip to content

Commit 6ad9a25

Browse files
committed
Post Locking: Replace exclusive lock UI with collaborative editing indicator when RTC is enabled.
When real-time collaboration is enabled, the post list no longer shows exclusive lock semantics (padlock icon, user avatar, "{user} is currently editing") since multiple users can collaboratively edit the same post. Instead: - Shows generic "Currently being edited" text without user-specific info. - Uses `wp-collaborative-editing` CSS class instead of `wp-locked`, which preserves checkbox and row action visibility (no exclusive lock restrictions). - Changes the "Edit" row action text to "Join" for locked posts. - Heartbeat responses send generic text with a `collaborative` flag. - Injects `_wpCollaborationEnabled` into `inline-edit-post` script so the heartbeat JS handler applies the correct class on dynamic lock updates. When RTC is disabled, classic lock behavior is completely unchanged. Backports WordPress/gutenberg#76322 to core. Props pkevan. See #75313.
1 parent 2bb252a commit 6ad9a25

5 files changed

Lines changed: 52 additions & 28 deletions

File tree

src/js/_enqueues/admin/inline-edit-post.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -613,18 +613,20 @@ $( function() {
613613
wp.heartbeat.interval( 10 );
614614
}
615615
}).on( 'heartbeat-tick.wp-check-locked-posts', function( e, data ) {
616-
var locked = data['wp-check-locked-posts'] || {};
616+
var locked = data['wp-check-locked-posts'] || {},
617+
isRtc = window._wpCollaborationEnabled,
618+
lockedClass = isRtc ? 'wp-collaborative-editing' : 'wp-locked';
617619

618620
$('#the-list tr').each( function(i, el) {
619621
var key = el.id, row = $(el), lock_data, avatar;
620622

621623
if ( locked.hasOwnProperty( key ) ) {
622-
if ( ! row.hasClass('wp-locked') ) {
624+
if ( ! row.hasClass( lockedClass ) ) {
623625
lock_data = locked[key];
624626
row.find('.column-title .locked-text').text( lock_data.text );
625627
row.find('.check-column checkbox').prop('checked', false);
626628

627-
if ( lock_data.avatar_src ) {
629+
if ( ! isRtc && lock_data.avatar_src ) {
628630
avatar = $( '<img />', {
629631
'class': 'avatar avatar-18 photo',
630632
width: 18,
@@ -635,10 +637,10 @@ $( function() {
635637
} );
636638
row.find('.column-title .locked-avatar').empty().append( avatar );
637639
}
638-
row.addClass('wp-locked');
640+
row.addClass( lockedClass );
639641
}
640-
} else if ( row.hasClass('wp-locked') ) {
641-
row.removeClass( 'wp-locked' ).find( '.locked-info span' ).empty();
642+
} else if ( row.hasClass( lockedClass ) ) {
643+
row.removeClass( lockedClass ).find( '.locked-info span' ).empty();
642644
}
643645
});
644646
}).on( 'heartbeat-send.wp-check-locked-posts', function( e, data ) {

src/wp-admin/css/list-tables.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,10 @@ tr.wp-locked .row-actions .trash {
635635
display: none;
636636
}
637637

638+
.wp-collaborative-editing .locked-info {
639+
display: block;
640+
}
641+
638642
#menu-locations-wrap .widefat {
639643
width: 60%;
640644
}

src/wp-admin/includes/class-wp-posts-list-table.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,10 +1119,15 @@ public function column_title( $post ) {
11191119
$lock_holder = wp_check_post_lock( $post->ID );
11201120

11211121
if ( $lock_holder ) {
1122-
$lock_holder = get_userdata( $lock_holder );
1123-
$locked_avatar = get_avatar( $lock_holder->ID, 18 );
1124-
/* translators: %s: User's display name. */
1125-
$locked_text = esc_html( sprintf( __( '%s is currently editing' ), $lock_holder->display_name ) );
1122+
if ( get_option( 'wp_enable_real_time_collaboration' ) ) {
1123+
$locked_avatar = '';
1124+
$locked_text = esc_html__( 'Currently being edited' );
1125+
} else {
1126+
$lock_holder = get_userdata( $lock_holder );
1127+
$locked_avatar = get_avatar( $lock_holder->ID, 18 );
1128+
/* translators: %s: User's display name. */
1129+
$locked_text = esc_html( sprintf( __( '%s is currently editing' ), $lock_holder->display_name ) );
1130+
}
11261131
} else {
11271132
$locked_avatar = '';
11281133
$locked_text = '';
@@ -1427,7 +1432,11 @@ public function single_row( $post, $level = 0 ) {
14271432
$lock_holder = wp_check_post_lock( $post->ID );
14281433

14291434
if ( $lock_holder ) {
1430-
$classes .= ' wp-locked';
1435+
if ( get_option( 'wp_enable_real_time_collaboration' ) ) {
1436+
$classes .= ' wp-collaborative-editing';
1437+
} else {
1438+
$classes .= ' wp-locked';
1439+
}
14311440
}
14321441

14331442
if ( $post->post_parent ) {
@@ -1481,12 +1490,14 @@ protected function handle_row_actions( $item, $column_name, $primary ) {
14811490
$title = _draft_or_post_title();
14821491

14831492
if ( $can_edit_post && 'trash' !== $post->post_status ) {
1493+
$is_rtc_locked = get_option( 'wp_enable_real_time_collaboration' ) && wp_check_post_lock( $post->ID );
1494+
14841495
$actions['edit'] = sprintf(
14851496
'<a href="%s" aria-label="%s">%s</a>',
14861497
get_edit_post_link( $post->ID ),
14871498
/* translators: %s: Post title. */
1488-
esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ),
1489-
__( 'Edit' )
1499+
esc_attr( sprintf( $is_rtc_locked ? __( 'Join editing &#8220;%s&#8221;' ) : __( 'Edit &#8220;%s&#8221;' ), $title ) ),
1500+
$is_rtc_locked ? __( 'Join' ) : __( 'Edit' )
14901501
);
14911502

14921503
/**

src/wp-admin/includes/misc.php

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,8 @@ function _customizer_mobile_viewport_meta( $viewport_meta ) {
11331133
* @return array The Heartbeat response.
11341134
*/
11351135
function wp_check_locked_posts( $response, $data, $screen_id ) {
1136-
$checked = array();
1136+
$checked = array();
1137+
$is_rtc_enabled = (bool) get_option( 'wp_enable_real_time_collaboration' );
11371138

11381139
if ( array_key_exists( 'wp-check-locked-posts', $data ) && is_array( $data['wp-check-locked-posts'] ) ) {
11391140
foreach ( $data['wp-check-locked-posts'] as $key ) {
@@ -1149,15 +1150,22 @@ function wp_check_locked_posts( $response, $data, $screen_id ) {
11491150
$user = get_userdata( $user_id );
11501151

11511152
if ( $user && current_user_can( 'edit_post', $post_id ) ) {
1152-
$send = array(
1153-
'name' => $user->display_name,
1154-
/* translators: %s: User's display name. */
1155-
'text' => sprintf( __( '%s is currently editing' ), $user->display_name ),
1156-
);
1157-
1158-
if ( get_option( 'show_avatars' ) ) {
1159-
$send['avatar_src'] = get_avatar_url( $user->ID, array( 'size' => 18 ) );
1160-
$send['avatar_src_2x'] = get_avatar_url( $user->ID, array( 'size' => 36 ) );
1153+
if ( $is_rtc_enabled ) {
1154+
$send = array(
1155+
'text' => __( 'Currently being edited' ),
1156+
'collaborative' => true,
1157+
);
1158+
} else {
1159+
$send = array(
1160+
'name' => $user->display_name,
1161+
/* translators: %s: User's display name. */
1162+
'text' => sprintf( __( '%s is currently editing' ), $user->display_name ),
1163+
);
1164+
1165+
if ( get_option( 'show_avatars' ) ) {
1166+
$send['avatar_src'] = get_avatar_url( $user->ID, array( 'size' => 18 ) );
1167+
$send['avatar_src_2x'] = get_avatar_url( $user->ID, array( 'size' => 36 ) );
1168+
}
11611169
}
11621170

11631171
$checked[ $key ] = $send;

src/wp-includes/collaboration.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
*/
1616
function wp_collaboration_inject_setting() {
1717
if ( get_option( 'wp_enable_real_time_collaboration' ) ) {
18-
wp_add_inline_script(
19-
'wp-core-data',
20-
'window._wpCollaborationEnabled = true;',
21-
'after'
22-
);
18+
$inline_script = 'window._wpCollaborationEnabled = true;';
19+
20+
wp_add_inline_script( 'wp-core-data', $inline_script, 'after' );
21+
wp_add_inline_script( 'inline-edit-post', $inline_script, 'before' );
2322
}
2423
}

0 commit comments

Comments
 (0)