You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Native Instagram Embed Support for Rebits: Added rich card embedding for Instagram Posts, Reels, and Stories (instagram.com/p/, /reel/, /stories/). Automatically parses usernames, post types, badges, descriptions, thumbnails preserving natural aspect ratios (1:1 square, 4:5 portrait, and landscape) with Reel video play overlays, profile picture avatars in gradient rings, and direct "View on Instagram" actions while preserving full compatibility with PNG card exports and dark/light feed themes.
X / Twitter Embed Support for Rebits: Upgraded X/Twitter Rebits to use responsive native card styling with verified author avatar, handle, exact timestamp, formatted tweet text, attached image media & multi-photo galleries, and direct X actions.
Contenteditable Micro-Editor with Live Hashtag & URL Highlighting: Upgraded composer and timeline edit modal textareas to a contenteditable micro-editor module (bitstream-editor.js). Features real-time #hashtag accent coloring, http:///https:// URL underline highlighting, caret-anchored hashtag autocomplete popup (Range.getBoundingClientRect()), inline Twemoji rendering, HTML entity escaping to prevent DOM XSS, and a plain-text paste sanitizer fallback for older browsers.
Direct Clipboard Image Paste in Composer: Added support for pasting images directly from the clipboard (Ctrl+V / Cmd+V) into the composer editor (bitstream-editor.js & bitstream-composer.js). Pasted images are automatically processed, compressed if necessary, uploaded to the WordPress media library, and attached to the bit with live thumbnail previews without needing to open the media upload dialog.
Changed
Composer Header Drafts & Scheduled Integration, Mobile Compose FAB, and Desktop Settings Relocation: Integrated direct 1-tap "Drafts (X)" and "Scheduled (Y)" pill buttons into both desktop and mobile composer headers (auto-hiding when count reaches 0), streamlined the mobile navigation bar into a balanced 3-button layout (Home, Search, More) paired with a dedicated floating action button (FAB) for composing, moved the desktop Settings link into the right sidebar Notifications & RSS widget for administrators, and retired the redundant left-rail Quick Actions block.
Inline Composer Expansions & Anchored Popovers: Replaced separate modal dialogs for Media, Link/Rebit, Schedule, and Mood in the composer with streamlined inline expansions, direct native uploads, and anchored popover menus across desktop and mobile.
Link / Rebit Popover: Replaced the inline URL expansion bar with a compact anchored popover offering autofocus URL input, instant Enter-key fetching, and Attach/Cancel controls with OpenGraph card rendering in the preview carousel.
Media Popover & Native Drag-and-Drop: Added a compact anchored popover offering "Upload from Device" (triggering native file picker) and "WordPress Media Library", alongside direct drag-and-drop file uploading onto the composer and direct clipboard image paste (Ctrl+V).
Schedule Popover: Replaced the schedule modal with an anchored popover featuring datetime selection and Set/Clear actions.
Mood Reaction Popover & Inline Edit Mode: Replaced the cumbersome mood popup and separate settings tab with a self-contained 320px floating reaction popover anchored directly above the emotion button. Displays available moods in a clean wrapping grid with instant 1-click selection and toggle deselect, an inline + button to create new moods on the fly, and a dedicated ✏️ Edit Mode. In Edit Mode, users can reorder moods via HTML5 drag-and-drop on desktop or touch drag on mobile with native haptic vibration feedback (navigator.vibrate pulses on pick-up and drop) and real-time floating finger-lift translation (translate3d tracking 44px above the fingertip for unobstructed visibility during drag), tap any mood to edit its emoji or feeling label in-place, tap × badges for instant deletion backed by a 5-second Undo toast and background server synchronization, and automatic exit from Edit Mode when clicking outside the popover or clicking the trigger icon.
Mood Card in Mobile Preview Carousel: Integrated the selected mood card directly into the composer's mobile preview carousel alongside Media and Rebit cards, formatted with the large emotion display matching desktop emotion-only posts (.bit-card-pure-mood) to maximize composer textarea space on mobile screens.
Anchored Popover for Post Share Options: Replaced the modal dialog for the post card share picker with a compact, anchored popover floating directly next to the share button. Dynamically positions above or below the button with viewport boundary clamping and automatically dismisses on page scroll, window resize, or click-outside. Retains the branded card generation modal for the secondary "Share as Image" preview.
Unify Quoting and Editing into Main Composer: Unified Quoting and Editing workflows directly into the main Composer on both desktop and mobile, retiring separate edit modal popups (.bs-edit-modal). Features an "Editing Bit #ID" banner with cancel controls, full access to moods, media attachments, and formatting tools, smooth scroll highlighting on desktop, full-viewport screen slide-ups on mobile, and automatic in-progress draft stashing and restoration.
Remove Options to Add Images, Links, or Moods from Edit Bit Screen: Dynamically hid the "Add Mood", "Add Media", and "Add Link" action buttons (.bs-edit-actions-row) and image paste uploads when editing an existing post in the edit modal, while preserving these options when composing a new quote bit.
Modularize Client-Side JavaScript: Deconstructed the monolithic 10,000+ line assets/js/bitstream.js script into five focused, separate module files (bitstream-lightbox.js, bitstream-cropper.js, bitstream-uploader.js, bitstream-composer.js, and bitstream-timeline.js) under assets/js/. Converted the main bitstream.js file into a lightweight bootstrapper that registers and initializes these modules on DOMContentLoaded. Registered the modular scripts in WordPress with dynamic cache-busting version hashes based on filemtime and linked them as dependencies of the main bitstream-js handle, simplifying enqueues in all display, admin, and block editor interfaces to use a single handle.
Make PWA Rewrite Flush Logic Dynamic: Replaced version-specific hardcoded option keys for PWA rewrites and shortcut rule flushing with a version-independent bitstream_flushed_version database check compared directly against BITSTREAM_VERSION, dynamically pruning deprecated options.
Optimize Custom Moods Propagation: Rewrote the custom mood edit propagation logic in handle_save_custom_moods to run a unified SELECT statement and batch UPDATE queries on the postmeta table instead of individual O(N) get_posts loops and update_post_meta() calls.
Consolidate Attachment Usage Scans: Consolidated duplicate attachment checking logic in class-ajax-handlers.php and class-admin-interface.php into a unified static helper BitStream_Content_Display::is_attachment_used(). Optimized database-level checking to query the inline image url and class names in a single combined SQL statement instead of separate queries.
Extract Block Editor JavaScript from Heredoc: Extracted the massive ~800 lines of Gutenberg block editor JavaScript from a PHP heredoc string in class-block-editor.php into a standalone asset file assets/js/bitstream-block.js registered and enqueued with standard wp_register_script() and cache-busting.
Encapsulate Global Layout-Rendering Functions: Moved timeline card, quoted post, ReBit media preview, and comment callback rendering functions out of the global bootstrap namespace into static methods within BitStream_Content_Display. Lightweight wrapper functions remain in bitstream.php for backward compatibility.
Hashtag Scan Performance Optimization: Replaced the inefficient O(N) PHP memory-regex parsing loop in get_hashtag_counts with a database-level postmeta lookup and indexing structure. Hashtags are now extracted on save/update, indexed once, and retrieved using optimized SQL query joins.
Harden Like Handler for Anonymous & Logged-In Users: Implemented dual-tracking in handle_like() using user IDs for logged-in users and hashed IP addresses for anonymous visitors stored in _bitstream_liked_by postmeta. Retained nopriv access so unauthenticated visitors can like bits while preventing duplicate like/unlike inflation.
Consolidate Inline Template Styles into Stylesheet: Extracted 250+ inline style="..." attributes scattered across render_card(), render_nested_quoted_card(), render_rebit_section(), render_og_card(), single_bit_styles(), and the mood modal into structured, reusable CSS classes in assets/css/bitstream.css (including .bitstream-mood-grid 3-column layout). Removed inline <style> injection from single_bit_styles().
Deduplicate Image Attachment Preview URL Helper: Extracted image size lookup logic into a private get_best_preview_url() helper method in class-ajax-handlers.php used by create_media_attachment_from_upload() and handle_get_attachment_data().
Refactor Composer Submission Handler: Extracted assemble_post_content(), persist_common_metadata(), and build_composer_response() helper methods to eliminate 150+ lines of duplicate logic between Bit and Rebit submit flows in handle_submit_composer().
Consolidate Frontend JavaScript Namespace: Exported media, timeline, and UI helper functions under window.BitStream.Media, window.BitStream.Timeline, and window.BitStream.UI while maintaining backward-compatible global aliases.
Optimize Attachment ID Collection during Post Deletion: Removed redundant attachment_url_to_postid() regex URL scanning from collect_bit_attachment_ids() in class-ajax-handlers.php, eliminating N+1 database queries per post cleanup while preserving ID resolution via meta, parent linkage, thumbnail, and wp-image-{id} classes.
Optimize Composer Draft Count Calculation: Replaced full WP_Query object instantiation in build_composer_response() in class-ajax-handlers.php with a lightweight direct $wpdb->get_var() prepared query to count author drafts without query overhead on composer submissions.
Lazy-Load Mood Modal Emoji Parsing: Optimized assets/js/bitstream-composer.js by caching twemoji parsing on the mood modal to run once on initial render instead of on every modal open, and replaced inline button styles in renderSavedMoods() with CSS classes .bitstream-mood-btn, .bitstream-mood-btn-emoji, and .bitstream-mood-btn-label.
Automatic Share Image Cache Cleaning on Bit/Rebit Edit: Configured post updates across composer submissions, admin edits, and save_post_bit hooks to automatically delete the cached share image PNG file and clear _bitstream_share_image_url and _bitstream_share_image_path metadata for the edited bit/rebit as well as any bits quoting it, ensuring share card images are always regenerated from the latest version.
Draft & Scheduled Item Previews Enhancement: Updated the Drafts and Scheduled list modals to display Rebit title/target link content (_bitstream_og_title or bitstream_rebit_url) instead of just a generic label, and added rich metadata badges for emotions/moods, attached media items, and quoted bit indicators across both Bits and Rebits in the list views.
Timeline Edit & Quote Modal Loading Indicator: Relocated form submit and metadata refetch loading indicators directly into the action buttons (showing an inline spinner and status text like "Updating..." or "Publishing...") instead of inserting a loading block into the modal body, preventing layout shifts during posting. Styled initial data fetching to display a centered full-height spinner animation until the form finishes populating.
Modern ReBit Mappings Hub & Modular Settings Architecture: Redesigned the legacy multi-form ReBit mappings management screen into a unified, responsive Master-Detail Mappings Hub. Features real-time client search filtering, 1-click popular preset auto-fill chips integrated directly inside the Add/Edit drawer with live badge previews and automatic URL normalization, and compact card rows with instant inline editing and deletion backed by a 5-second Undo toast. Replaced the 400KB external JSON icon modal with a lightweight, curated icon picker popover. Extracted client-side settings interactivity into a dedicated modular script (assets/js/bitstream-settings.js) registered under window.BitStream.Settings.
Fixed
Mobile Composer Post Button & Actions Visibility: Fixed an issue on mobile where tall preview cards (such as X/Twitter Rebits, Instagram embeds, media grids, or quoted bits) pushed the composer actions row and "Post Bit" button off-screen. Wrapped the actions toolbar, status message, and submit button in a sticky bottom-bar container (position: sticky; bottom) so they remain pinned at the viewport bottom while the modal body scrolls naturally through tall content. Includes safe-area inset padding, a subtle divider border, and dark-mode background support.
PWA Rebit & Web Link Share Target Opening: Fixed an issue where sharing web links, URLs, or external text from other apps to the BitStream PWA displayed the "Content shared to BitStream!" toast but failed to open the composer screen on mobile. Ensured the mobile composer screen slides up and unhides automatically upon detecting shared URLs or composer_tab=rebit, fetches OpenGraph metadata to render live card previews immediately, safely extracts and decodes shared URLs and accompanying commentary text, fixes double-encoding in server-side share redirects, and sets notification toast z-index above the mobile composer screen.
PWA Gallery Video Sharing: Fixed an issue where sharing videos from a mobile gallery app to the BitStream PWA opened the composer but remained stuck on "Loading shared content..." without uploading. Buffered incoming shared media streams using detached Blob.slice() handles in the service worker (sw.js) with explicit transaction.oncomplete commitment and immediate db.close() connection release to prevent IndexedDB lockups across threads, implemented unversioned database opening with blocked event fallbacks and safety timeouts in bitstream-composer.js to ensure the composer never freezes on database version transitions, implemented cold-start retry polling in uploadComposerMedia (bitstream-composer.js) so uploads wait for asynchronous media modules to finish loading before initiating, updated uploadMultipleFiles (bitstream-uploader.js) to stream live percentage progress directly to the composer status bar and return attachment objects, added dynamic cache-busting to the service worker registration URL via sw.jsfilemtime, corrected chunked upload multipart parameter mismatches (chunk vs chunk_data and mime vs mime_type) in assets/js/bitstream-uploader.js and includes/class-ajax-handlers.php, added filename and extension normalization for video Blobs restored from IndexedDB, expanded Web Share Target file filters in manifest.json with video MIME types and extensions, hooked upload_mimes in bitstream.php to ensure common video formats are accepted by WordPress, detected dropped requests exceeding post_max_size in class-pwa-manager.php with informative user error handling, and added video play-icon overlays with metadata preloading to media preview grids.
Author Line Mood Spacing: Fixed an issue where an excessive gap appeared between the post author name and the "is feeling" mood status text on timeline and quoted cards due to multi-line template whitespace and redundant CSS margin-left.
Rebit Link Preview Banner Margin and Floating Corners: Fixed an issue where generic Rebit link preview cards rendered with an awkward empty gap/margin above the image and floating rounded corners inside the card container. Removed .bit-rebit-preview img from the post-content image defaults and styled it flush with full container width, zero margins, no inner radius, and object-fit: cover.
Live Photos & HEIC Composer Previews and Cropping: Fixed composer media preview squares and the image cropper for HEIC/motion photo uploads and standard web images. Small preview squares use optimized preview URLs, while the cropper uses the full-resolution original image for web formats (and converts HEIC uploads to full-quality JPEGs on the server with highest-res fallback). Fixed the cropper dimensions indicator to calculate against the true original image dimensions rather than downscaled preview dimensions.
Hashtags Preceded by Emojis, Punctuation, or Symbols: Fixed hashtag regex lookbehinds across frontend rendering, database indexing, and micro-editor formatting/autocomplete to allow hashtags directly following emojis (e.g. 😋#yum), quotes, or punctuation without requiring whitespace.
Mobile Rebit Draft Preview Overflow Fix: Fixed .bitstream-composer-item-rebit-preview using width: fit-content; max-width: 100%; and .bitstream-composer-draft-info using flex: 1 1 0%; overflow: hidden; to ensure long Rebit titles/URLs truncate with an ellipsis within card bounds on mobile screens.
Quote Bit Modal Title & Loading State: Fixed the timeline quote modal displaying "Edit Bit" as its title while loading a quote preview by setting the modal title immediately to "Quote Bit" upon opening, and ensured edit modals set their titles accurately ("Edit Bit" / "Edit Rebit") during loading.
Saving Mood-Only Bit to Drafts & Broken Drafts Emojis: Fixed a validation issue in composer draft saving (assets/js/bitstream-composer.js) where attempting to save a bit draft containing only a mood or quote triggered a "there's nothing to save" error, updated auto-save and composer discard checks to evaluate mood and quote fields, added mood emoji/emotion fallback text for empty draft items in the drafts list, fixed 404 URL generation for variation-selector emojis (e.g. 👁🗨) by retaining -fe0f in Twemoji asset URLs, and ensured parseEmojis() is called when opening the drafts and scheduled modals.
Fragile OG Data Fetching on Rebit Post Save: Replaced unsafe $_POST superglobal manipulation and faked AJAX handler calls in save_rebit_og_data() with a direct call to BitStream_OG_Fetcher::fetch_og_data(), preventing process termination during background post saves.
Stray CSS Rule in Single Bit Styles: Fixed an orphaned CSS declaration in single_bit_styles() inside class-content-display.php that caused invalid CSS in the <head> of single-bit pages.
Redundant Horizontal Bar on Single Bit Pages: Removed duplicate <hr> element rendered immediately before the card footer in render_card().
Like Button AJAX Mismatch: Fixed bit-like frontend click handler sending mismatched action and nonce parameters (bitstream_like_post/like_post_nonce vs bitstream_like/like_nonce), restoring like/unlike functionality across all pages.
Single Bit Quote Modal Initialization: Added modal initialization before calling openTimelineQuoteModal on .bit-quote clicks so quote modals launch properly from single bit permalinks.
Scheduled Rebits and Scheduled Count Sync: Fixed scheduled Rebits falling back to immediate publish status due to build_schedule_args() only looking for rebit_schedule_enabled (while composer forms output bit_schedule_enabled), and added automatic user post count flushing in handle_save_post() so scheduled post counters and modals stay in sync.
Timeline State Desync on Post Deletion: Fixed sidebar hashtag/emotion counters and timeline state remaining out of sync after a post is deleted by triggering a page reload once the deletion success animation completes.
Rebit Draft OG Metadata Not Loading: Fixed handle_get_draft_data using incorrect meta keys (bitstream_rebit_og_title/desc/image instead of _bitstream_og_title/desc/image), which caused the title, description, and image fields to always be empty when loading a saved Rebit draft back into the composer.
Mood Propagation Querying Non-Existent Post Type: Fixed handle_save_custom_moods querying for a rebit post type (which does not exist) alongside bit when propagating mood label edits to past posts.
Future Post Scheduler Timezone Offset Bug: Fixed scheduled post validation comparing the UTC timestamp from getTimestamp() with timezone-offset current_time('timestamp'). Corrected to compare against UTC time().
Deprecated current_time() Calls: Replaced deprecated current_time('timestamp') with time() when calculating relative post ages on cards and quoted posts to prevent deprecation warnings.
Post Title and Slug Auto-Regeneration: Added current title pattern validation in auto_generate_title() to prevent post titles and slugs from being regenerated (and daily count transients incremented) on updates/saves of existing posts.
Missing Custom Thumbnail Metadata on Rebit Drafts: Added rebit_attachment_id to the returned payload in handle_get_draft_data() so custom uploaded images for drafts populate correctly when loaded back into the composer.
Rebit Commentary Description Newline Stripping: Changed Rebit OG description sanitization to use sanitize_textarea_field() instead of sanitize_text_field() to preserve line breaks when saving cards.
WebP Transparency Loss on GD Fallback: Enabled alpha blending and saving flags in the GD WebP metadata stripping fallback so WebP images with transparent backgrounds do not render black/gray backgrounds.
Undefined Variable PHP Notice in Cache Buster: Declared $attachment_id = 0 inside the image cache buster callback to prevent PHP notices when checking tags without valid image IDs.
Interrupted Chunk Upload Directory Accumulation Leak: Integrated temporary upload chunk cleanup (deleting files/folders older than 24 hours under wp-content/uploads/bitstream-chunks/) into the weekly automated media cleanup routine.
JavaScript Compatibility Errors on PHP 7.4: Replaced PHP 8.0+ functions str_starts_with() and str_contains() with PHP 7.4-compatible strpos() checks inside OpenGraph scraping routines.
JavaScript Early Loading DOM Errors: Wrapped the mobile bottom navigation script execution block in DOMContentLoaded to prevent runtime query errors if scripts load before elements are parsed.