| 1 |
<?php |
| 2 |
/** |
| 3 |
* This template contains the Friends 4.0 news entry. |
| 4 |
* |
| 5 |
* @package Friends |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace Friends; |
| 9 |
|
| 10 |
$statuses = isset( $args['statuses'] ) ? $args['statuses'] : array(); |
| 11 |
$all_complete = isset( $args['all_complete'] ) ? $args['all_complete'] : true; |
| 12 |
$has_in_progress = isset( $args['has_in_progress'] ) ? $args['has_in_progress'] : false; |
| 13 |
|
| 14 |
?> |
| 15 |
<div class="friends-news-entry-body"> |
| 16 |
<h2><?php esc_html_e( 'Friends 4.0: A Major Update', 'friends' ); ?></h2> |
| 17 |
|
| 18 |
<div class="friends-news-changes"> |
| 19 |
<h3><?php esc_html_e( 'Themes', 'friends' ); ?></h3> |
| 20 |
|
| 21 |
<div class="friends-news-change"> |
| 22 |
<h4><?php esc_html_e( 'Dark Mode', 'friends' ); ?></h4> |
| 23 |
<p><?php esc_html_e( 'The default Friends theme now has a dark mode that follows your system preferences.', 'friends' ); ?></p> |
| 24 |
</div> |
| 25 |
|
| 26 |
<div class="friends-news-change"> |
| 27 |
<h4><?php esc_html_e( 'Block Theme', 'friends' ); ?></h4> |
| 28 |
<p><?php esc_html_e( 'A block-based theme that integrates with your site\'s active theme, letting you customize the Friends page templates via the Site Editor.', 'friends' ); ?></p> |
| 29 |
</div> |
| 30 |
|
| 31 |
<div class="friends-news-change"> |
| 32 |
<h4><?php esc_html_e( 'Google Reader Theme', 'friends' ); ?></h4> |
| 33 |
<p><?php esc_html_e( 'A Google Reader-inspired theme with a compact list view where posts expand accordion-style. Includes keyboard shortcuts (j/k to navigate, s to star, v to open original, ? to see all shortcuts) and full dark mode support.', 'friends' ); ?></p> |
| 34 |
</div> |
| 35 |
|
| 36 |
<div class="friends-news-change"> |
| 37 |
<h4><?php esc_html_e( 'Mastodon Theme', 'friends' ); ?></h4> |
| 38 |
<p><?php esc_html_e( 'A Mastodon-style theme with a 3-column layout: user info and search on the left, timeline in the center, and navigation on the right. Features card-based posts with avatars, collapsible filter chips, and full light/dark mode support.', 'friends' ); ?></p> |
| 39 |
</div> |
| 40 |
|
| 41 |
<h3><?php esc_html_e( 'Subscriptions', 'friends' ); ?></h3> |
| 42 |
|
| 43 |
<div class="friends-news-change"> |
| 44 |
<h4><?php esc_html_e( 'Subscription Folders', 'friends' ); ?></h4> |
| 45 |
<p><?php esc_html_e( 'Organize your subscriptions into folders. You can move subscriptions into folders from the author page. The friends list can be grouped by folder with collapsible sections. Starred subscriptions are shown separately for quick access.', 'friends' ); ?></p> |
| 46 |
</div> |
| 47 |
|
| 48 |
<div class="friends-news-change"> |
| 49 |
<h4><?php esc_html_e( 'Improved Subscriptions and Followers Pages', 'friends' ); ?></h4> |
| 50 |
<p><?php esc_html_e( 'The subscriptions and followers pages now have filtering, sorting, and pagination. Browse subscriptions by starred or folder, sort by name, date, or post count, and navigate large lists with ease.', 'friends' ); ?></p> |
| 51 |
</div> |
| 52 |
|
| 53 |
<h3><?php esc_html_e( 'Compatibility', 'friends' ); ?></h3> |
| 54 |
|
| 55 |
<div class="friends-news-change"> |
| 56 |
<h4><?php esc_html_e( 'Friendship Functionality Removed', 'friends' ); ?></h4> |
| 57 |
<p><?php esc_html_e( 'The two-way friendship functionality has been removed. It only worked between WordPress sites with the Friends plugin installed. Your existing friends are now subscriptions. Similar functionality could be implemented via ActivityPub in the future, which would work across the whole Fediverse.', 'friends' ); ?></p> |
| 58 |
</div> |
| 59 |
|
| 60 |
<div class="friends-news-change"> |
| 61 |
<h4><?php esc_html_e( 'Friend Tags', 'friends' ); ?></h4> |
| 62 |
<p><?php esc_html_e( 'Posts from friends now use a dedicated taxonomy instead of sharing post tags with your blog. This prevents other people\'s tags from polluting your own tag list.', 'friends' ); ?></p> |
| 63 |
</div> |
| 64 |
|
| 65 |
<div class="friends-news-change"> |
| 66 |
<h4><?php esc_html_e( 'ActivityPub 7.0 Compatibility', 'friends' ); ?></h4> |
| 67 |
<p><?php esc_html_e( 'ActivityPub feeds are now linked to actor records from the ActivityPub plugin, improving reliability and enabling better URL synchronization.', 'friends' ); ?></p> |
| 68 |
</div> |
| 69 |
|
| 70 |
<div class="friends-news-change"> |
| 71 |
<h4><?php esc_html_e( 'Header Images', 'friends' ); ?></h4> |
| 72 |
<p><?php esc_html_e( 'The ActivityPub header image is now used if available, giving friend profiles a richer look.', 'friends' ); ?></p> |
| 73 |
</div> |
| 74 |
|
| 75 |
</div> |
| 76 |
|
| 77 |
<?php if ( ! empty( $statuses ) ) : ?> |
| 78 |
<h2><?php esc_html_e( 'Migration Status', 'friends' ); ?></h2> |
| 79 |
<p class="description"> |
| 80 |
<?php esc_html_e( 'These migrations update your data for Friends 4.0. Batched migrations process data in the background and may take a while to complete. Reload the page to check the current status.', 'friends' ); ?> |
| 81 |
</p> |
| 82 |
|
| 83 |
<table class="wp-list-table widefat fixed striped" id="friends-migrations-table"> |
| 84 |
<thead> |
| 85 |
<tr> |
| 86 |
<th style="width: 30%;"><?php esc_html_e( 'Migration', 'friends' ); ?></th> |
| 87 |
<th style="width: 40%;"><?php esc_html_e( 'Description', 'friends' ); ?></th> |
| 88 |
<th style="width: 15%;"><?php esc_html_e( 'Status', 'friends' ); ?></th> |
| 89 |
<th style="width: 15%;"><?php esc_html_e( 'Actions', 'friends' ); ?></th> |
| 90 |
</tr> |
| 91 |
</thead> |
| 92 |
<tbody> |
| 93 |
<?php foreach ( $statuses as $migration_id => $migration_status ) : ?> |
| 94 |
<tr data-migration-id="<?php echo esc_attr( $migration_id ); ?>"> |
| 95 |
<td> |
| 96 |
<strong><?php echo esc_html( $migration_status['title'] ); ?></strong> |
| 97 |
<?php if ( $migration_status['batched'] ) : ?> |
| 98 |
<span class="dashicons dashicons-database" title="<?php esc_attr_e( 'Batched migration', 'friends' ); ?>"></span> |
| 99 |
<?php endif; ?> |
| 100 |
</td> |
| 101 |
<td><?php echo esc_html( $migration_status['description'] ); ?></td> |
| 102 |
<td class="migration-status"> |
| 103 |
<?php Migration::render_status_badge( $migration_status ); ?> |
| 104 |
</td> |
| 105 |
<td> |
| 106 |
<?php if ( ! empty( $migration_status['in_progress'] ) ) : ?> |
| 107 |
<button type="button" class="button button-primary process-batch" data-migration-id="<?php echo esc_attr( $migration_id ); ?>"> |
| 108 |
<?php esc_html_e( 'Process Now', 'friends' ); ?> |
| 109 |
</button> |
| 110 |
<?php else : ?> |
| 111 |
<button type="button" class="button button-secondary run-migration" data-migration-id="<?php echo esc_attr( $migration_id ); ?>"> |
| 112 |
<?php esc_html_e( 'Run', 'friends' ); ?> |
| 113 |
</button> |
| 114 |
<?php endif; ?> |
| 115 |
</td> |
| 116 |
</tr> |
| 117 |
<?php endforeach; ?> |
| 118 |
</tbody> |
| 119 |
</table> |
| 120 |
|
| 121 |
<?php if ( $all_complete ) : ?> |
| 122 |
<div class="friends-news-status-complete"> |
| 123 |
<p> |
| 124 |
<span class="dashicons dashicons-yes-alt"></span> |
| 125 |
<?php esc_html_e( 'All migrations have completed successfully. You are all set!', 'friends' ); ?> |
| 126 |
</p> |
| 127 |
</div> |
| 128 |
<?php elseif ( $has_in_progress ) : ?> |
| 129 |
<div class="friends-news-status-progress"> |
| 130 |
<p> |
| 131 |
<span class="dashicons dashicons-update"></span> |
| 132 |
<?php esc_html_e( 'Some migrations are still processing in the background. You can continue using the plugin while they complete.', 'friends' ); ?> |
| 133 |
</p> |
| 134 |
</div> |
| 135 |
<?php endif; ?> |
| 136 |
|
| 137 |
<p class="submit"> |
| 138 |
<a href="<?php echo esc_url( admin_url( 'admin.php?page=friends-migrations' ) ); ?>" class="button button-secondary"> |
| 139 |
<?php esc_html_e( 'Migrations Overview', 'friends' ); ?> |
| 140 |
</a> |
| 141 |
</p> |
| 142 |
<?php endif; ?> |
| 143 |
</div> |
| 144 |
|
| 145 |
<script> |
| 146 |
jQuery(document).ready(function($) { |
| 147 |
$('.process-batch').on('click', function() { |
| 148 |
var $button = $(this); |
| 149 |
var $row = $button.closest('tr'); |
| 150 |
var migrationId = $button.data('migration-id'); |
| 151 |
|
| 152 |
$button.prop('disabled', true).text('<?php echo esc_js( __( 'Processing...', 'friends' ) ); ?>'); |
| 153 |
|
| 154 |
$.post(ajaxurl, { |
| 155 |
action: 'friends_process_migration_batch', |
| 156 |
migration_id: migrationId, |
| 157 |
_wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-process-batch' ) ); ?>' |
| 158 |
}, function(response) { |
| 159 |
if (response.success) { |
| 160 |
$row.find('.migration-status').html(response.data.html); |
| 161 |
if (response.data.in_progress) { |
| 162 |
$button.prop('disabled', false).text('<?php echo esc_js( __( 'Process Now', 'friends' ) ); ?>'); |
| 163 |
} else { |
| 164 |
$button.removeClass('button-primary process-batch').addClass('button-secondary run-migration') |
| 165 |
.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>'); |
| 166 |
} |
| 167 |
} else { |
| 168 |
alert(response.data.message || '<?php echo esc_js( __( 'Processing failed.', 'friends' ) ); ?>'); |
| 169 |
$button.prop('disabled', false).text('<?php echo esc_js( __( 'Process Now', 'friends' ) ); ?>'); |
| 170 |
} |
| 171 |
}).fail(function() { |
| 172 |
alert('<?php echo esc_js( __( 'Request failed.', 'friends' ) ); ?>'); |
| 173 |
$button.prop('disabled', false).text('<?php echo esc_js( __( 'Process Now', 'friends' ) ); ?>'); |
| 174 |
}); |
| 175 |
}); |
| 176 |
|
| 177 |
$('.run-migration').on('click', function() { |
| 178 |
var $button = $(this); |
| 179 |
var $row = $button.closest('tr'); |
| 180 |
var migrationId = $button.data('migration-id'); |
| 181 |
|
| 182 |
$button.prop('disabled', true).text('<?php echo esc_js( __( 'Running...', 'friends' ) ); ?>'); |
| 183 |
|
| 184 |
$.post(ajaxurl, { |
| 185 |
action: 'friends_run_migration', |
| 186 |
migration_id: migrationId, |
| 187 |
_wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-run-migration' ) ); ?>' |
| 188 |
}, function(response) { |
| 189 |
if (response.success) { |
| 190 |
if (response.data.batched) { |
| 191 |
pollMigrationStatus(migrationId, $row, $button); |
| 192 |
} else { |
| 193 |
refreshMigrationStatus(migrationId, $row, $button); |
| 194 |
} |
| 195 |
} else { |
| 196 |
alert(response.data.message || '<?php echo esc_js( __( 'Migration failed.', 'friends' ) ); ?>'); |
| 197 |
$button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>'); |
| 198 |
} |
| 199 |
}).fail(function() { |
| 200 |
alert('<?php echo esc_js( __( 'Request failed.', 'friends' ) ); ?>'); |
| 201 |
$button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>'); |
| 202 |
}); |
| 203 |
}); |
| 204 |
|
| 205 |
function pollMigrationStatus(migrationId, $row, $button) { |
| 206 |
$.post(ajaxurl, { |
| 207 |
action: 'friends_get_migration_status', |
| 208 |
migration_id: migrationId, |
| 209 |
_wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-migration-status' ) ); ?>' |
| 210 |
}, function(response) { |
| 211 |
if (response.success) { |
| 212 |
$row.find('.migration-status').html(response.data.html); |
| 213 |
if (response.data.in_progress) { |
| 214 |
setTimeout(function() { |
| 215 |
pollMigrationStatus(migrationId, $row, $button); |
| 216 |
}, 2000); |
| 217 |
} else { |
| 218 |
$button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>'); |
| 219 |
} |
| 220 |
} |
| 221 |
}); |
| 222 |
} |
| 223 |
|
| 224 |
function refreshMigrationStatus(migrationId, $row, $button) { |
| 225 |
$.post(ajaxurl, { |
| 226 |
action: 'friends_get_migration_status', |
| 227 |
migration_id: migrationId, |
| 228 |
_wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-migration-status' ) ); ?>' |
| 229 |
}, function(response) { |
| 230 |
if (response.success) { |
| 231 |
$row.find('.migration-status').html(response.data.html); |
| 232 |
} |
| 233 |
$button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>'); |
| 234 |
}); |
| 235 |
} |
| 236 |
}); |
| 237 |
</script> |
| 238 |
|