Skip to content

Commit 26dbfa7

Browse files
authored
Increased progress bar height & scroll fixes (#103)
1 parent f7943b2 commit 26dbfa7

3 files changed

Lines changed: 60 additions & 28 deletions

File tree

src/layouts/bible/DraftingPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,28 +211,28 @@ const DraftingUI: React.FC<DraftingUIProps> = ({
211211
<div className='flex h-full flex-col overflow-hidden'>
212212
<div className='flex-shrink-0'>
213213
<div className='flex items-center justify-between px-6 py-4'>
214-
<div>
214+
<div className='flex-shrink-0'>
215215
<h2 className='text-3xl font-bold text-gray-900'>
216216
{projectItem.book} {projectItem.chapterNumber}
217217
</h2>
218218
</div>
219-
<div className='flex items-center gap-4'>
219+
<div className='flex flex-1 items-center justify-end gap-4'>
220220
<div className='flex items-center gap-2'>
221221
{isAnythingSaving && (
222222
<Loader className='h-4 w-4 animate-spin text-[var(--primary)]' />
223223
)}
224224
{hasAnyError && <span className='text-sm text-red-500'>Auto-save failed</span>}
225225
</div>
226226
<div className='bg-input rounded-lg border md:w-50 lg:w-76 xl:w-105'>
227-
<div className='h-2 overflow-hidden rounded-full'>
227+
<div className='h-4 overflow-hidden rounded-full'>
228228
<div
229229
className='bg-primary h-full rounded-full transition-all duration-300'
230230
style={{ width: `${progressPercentage}%` }}
231231
></div>
232232
</div>
233233
</div>
234234
<Button
235-
className={`px-6 py-2 font-medium transition-all ${
235+
className={`flex-shrink-0 px-6 py-2 font-medium transition-all ${
236236
isTranslationComplete
237237
? 'bg-primary hover:bg-primary-hover cursor-pointer text-white'
238238
: 'cursor-not-allowed bg-gray-300 text-gray-500'

src/layouts/bible/SourcePanel.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const SourcePanel: React.FC<SourcePanelProps> = ({
1919
onScroll,
2020
}) => {
2121
const textareaRefs = useRef<Record<number, HTMLTextAreaElement | null>>({});
22+
const verseRefs = useRef<Record<number, HTMLDivElement | null>>({});
2223

2324
const autoResizeTextarea = (textarea: HTMLTextAreaElement) => {
2425
textarea.style.height = 'auto';
@@ -29,6 +30,24 @@ export const SourcePanel: React.FC<SourcePanelProps> = ({
2930
onScroll(e.currentTarget.scrollTop);
3031
};
3132

33+
useEffect(() => {
34+
const activeVerseElement = verseRefs.current[activeVerseId];
35+
if (activeVerseElement && scrollRef.current) {
36+
const container = scrollRef.current;
37+
const verseTop = activeVerseElement.offsetTop;
38+
const verseHeight = activeVerseElement.offsetHeight;
39+
const containerHeight = container.clientHeight;
40+
const currentScroll = container.scrollTop;
41+
42+
if (verseTop < currentScroll || verseTop + verseHeight > currentScroll + containerHeight) {
43+
container.scrollTo({
44+
top: verseTop - containerHeight / 2 + verseHeight / 2,
45+
behavior: 'smooth',
46+
});
47+
}
48+
}
49+
}, [activeVerseId, scrollRef]);
50+
3251
useEffect(() => {
3352
verses.forEach(verse => {
3453
const textarea = textareaRefs.current[verse.verseNumber];
@@ -43,7 +62,6 @@ export const SourcePanel: React.FC<SourcePanelProps> = ({
4362
<div className='bg-background sticky top-0 z-10 ml-8 px-6 py-4'>
4463
<h3 className='text-xl font-bold text-gray-800'>{bibleName}</h3>
4564
</div>
46-
4765
<div
4866
ref={scrollRef}
4967
className='scrollbar-hide flex-1 overflow-hidden px-6 pt-2'
@@ -57,10 +75,10 @@ export const SourcePanel: React.FC<SourcePanelProps> = ({
5775
<div className='space-y-4 pb-6'>
5876
{verses.map(verse => {
5977
const isActive = activeVerseId === verse.verseNumber;
60-
6178
return (
6279
<div
6380
key={verse.verseNumber}
81+
ref={el => (verseRefs.current[verse.verseNumber] = el)}
6482
className={`flex items-start transition-all ${isActive ? 'opacity-100' : 'opacity-70'}`}
6583
>
6684
<div className='w-8 flex-shrink-0'>

src/layouts/bible/TargetPanel.tsx

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import type React from 'react';
22
import { useEffect, useRef } from 'react';
33

4-
import { ChevronRight } from 'lucide-react';
5-
64
import { Button } from '@/components/ui/button';
75

86
import type { TargetVerse } from './DraftingPage';
@@ -78,12 +76,29 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
7876
};
7977

8078
useEffect(() => {
79+
const activeVerseElement = verseRefs.current[activeVerseId];
8180
const textarea = textareaRefs.current[activeVerseId];
81+
82+
if (activeVerseElement && scrollRef.current) {
83+
const container = scrollRef.current;
84+
const verseTop = activeVerseElement.offsetTop;
85+
const verseHeight = activeVerseElement.offsetHeight;
86+
const containerHeight = container.clientHeight;
87+
const currentScroll = container.scrollTop;
88+
89+
if (verseTop < currentScroll || verseTop + verseHeight > currentScroll + containerHeight) {
90+
container.scrollTo({
91+
top: verseTop - containerHeight / 2 + verseHeight / 2,
92+
behavior: 'smooth',
93+
});
94+
}
95+
}
96+
8297
if (textarea) {
8398
textarea.focus();
8499
autoResizeTextarea(textarea);
85100
}
86-
}, [activeVerseId]);
101+
}, [activeVerseId, scrollRef]);
87102

88103
useEffect(() => {
89104
if (verses.length === 0) {
@@ -115,7 +130,7 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
115130
style={{ scrollbarWidth: 'thin' }}
116131
onScroll={handleScroll}
117132
>
118-
<div className='space-y-4 pb-6'>
133+
<div className={`space-y-4 ${verses.length < totalSourceVerses ? 'pb-48' : 'pb-6'}`}>
119134
{Array.from({ length: totalSourceVerses }, (_, index) => {
120135
const verseId = index + 1;
121136
const TargetVerse = verses.find(kv => kv.verseNumber === verseId);
@@ -152,25 +167,24 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
152167
</div>
153168
);
154169
})}
155-
</div>
156170

157-
{verses.length < totalSourceVerses && (
158-
<div className='mb-12 flex justify-end pb-6'>
159-
<Button
160-
className={`bg-primary flex items-center gap-2 px-6 py-2 font-medium shadow-lg transition-all ${
161-
verses.find(v => v.verseNumber === activeVerseId)?.content.trim()
162-
? 'hover:bg-primary-hover cursor-pointer text-white'
163-
: 'cursor-not-allowed bg-gray-300 text-gray-500'
164-
}`}
165-
disabled={!verses.find(v => v.verseNumber === activeVerseId)?.content.trim()}
166-
title='Enter'
167-
onClick={() => moveToNextVerse()}
168-
>
169-
Next Verse
170-
<ChevronRight className='h-4 w-4' />
171-
</Button>
172-
</div>
173-
)}
171+
{verses.length < totalSourceVerses && (
172+
<div className='flex justify-end'>
173+
<Button
174+
className={`bg-primary flex items-center gap-2 px-6 py-2 font-medium shadow-lg transition-all ${
175+
verses.find(v => v.verseNumber === activeVerseId)?.content.trim()
176+
? 'hover:bg-primary-hover cursor-pointer text-white'
177+
: 'cursor-not-allowed bg-gray-300 text-gray-500'
178+
}`}
179+
disabled={!verses.find(v => v.verseNumber === activeVerseId)?.content.trim()}
180+
title='Enter'
181+
onClick={() => moveToNextVerse()}
182+
>
183+
Next Verse
184+
</Button>
185+
</div>
186+
)}
187+
</div>
174188
</div>
175189
</div>
176190
);

0 commit comments

Comments
 (0)