diff --git a/packages/web/src/Effects.ts b/packages/web/src/Effects.ts
index b2a2c842..2a23fabf 100644
--- a/packages/web/src/Effects.ts
+++ b/packages/web/src/Effects.ts
@@ -1,8 +1,7 @@
-import { effects as datasourceEffects } from "./dataSources/effects"
import { useDownloadsEffects } from "./download/effects"
import { useCleanupDanglingLinks } from "./links/useCleanupDanglingLinks"
-
-const effects = [...datasourceEffects, useDownloadsEffects]
+
+const effects = [useDownloadsEffects]
export const Effects = () => {
effects.forEach((effectHook) => effectHook())
diff --git a/packages/web/src/constants.shared.ts b/packages/web/src/constants.shared.ts
index 231f70d4..e5c2b0a7 100644
--- a/packages/web/src/constants.shared.ts
+++ b/packages/web/src/constants.shared.ts
@@ -15,4 +15,4 @@ export const API_URL =
import.meta.env.VITE_API_URL || `http://localhost:5173/api/dev`
export const API_COUCH_URI =
import.meta.env.VITE_API_COUCH_URI || `https://${hostname}:4003`
-export const CLEANUP_DANGLING_LINKS_INTERVAL = 1000 * 60 * 5 // 5mn
+export const CLEANUP_DANGLING_LINKS_INTERVAL = 1000 * 60 * 10 // 10mn
diff --git a/packages/web/src/dataSources/DataSourcesActionsDrawer.tsx b/packages/web/src/dataSources/DataSourcesActionsDrawer.tsx
index b1be617b..0c0b5feb 100644
--- a/packages/web/src/dataSources/DataSourcesActionsDrawer.tsx
+++ b/packages/web/src/dataSources/DataSourcesActionsDrawer.tsx
@@ -1,6 +1,5 @@
import {
Drawer,
- ListItem,
List,
ListItemIcon,
ListItemText,
@@ -14,9 +13,11 @@ import {
RadioButtonUncheckedOutlined,
CheckCircleRounded
} from "@mui/icons-material"
-import { useSynchronizeDataSource } from "./helpers"
+import {
+ useDataSourceIncrementalModify,
+ useSynchronizeDataSource
+} from "./helpers"
import { useDataSource } from "./useDataSource"
-import { toggleDatasourceProtected } from "./triggers"
import { useSignalValue } from "reactjrx"
import { libraryStateSignal } from "../library/states"
import { useRemoveDataSource } from "./useRemoveDataSource"
@@ -29,6 +30,7 @@ export const DataSourcesActionsDrawer: FC<{
const { mutate: removeDataSource } = useRemoveDataSource()
const { data: dataSource } = useDataSource(openWith)
const library = useSignalValue(libraryStateSignal)
+ const { mutate: modifyDataSource } = useDataSourceIncrementalModify()
return (
<>
@@ -46,17 +48,22 @@ export const DataSourcesActionsDrawer: FC<{
- {
- toggleDatasourceProtected(openWith)
-
const datasourceWillBeHidden =
!dataSource?.isProtected && !library.isLibraryUnlocked
if (datasourceWillBeHidden) {
onClose()
}
+
+ modifyDataSource({
+ id: openWith,
+ mutationFunction: (old) => ({
+ ...old,
+ isProtected: !old.isProtected
+ })
+ })
}}
>
@@ -67,11 +74,10 @@ export const DataSourcesActionsDrawer: FC<{
primary="Mark as protected"
secondary="This will lock and hide books behind it. Use unlock features to display them"
/>
-
+
- {
onClose()
removeDataSource({ id: openWith })
@@ -81,7 +87,7 @@ export const DataSourcesActionsDrawer: FC<{
-
+
>
diff --git a/packages/web/src/dataSources/effects.ts b/packages/web/src/dataSources/effects.ts
deleted file mode 100644
index 7091dd40..00000000
--- a/packages/web/src/dataSources/effects.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
- catchError,
- switchMap,
- from,
- mergeMap,
- EMPTY,
- withLatestFrom,
- filter
-} from "rxjs"
-import { isDefined, useSubscribeEffect } from "reactjrx"
-import { latestDatabase$ } from "../rxdb/RxDbProvider"
-import { toggleDatasourceProtected$ } from "./triggers"
-import { Report } from "../debug/report.shared"
-
-const useToggleDataSourceProtectedAction = () => {
- useSubscribeEffect(
- () =>
- toggleDatasourceProtected$.pipe(
- withLatestFrom(latestDatabase$),
- mergeMap(([id, db]) =>
- from(db.datasource.findOne({ selector: { _id: id } }).exec()).pipe(
- filter(isDefined),
- switchMap((doc) =>
- from(
- doc?.incrementalPatch({
- isProtected: !doc.isProtected
- })
- )
- ),
- catchError((err) => {
- Report.error(err)
-
- return EMPTY
- })
- )
- )
- ),
- []
- )
-}
-
-export const effects = [useToggleDataSourceProtectedAction]
diff --git a/packages/web/src/dataSources/helpers.ts b/packages/web/src/dataSources/helpers.ts
index 97d808c0..3a31ff49 100644
--- a/packages/web/src/dataSources/helpers.ts
+++ b/packages/web/src/dataSources/helpers.ts
@@ -2,20 +2,23 @@ import { useDatabase } from "../rxdb"
import { DataSourceDocType, ObokuErrorCode } from "@oboku/shared"
import { Report } from "../debug/report.shared"
import { plugins } from "../plugins/configure"
-import { useCallback, useMemo } from "react"
+import { useMemo } from "react"
import { useNetworkState } from "react-use"
import { useSyncReplicate } from "../rxdb/replication/useSyncReplicate"
-import { catchError, EMPTY, from, switchMap, map, of, filter } from "rxjs"
+import { catchError, EMPTY, from, switchMap, map, filter, first } from "rxjs"
import { usePluginSynchronize } from "../plugins/usePluginSynchronize"
import { isDefined, useMutation } from "reactjrx"
import { isPluginError } from "../plugins/plugin-front"
import { getDataSourcePlugin } from "./getDataSourcePlugin"
import { httpClient } from "../http/httpClient"
import { createDialog } from "../common/dialogs/createDialog"
+import { latestDatabase$ } from "../rxdb/RxDbProvider"
+import { ModifyFunction } from "rxdb"
export const useSynchronizeDataSource = () => {
const { db: database } = useDatabase()
- const { atomicUpdateDataSource } = useAtomicUpdateDataSource()
+ const { mutateAsync: atomicUpdateDataSource } =
+ useDataSourceIncrementalPatch()
const synchronizeDataSource = usePluginSynchronize()
const network = useNetworkState()
const { mutateAsync: sync } = useSyncReplicate()
@@ -38,20 +41,27 @@ export const useSynchronizeDataSource = () => {
filter(isDefined),
switchMap((dataSource) => from(synchronizeDataSource(dataSource))),
switchMap((data) => {
- return atomicUpdateDataSource(_id, (old) => {
- old.syncStatus = `fetching`
-
- return old
- }).pipe(
+ return from(
+ atomicUpdateDataSource({
+ id: _id,
+ patch: {
+ syncStatus: "fetching"
+ }
+ })
+ ).pipe(
switchMap(() => from(sync([database.datasource]))),
switchMap(() => from(httpClient.syncDataSource(_id, data.data))),
catchError((e) =>
- atomicUpdateDataSource(_id, (old) => ({
- ...old,
- syncStatus: null,
- lastSyncErrorCode:
- ObokuErrorCode.ERROR_DATASOURCE_NETWORK_UNREACHABLE
- })).pipe(
+ from(
+ atomicUpdateDataSource({
+ id: _id,
+ patch: {
+ syncStatus: null,
+ lastSyncErrorCode:
+ ObokuErrorCode.ERROR_DATASOURCE_NETWORK_UNREACHABLE
+ }
+ })
+ ).pipe(
map((_) => {
throw e
})
@@ -108,23 +118,51 @@ export const useRemoveDataSource = () => {
db?.datasource.findOne({ selector: { _id: id } }).remove()
})
}
-export const useAtomicUpdateDataSource = () => {
- const { db: database } = useDatabase()
- const atomicUpdateDataSource = useCallback(
- (id: string, mutationFunction: any) =>
- of(database).pipe(
- filter(isDefined),
+export const useDataSourceIncrementalPatch = () => {
+ return useMutation({
+ mutationFn: ({
+ id,
+ patch
+ }: {
+ id: string
+ patch: Partial
+ }) =>
+ latestDatabase$.pipe(
+ first(),
switchMap((db) =>
from(db.datasource.findOne({ selector: { _id: id } }).exec())
),
- filter(isDefined),
- switchMap((item) => from(item.incrementalModify(mutationFunction)))
- ),
- [database]
- )
+ switchMap((item) => {
+ if (!item) return EMPTY
+
+ return from(item.incrementalPatch(patch))
+ })
+ )
+ })
+}
+
+export const useDataSourceIncrementalModify = () => {
+ return useMutation({
+ mutationFn: ({
+ id,
+ mutationFunction
+ }: {
+ id: string
+ mutationFunction: ModifyFunction
+ }) =>
+ latestDatabase$.pipe(
+ first(),
+ switchMap((db) =>
+ from(db.datasource.findOne({ selector: { _id: id } }).exec())
+ ),
+ switchMap((item) => {
+ if (!item) return EMPTY
- return { atomicUpdateDataSource }
+ return from(item.incrementalModify(mutationFunction))
+ })
+ )
+ })
}
export const useDataSourceHelpers = (
diff --git a/packages/web/src/dataSources/triggers.ts b/packages/web/src/dataSources/triggers.ts
deleted file mode 100644
index 53541543..00000000
--- a/packages/web/src/dataSources/triggers.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { ObservedValueOf, Subject } from "rxjs"
-
-const toggleDatasourceProtectedSubject = new Subject()
-
-export const toggleDatasourceProtected = (
- options: ObservedValueOf
-) => toggleDatasourceProtectedSubject.next(options)
-
-export const toggleDatasourceProtected$ =
- toggleDatasourceProtectedSubject.asObservable()