@@ -270,11 +270,7 @@ export async function renderPatchList(patches) {
270270 // Detect conflicts in patches
271271 conflictState = detectPatchConflicts ( patches ) ;
272272
273- // Show alert if conflicts detected AND we should show it (only on document open or after reconciliation)
274- if ( conflictState . conflictGroups . length > 0 && showConflictAlertOnNextRefresh ) {
275- showConflictAlertOnNextRefresh = false ;
276- showConflictAlert ( conflictState . conflictGroups , patches ) ;
277- }
273+ // Reset the flag (we no longer show alerts, conflicts are visible in timeline)
278274
279275 // Get filter values
280276 const authorFilter = document . getElementById ( "filter-author" ) ?. value || "all" ;
@@ -530,7 +526,6 @@ export async function renderPatchList(patches) {
530526 </div>
531527 <div class="timeline-item-actions">
532528 <button class="preview-btn" data-patch-id="${ patch . id } " title="Preview diff">🔍 Preview</button>
533- <button class="view-btn" data-patch-id="${ patch . id } " title="View content">👁️</button>
534529 <button class="restore-btn" data-patch-id="${ patch . id } " title="Restore to this version">↩</button>
535530 </div>
536531 </div>
@@ -570,15 +565,6 @@ export async function renderPatchList(patches) {
570565 await restoreToPatch ( patchId ) ;
571566 } ) ;
572567 } ) ;
573-
574- // Add click handlers for view buttons
575- list . querySelectorAll ( '.view-btn' ) . forEach ( btn => {
576- btn . addEventListener ( 'click' , async ( e ) => {
577- e . stopPropagation ( ) ;
578- const patchId = parseInt ( btn . dataset . patchId ) ;
579- await viewPatchContent ( patchId ) ;
580- } ) ;
581- } ) ;
582568}
583569
584570/**
@@ -627,36 +613,6 @@ async function previewPatch(patchId) {
627613 enterPreview ( patchId , currentContent , mergedResult ) ;
628614}
629615
630- /**
631- * View the content of a patch in a modal
632- * @param {number } patchId - The ID of the patch to view
633- */
634- async function viewPatchContent ( patchId ) {
635- const patch = await fetchPatch ( patchId ) ;
636- if ( ! patch ) {
637- alert ( "Failed to load patch" ) ;
638- return ;
639- }
640-
641- const content = patch . data ?. snapshot || "No content available" ;
642-
643- // Get previous SAVE patch for diff (not edit patches)
644- const allPatches = await fetchPatchList ( ) ;
645- const savePatchesOnly = allPatches . filter ( p => hasSnapshotContent ( p ) ) ;
646- const currentIndex = savePatchesOnly . findIndex ( p => p . id === patchId ) ;
647- let diff = null ;
648-
649- if ( currentIndex > 0 ) {
650- const previousPatch = savePatchesOnly [ currentIndex - 1 ] ;
651- const previousContent = previousPatch . data ?. snapshot || '' ;
652- diff = calculateDiff ( previousContent , content ) ;
653- } else {
654- diff = "No previous version to compare with" ;
655- }
656-
657- showContentModal ( patchId , content , diff ) ;
658- }
659-
660616/**
661617 * Format character-level diff with better line grouping
662618 * @param {string } oldText - Previous text
@@ -713,106 +669,6 @@ function calculateDiff(oldText, newText) {
713669 return lines . join ( '\n' ) ;
714670}
715671
716- /**
717- * Show a modal with patch content
718- * @param {number } patchId - Patch ID
719- * @param {string } content - Content to display
720- * @param {string } diff - Diff to display
721- */
722- function showContentModal ( patchId , content , diff ) {
723- let modal = document . getElementById ( "patch-content-modal" ) ;
724-
725- if ( ! modal ) {
726- // Create modal on first use
727- modal = document . createElement ( "div" ) ;
728- modal . id = "patch-content-modal" ;
729- modal . className = "modal" ;
730-
731- modal . innerHTML = `
732- <div class="modal-content">
733- <div class="modal-header">
734- <h2>Patch Content</h2>
735- <span class="modal-close">×</span>
736- </div>
737- <div class="modal-tabs">
738- <button class="tab-btn active" data-tab="content">Content</button>
739- <button class="tab-btn" data-tab="diff">Diff</button>
740- </div>
741- <div class="modal-body">
742- <pre id="patch-content" class="tab-content visible"></pre>
743- <pre id="patch-diff" class="tab-content"></pre>
744- </div>
745- <div class="modal-footer">
746- <button class="modal-close-btn">Close</button>
747- </div>
748- </div>
749- ` ;
750-
751- document . body . appendChild ( modal ) ;
752-
753- // Close handlers
754- const closeModal = ( ) => { modal . style . display = "none" ; } ;
755- modal . querySelector ( ".modal-close" ) . onclick = closeModal ;
756- modal . querySelector ( ".modal-close-btn" ) . onclick = closeModal ;
757-
758- // Click outside to close
759- modal . addEventListener ( "click" , ( event ) => {
760- if ( event . target === modal ) {
761- closeModal ( ) ;
762- }
763- } ) ;
764-
765- // Tab switching
766- modal . querySelectorAll ( ".tab-btn" ) . forEach ( btn => {
767- btn . addEventListener ( "click" , ( e ) => {
768- const tab = e . target . dataset . tab ;
769-
770- // Update button states
771- modal . querySelectorAll ( ".tab-btn" ) . forEach ( b => {
772- b . classList . remove ( "active" ) ;
773- } ) ;
774- e . target . classList . add ( "active" ) ;
775-
776- // Show/hide content
777- modal . querySelectorAll ( ".tab-content" ) . forEach ( c => {
778- c . classList . remove ( "visible" ) ;
779- } ) ;
780-
781- if ( tab === "content" ) {
782- modal . querySelector ( "#patch-content" ) . classList . add ( "visible" ) ;
783- } else if ( tab === "diff" ) {
784- modal . querySelector ( "#patch-diff" ) . classList . add ( "visible" ) ;
785- }
786- } ) ;
787- } ) ;
788- }
789-
790- // Update content
791- const contentEl = modal . querySelector ( "#patch-content" ) ;
792- const diffEl = modal . querySelector ( "#patch-diff" ) ;
793- const headerEl = modal . querySelector ( ".modal-header h2" ) ;
794-
795- if ( contentEl ) contentEl . textContent = content ;
796- if ( diffEl ) diffEl . textContent = diff || "No diff available" ;
797- if ( headerEl ) headerEl . textContent = `Patch #${ patchId } ` ;
798-
799- // Reset to content tab
800- modal . querySelectorAll ( ".tab-btn" ) . forEach ( b => {
801- b . classList . remove ( "active" ) ;
802- } ) ;
803- const contentBtn = modal . querySelector ( '[data-tab="content"]' ) ;
804- if ( contentBtn ) {
805- contentBtn . classList . add ( "active" ) ;
806- }
807-
808- modal . querySelectorAll ( ".tab-content" ) . forEach ( c => {
809- c . classList . remove ( "visible" ) ;
810- } ) ;
811- modal . querySelector ( "#patch-content" ) . classList . add ( "visible" ) ;
812-
813- // Show modal
814- modal . style . display = "block" ;
815- }
816672
817673export function renderPatchDetails ( patch ) {
818674 const details = document . getElementById ( "timeline-details" ) ;
@@ -887,30 +743,6 @@ async function resetToOriginal() {
887743// Track last alert time to prevent spam
888744let lastConflictAlertTime = 0 ;
889745
890- /**
891- * Show alert when conflicts are detected
892- * @param {Array<Array<number>> } conflictGroups - Groups of conflicting patch IDs
893- * @param {Array } patches - All patches
894- */
895- function showConflictAlert ( conflictGroups , patches ) {
896- // Only show alert once per timeline load (avoid spam on filters)
897- const timeSinceLastAlert = Date . now ( ) - lastConflictAlertTime ;
898- if ( timeSinceLastAlert < 5000 ) {
899- return ; // Don't spam alerts
900- }
901- lastConflictAlertTime = Date . now ( ) ;
902-
903- const groupCount = conflictGroups . length ;
904- let message = `⚠️ ${ groupCount } conflict group${ groupCount > 1 ? 's' : '' } detected.\n\n` ;
905-
906- // Add details about each group
907- conflictGroups . forEach ( ( group , index ) => {
908- const patchIds = group . map ( id => `#${ id } ` ) . join ( ', ' ) ;
909- message += `Group ${ index + 1 } : Patches ${ patchIds } modify the same text.\n` ;
910- } ) ;
911-
912- alert ( message ) ;
913- }
914746
915747/**
916748 * Get the current conflict state (for use by other modules)
0 commit comments