Skip to content

Commit

Permalink
feat(project): support loading more cloudStorage data (#1443)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cheerego7 authored Mar 29, 2022
1 parent 527da10 commit 7a4af54
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 5 deletions.
75 changes: 75 additions & 0 deletions desktop/renderer-app/src/pages/CloudStoragePage/store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ export class CloudStorageStore extends CloudStorageStoreBase {
public insertCourseware: (file: CloudStorageFile) => void;
public onCoursewareInserted?: () => void;

public cloudStorageSinglePageFiles = 50;

/** In order to avoid multiple calls the fetchMoreCloudStorageData
* when request fetchMoreCloudStorageData after files length is 0 */
public hasMoreFile = false;
public isFetchingFiles = false;

// a set of taskUUIDs representing querying tasks
private convertStatusManager = new ConvertStatusManager();

Expand All @@ -73,12 +80,15 @@ export class CloudStorageStore extends CloudStorageStoreBase {

makeObservable(this, {
filesMap: observable,
isFetchingFiles: observable,

pendingUploadTasks: computed,
uploadingUploadTasks: computed,
successUploadTasks: computed,
failedUploadTasks: computed,
files: computed,
currentFilesLength: computed,
cloudStorageDataPagination: computed,

fileMenus: action,
onItemMenuClick: action,
Expand Down Expand Up @@ -113,6 +123,14 @@ export class CloudStorageStore extends CloudStorageStoreBase {
return observable.array([...this.filesMap.values()]);
}

public get currentFilesLength(): number {
return this.filesMap.size;
}

public get cloudStorageDataPagination(): number {
return Math.ceil(this.currentFilesLength / this.cloudStorageSinglePageFiles);
}

/** Render file menus item base on fileUUID */
public fileMenus = (
file: CloudStorageFileUI,
Expand Down Expand Up @@ -278,6 +296,62 @@ export class CloudStorageStore extends CloudStorageStoreBase {
this.uploadTaskManager.addTasks(Array.from(files));
}

public getFilesLength = (): number => {
return this.filesMap.size;
};

public fetchMoreCloudStorageData = async (page: number): Promise<void> => {
if (this.isFetchingFiles) {
return;
}

const cloudStorageTotalPagesFilesCount =
this.cloudStorageDataPagination * this.cloudStorageSinglePageFiles;

if (this.currentFilesLength >= cloudStorageTotalPagesFilesCount && this.hasMoreFile) {
this.isFetchingFiles = true;

try {
const { files: cloudFiles } = await listFiles({
page,
order: "DESC",
});

this.isFetchingFiles = false;

this.hasMoreFile = cloudFiles.length === 0;

for (const cloudFile of cloudFiles) {
const file = this.filesMap.get(cloudFile.fileUUID);

runInAction(() => {
if (file) {
file.fileName = cloudFile.fileName;
file.createAt = cloudFile.createAt;
file.fileSize = cloudFile.fileSize;
file.convert = CloudStorageStore.mapConvertStep(cloudFile.convertStep);
file.taskToken = cloudFile.taskToken;
file.taskUUID = cloudFile.taskUUID;
file.external = cloudFile.external;
} else {
this.filesMap.set(
cloudFile.fileUUID,
observable.object({
...cloudFile,
convert: CloudStorageStore.mapConvertStep(
cloudFile.convertStep,
),
}),
);
}
});
}
} catch {
this.isFetchingFiles = false;
}
}
};

public initialize({
onCoursewareInserted,
}: { onCoursewareInserted?: () => void } = {}): () => void {
Expand All @@ -297,6 +371,7 @@ export class CloudStorageStore extends CloudStorageStoreBase {
(currLen, prevLen) => {
if (currLen < prevLen) {
this.refreshFilesNowDebounced();
this.hasMoreFile = true;
}
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
CloudStorageFileListFileNameProps,
} from "./CloudStorageFileListFileName";
import { useTranslation } from "react-i18next";
import { SVGListLoading } from "../../FlatIcons";

export interface CloudStorageFileListProps
extends Pick<
Expand All @@ -28,6 +29,7 @@ export interface CloudStorageFileListProps
files: CloudStorageFile[];
/** User selected file UUIDs */
selectedFileUUIDs: string[];
isLoadingData: Boolean;
/** Fires when user select or deselect files */
onSelectionChange: (fileUUID: string[]) => void;
}
Expand All @@ -44,6 +46,7 @@ export const CloudStorageFileList: React.FC<CloudStorageFileListProps> = ({
titleClickable = false,
onItemTitleClick,
renamingFileUUID,
isLoadingData,
onRename,
}) => {
const { t } = useTranslation();
Expand Down Expand Up @@ -138,6 +141,11 @@ export const CloudStorageFileList: React.FC<CloudStorageFileListProps> = ({
}}
size="small"
/>
{isLoadingData && (
<div className="cloud-storage-pull-up-loading">
<SVGListLoading />
</div>
)}
{files.length <= 0 && (
<div className="cloud-storage-file-list-empty">
<div className="cloud-storage-file-list-empty-content">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
}
}

.cloud-storage-pull-up-loading {
margin: 0 auto;
}

.cloud-storage-file-list-filename-container {
position: relative;
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export const SuggestedIcons: Story = ({ active }) => (
"CircleInfoOutlined",
"CircleInfoFilled",
"Load",
"ListLoading",
]}
title="Suggested Icons"
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import "../style.less";
import React from "react";
import { FlatIconProps } from "../types";

export const SVGListLoading: React.FC<FlatIconProps> = ({
active,
className = "",
...restProps
}) => {
return (
<svg
className={`${className} flat-icon ${active ? "is-active" : ""}`}
fill="none"
height="50"
viewBox="0 0 50 50"
width="50"
xmlns="http://www.w3.org/2000/svg"
{...restProps}
>
<rect height="50" width="50" />
<circle cx="13" cy="25" fill="#3381FF" r="2" />
<circle cx="25" cy="25" fill="#3381FF" r="4" />
<circle cx="37" cy="25" fill="#3381FF" r="2" />
</svg>
);
};

export default SVGListLoading;
1 change: 1 addition & 0 deletions packages/flat-components/src/components/FlatIcons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export * from "./icons/SVGHomeOutlined";
export * from "./icons/SVGInfo";
export * from "./icons/SVGLast";
export * from "./icons/SVGLeft";
export * from "./icons/SVGListLoading";
export * from "./icons/SVGLoad";
export * from "./icons/SVGLoop";
export * from "./icons/SVGMenuFold";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import { CloudStorageFileList } from "../../components/CloudStorage";

export interface CloudStorageFileListContainerProps {
store: CloudStorageStore;
isLoadingData: Boolean;
}

export const CloudStorageFileListContainer = observer<CloudStorageFileListContainerProps>(
function CloudStorageFileListContainer({ store }) {
function CloudStorageFileListContainer({ store, isLoadingData }) {
return (
<CloudStorageFileList
titleClickable
fileMenus={store.fileMenus}
files={toJS(store.files)}
isLoadingData={isLoadingData}
renamingFileUUID={store.renamingFileUUID}
selectedFileUUIDs={toJS(store.selectedFileUUIDs)}
onItemMenuClick={store.onItemMenuClick}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "./style.less";

import React, { useCallback, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { observer } from "mobx-react-lite";
import { Button, Dropdown, Menu } from "antd";
import { FormOutlined } from "@ant-design/icons";
Expand Down Expand Up @@ -55,8 +55,15 @@ const onDragOver = (event: React.DragEvent<HTMLDivElement>): void => {
export const CloudStorageContainer = observer<CloudStorageContainerProps>(
function CloudStorageContainer({ store }) {
const { t } = useTranslation();

const cloudStorageContainerRef = useRef<HTMLDivElement>(null);
const [isH5PanelVisible, setH5PanelVisible] = useState(false);
const [isAtTheBottom, setIsAtTheBottom] = useState(false);

useEffect(() => {
if (isAtTheBottom) {
void store.fetchMoreCloudStorageData(store.cloudStorageDataPagination + 1);
}
}, [isAtTheBottom, store]);

const handleMenuClick = useCallback(({ key }: { key: string }) => {
if (key === "h5") {
Expand Down Expand Up @@ -99,6 +106,18 @@ export const CloudStorageContainer = observer<CloudStorageContainerProps>(
</div>
);

const onCloudStorageListScroll = (): void => {
if (cloudStorageContainerRef.current) {
const scrollViewOffsetY = cloudStorageContainerRef.current.scrollTop;
const scrollViewFrameHeight = cloudStorageContainerRef.current.clientHeight;
const scrollViewContentHeight = cloudStorageContainerRef.current.scrollHeight;

setIsAtTheBottom(
scrollViewOffsetY + scrollViewFrameHeight >= scrollViewContentHeight,
);
}
};

return (
<div className="cloud-storage-container" onDragOver={onDragOver} onDrop={onDrop}>
{!store.compact && (
Expand All @@ -118,9 +137,16 @@ export const CloudStorageContainer = observer<CloudStorageContainerProps>(
{containerBtns}
</div>
)}
<div className="cloud-storage-container-file-list fancy-scrollbar">
<div
ref={cloudStorageContainerRef}
className="cloud-storage-container-file-list fancy-scrollbar"
onScroll={onCloudStorageListScroll}
>
{store.totalUsageHR ? (
<CloudStorageFileListContainer store={store} />
<CloudStorageFileListContainer
isLoadingData={store.isFetchingFiles}
store={store}
/>
) : (
<CloudStorageSkeletons isCompactMode={store.compact} />
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ export abstract class CloudStorageStore {
/** User cloud storage files */
public abstract files: CloudStorageFile[];

/** get fetch data pagination value of cloudStorage. */
public abstract cloudStorageDataPagination: number;

/** Render file menus item base on fileUUID */
public abstract fileMenus: (
file: CloudStorageFile,
Expand Down Expand Up @@ -157,4 +160,16 @@ export abstract class CloudStorageStore {

/** When file(s) are dropped in the container. */
public abstract onDropFile(files: FileList): void;

/** When file(s) are dropped in the container. */
public abstract onDropFile(files: FileList): void;

/** In order to avoid multiple calls the fetchMoreCloudStorageData when fetching data */
public abstract isFetchingFiles: boolean;

/** Cloud storage single page data returned by the server */
public abstract cloudStorageSinglePageFiles: number;

/** When cloudStorage files is 50 or more, pull up to bottom that loading will fetch more pagination Data of the cloudStorage. */
public abstract fetchMoreCloudStorageData: (page: number) => Promise<void>;
}
Loading

0 comments on commit 7a4af54

Please sign in to comment.