Release notes / WPMediaVerse
Free Plugin Plugin

WPMediaVerse

WordPress media library treats every photo and video like an attachment, and at 10k uploads it crawls. WPMediaVerse runs on dedicated database tables with feeds, lightboxes, direct messages, and OpenAI Vision moderation included.

7 releases
v1.3.0 latest
May 17, 2026 shipped

v1.3.0 Latest

May 17, 2026
New 16 Improve 3 Fix 8 Dev 2 Compat 1

New

  • Automatic image optimization on every upload. JPEGs, PNGs, and GIFs are re-encoded for smaller file size with hidden camera data stripped. Most uploads drop 10 to 30 percent without any visible quality change.
  • WebP image format support. Every uploaded image gets a second copy in WebP, around 25 to 35 percent smaller than JPEG. Modern browsers automatically use the smaller file; older browsers keep using the original.
  • AVIF image format support for even smaller files. AVIF is roughly 30 percent smaller than WebP again. Opt in from Settings, Storage tab. Default off because AVIF encoding takes longer than WebP.
  • Frontend serves WebP across every surface. Explore grid, BuddyPress activity feed, dashboard cards, single-media view, and the lightbox all swap in WebP automatically when the visitor's browser supports it.
  • Private images now also serve WebP and AVIF. Access-rule-protected media gets the same modern-format speed boost as public media.
  • Cloud storage migration tools. Move existing local media to S3 or BunnyCDN in batches, then clean up the local copies after verification. New WP-CLI command "wp mvs migrate-storage --from=local --to=bunnycdn" handles the bulk move with idempotent resume support.
  • Direct CDN URLs for public media. New setting on the Storage tab (default off): when enabled on a cloud-storage install, public images load directly from your CDN edge instead of being proxied through WordPress. Cuts WordPress out of the hot path for image requests.
  • WP-CLI commands to optimize existing media. Run "wp mvs optimize 123" on one item or "wp mvs optimize-bulk" across the whole library. Resume-safe if interrupted.
  • New Optimization column on the All Media admin listing. Shows percent saved per file at a glance. Row actions Optimize and Details added. The Details page shows everything stored about a file with inline buttons to re-optimize, repair thumbnails, or move to trash.
  • Filename strategy setting. New uploads can be saved with hashed filenames or sanitized original names. Hashed mode keeps the user-facing filename visible in downloads and the REST API; only the on-disk file uses the hash. Existing files are never renamed.
  • Faster search at scale. The Explore search now uses a FULLTEXT index for 3+ character queries, returning results across 100,000+ media items in milliseconds instead of seconds. Sites that cannot enable FULLTEXT continue working on the existing LIKE search.
  • Automatic view-event cleanup. View tracking events older than 90 days are pruned daily. Window is configurable per site (0 to disable, max 730 days). Keeps the database lean on long-running sites.
  • Default video poster for videos without an embedded cover image. Previously these showed a black frame. Now they render a clean placeholder.
  • Audio card design. Audio with embedded cover art shows the cover; audio without art shows a unique waveform image generated from the file id.
  • Compatibility with EWWW, Imagify, Smush, and ShortPixel image optimizers through a single extension point. If you already use one of these, leave it active; it runs alongside the built-in optimization.
  • Opt-in usage telemetry to help us prioritize features. Default off. No personal data, file names, or content ever leaves your site. Counters stay local.

Improve

  • Explore feed shows newest media first. Albums no longer pin to the top of page one because they are static containers. Album pages remain accessible by their permalinks.
  • Per-request media cache for activity feeds and dashboards. Each media item is loaded from the database once per page even when rendered many times. Drops query count on busy pages.
  • Production stability commitments documented for site owners. The plugin will deprecate features through proper notice periods of at least two major versions instead of removing them without warning.

