Skip to content

Commit fc4e548

Browse files
Merge pull request #122 from ThisIs-Developer/feature/find-replace-redesign
fix(editor): fix global shortcut interception, scroll view centering,…
2 parents 2ae3007 + 81584fa commit fc4e548

4 files changed

Lines changed: 200 additions & 58 deletions

File tree

desktop-app/resources/js/script.js

Lines changed: 96 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3951,32 +3951,52 @@ This is a fully client-side application. Your content never leaves your browser
39513951
});
39523952
}
39533953

3954+
let frPreferredDocked = false;
3955+
39543956
function toggleFrDockMode() {
39553957
const panel = document.getElementById('find-replace-modal');
39563958
const dockBtn = document.getElementById('find-replace-dock');
3957-
const editorWrapper = document.querySelector('.editor-dock-wrapper') || document.querySelector('.content-container');
3958-
if (!panel || !dockBtn || !editorWrapper) return;
3959+
const contentCont = document.querySelector('.content-container');
3960+
if (!panel || !dockBtn || !contentCont) return;
39593961

39603962
isFrDocked = !isFrDocked;
3963+
3964+
// Save preference to localStorage
3965+
frPreferredDocked = isFrDocked;
3966+
localStorage.setItem('find-replace-docked', frPreferredDocked ? 'true' : 'false');
3967+
39613968
if (isFrDocked) {
39623969
panel.classList.add('docked');
39633970
panel.style.left = 'auto';
39643971
panel.style.top = 'auto';
39653972
panel.style.right = 'auto';
3966-
// Append panel to dock container
3967-
editorWrapper.appendChild(panel);
3973+
3974+
// Append panel to dock container (.content-container)
3975+
contentCont.appendChild(panel);
3976+
contentCont.classList.add('fr-docked');
3977+
contentCont.style.setProperty('--dock-width', '340px');
3978+
39683979
dockBtn.innerHTML = '<i class="bi bi-window"></i>';
39693980
dockBtn.title = "Toggle Floating Mode";
39703981
} else {
39713982
panel.classList.remove('docked');
3983+
39723984
// Reset position and float on body
39733985
document.body.appendChild(panel);
3974-
panel.style.top = '100px';
3975-
panel.style.right = '20px';
3976-
panel.style.left = 'auto';
3986+
contentCont.classList.remove('fr-docked');
3987+
contentCont.style.setProperty('--dock-width', '0px');
3988+
3989+
panel.style.top = '';
3990+
panel.style.left = '';
3991+
panel.style.right = '';
3992+
39773993
dockBtn.innerHTML = '<i class="bi bi-layout-sidebar-reverse"></i>';
39783994
dockBtn.title = "Toggle Dock Mode";
39793995
}
3996+
3997+
// Ensure display is flex and recalculate split panes
3998+
panel.style.display = 'flex';
3999+
applyPaneWidths();
39804000
}
39814001

39824002
function updateFindControls() {
@@ -4059,16 +4079,21 @@ This is a fully client-side application. Your content never leaves your browser
40594079
markdownEditor.focus();
40604080
markdownEditor.setSelectionRange(match.start, match.end);
40614081

4062-
// Auto-scroll logic if editor cursor is near find-replace panel
4063-
requestAnimationFrame(() => {
4064-
const panel = document.getElementById('find-replace-modal');
4065-
if (!isFrDocked && panel && panel.style.display !== 'none') {
4066-
const panelRect = panel.getBoundingClientRect();
4067-
// Check if selection coords intersect
4068-
// Simplification: if panel is right-aligned, push editor view left if needed,
4069-
// or just let native setSelectionRange scroll to cursor naturally.
4070-
}
4071-
});
4082+
// Explicitly scroll editor to center active match in viewport
4083+
try {
4084+
const styles = window.getComputedStyle(markdownEditor);
4085+
const lineHeight = parseFloat(styles.lineHeight) || 21;
4086+
const textBefore = markdownEditor.value.slice(0, match.start);
4087+
const lineIndex = textBefore.split('\n').length - 1;
4088+
const editorHeight = markdownEditor.clientHeight;
4089+
const targetScrollTop = Math.max(0, (lineIndex * lineHeight) - (editorHeight / 2) + (lineHeight / 2));
4090+
4091+
markdownEditor.scrollTop = targetScrollTop;
4092+
syncHighlightScroll();
4093+
syncLineNumberScroll();
4094+
} catch (e) {
4095+
console.warn("Viewport centering scroll failed:", e);
4096+
}
40724097
}
40734098

40744099
function cycleFindMatch(direction) {
@@ -4093,6 +4118,17 @@ This is a fully client-side application. Your content never leaves your browser
40934118
findReplaceInput.value = selected;
40944119
}
40954120

