diff --git a/src/App.tsx b/src/App.tsx index f33663e..c2d1896 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import * as React from "react"; import { List as ImmutableList } from "immutable"; import { connect, useDispatch } from "react-redux"; -import { useHistory } from "react-router"; +import { useHistory, useLocation } from "react-router"; import { BrowserRouter } from "react-router-dom"; import { MuiThemeProvider as ThemeProvider, createMuiTheme } from "@material-ui/core/styles"; // v1.x import amber from "@material-ui/core/colors/amber"; @@ -67,9 +67,9 @@ export const routeResolver = new RouteResolver({ new: "new", }, }, - journals: { + collections: { _id: { - _base: ":journalUid", + _base: ":colUid", edit: "edit", items: { _id: { diff --git a/src/Collections/CollectionList.tsx b/src/Collections/CollectionList.tsx new file mode 100644 index 0000000..46c1402 --- /dev/null +++ b/src/Collections/CollectionList.tsx @@ -0,0 +1,83 @@ +// SPDX-FileCopyrightText: © 2017 EteSync Authors +// SPDX-License-Identifier: AGPL-3.0-only + +import * as React from "react"; + +import { Link, useHistory } from "react-router-dom"; + +import IconButton from "@material-ui/core/IconButton"; +import IconAdd from "@material-ui/icons/Add"; +import ContactsIcon from "@material-ui/icons/Contacts"; +import CalendarTodayIcon from "@material-ui/icons/CalendarToday"; +import FormatListBulletedIcon from "@material-ui/icons/FormatListBulleted"; + +import { List, ListItem } from "../widgets/List"; + +import AppBarOverride from "../widgets/AppBarOverride"; +import Container from "../widgets/Container"; + +import { routeResolver } from "../App"; +import { CachedCollection } from "../Pim/helpers"; + +interface PropsType { + collections: CachedCollection[]; +} + +export default function CollectionList(props: PropsType) { + const history = useHistory(); + + const collectionMap = { + "etebase.vcard": [], + "etebase.vevent": [], + "etebase.vtodo": [], + }; + + function colClicked(colUid: string) { + history.push(routeResolver.getRoute("collections._id", { colUid })); + } + + for (const col of props.collections) { + if (collectionMap[col.metadata.type]) { + const colorBox = undefined; // FIXME + collectionMap[col.metadata.type].push(( + colClicked(col.collection.uid)}> + {col.metadata.name} + + )); + } + } + + return ( + + + + + + + + } + nestedItems={collectionMap["etebase.vcard"]} + /> + + } + nestedItems={collectionMap["etebase.vevent"]} + /> + + } + nestedItems={collectionMap["etebase.vtodo"]} + /> + + + ); +} diff --git a/src/Collections/Main.tsx b/src/Collections/Main.tsx new file mode 100644 index 0000000..c05c436 --- /dev/null +++ b/src/Collections/Main.tsx @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: © 2020 EteSync Authors +// SPDX-License-Identifier: AGPL-3.0-only + +import * as React from "react"; +import { Switch, Route, useHistory } from "react-router"; + +import { useCredentials } from "../credentials"; +import { useCollections } from "../etebase-helpers"; +import { routeResolver } from "../App"; +import LoadingIndicator from "../widgets/LoadingIndicator"; + +import { CachedCollection, getDecryptCollectionsFunction, PimFab } from "../Pim/helpers"; +import CollectionList from "./CollectionList"; + +const decryptCollections = getDecryptCollectionsFunction(); + +export default function CollectionsMain() { + const [cachedCollections, setCachedCollections] = React.useState(); + const history = useHistory(); + const etebase = useCredentials()!; + const collections = useCollections(etebase); + + React.useEffect(() => { + if (collections) { + decryptCollections(collections) + .then((entries) => setCachedCollections(entries)); + // FIXME: handle failure to decrypt collections + } + }, [collections]); + + if (!cachedCollections) { + return ( + + ); + } + + return ( + + + + history.push( + routeResolver.getRoute("collections.new") + )} + /> + + + ); +} + diff --git a/src/Pim/helpers.tsx b/src/Pim/helpers.tsx index cc668b0..fa6b984 100644 --- a/src/Pim/helpers.tsx +++ b/src/Pim/helpers.tsx @@ -21,7 +21,7 @@ export function getItemNavigationUid(item: PimType) { return `${item.collectionUid}|${item.itemUid}`; } -export function getDecryptCollectionsFunction(_colType: string) { +export function getDecryptCollectionsFunction(_colType?: string) { return memoize( async function (collections: Etebase.Collection[]) { const entries: CachedCollection[] = []; diff --git a/src/SideMenu/index.tsx b/src/SideMenu/index.tsx index cd48c1f..c901132 100644 --- a/src/SideMenu/index.tsx +++ b/src/SideMenu/index.tsx @@ -44,11 +44,11 @@ export default function SideMenu(props: PropsType) { loggedInItems = ( } onClick={() => { props.onCloseDrawerRequest(); - history.push(routeResolver.getRoute("journals")); + history.push(routeResolver.getRoute("collections")); }} /> } onClick={() => { props.onCloseDrawerRequest(); - history.push(routeResolver.getRoute("journals.import")); + history.push(routeResolver.getRoute("collections.import")); }} /> ; - collection: EteSync.CollectionInfo; - entries: List; -} - +export type SyncInfoJournal = any; export type SyncInfo = Map; export default function SyncGate() { const etebase = useCredentials(); const settings = useSelector((state: StoreState) => state.settings); - const userInfo = useSelector((state: StoreState) => state.cache.userInfo); - const journals = useSelector((state: StoreState) => state.cache.journals); const dispatch = useDispatch(); const [loading, setLoading] = React.useState(true); @@ -69,9 +59,6 @@ export default function SyncGate() { // FIXME: Shouldn't be here moment.locale(settings.locale); - // FIXME: remove - const etesync = etebase as any; - return ( - {false && ( - <> - ( - - )} - /> - - )} + + + state.cache2.collections); return usePromiseMemo( - getCollectionsByType(cachedCollections, colType, etebase), + (colType) ? + getCollectionsByType(cachedCollections, colType, etebase) : + getCollections(cachedCollections, etebase), [etebase, cachedCollections, colType] ); }