mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-03-25 16:48:50 +08:00
Compare commits
1 Commits
v0.26.0-be
...
graphite-b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afa108d517 |
@@ -114,6 +114,18 @@ export const AllPage = () => {
|
|||||||
const collectionService = useService(CollectionService);
|
const collectionService = useService(CollectionService);
|
||||||
const pinnedCollectionService = useService(PinnedCollectionService);
|
const pinnedCollectionService = useService(PinnedCollectionService);
|
||||||
|
|
||||||
|
const isCollectionDataReady = useLiveData(
|
||||||
|
collectionService.collectionDataReady$
|
||||||
|
);
|
||||||
|
|
||||||
|
const isPinnedCollectionDataReady = useLiveData(
|
||||||
|
pinnedCollectionService.pinnedCollectionDataReady$
|
||||||
|
);
|
||||||
|
|
||||||
|
const pinnedCollections = useLiveData(
|
||||||
|
pinnedCollectionService.pinnedCollections$
|
||||||
|
);
|
||||||
|
|
||||||
const [selectedCollectionId, setSelectedCollectionId] = useState<
|
const [selectedCollectionId, setSelectedCollectionId] = useState<
|
||||||
string | null
|
string | null
|
||||||
>(null);
|
>(null);
|
||||||
@@ -124,17 +136,28 @@ export const AllPage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if selected collection is not found, set selected collection id to null
|
// if selected collection is not in pinned collections, set selected collection id to null
|
||||||
if (!selectedCollection && selectedCollectionId) {
|
if (
|
||||||
|
isPinnedCollectionDataReady &&
|
||||||
|
selectedCollectionId &&
|
||||||
|
!pinnedCollections.some(c => c.collectionId === selectedCollectionId)
|
||||||
|
) {
|
||||||
setSelectedCollectionId(null);
|
setSelectedCollectionId(null);
|
||||||
}
|
}
|
||||||
}, [selectedCollection, selectedCollectionId]);
|
}, [isPinnedCollectionDataReady, pinnedCollections, selectedCollectionId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// if selected collection is not found, set selected collection id to null
|
||||||
|
if (!selectedCollection && selectedCollectionId && isCollectionDataReady) {
|
||||||
|
setSelectedCollectionId(null);
|
||||||
|
}
|
||||||
|
}, [isCollectionDataReady, selectedCollection, selectedCollectionId]);
|
||||||
|
|
||||||
const selectedCollectionInfo = useLiveData(
|
const selectedCollectionInfo = useLiveData(
|
||||||
selectedCollection ? selectedCollection.info$ : null
|
selectedCollection ? selectedCollection.info$ : null
|
||||||
);
|
);
|
||||||
|
|
||||||
const [tempFilters, setTempFilters] = useState<FilterParams[]>([]);
|
const [tempFilters, setTempFilters] = useState<FilterParams[] | null>(null);
|
||||||
|
|
||||||
const [explorerContextValue] = useState(createDocExplorerContext);
|
const [explorerContextValue] = useState(createDocExplorerContext);
|
||||||
|
|
||||||
@@ -178,10 +201,9 @@ export const AllPage = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const subscription = collectionRulesService
|
const subscription = collectionRulesService
|
||||||
.watch(
|
.watch(
|
||||||
// collection filters and temp filters can't exist at the same time
|
|
||||||
selectedCollectionInfo
|
selectedCollectionInfo
|
||||||
? {
|
? {
|
||||||
filters: selectedCollectionInfo.rules.filters,
|
filters: tempFilters ?? selectedCollectionInfo.rules.filters,
|
||||||
groupBy,
|
groupBy,
|
||||||
orderBy,
|
orderBy,
|
||||||
extraAllowList: selectedCollectionInfo.allowList,
|
extraAllowList: selectedCollectionInfo.allowList,
|
||||||
@@ -303,42 +325,74 @@ export const AllPage = () => {
|
|||||||
});
|
});
|
||||||
}, [docsService.list, openConfirmModal, selectedDocIds, t]);
|
}, [docsService.list, openConfirmModal, selectedDocIds, t]);
|
||||||
|
|
||||||
|
const handleSelectCollection = useCallback((collectionId: string) => {
|
||||||
|
setSelectedCollectionId(collectionId);
|
||||||
|
setTempFilters(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleEditCollection = useCallback(
|
||||||
|
(collectionId: string) => {
|
||||||
|
const collection = collectionService.collection$(collectionId).value;
|
||||||
|
if (!collection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedCollectionId(collectionId);
|
||||||
|
setTempFilters(collection.info$.value.rules.filters);
|
||||||
|
},
|
||||||
|
[collectionService]
|
||||||
|
);
|
||||||
|
|
||||||
const handleSaveFilters = useCallback(() => {
|
const handleSaveFilters = useCallback(() => {
|
||||||
openPromptModal({
|
if (selectedCollectionId) {
|
||||||
title: t['com.affine.editCollection.saveCollection'](),
|
collectionService.updateCollection(selectedCollectionId, {
|
||||||
label: t['com.affine.editCollectionName.name'](),
|
rules: {
|
||||||
inputOptions: {
|
filters: tempFilters ?? [],
|
||||||
placeholder: t['com.affine.editCollectionName.name.placeholder'](),
|
},
|
||||||
},
|
});
|
||||||
children: t['com.affine.editCollectionName.createTips'](),
|
setTempFilters(null);
|
||||||
confirmText: t['com.affine.editCollection.save'](),
|
} else {
|
||||||
cancelText: t['com.affine.editCollection.button.cancel'](),
|
openPromptModal({
|
||||||
confirmButtonOptions: {
|
title: t['com.affine.editCollection.saveCollection'](),
|
||||||
variant: 'primary',
|
label: t['com.affine.editCollectionName.name'](),
|
||||||
},
|
inputOptions: {
|
||||||
onConfirm(name) {
|
placeholder: t['com.affine.editCollectionName.name.placeholder'](),
|
||||||
const id = collectionService.createCollection({
|
},
|
||||||
name,
|
children: t['com.affine.editCollectionName.createTips'](),
|
||||||
rules: {
|
confirmText: t['com.affine.editCollection.save'](),
|
||||||
filters: tempFilters,
|
cancelText: t['com.affine.editCollection.button.cancel'](),
|
||||||
},
|
confirmButtonOptions: {
|
||||||
});
|
variant: 'primary',
|
||||||
pinnedCollectionService.addPinnedCollection({
|
},
|
||||||
collectionId: id,
|
onConfirm(name) {
|
||||||
index: pinnedCollectionService.indexAt('after'),
|
const id = collectionService.createCollection({
|
||||||
});
|
name,
|
||||||
setTempFilters([]);
|
rules: {
|
||||||
setSelectedCollectionId(id);
|
filters: tempFilters ?? [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
pinnedCollectionService.addPinnedCollection({
|
||||||
|
collectionId: id,
|
||||||
|
index: pinnedCollectionService.indexAt('after'),
|
||||||
|
});
|
||||||
|
setTempFilters(null);
|
||||||
|
setSelectedCollectionId(id);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}, [
|
}, [
|
||||||
collectionService,
|
collectionService,
|
||||||
openPromptModal,
|
openPromptModal,
|
||||||
pinnedCollectionService,
|
pinnedCollectionService,
|
||||||
|
selectedCollectionId,
|
||||||
t,
|
t,
|
||||||
tempFilters,
|
tempFilters,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const handleNewTempFilter = useCallback((params: FilterParams) => {
|
||||||
|
setSelectedCollectionId(null);
|
||||||
|
setTempFilters([params]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DocExplorerContext.Provider value={explorerContextValue}>
|
<DocExplorerContext.Provider value={explorerContextValue}>
|
||||||
<ViewTitle title={t['All pages']()} />
|
<ViewTitle title={t['All pages']()} />
|
||||||
@@ -352,29 +406,24 @@ export const AllPage = () => {
|
|||||||
<div className={styles.pinnedCollection}>
|
<div className={styles.pinnedCollection}>
|
||||||
<PinnedCollections
|
<PinnedCollections
|
||||||
activeCollectionId={selectedCollectionId}
|
activeCollectionId={selectedCollectionId}
|
||||||
onClickAll={() => setSelectedCollectionId(null)}
|
onActiveAll={() => setSelectedCollectionId(null)}
|
||||||
onClickCollection={collectionId => {
|
onActiveCollection={handleSelectCollection}
|
||||||
setSelectedCollectionId(collectionId);
|
onAddFilter={handleNewTempFilter}
|
||||||
setTempFilters([]);
|
onEditCollection={handleEditCollection}
|
||||||
}}
|
hiddenAdd={tempFilters !== null}
|
||||||
onAddFilter={params => {
|
|
||||||
setSelectedCollectionId(null);
|
|
||||||
setTempFilters([...(tempFilters ?? []), params]);
|
|
||||||
}}
|
|
||||||
hiddenAdd={tempFilters.length > 0}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{tempFilters.length > 0 && (
|
{tempFilters !== null && (
|
||||||
<div className={styles.filterArea}>
|
<div className={styles.filterArea}>
|
||||||
<Filters
|
<Filters
|
||||||
className={styles.filters}
|
className={styles.filters}
|
||||||
filters={tempFilters ?? []}
|
filters={tempFilters}
|
||||||
onChange={handleFilterChange}
|
onChange={handleFilterChange}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="plain"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setTempFilters([]);
|
setTempFilters(null);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t['Cancel']()}
|
{t['Cancel']()}
|
||||||
|
|||||||
@@ -27,6 +27,38 @@ export const item = style({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const itemContent = style({
|
||||||
|
display: 'inline-block',
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
textAlign: 'center',
|
||||||
|
maxWidth: '128px',
|
||||||
|
minWidth: '32px',
|
||||||
|
|
||||||
|
selectors: {
|
||||||
|
[`${item}:hover > &`]: {
|
||||||
|
mask:
|
||||||
|
'linear-gradient(#fff) left / calc(100% - 32px) no-repeat,' +
|
||||||
|
'linear-gradient(90deg,#fff 0%,transparent 50%,transparent 100%) right / 32px no-repeat',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const editIconButton = style({
|
||||||
|
opacity: 0,
|
||||||
|
marginLeft: -16,
|
||||||
|
backgroundColor: cssVarV2('layer/background/hoverOverlay'),
|
||||||
|
|
||||||
|
selectors: {
|
||||||
|
[`${item}:hover > &`]: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const closeButton = style({});
|
||||||
|
|
||||||
export const container = style({
|
export const container = style({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
|||||||
@@ -7,7 +7,13 @@ import {
|
|||||||
} from '@affine/core/modules/collection';
|
} from '@affine/core/modules/collection';
|
||||||
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
import type { FilterParams } from '@affine/core/modules/collection-rules';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { CollectionsIcon, FilterIcon, PlusIcon } from '@blocksuite/icons/rc';
|
import {
|
||||||
|
CloseIcon,
|
||||||
|
CollectionsIcon,
|
||||||
|
EditIcon,
|
||||||
|
FilterIcon,
|
||||||
|
PlusIcon,
|
||||||
|
} from '@blocksuite/icons/rc';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
|
|
||||||
@@ -17,10 +23,14 @@ export const PinnedCollectionItem = ({
|
|||||||
record,
|
record,
|
||||||
isActive,
|
isActive,
|
||||||
onClick,
|
onClick,
|
||||||
|
onClickRemove,
|
||||||
|
onClickEdit,
|
||||||
}: {
|
}: {
|
||||||
record: PinnedCollectionRecord;
|
record: PinnedCollectionRecord;
|
||||||
|
onClickRemove: () => void;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
|
onClickEdit: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const collectionService = useService(CollectionService);
|
const collectionService = useService(CollectionService);
|
||||||
@@ -38,22 +48,46 @@ export const PinnedCollectionItem = ({
|
|||||||
data-active={isActive ? 'true' : undefined}
|
data-active={isActive ? 'true' : undefined}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{name ?? t['Untitled']()}
|
<span className={styles.itemContent}>{name ?? t['Untitled']()}</span>
|
||||||
|
<IconButton
|
||||||
|
size="16"
|
||||||
|
className={styles.editIconButton}
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onClickEdit();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<EditIcon />
|
||||||
|
</IconButton>
|
||||||
|
{isActive && (
|
||||||
|
<IconButton
|
||||||
|
className={styles.closeButton}
|
||||||
|
size="16"
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onClickRemove();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PinnedCollections = ({
|
export const PinnedCollections = ({
|
||||||
activeCollectionId,
|
activeCollectionId,
|
||||||
onClickAll,
|
onActiveAll,
|
||||||
onClickCollection,
|
onActiveCollection,
|
||||||
onAddFilter,
|
onAddFilter,
|
||||||
|
onEditCollection,
|
||||||
hiddenAdd,
|
hiddenAdd,
|
||||||
}: {
|
}: {
|
||||||
activeCollectionId: string | null;
|
activeCollectionId: string | null;
|
||||||
onClickAll: () => void;
|
onActiveAll: () => void;
|
||||||
onClickCollection: (collectionId: string) => void;
|
onActiveCollection: (collectionId: string) => void;
|
||||||
onAddFilter: (params: FilterParams) => void;
|
onAddFilter: (params: FilterParams) => void;
|
||||||
|
onEditCollection: (collectionId: string) => void;
|
||||||
hiddenAdd?: boolean;
|
hiddenAdd?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
@@ -74,22 +108,32 @@ export const PinnedCollections = ({
|
|||||||
<div
|
<div
|
||||||
className={styles.item}
|
className={styles.item}
|
||||||
data-active={activeCollectionId === null ? 'true' : undefined}
|
data-active={activeCollectionId === null ? 'true' : undefined}
|
||||||
onClick={onClickAll}
|
onClick={onActiveAll}
|
||||||
role="button"
|
role="button"
|
||||||
>
|
>
|
||||||
{t['com.affine.all-docs.pinned-collection.all']()}
|
{t['com.affine.all-docs.pinned-collection.all']()}
|
||||||
</div>
|
</div>
|
||||||
{pinnedCollections.map(record => (
|
{pinnedCollections.map((record, index) => (
|
||||||
<PinnedCollectionItem
|
<PinnedCollectionItem
|
||||||
key={record.collectionId}
|
key={record.collectionId}
|
||||||
record={record}
|
record={record}
|
||||||
isActive={activeCollectionId === record.collectionId}
|
isActive={activeCollectionId === record.collectionId}
|
||||||
onClick={() => onClickCollection(record.collectionId)}
|
onClick={() => onActiveCollection(record.collectionId)}
|
||||||
|
onClickEdit={() => onEditCollection(record.collectionId)}
|
||||||
|
onClickRemove={() => {
|
||||||
|
const nextCollectionId = pinnedCollections[index - 1]?.collectionId;
|
||||||
|
if (nextCollectionId) {
|
||||||
|
onActiveCollection(nextCollectionId);
|
||||||
|
} else {
|
||||||
|
onActiveAll();
|
||||||
|
}
|
||||||
|
pinnedCollectionService.removePinnedCollection(record.collectionId);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{!hiddenAdd && (
|
{!hiddenAdd && (
|
||||||
<AddPinnedCollection
|
<AddPinnedCollection
|
||||||
onAddPinnedCollection={handleAddPinnedCollection}
|
onPinCollection={handleAddPinnedCollection}
|
||||||
onAddFilter={onAddFilter}
|
onAddFilter={onAddFilter}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -98,17 +142,17 @@ export const PinnedCollections = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const AddPinnedCollection = ({
|
export const AddPinnedCollection = ({
|
||||||
onAddPinnedCollection,
|
onPinCollection,
|
||||||
onAddFilter,
|
onAddFilter,
|
||||||
}: {
|
}: {
|
||||||
onAddPinnedCollection: (collectionId: string) => void;
|
onPinCollection: (collectionId: string) => void;
|
||||||
onAddFilter: (params: FilterParams) => void;
|
onAddFilter: (params: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Menu
|
<Menu
|
||||||
items={
|
items={
|
||||||
<AddPinnedCollectionMenuContent
|
<AddPinnedCollectionMenuContent
|
||||||
onAddPinnedCollection={onAddPinnedCollection}
|
onPinCollection={onPinCollection}
|
||||||
onAddFilter={onAddFilter}
|
onAddFilter={onAddFilter}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@@ -121,10 +165,10 @@ export const AddPinnedCollection = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const AddPinnedCollectionMenuContent = ({
|
export const AddPinnedCollectionMenuContent = ({
|
||||||
onAddPinnedCollection,
|
onPinCollection,
|
||||||
onAddFilter,
|
onAddFilter,
|
||||||
}: {
|
}: {
|
||||||
onAddPinnedCollection: (collectionId: string) => void;
|
onPinCollection: (collectionId: string) => void;
|
||||||
onAddFilter: (params: FilterParams) => void;
|
onAddFilter: (params: FilterParams) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [addingFilter, setAddingFilter] = useState<boolean>(false);
|
const [addingFilter, setAddingFilter] = useState<boolean>(false);
|
||||||
@@ -167,7 +211,7 @@ export const AddPinnedCollectionMenuContent = ({
|
|||||||
prefixIcon={<CollectionsIcon />}
|
prefixIcon={<CollectionsIcon />}
|
||||||
suffixIcon={<PlusIcon />}
|
suffixIcon={<PlusIcon />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onAddPinnedCollection(meta.id);
|
onPinCollection(meta.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{meta.name ?? t['Untitled']()}
|
{meta.name ?? t['Untitled']()}
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ export class CollectionService extends Service {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
readonly collectionDataReady$ = LiveData.from(
|
||||||
|
this.store.watchCollectionDataReady(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
// collection metas used in collection list, only include `id` and `name`, without `rules` and `allowList`
|
// collection metas used in collection list, only include `id` and `name`, without `rules` and `allowList`
|
||||||
readonly collectionMetas$ = LiveData.from(
|
readonly collectionMetas$ = LiveData.from(
|
||||||
this.store.watchCollectionMetas(),
|
this.store.watchCollectionMetas(),
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ export class PinnedCollectionService extends Service {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pinnedCollectionDataReady$ = LiveData.from(
|
||||||
|
this.pinnedCollectionStore.watchPinnedCollectionDataReady(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
pinnedCollections$ = LiveData.from<PinnedCollectionRecord[]>(
|
pinnedCollections$ = LiveData.from<PinnedCollectionRecord[]>(
|
||||||
this.pinnedCollectionStore.watchPinnedCollections(),
|
this.pinnedCollectionStore.watchPinnedCollections(),
|
||||||
[]
|
[]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { map, type Observable, switchMap } from 'rxjs';
|
import { distinctUntilChanged, map, type Observable, switchMap } from 'rxjs';
|
||||||
import { Array as YArray } from 'yjs';
|
import { Array as YArray } from 'yjs';
|
||||||
|
|
||||||
import type { FilterParams } from '../../collection-rules';
|
import type { FilterParams } from '../../collection-rules';
|
||||||
@@ -35,6 +35,17 @@ export class CollectionStore extends Store {
|
|||||||
return this.rootYDoc.getMap('setting');
|
return this.rootYDoc.getMap('setting');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchCollectionDataReady() {
|
||||||
|
return this.workspaceService.workspace.engine.doc
|
||||||
|
.docState$(this.workspaceService.workspace.id)
|
||||||
|
.pipe(
|
||||||
|
map(docState => {
|
||||||
|
return docState.ready;
|
||||||
|
}),
|
||||||
|
distinctUntilChanged()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
watchCollectionMetas() {
|
watchCollectionMetas() {
|
||||||
return yjsGetPath(this.workspaceSettingYMap, 'collections').pipe(
|
return yjsGetPath(this.workspaceSettingYMap, 'collections').pipe(
|
||||||
switchMap(yjsObserveDeep),
|
switchMap(yjsObserveDeep),
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ export class PinnedCollectionStore extends Store {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watchPinnedCollectionDataReady() {
|
||||||
|
return this.workspaceDBService.db.pinnedCollections.isReady$;
|
||||||
|
}
|
||||||
|
|
||||||
watchPinnedCollections(): Observable<PinnedCollectionRecord[]> {
|
watchPinnedCollections(): Observable<PinnedCollectionRecord[]> {
|
||||||
return this.workspaceDBService.db.pinnedCollections.find$();
|
return this.workspaceDBService.db.pinnedCollections.find$();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type {
|
|||||||
TableSchemaBuilder,
|
TableSchemaBuilder,
|
||||||
} from '@toeverything/infra';
|
} from '@toeverything/infra';
|
||||||
import { Entity, LiveData } from '@toeverything/infra';
|
import { Entity, LiveData } from '@toeverything/infra';
|
||||||
import { map } from 'rxjs';
|
import { distinctUntilChanged, map } from 'rxjs';
|
||||||
|
|
||||||
import type { WorkspaceService } from '../../workspace';
|
import type { WorkspaceService } from '../../workspace';
|
||||||
|
|
||||||
@@ -19,10 +19,23 @@ export class WorkspaceDBTable<
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReady$ = LiveData.from(
|
||||||
|
this.workspaceService.workspace.engine.doc
|
||||||
|
.docState$(this.props.storageDocId)
|
||||||
|
.pipe(
|
||||||
|
map(docState => docState.ready),
|
||||||
|
distinctUntilChanged()
|
||||||
|
),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
isSyncing$ = LiveData.from(
|
isSyncing$ = LiveData.from(
|
||||||
this.workspaceService.workspace.engine.doc
|
this.workspaceService.workspace.engine.doc
|
||||||
.docState$(this.props.storageDocId)
|
.docState$(this.props.storageDocId)
|
||||||
.pipe(map(docState => docState.syncing)),
|
.pipe(
|
||||||
|
map(docState => docState.syncing),
|
||||||
|
distinctUntilChanged()
|
||||||
|
),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user