diff --git a/apps/readest-app/public/locales/ar/translation.json b/apps/readest-app/public/locales/ar/translation.json index 4c1ba794..40b6fec5 100644 --- a/apps/readest-app/public/locales/ar/translation.json +++ b/apps/readest-app/public/locales/ar/translation.json @@ -67,7 +67,6 @@ "Page": "الصفحة", "Paging Animation": "رسوم متحركةعند الانتقال إلى صفحة جديدة", "Paragraph": "فقرة", - "Parallel Read": "قراءة متوازية", "Published:": "تاريخ النشر:", "Publisher:": "الناشر:", "Reading Progress Synced": "تمت مزامنة تقدم القراءة", @@ -415,5 +414,8 @@ "DeepL Pro Access (200K characters/day)": "وصول احترافي إلى DeepL (200 ألف حرف يوميًا)", "Complete Your Subscription": "أكمل اشتراكك", "{{percentage}}% of Cloud Sync Space Used.": "تم استخدام {{percentage}}% من مساحة المزامنة السحابية.", - "Cloud Sync Storage": "مساحة المزامنة السحابية" + "Cloud Sync Storage": "مساحة المزامنة السحابية", + "Parallel Read": "القراءة المتزامنة", + "Disable": "تعطيل", + "Enable": "تمكين" } diff --git a/apps/readest-app/public/locales/de/translation.json b/apps/readest-app/public/locales/de/translation.json index dda78bb0..bc2eef71 100644 --- a/apps/readest-app/public/locales/de/translation.json +++ b/apps/readest-app/public/locales/de/translation.json @@ -67,7 +67,6 @@ "Page": "Seite", "Paging Animation": "Blätter-Animation", "Paragraph": "Absatz", - "Parallel Read": "Paralleles Lesen", "Published:": "Veröffentlicht:", "Publisher:": "Verlag:", "Reading Progress Synced": "Lesevorgang synchronisiert", @@ -399,5 +398,8 @@ "DeepL Pro Access (200K characters/day)": "DeepL Pro-Zugang (200.000 Zeichen/Tag)", "Complete Your Subscription": "Abschließen Sie Ihr Abonnement", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% des Cloud-Synchronisierungsspeichers verwendet.", - "Cloud Sync Storage": "Cloud-Speicher" + "Cloud Sync Storage": "Cloud-Speicher", + "Parallel Read": "Paralleles Lesen", + "Disable": "Deaktivieren", + "Enable": "Aktivieren" } diff --git a/apps/readest-app/public/locales/el/translation.json b/apps/readest-app/public/locales/el/translation.json index e038e8a4..4db71714 100644 --- a/apps/readest-app/public/locales/el/translation.json +++ b/apps/readest-app/public/locales/el/translation.json @@ -399,5 +399,7 @@ "DeepL Pro Access (200K characters/day)": "Pro πρόσβαση στο DeepL (200.000 χαρακτήρες/ημέρα)", "Complete Your Subscription": "Ολοκληρώστε τη συνδρομή σας", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% του χώρου συγχρονισμού στο cloud χρησιμοποιήθηκε.", - "Cloud Sync Storage": "Χώρος συγχρονισμού cloud" + "Cloud Sync Storage": "Χώρος συγχρονισμού cloud", + "Disable": "Απενεργοποίηση", + "Enable": "Ενεργοποίηση" } diff --git a/apps/readest-app/public/locales/es/translation.json b/apps/readest-app/public/locales/es/translation.json index 72fbae8b..ef3e1a6d 100644 --- a/apps/readest-app/public/locales/es/translation.json +++ b/apps/readest-app/public/locales/es/translation.json @@ -403,5 +403,7 @@ "Your payment is being processed. This usually takes a few moments.": "Tu pago se está procesando. Normalmente tarda unos momentos.", "Complete Your Subscription": "Completa tu suscripción", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% del espacio de sincronización en la nube utilizado.", - "Cloud Sync Storage": "Almacenamiento en la nube" + "Cloud Sync Storage": "Almacenamiento en la nube", + "Disable": "Desactivar", + "Enable": "Activar" } diff --git a/apps/readest-app/public/locales/fr/translation.json b/apps/readest-app/public/locales/fr/translation.json index 529e6ce7..1f78053e 100644 --- a/apps/readest-app/public/locales/fr/translation.json +++ b/apps/readest-app/public/locales/fr/translation.json @@ -403,5 +403,7 @@ "DeepL Pro Access (200K characters/day)": "Accès Pro à DeepL (200 000 caractères/jour)", "Complete Your Subscription": "Complétez votre abonnement", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% de l’espace de synchronisation cloud utilisé.", - "Cloud Sync Storage": "Stockage de synchronisation cloud" + "Cloud Sync Storage": "Stockage de synchronisation cloud", + "Disable": "Désactiver", + "Enable": "Activer" } diff --git a/apps/readest-app/public/locales/hi/translation.json b/apps/readest-app/public/locales/hi/translation.json index 1b123fe7..8c0536cd 100644 --- a/apps/readest-app/public/locales/hi/translation.json +++ b/apps/readest-app/public/locales/hi/translation.json @@ -399,5 +399,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL प्रो एक्सेस (200,000 अक्षर/दिन)", "Complete Your Subscription": "अपनी सदस्यता पूरी करें", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% क्लाउड सिंक स्पेस का उपयोग किया गया है।", - "Cloud Sync Storage": "क्लाउड सिंक स्टोरेज" + "Cloud Sync Storage": "क्लाउड सिंक स्टोरेज", + "Disable": "अक्षम करें", + "Enable": "सक्षम करें" } diff --git a/apps/readest-app/public/locales/id/translation.json b/apps/readest-app/public/locales/id/translation.json index af0b7c15..a76d7c6d 100644 --- a/apps/readest-app/public/locales/id/translation.json +++ b/apps/readest-app/public/locales/id/translation.json @@ -395,5 +395,7 @@ "DeepL Pro Access (200K characters/day)": "Akses DeepL Pro (200.000 karakter/hari)", "Complete Your Subscription": "Selesaikan Langganan Anda", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% ruang sinkronisasi cloud terpakai", - "Cloud Sync Storage": "Ruang cloud" + "Cloud Sync Storage": "Ruang cloud", + "Disable": "Nonaktifkan", + "Enable": "Aktifkan" } diff --git a/apps/readest-app/public/locales/it/translation.json b/apps/readest-app/public/locales/it/translation.json index 9ee786d5..c8dd1b70 100644 --- a/apps/readest-app/public/locales/it/translation.json +++ b/apps/readest-app/public/locales/it/translation.json @@ -403,5 +403,7 @@ "DeepL Pro Access (200K characters/day)": "Accesso DeepL Pro (200.000 caratteri/giorno)", "Complete Your Subscription": "Completa l'abbonamento", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% dello spazio cloud usato", - "Cloud Sync Storage": "Spazio cloud" + "Cloud Sync Storage": "Spazio cloud", + "Disable": "Disabilita", + "Enable": "Abilita" } diff --git a/apps/readest-app/public/locales/ja/translation.json b/apps/readest-app/public/locales/ja/translation.json index f432d077..b610a33b 100644 --- a/apps/readest-app/public/locales/ja/translation.json +++ b/apps/readest-app/public/locales/ja/translation.json @@ -395,5 +395,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL Proアクセス(1日20万文字)", "Complete Your Subscription": "サブスクリプションを完了する", "{{percentage}}% of Cloud Sync Space Used.": "クラウド同期スペースの使用量は{{percentage}}%です。", - "Cloud Sync Storage": "クラウド同期容量" + "Cloud Sync Storage": "クラウド同期容量", + "Disable": "無効にする", + "Enable": "有効にする" } diff --git a/apps/readest-app/public/locales/ko/translation.json b/apps/readest-app/public/locales/ko/translation.json index d5475588..8955bc3b 100644 --- a/apps/readest-app/public/locales/ko/translation.json +++ b/apps/readest-app/public/locales/ko/translation.json @@ -395,5 +395,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL Pro 액세스 (일 20만자)", "Complete Your Subscription": "구독 완료", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}%의 클라우드 동기화 공간 사용됨.", - "Cloud Sync Storage": "클라우드 저장 공간" + "Cloud Sync Storage": "클라우드 저장 공간", + "Disable": "비활성화", + "Enable": "활성화" } diff --git a/apps/readest-app/public/locales/nl/translation.json b/apps/readest-app/public/locales/nl/translation.json index ba78e38a..26f33142 100644 --- a/apps/readest-app/public/locales/nl/translation.json +++ b/apps/readest-app/public/locales/nl/translation.json @@ -399,5 +399,7 @@ "Thank you for your subscription! Your payment has been processed successfully.": "Bedankt voor je abonnement! Je betaling is succesvol verwerkt.", "Complete Your Subscription": "Voltooi uw abonnement", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% van de cloud-synchronisatie ruimte gebruikt.", - "Cloud Sync Storage": "Cloud Sync Opslag" + "Cloud Sync Storage": "Cloud Sync Opslag", + "Disable": "Uitschakelen", + "Enable": "Inschakelen" } diff --git a/apps/readest-app/public/locales/pl/translation.json b/apps/readest-app/public/locales/pl/translation.json index f18ac07a..9e843410 100644 --- a/apps/readest-app/public/locales/pl/translation.json +++ b/apps/readest-app/public/locales/pl/translation.json @@ -407,5 +407,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL Pro (200 tys. znaków/dzień)", "Complete Your Subscription": "Ukończ subskrypcję", "{{percentage}}% of Cloud Sync Space Used.": "Użyto {{percentage}}% przestrzeni synchronizacji w chmurze.", - "Cloud Sync Storage": "Miejsce w chmurze" + "Cloud Sync Storage": "Miejsce w chmurze", + "Disable": "Wyłącz", + "Enable": "Włącz" } diff --git a/apps/readest-app/public/locales/pt/translation.json b/apps/readest-app/public/locales/pt/translation.json index 7b5523ef..f3ba8484 100644 --- a/apps/readest-app/public/locales/pt/translation.json +++ b/apps/readest-app/public/locales/pt/translation.json @@ -403,5 +403,7 @@ "DeepL Pro Access (200K characters/day)": "Acesso ao DeepL Pro (200 mil caracteres/dia)", "Complete Your Subscription": "Complete sua assinatura", "{{percentage}}% of Cloud Sync Space Used.": "{{percentage}}% do espaço de sincronização na nuvem utilizado.", - "Cloud Sync Storage": "Armazenamento na Nuvem" + "Cloud Sync Storage": "Armazenamento na Nuvem", + "Disable": "Desativar", + "Enable": "Ativar" } diff --git a/apps/readest-app/public/locales/ru/translation.json b/apps/readest-app/public/locales/ru/translation.json index 4d6ca9dd..f03a6a18 100644 --- a/apps/readest-app/public/locales/ru/translation.json +++ b/apps/readest-app/public/locales/ru/translation.json @@ -407,5 +407,7 @@ "DeepL Pro Access (200K characters/day)": "Доступ к DeepL Pro (200 тыс. символов/день)", "Complete Your Subscription": "Завершите подписку", "{{percentage}}% of Cloud Sync Space Used.": "Использовано {{percentage}}% облачного пространства для синхронизации.", - "Cloud Sync Storage": "Облачное хранилище" + "Cloud Sync Storage": "Облачное хранилище", + "Disable": "Отключить", + "Enable": "Включить" } diff --git a/apps/readest-app/public/locales/tr/translation.json b/apps/readest-app/public/locales/tr/translation.json index 210c9640..f71551e7 100644 --- a/apps/readest-app/public/locales/tr/translation.json +++ b/apps/readest-app/public/locales/tr/translation.json @@ -399,5 +399,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL Pro Erişim (Günde 200K karakter)", "Complete Your Subscription": "Aboneliğinizi Tamamlayın", "{{percentage}}% of Cloud Sync Space Used.": "Bulut Senkronizasyon Alanının %{{percentage}}'si Kullanıldı.", - "Cloud Sync Storage": "Bulut Senkronizasyon Depolama" + "Cloud Sync Storage": "Bulut Senkronizasyon Depolama", + "Disable": "Devre Dışı Bırak", + "Enable": "Etkinleştir" } diff --git a/apps/readest-app/public/locales/uk/translation.json b/apps/readest-app/public/locales/uk/translation.json index 46c52ef3..2c9055f4 100644 --- a/apps/readest-app/public/locales/uk/translation.json +++ b/apps/readest-app/public/locales/uk/translation.json @@ -407,5 +407,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL Pro доступ (200 тис. символів/день)", "Complete Your Subscription": "Завершіть підписку", "{{percentage}}% of Cloud Sync Space Used.": "Використано {{percentage}}% хмарного сховища.", - "Cloud Sync Storage": "Облачне хранилище" + "Cloud Sync Storage": "Облачне хранилище", + "Disable": "Вимкнути", + "Enable": "Увімкнути" } diff --git a/apps/readest-app/public/locales/vi/translation.json b/apps/readest-app/public/locales/vi/translation.json index c074a752..d0d71cc3 100644 --- a/apps/readest-app/public/locales/vi/translation.json +++ b/apps/readest-app/public/locales/vi/translation.json @@ -395,5 +395,7 @@ "DeepL Pro Access (200K characters/day)": "Truy cập DeepL Pro (200.000 ký tự/ngày)", "Complete Your Subscription": "Hoàn tất đăng ký của bạn", "{{percentage}}% of Cloud Sync Space Used.": "Đã sử dụng {{percentage}}% không gian đồng bộ đám mây.", - "Cloud Sync Storage": "Lưu trữ đồng bộ đám mây" + "Cloud Sync Storage": "Lưu trữ đồng bộ đám mây", + "Disable": "Tắt", + "Enable": "Bật" } diff --git a/apps/readest-app/public/locales/zh-CN/translation.json b/apps/readest-app/public/locales/zh-CN/translation.json index f81dcd52..a85c4b3e 100644 --- a/apps/readest-app/public/locales/zh-CN/translation.json +++ b/apps/readest-app/public/locales/zh-CN/translation.json @@ -395,5 +395,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL Pro(每日20万字符)", "Complete Your Subscription": "完成您的订阅", "{{percentage}}% of Cloud Sync Space Used.": "已使用 {{percentage}}% 的云同步空间。", - "Cloud Sync Storage": "云同步空间" + "Cloud Sync Storage": "云同步空间", + "Disable": "禁用", + "Enable": "启用" } diff --git a/apps/readest-app/public/locales/zh-TW/translation.json b/apps/readest-app/public/locales/zh-TW/translation.json index 80821883..0753a3c1 100644 --- a/apps/readest-app/public/locales/zh-TW/translation.json +++ b/apps/readest-app/public/locales/zh-TW/translation.json @@ -395,5 +395,7 @@ "DeepL Pro Access (200K characters/day)": "DeepL Pro(每日20萬字)", "Complete Your Subscription": "完成您的訂閱", "{{percentage}}% of Cloud Sync Space Used.": "已使用 {{percentage}}% 的雲同步空間。", - "Cloud Sync Storage": "雲同步空間" + "Cloud Sync Storage": "雲同步空間", + "Disable": "禁用", + "Enable": "啟用" } diff --git a/apps/readest-app/src/app/reader/components/BooksGrid.tsx b/apps/readest-app/src/app/reader/components/BooksGrid.tsx index 8a023953..fc4f1571 100644 --- a/apps/readest-app/src/app/reader/components/BooksGrid.tsx +++ b/apps/readest-app/src/app/reader/components/BooksGrid.tsx @@ -30,7 +30,7 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { const { appService } = useEnv(); const { getConfig, getBookData } = useBookDataStore(); const { getProgress, getViewState, getViewSettings } = useReaderStore(); - const { getGridInsets, setGridInsets, hoveredBookKey } = useReaderStore(); + const { setGridInsets, hoveredBookKey } = useReaderStore(); const { isSideBarVisible, sideBarBookKey } = useSidebarStore(); const { isFontLayoutSettingsDialogOpen, setFontLayoutSettingsDialogOpen } = useSettingsStore(); @@ -46,16 +46,21 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [sideBarBookKey]); + const calcGridInsets = (index: number, count: number) => { + if (!screenInsets) return { top: 0, right: 0, bottom: 0, left: 0 }; + const { top, right, bottom, left } = getInsetEdges(index, count, aspectRatio); + return { + top: top ? screenInsets.top : 0, + right: right ? screenInsets.right : 0, + bottom: bottom ? screenInsets.bottom : 0, + left: left ? screenInsets.left : 0, + }; + }; + useEffect(() => { if (!screenInsets) return; bookKeys.forEach((bookKey, index) => { - const { top, right, bottom, left } = getInsetEdges(index, bookKeys.length, aspectRatio); - const gridInsets = { - top: top ? screenInsets.top : 0, - right: right ? screenInsets.right : 0, - bottom: bottom ? screenInsets.bottom : 0, - left: left ? screenInsets.left : 0, - }; + const gridInsets = calcGridInsets(index, bookKeys.length); setGridInsets(bookKey, gridInsets); }); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -76,9 +81,9 @@ const BooksGrid: React.FC = ({ bookKeys, onCloseBook }) => { const config = getConfig(bookKey); const progress = getProgress(bookKey); const viewSettings = getViewSettings(bookKey); - const gridInsets = getGridInsets(bookKey); + const gridInsets = calcGridInsets(index, bookKeys.length); const { book, bookDoc } = bookData || {}; - if (!book || !config || !bookDoc || !viewSettings || !gridInsets) return null; + if (!book || !config || !bookDoc || !viewSettings) return null; const { section, pageinfo, timeinfo, sectionLabel } = progress || {}; const isBookmarked = getViewState(bookKey)?.ribbonVisible; diff --git a/apps/readest-app/src/app/reader/components/sidebar/BookMenu.tsx b/apps/readest-app/src/app/reader/components/sidebar/BookMenu.tsx index 0aef8cf0..01caea21 100644 --- a/apps/readest-app/src/app/reader/components/sidebar/BookMenu.tsx +++ b/apps/readest-app/src/app/reader/components/sidebar/BookMenu.tsx @@ -13,6 +13,7 @@ import { eventDispatcher } from '@/utils/event'; import { DOWNLOAD_READEST_URL } from '@/services/constants'; import useBooksManager from '../../hooks/useBooksManager'; import MenuItem from '@/components/MenuItem'; +import { useParallelViewStore } from '@/store/parallelViewStore'; interface BookMenuProps { menuClassName?: string; @@ -21,10 +22,11 @@ interface BookMenuProps { const BookMenu: React.FC = ({ menuClassName, setIsDropdownOpen }) => { const _ = useTranslation(); - const { getViewSettings, setViewSettings } = useReaderStore(); + const { bookKeys, getViewSettings, setViewSettings } = useReaderStore(); const { getVisibleLibrary } = useLibraryStore(); const { openParallelView } = useBooksManager(); const { sideBarBookKey } = useSidebarStore(); + const { parallelViews, setParallel, unsetParallel } = useParallelViewStore(); const viewSettings = getViewSettings(sideBarBookKey!); const [isSortedTOC, setIsSortedTOC] = React.useState(viewSettings?.sortedTOC || false); @@ -59,6 +61,14 @@ const BookMenu: React.FC = ({ menuClassName, setIsDropdownOpen }) } setTimeout(() => window.location.reload(), 100); }; + const handleSetParallel = () => { + setParallel(bookKeys); + setIsDropdownOpen?.(false); + }; + const handleUnsetParallel = () => { + unsetParallel(bookKeys); + setIsDropdownOpen?.(false); + }; const isWebApp = isWebAppPlatform(); @@ -67,7 +77,19 @@ const BookMenu: React.FC = ({ menuClassName, setIsDropdownOpen }) tabIndex={0} className={clsx('book-menu dropdown-content border-base-100 z-20 shadow-2xl', menuClassName)} > - + 1 ? 'lg:tooltip lg:tooltip-bottom' : ''} + tooltip={parallelViews.length > 0 ? _('Disable') : bookKeys.length > 1 ? _('Enable') : ''} + Icon={parallelViews.length > 0 && bookKeys.length > 1 ? MdCheck : undefined} + onClick={ + parallelViews.length > 0 + ? handleUnsetParallel + : bookKeys.length > 1 + ? handleSetParallel + : undefined + } + >
    {getVisibleLibrary() .filter((book) => book.format !== 'PDF' && book.format !== 'CBZ') @@ -94,6 +116,7 @@ const BookMenu: React.FC = ({ menuClassName, setIsDropdownOpen }) ))}