4121+
// Restore docked/floating mode preference
4122+
const wasDockedPref = localStorage.getItem('find-replace-docked') === 'true';
4123+
4124+
if (wasDockedPref) {
4125+
isFrDocked = false; // Set false so toggleFrDockMode() turns it to true
4126+
toggleFrDockMode();
4127+
} else {
4128+
isFrDocked = true; // Set true so toggleFrDockMode() turns it to false
4129+
toggleFrDockMode();
4130+
}
4131+
40964132
findReplaceModal.style.display = 'flex';
40974133

40984134
requestAnimationFrame(function() {
@@ -4109,11 +4145,16 @@ This is a fully client-side application. Your content never leaves your browser
41094145
function closeFindReplaceModal() {
41104146
isFindModalOpen = false;
41114147
const panel = document.getElementById('find-replace-modal');
4148+
const contentCont = document.querySelector('.content-container');
41124149
if (panel) {
41134150
panel.style.display = 'none';
41144151
if (isFrDocked) {
4115-
// Undock and return to body
4116-
toggleFrDockMode();
4152+
// Reset split layout styles when closed
4153+
if (contentCont) {
4154+
contentCont.classList.remove('fr-docked');
4155+
contentCont.style.setProperty('--dock-width', '0px');
4156+
applyPaneWidths();
4157+
}
41174158
}
41184159
}
41194160
findMatches = [];
@@ -4587,8 +4628,8 @@ This is a fully client-side application. Your content never leaves your browser
45874628
if (currentViewMode !== 'split') return;
45884629

45894630
const previewPercent = 100 - editorWidthPercent;
4590-
editorPaneElement.style.flex = `0 0 calc(${editorWidthPercent}% - 4px)`;
4591-
previewPaneElement.style.flex = `0 0 calc(${previewPercent}% - 4px)`;
4631+
editorPaneElement.style.flex = `0 0 calc((100% - var(--dock-width, 0px)) * ${editorWidthPercent / 100} - 4px)`;
4632+
previewPaneElement.style.flex = `0 0 calc((100% - var(--dock-width, 0px)) * ${previewPercent / 100} - 4px)`;
45924633
scheduleLineNumberUpdate();
45934634
}
45944635

@@ -4731,11 +4772,6 @@ This is a fully client-side application. Your content never leaves your browser
47314772

47324773
// Editor key handlers for list continuation and indentation
47334774
markdownEditor.addEventListener("keydown", function(e) {
4734-
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'f') {
4735-
e.preventDefault();
4736-
openFindReplaceModal();
4737-
return;
4738-
}
47394775
if (handleListEnter(e)) {
47404776
return;
47414777
}
@@ -5954,7 +5990,40 @@ This is a fully client-side application. Your content never leaves your browser
59545990
if (e.target === shareModal) closeShareModal();
59555991
});
59565992
document.addEventListener('keydown', function (e) {
5957-
if (e.key === 'Escape' && shareModal.classList.contains('is-visible')) closeShareModal();
5993+
if (e.key === 'Escape' && shareModal.classList.contains('is-visible')) {
5994+
closeShareModal();
5995+
}
5996+
5997+
// Global Ctrl+F / Cmd+F interception
5998+
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'f') {
5999+
e.preventDefault();
6000+
openFindReplaceModal();
6001+
const findInput = document.getElementById('find-replace-input');
6002+
if (findInput) {
6003+
findInput.focus();
6004+
findInput.select();
6005+
}
6006+
return;
6007+
}
6008+
6009+
// Global Ctrl+H / Cmd+H interception
6010+
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'h') {
6011+
e.preventDefault();
6012+
openFindReplaceModal();
6013+
const replaceInput = document.getElementById('find-replace-with');
6014+
if (replaceInput) {
6015+
replaceInput.focus();
6016+
replaceInput.select();
6017+
}
6018+
return;
6019+
}
6020+
6021+
// Global Escape dismissal for find-replace panel
6022+
if (e.key === 'Escape' && isFindModalOpen) {
6023+
e.preventDefault();
6024+
closeFindReplaceModal();
6025+
return;
6026+
}
59586027
});
59596028

59606029
shareButton.addEventListener('click', openShareModal);

desktop-app/resources/styles.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,12 +573,14 @@ body {
573573
}
574574

575575
.find-highlight {
576-
background-color: rgba(255, 196, 0, 0.35);
576+
background-color: var(--fr-match-highlight, rgba(255, 223, 93, 0.4)) !important;
577577
border-radius: 2px;
578+
color: transparent !important;
578579
}
579580

580581
.find-highlight.active {
581-
background-color: rgba(255, 196, 0, 0.65);
582+
background-color: var(--fr-match-active, #ff9b30) !important;
583+
color: transparent !important;
582584
}
583585

584586
/* Dropdown improvements */

0 commit comments

Comments
 (0)