Fix

  • Security: BuddyPress activity privacy now follows media privacy. Previously a non-public media uploaded to a BP activity would leak the activity card (composer text, timestamp, author) to the public stream. Activity visibility is now derived from the strictest of the media and album privacy settings.
  • Security: REST per-page hardening across all list endpoints. Callers can no longer request unbounded result sets to slow the site. Maximum is filterable for trusted environments.
  • Cloud storage uploads now generate thumbnails reliably. Some cloud-driver uploads previously failed to produce thumbnails silently.
  • Image optimization never makes a file larger. If the optimized version is bigger than the source, the original is kept.
  • Animated GIFs stay animated. The optimization pass now detects animated GIFs and skips them so they aren't flattened to their first frame.
  • Broken thumbnail icons no longer appear for videos and audio when no poster image is available. Videos fall back to their first frame; audio falls back to the music icon.
  • Most MP4 video uploads now generate proper poster images on managed WordPress hosts. Previously some uploads silently fell back to a low-quality thumbnail because of how managed hosting environments configure server binaries.
  • Cleared all PHP 8.4 and PHP 8.5 compatibility warnings. The plugin runs cleanly on the latest PHP versions.

Dev

  • New action hook mvs_media_privacy_changed fires when a media's privacy column is updated. Useful for activity adapters and audit logs.
  • New StorageDriverInterface::download($path, $local_dest) method on Local, S3, and BunnyCDN drivers. Third-party storage drivers must implement it.

Compat

  • Paired with WPMediaVerse Pro 1.3.0. Install both updates together when running Pro.

v1.2.0

New 23 Fix 16