+
{ const updatedKeys = [...bookKeys, newKey]; setBookKeys(updatedKeys); } - if (isParallel) setParallel(sideBarBookKey!, newKey); + if (isParallel) setParallel([sideBarBookKey!, newKey]); setSideBarBookKey(newKey); setShouldUpdateSearchParams(true); }; diff --git a/apps/readest-app/src/store/parallelViewStore.ts b/apps/readest-app/src/store/parallelViewStore.ts index 7876bac9..32e5929e 100644 --- a/apps/readest-app/src/store/parallelViewStore.ts +++ b/apps/readest-app/src/store/parallelViewStore.ts @@ -2,8 +2,8 @@ import { create } from 'zustand'; interface ParallelViewState { parallelViews: Set[]; - setParallel: (bookKey1: string, bookKey2: string) => void; - unsetParallel: (bookKey1: string, bookKey2: string) => void; + setParallel: (bookKeys: string[]) => void; + unsetParallel: (bookKeys: string[]) => void; areParallels: (bookKey1: string, bookKey2: string) => boolean; getParallels: (bookKey: string) => Set | null; } @@ -11,48 +11,59 @@ interface ParallelViewState { export const useParallelViewStore = create((set, get) => ({ parallelViews: [], - setParallel: (bookKey1: string, bookKey2: string) => { + setParallel: (bookKeys: string[]) => { set((state) => { - const newGroups = [...state.parallelViews]; - const group1 = newGroups.find((group) => group.has(bookKey1)); - const group2 = newGroups.find((group) => group.has(bookKey2)); - - if (group1 && group2) { - if (group1 !== group2) { - group1.forEach((key) => group2.add(key)); - newGroups.splice(newGroups.indexOf(group1), 1); - } - } else if (group1) { - group1.add(bookKey2); - } else if (group2) { - group2.add(bookKey1); - } else { - // Neither book is in a group, create a new group - newGroups.push(new Set([bookKey1, bookKey2])); + const uniqueKeys = [...new Set(bookKeys.filter((key) => key.trim() !== ''))]; + if (uniqueKeys.length < 2) { + return state; } + const newGroups = [...state.parallelViews]; + const existingGroups = newGroups.filter((group) => uniqueKeys.some((key) => group.has(key))); + + let targetGroup: Set; + if (existingGroups.length === 0) { + targetGroup = new Set(uniqueKeys); + newGroups.push(targetGroup); + } else if (existingGroups.length === 1) { + targetGroup = existingGroups[0]!; + uniqueKeys.forEach((key) => targetGroup.add(key)); + } else { + targetGroup = existingGroups[0]!; + existingGroups.slice(1).forEach((group) => { + group.forEach((key) => targetGroup.add(key)); + const index = newGroups.indexOf(group); + if (index > -1) { + newGroups.splice(index, 1); + } + }); + uniqueKeys.forEach((key) => targetGroup.add(key)); + } + + console.log('Set parallel groups:', newGroups); return { parallelViews: newGroups }; }); }, - unsetParallel: (bookKey1: string, bookKey2: string) => { + unsetParallel: (bookKeys: string[]) => { set((state) => { - const newGroups = [...state.parallelViews]; - const group = newGroups.find((group) => group.has(bookKey1) && group.has(bookKey2)); - - if (group) { - group.delete(bookKey1); - group.delete(bookKey2); - - // If the group becomes disjointed, split into separate groups - const remainingKeys = Array.from(group); - if (remainingKeys.length > 0) { - newGroups.push(new Set(remainingKeys)); - } - - // Remove the original group - newGroups.splice(newGroups.indexOf(group), 1); + const uniqueKeys = [...new Set(bookKeys.filter((key) => key.trim() !== ''))]; + if (uniqueKeys.length === 0) { + return state; } + const newGroups = [...state.parallelViews]; + const affectedGroups = newGroups.filter((group) => uniqueKeys.some((key) => group.has(key))); + affectedGroups.forEach((group) => { + uniqueKeys.forEach((key) => group.delete(key)); + if (group.size <= 1) { + const index = newGroups.indexOf(group); + if (index > -1) { + newGroups.splice(index, 1); + } + } + }); + + console.log('Unset parallel groups:', newGroups); return { parallelViews: newGroups }; }); },