New

  • Member Photos block + shortcode (`mvs/member-photos`, `[mvs_member_photos]`) - auto-detects whose photos to show: explicit `userId` → BP displayed user → post author → current user. Drop it into a BP profile, an author template, or a regular page and it just works.
  • PDF Viewer block + shortcode (`mvs/pdf-viewer`, `[mvs_pdf_viewer]`) - embeds PDFs uploaded to WPMediaVerse using the browser's native PDF viewer (`#view=FitH`); inspector exposes height (200-1400 px) and toolbar toggle. Five distinct empty states (no id / not found / not a PDF / no permission / asset missing) - never a blank rectangle.
  • More sort options on Media Grid - added "Most Popular", "Most Viewed", "Most Reactions", and "Random". Asc/Desc direction toggle exposed in the inspector (hidden when sort = Random). New `userId` attribute on `mvs/media-grid` and `user_id` attr on `[mvs_gallery]` filter to one author.
  • Search autocomplete on the Explore feed - type two or more characters and a top-8 title-match dropdown opens (debounced 250 ms). Full keyboard support: ArrowDown / ArrowUp / Enter / ESC. ARIA combobox + listbox semantics so screen readers announce matches as you type.
  • Lightbox Download button - toolbar button next to Share + Open. Counts each download in `mvs_media_stats.downloads`; rate-limited at 30/min/user via the central `RateLimiter`. New `POST /mvs/v1/media/{id}/download` REST endpoint.
  • Per-media Edit modal - click the Edit button on your own dashboard cards to change title, description, privacy, and allow-download per-media. Save → live update without reload. `PUT /mvs/v1/media/{id}` now accepts `allow_download` (boolean) and `prepare_item_for_response` emits it (defaults `true` when meta absent).
  • Member Photos card - redesigned hero card with avatar + display name + handle + bio + stats (photos / followers / following) + View Profile + Follow/Following toggle. Container-query responsive: switches to vertical stack at <520 px container width (so it fits a sidebar widget) and remains compact at 320 px.
  • "Update URL slug" opt-in checkbox - present in the per-media Edit modal AND on `/media/{slug}/` inline-edit form, sitting beside Privacy on the same row. Off by default - title edits leave the URL stable. Tick to regenerate the slug from the new title; if you're currently viewing the old URL, the page redirects to the new one automatically (no 404 on reload).
  • Open Graph + Twitter Card meta on every `/media/{slug}/` page - `og:title` / `og:type` / `og:url` / `og:site_name` / `og:description` / `og:image` / `og:image:alt` plus `twitter:card=summary_large_image` + `twitter:title/description/image`. Paste a media URL into Slack / Twitter / LinkedIn / Discord and it unfurls correctly.
  • Popular tag pills in the upload modal - top-8 most-used tags surface as click-to-add chips below the tags input. Clicking a pill appends to the comma-separated input and de-dupes silently.
  • Upload modal polish - preview tiles show filename + per-tile (×) remove button; audio files get an audio-fallback icon (no broken-image SVG).
  • Bulk Actions on All Media - multi-select header/footer checkboxes + a Bulk Actions toolbar. Action menu is context-aware to the active filter: in the Trash filter → Restore + Delete permanently; otherwise → Move to Trash. Capability + `wp_nonce_field('mvs_bulk_media')` gates on submit; success notice with count + action.
  • Chat panel visibility setting under Direct Messages - pick where the floating chat panel renders: Everywhere (default) / WPMediaVerse pages only / BuddyPress pages only / Disabled. New `mvs_should_render_chat_panel` filter wraps the resolved decision so themes / add-ons can fine-tune by URL pattern.
  • Global "Allow downloads" toggle under Media Display - single switch that hides the new lightbox Download button site-wide AND makes the `record_download` REST endpoint refuse with 403. Per-media `allow_download` meta still gates further when the global is on.
  • 6-reaction accessibility in the lightbox - Like / Love / Haha / Wow / Sad / Angry each carry sentence-form `aria-label` and `aria-pressed` toggles; the emoji span is `aria-hidden`; the wrapper carries `role="group" aria-label="Reactions"`. Toolbar buttons (Favorite / Share / Download / Open / Report) all gain `aria-label`. `:focus-visible` outline on `.mvs-lightbox-action / -close / -nav` so keyboard nav is visible.
  • Block render forms a11y - explore-feed search input, media-upload file input + privacy select + title/description/tags inputs all gain `aria-label` (placeholder ≠ label per WCAG).
  • Search-mode toggle a11y - Media / People toggle on `templates/explore.php` gets `role="tablist"` + `role="tab"` + `aria-selected` semantics; search input gets a screen-reader label.
  • BuddyPress notification dedup - restored `NotificationIntegration` (mirrors `mvs_notification_created` to BP's `bp_notifications_add_notification`) and added a `function_exists('buddypress')` guard around the dashboard's `.mvs-notification-bell` markup so BP-active sites render notifications in the BP nav bell only - never twice.
  • `Core\SettingsHelper` - canonical static accessor for paired-plugin settings reads. First slot covers the page-id family (`dashboard` / `explore` / `upload`) plus `mvs_thumbnail_size` and `mvs_openai_api_key`. Pro and themes must use this instead of direct `get_option('mvs_page_*')` reads (Free invariant A4).
  • Hook signatures now carry full type-annotated arg shapes in `audit/manifest.json` (`args_signature[]` on 14 of 22 hooks); enables Pro arch-check A11 to detect cross-plugin contract drift.
  • `SettingsContractTest` enforces register_setting whitelist alignment - settings registration drift is now caught at unit-test time rather than at customer save-time.
  • Block standard alignment (Phase 7) - Free's 9 registered Gutenberg blocks now share the same Spacing / Border / Shadow / Visibility inspector panels as Pro and wbcom-essential. `WPMediaVerse\Blocks\StandardAttributes` injects the 20 standard layout attrs via the `block_type_metadata` filter; `WPMediaVerse\Blocks\MVS_CSS` collects per-instance scoped CSS keyed off `mvs-block-{uniqueId}` and dumps it on `wp_footer`. Pro's `src/shared/` tree (17 files) ported with text-domain swaps.
  • `BaseBPTabIntegration` extracted (Phase 5 P2.4) from `ProfileTabIntegration` + `GroupTabIntegration` - a single bug fix on either BP tab now propagates to both. Net delta -109 lines.

Fix

  • Lightbox Share no longer falls back to a `window.prompt()` "Copy this link:" popup when neither `navigator.share` nor clipboard write is available - instead a toast error renders. `mvs_media_stats.shares` now also increments via the new `POST /mvs/v1/media/{id}/share` REST endpoint.
  • Lightbox toolbar fits 5 actions on one row - the previous layout used inline-flex + per-button padding 24 px + `margin-left: auto` on Report which overflowed the 380 px sidebar (~414 px content) and produced a horizontal scrollbar. Now `flex: 1` + `space-between` distributes evenly; the toolbar always fits at desktop AND on mobile. Below 768 px the lightbox stacks vertically (image on top, sidebar full-width below) and below 380 px labels collapse to icons-only.
  • Moderation webhooks now fire reliably. Two listeners (`WebhookService::on_media_moderated` + `CacheService::on_moderation_change`) were registered against `mvs_media_moderated`, but the firer in `ModerationService::set_status()` uses `mvs_moderation_changed` (the established hook name; `LoggerService` already used it). Result: customers using outbound webhooks for moderation approve/reject events were getting zero events delivered, and the moderation-status cache stayed stale. Both listeners renamed to the correct hook name. Affected since: 1.0.0.
  • `mvs_reaction_removed` action now fires when a user un-reacts. The action existed conceptually (cache invalidation listener was registered) but `ReactionService::remove()` never fired it, so the media-stat cache stayed warm with the old reaction count after an un-react. The reaction count itself was correct (re-read from DB), but cached aggregates lagged.
  • `mvs_share_recorded` action now fires from the new `record_share` REST endpoint so the cache invalidation listener clears the media-stat row. Without this, share counts in feed cards lagged behind reality until the cache TTL expired.
  • Search autocomplete on the Explore feed now aborts in-flight requests when a newer keystroke arrives. Previously, typing fast (e.g. "ne" then "new" within 250 ms) could leave the slower "ne" results visible if its response landed second - a classic race condition. Each keystroke now spawns an `AbortController`-equipped fetch and supersedes any in-flight request.
  • Title edit no longer changes the URL slug. Editing a media title and saving used to silently regenerate the slug - meaning the URL the user just had in their address bar 404'd on reload, and any inbound links / social shares / search-engine cache pointing at the old URL stopped working. Slug now stays stable; admins can opt into a slug change explicitly via the new "Update URL slug" checkbox in the Edit modal and on `/media/{slug}/`.
  • BuddyPress activity no longer renders the same image twice. A Phase 8 "linkage table" code path was appending its rendered grid even when the activity content already contained the inline grid markup - so every composer-posted activity rendered each image twice on the activity permalink page. The render filter now uses inline content as the authoritative copy and only falls back to the linkage path when content is empty.
  • Author profile URLs no longer leak BuddyPress mention HTML. Five sites (Instagram feed cards, leaderboard, dashboard "View Profile" button, follower notifications, and a sibling Instagram card template) built `/media/@user/` URLs inline. When BuddyPress's `bp_activity_at_name_filter` ran on the surrounding output, the `@user` substring inside the URL was rewritten into a full BP mention `<a class='bp-suggestions-mention' …>@user</a>` - corrupting the URL with literal HTML and producing dead links. All five now route through the canonical `TemplateHelpers::get_user_profile_url()` which resolves to the BuddyPress profile when BP is active and the plugin's `/media/@user/` route otherwise.
  • Lightbox `Favorite` button is no longer rendered twice in the action toolbar. Earlier 1.2.0 builds rendered a duplicate Favorite button on certain page contexts. Single button now, with the label flipping between "Favorite" and "Favorited" via the `aria-pressed` state.
  • Demo data importer now runs end-to-end on every install. The `seed-demo-data.php` script (and its sibling `populate-showcase.php` + `cleanup-demo-data.php`) called `MediaRepository::*` static-style; the repository is a container service with instance methods only, so every demo seed attempt fataled with `cannot be called statically`. All 14 call sites swept to the canonical container-resolved instance API. Running the demo seeder now produces 50 media items + 5 demo users + 5 albums + 159 reactions + 30 comments + 40 favorites + 20 follows + 3 reports cleanly.
  • `AlbumService::create()` added - the service had `add_items` / `get_items` / `set_cover` etc. but no top-level `create()` method, so any non-REST caller (seeder, future WP-CLI command, theme code) had to repeat the `wp_insert_post('mvs_album')` + privacy + group_id + categories meta writes inline. Centralised. The `AlbumController::create_item` REST endpoint now delegates to it.
  • `PUT /media/{id}` `allow_download` flag now accepts every body encoding. The flag was previously read only from the JSON body via `$request->get_json_params()` - fine for JS apiFetch (the dominant path), but form-encoded clients and internal `$request->set_param()` calls silently dropped the flag. Now read via `$request->get_param()` which covers all sources uniformly.
  • `mvs_should_render_chat_panel` filter passes the resolved visibility setting as a second argument, so callbacks can scope their override by the admin's chosen mode (`everywhere` / `mvs_pages` / `bp_pages`). Backward-compatible: existing 1-arg callbacks keep working; the new arg is just ignored if not declared.
  • Stats block fits on narrow phones. The `mvs/media-stats` block grid used a 180 px minimum track which pushed the block 11 px past its container on viewports below ~390 px. Switched to `minmax(min(180px, 100%), 1fr)` so the minimum collapses gracefully; below 480 px cards stack one per row.
  • DM access dropdown (Settings → Social → "Who can send me direct messages") no longer silently reverts "Nobody" or "Mutual followers only" to "Everyone" on save. Same root cause silently flipped the "Show online status" preference. The save path looked successful (admin notice "Settings saved." appeared) but the option stored a different value than the dropdown showed. After upgrading to 1.2.0, please reopen Settings → Social and confirm your preferred DM access and online-status visibility - the dropdown now reflects the saved value byte-for-byte. Affected since: 1.1.0. Commit: `d986525`.

v1.1.3

April 29, 2026
New 2 Improve 1 Fix 17 Security 1

New

  • Video uploads now get a real poster thumbnail extracted from the file's embedded cover atom via WP core's getID3 - no ffmpeg required. Works for phone-shot MP4/MOV; screen recordings without an embedded cover fall through to a native `<video preload="metadata">` preview in the grid so the browser paints the first frame - matching what the single media view already does
  • Thumbnail pipeline centralized in `UploadService::generate_thumbnails()` (now public). Pro CLI importers and MigrationPage delegate here via `Plugin::free_service('upload')`, so Free uploads and Pro imports share identical fallback, sizing, and logging. New `mvs_thumbnail_sizes` filter lets themes/add-ons tune sizes without patching

Improve

  • All close, dismiss, and navigation icons in the lightbox, upload modal, and toast notifications replaced with proper Lucide icons (rounded caps, correct paths). Lightbox CSS consolidated into frontend.css as a single source of truth

Fix

  • Lightbox now opens the original full-size image instead of the low-res grid thumbnail. New Display setting "Lightbox Image Size" lets admins pick Original / Large / Medium / Auto (defaults to Original)
  • Lightbox opens full-viewport in Facebook-style layout - image fills the left panel, social sidebar on the right; close button (X) correctly positioned and visible over the image panel
  • Hardcoded emoji characters (play triangle, music note) replaced with inline Lucide SVGs across grids, dashboard, BP activity audio cards, and BP upload preview. WordPress was auto-converting the Unicode chars to emoji images, which looked different across browsers and didn't match the plugin's Lucide-based design
  • Video, audio, and generic placeholders now share a unified frame (aspect-ratio + gradient background) so grids never collapse based on media type - any mix of image/video/audio uploads renders with consistent cell sizing
  • BuddyPress activity stream thumbnails render reliably - defensive `file_url` fallback in `MediaDisplayHelper` when custom `thumb_*` meta is missing, and a path-5 recovery in `ActivityContentIntegration` that rebuilds the grid from `_mvs_media_ids` meta when an activity's saved content lost its markup
  • Delete action no longer leaks onto public grids. The per-item trash icon now only renders on BuddyPress profile and group media tabs (where `show_actions` is explicitly opted in); Explore, Albums, and Collections never show it
  • Settings sidebar brand icon is now clearly visible - the eyebrow-text rule was cascading gray onto the logo SVG, making it blend into the red gradient
  • Dead meta-key reads cleaned up. `ActivityContentIntegration` and Pro's `TranscriptionService` were looking up `attachment_id` meta (dropped in migration v8) - both now use `wp_attachment_id` which importers actually write
  • Every upload path now guarantees all three thumbnail sizes (`thumb_large`, `thumb_medium`, `thumb_thumb`). WP's `multi_resize()` skips sizes that would upscale the source, so small images (under 1024px) used to leave `thumb_large` empty - now the pipeline backfills any missing size with `file_url` (the original IS the largest version)
  • Demo data importer (`seed-demo-data.php` / Overview admin button) now routes through `UploadService::handle()` instead of inserting rows directly, so demo content exercises the full real-upload pipeline - including thumbnail generation, video poster extraction, `mvs_media_uploaded` hook, and LoggerService
  • Silent failures in the thumbnail pipeline are now logged to `mvs_error_log` via `LoggerService` - missing source file, GD/Imagick unavailable, and `multi_resize()` returning empty each write a warning with the media ID for diagnostics
  • Missing "Upload Page" setting added to Settings → General → Pages. The option was read in 3 places but had no admin UI, so custom [mvs_upload] shortcode pages could not be assigned
  • Album cover selection now persists - picking a cover from the album edit page writes to the post meta instead of silently no-op'ing, and the album preview shows the chosen image
  • Albums without an explicitly pinned cover fall back to the first image in the album so they never render with a broken/placeholder cover
  • Lightbox "Favorite" label no longer ships with a duplicated heart emoji prefix - the Lucide icon renders alone as intended
  • 5 free bug cards carried over from 1.1.2 - grid columns=5 rendering, stats page filter date ranges, tag cloud count accuracy, lightbox Favorite visibility for signed-in users, lightbox Share double-icon
  • Thumbnails no longer return 403 errors for logged-in users; album cover thumbnails go through signed URL service for consistent access control

Security

  • `uninstall.php` now has an `ABSPATH` guard alongside the existing `WP_UNINSTALL_PLUGIN` check

v1.1.2

New 13 Improve 1 Fix 18 Security 1

New

  • Add New Tag button on the Tags admin screen
  • Sortable columns on the Tags admin table
  • Back button on every detail page on mobile
  • Touch targets now meet Apple's 44×44 minimum everywhere on mobile
  • Floating upload button respects the iOS safe area (no more overlap with the home bar)
  • Bottom-sheet modals on mobile - slide up from the bottom with a drag handle, like native iOS apps
  • Sticky action bar on the single-media page on mobile - Like, Share, Edit, and Delete stay pinned to the bottom with a blurred backdrop
  • Skeleton loaders while content is loading (smoother than spinners)
  • Instant visual feedback when you tap Like, Favorite, or Follow - the button rolls back automatically if the action fails
  • Tab strips on mobile now scroll horizontally with an edge fade and snap to the active tab
  • Compact icon-with-tooltip buttons on dense action rows on mobile
  • Lucide icons now ship with the plugin - no longer dependent on the active theme to load them
  • Filters to let extensions register custom notification types (`mvs_notification_types`, `mvs_notification_message`)

Improve

  • Updated translation template (POT) with all new strings

Fix

  • Setting Grid Columns to 5 now actually renders 5 columns on the Explore page, single-album view, collections, and dashboard grids (was collapsing to a single column because the 5-column CSS rule was missing)
  • Stats page Today / This Week / This Month / All Time filters now change the Media count and Albums count - previously these cards ignored the date range and looked identical for every filter
  • New tags now show up in the Explore tag cloud immediately after upload (tag count used to stay at 0 because WordPress couldn't count media stored in our custom table - now counted correctly for both tags and categories, plus a one-time backfill for existing tags)
  • Favorite button in the lightbox is now visible to all signed-in users, including the media owner (matches the behaviour of the single-media page)
  • Lightbox Share button no longer shows two icons - now uses the same clean Lucide icon set as the single-media page (Favorite / Share / Open / Report all unified)
  • Bulk-deleting tags no longer produces an error
  • Tag admin pagination count now matches the actual number of tags
  • Sort order is preserved when using bulk actions on tags
  • Deleting a tag now redirects back to a valid page instead of an error page
  • Lightbox opens instantly from media grids - no extra loading delay
  • Moderation queue's AI Flagged tab now correctly lists flagged media (was showing empty)
  • Duplicate-upload "Warn" mode now actually shows a warning when a matching file already exists
  • Fresh installs now have the default Allowed File Types ticked on first visit
  • Album categories are now fully wired - create, update, filter by category, and see category links on single-album pages
  • Demo data cleanup now also removes the tags created by the demo seeder
  • "Allow per-upload privacy" admin setting is now honoured on every upload surface - block editor, BuddyPress activity form, and the backend upload handler
  • BuddyPress activity upload now shows a privacy selector once a file is selected, when per-upload privacy is enabled
  • User deletion and GDPR erasure now clean up all related data - access rules, access grants, view history, direct messages, and conversation participants - so no orphan records are left behind

Security

  • Tag management screens now verify user capability and nonce on every action

v1.1.1

New 3 Improve 2 Fix 23

New

  • CLI command `wp mvs generate-video-thumbnails` - batch generates video thumbnails via ffmpeg
  • Auto-generate video thumbnails from browser during upload
  • Improved audio placeholder in media grid (gradient background, larger icon)

Improve

  • Social settings docs updated to match actual implementation
  • 609 CLI test assertions across 30 suites (was 271 across 14)

Fix

  • Single media page - comments, reactions, favorites, follow, and report now work (Interactivity API store loading)
  • Signed URL serving for all media files - images and videos load correctly with .htaccess protection
  • Anonymous users can now view public media in lightbox without 401/403 errors
  • Notification titles show correct media name from mvs_media_index (not WordPress post title)
  • Notification owner lookup uses MediaRepository instead of get_post_field()
  • DM notifications now fire when messages are sent via REST API
  • Favorite notifications now fire on toggle
  • Reaction counts properly sync to mvs_media_index on add/remove
  • Delete cascade cleans up reactions, favorites, comments, mentions, album items, notifications, and activity
  • Privacy enforcement on REST API - anonymous users blocked from members/private media
  • Block bypass prevented - cannot follow a blocked user
  • Profile Message button respects recipient-level DM privacy setting
  • Messaging page dark mode uses theme data-theme attribute instead of OS prefers-color-scheme
  • Messages page auto-loads conversations on /messages/ (was blank)
  • Chat header avatar hidden when no conversation selected (no broken image)
  • Report modal spacing between dropdown and buttons
  • Allowed file types admin setting wired to frontend upload UIs
  • Album upload links files to album after creation
  • Album mode allows multiple file selection
  • Admin grid columns setting is now the source of truth for all media-grid blocks
  • Thumbnail style setting applied to explore and dashboard grids
  • ID column added to admin All Media table
  • Video thumbnail preview in upload modal (canvas frame capture)

v1.1.0

New 8 Improve 7 Fix 19 Security 2

New

  • Unified Load More across all layouts (event delegation, no page reloads)
  • Full-grid lightbox navigation (prev/next browses all loaded items)
  • Unified Moderation page - AI Flagged, Pending, User Reports (Pro), Resolved tabs
  • Unified Stats page - Overview + Video Analytics (Pro) tab
  • Activity logging for uploads, moderation, reports, and user actions
  • Settings page header bar with version badge and Setup Wizard link
  • Lightbox video and audio playback - native player controls for all media types
  • Upload capabilities granted to all roles on activation (including custom and BuddyPress roles)

Improve

  • Complete admin UX overhaul following wbcom-modern-admin rulebook
  • CSS design token system - 20 semantic tokens replace 90+ hardcoded hex values
  • Lightbox works for logged-out users (read-only reactions, comments visible)
  • REST API tag, category, search, scope, group_covers filters + stats in response
  • Cleaner admin menu - Migration, Reports, Analytics hidden from sidebar
  • FAB upload button only shows on MVS pages for focused UX
  • BuddyPress activity lightbox supports video and audio inline playback

Fix

  • Delete button not working (state binding mismatch in confirm dialog)
  • Media single URLs with underscores redirecting to wrong page
  • Setup wizard page mapping using wrong page IDs after site reset
  • Grid columns setting ignored due to block.json default override
  • Toast notification bindings across all templates
  • Notification items missing clickable links
  • Album cover image quality upgraded from medium to large
  • Share button link generation with proper error handling
  • Default privacy not applied to new uploads
  • BP Activity form script loading from wrong path
  • Stats REST endpoint returns zeros for new media (was 404)
  • Confirm dialog dynamic button labels (Report/Delete)
  • Report dialog with reason dropdown selector
  • Third-party notice suppression on all admin pages including CPTs
  • Interactivity API shared-ui loading from build path
  • moderation_status filter on explore page
  • Unified per_page to use mvs_items_per_page setting everywhere
  • Accessibility - visible focus rings, aria-current, aria-label, reduced-motion
  • Removed all inline styles from admin PHP templates (14 instances)

Security

  • Sanitized $_SERVER['REQUEST_URI'] in login redirect
  • Webhook SSL verify uses wp_is_local_environment for local dev

v1.0.0

Note 11

Note

  • Initial release - complete media platform for WordPress
  • Custom database tables (mvs_media_index, mvs_media_meta, mvs_media_stats) - zero wp_posts pollution
  • 38 features across core platform, social layer, BuddyPress integration, and developer tools
  • 6-level privacy system with BuddyPress-aware fallback
  • AI moderation with OpenAI Vision - flag, quarantine, or reject uploads automatically
  • 13 Gutenberg blocks powered by WordPress Interactivity API
  • 8 shortcodes for embedding media features anywhere
  • 80+ REST API endpoints across 17 controllers
  • 8 WP-CLI commands for bulk operations and maintenance
  • Template override system
  • GDPR data export and erasure