Feat: hidden file name if overflows

This commit is contained in:
HFO4 2022-02-27 14:39:04 +08:00
parent e730d726bb
commit c97e0ca910
5 changed files with 90 additions and 38 deletions

View File

@ -47,18 +47,12 @@ const useStyles = makeStyles((theme) => ({
position: "fixed",
inset: "-1!important",
},
minWidth: {
[theme.breakpoints.up("sm")]: {
minWidth: 500,
},
padding: 0,
},
paddingZero: {
padding: 0,
},
dialogContent: {
[theme.breakpoints.up("sm")]: {
minWidth: 500,
width: 500,
maxHeight: "calc(100vh - 140px)",
},
padding: 0,

View File

@ -6,6 +6,7 @@ import {
ListItemSecondaryAction,
ListItemText,
makeStyles,
Tooltip,
} from "@material-ui/core";
import TypeIcon from "../../FileManager/TypeIcon";
import { useUpload } from "../UseUpload";
@ -16,6 +17,8 @@ import { darken, lighten } from "@material-ui/core/styles/colorManipulator";
import { useTheme } from "@material-ui/core/styles";
import Chip from "@material-ui/core/Chip";
import DeleteIcon from "@material-ui/icons/Delete";
import RefreshIcon from "@material-ui/icons/Refresh";
import useMediaQuery from "@material-ui/core/useMediaQuery";
const useStyles = makeStyles((theme) => ({
progressContent: {
@ -39,6 +42,11 @@ const useStyles = makeStyles((theme) => ({
},
fileName: {
wordBreak: "break-all",
[theme.breakpoints.up("sm")]: {
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
},
},
successStatus: {
color: theme.palette.success.main,
@ -54,6 +62,10 @@ const useStyles = makeStyles((theme) => ({
delete: {
zIndex: 9,
},
fileNameContainer: {
display: "flex",
alignItems: "center",
},
}));
const getSpeedText = (speed, speedAvg, useSpeedAvg) => {
@ -68,7 +80,10 @@ const getSpeedText = (speed, speedAvg, useSpeedAvg) => {
export default function UploadTask({ uploader, useAvgSpeed, onCancel }) {
const classes = useStyles();
const theme = useTheme();
const { status, error, progress, speed, speedAvg } = useUpload(uploader);
const { status, error, progress, speed, speedAvg, retry } = useUpload(
uploader
);
const fullScreen = useMediaQuery(theme.breakpoints.down("sm"));
const [loading, setLoading] = useState(false);
const statusText = useMemo(() => {
@ -112,14 +127,14 @@ export default function UploadTask({ uploader, useAvgSpeed, onCancel }) {
const resumeLabel = useMemo(
() =>
uploader.task.resumed ? (
uploader.task.resumed && !fullScreen ? (
<Chip
className={classes.disabledBadge}
size="small"
label={"断点续传"}
/>
) : null,
[status]
[status, fullScreen]
);
const progressBar = useMemo(
@ -147,6 +162,30 @@ export default function UploadTask({ uploader, useAvgSpeed, onCancel }) {
});
};
const secondaryAction = useMemo(() => {
if (status === Status.error) {
return (
<Tooltip title={"重试"}>
<IconButton aria-label="Delete" onClick={() => retry()}>
<RefreshIcon />
</IconButton>
</Tooltip>
);
}
return (
<Tooltip title={"取消并删除"}>
<IconButton
aria-label="Delete"
disabled={loading}
onClick={() => cancel()}
>
<DeleteIcon />
</IconButton>
</Tooltip>
);
}, [status, loading]);
return (
<>
<div className={classes.progressContainer}>
@ -156,21 +195,17 @@ export default function UploadTask({ uploader, useAvgSpeed, onCancel }) {
<ListItemText
className={classes.listAction}
primary={
<span className={classes.fileName}>
{uploader.task.name}
{resumeLabel}
</span>
<div className={classes.fileNameContainer}>
<div className={classes.fileName}>
{uploader.task.name}
</div>
<div>{resumeLabel}</div>
</div>
}
secondary={statusText}
/>
<ListItemSecondaryAction className={classes.delete}>
<IconButton
aria-label="Delete"
disabled={loading}
onClick={() => cancel()}
>
<DeleteIcon />
</IconButton>
{secondaryAction}
</ListItemSecondaryAction>
</ListItem>
</div>

View File

@ -70,5 +70,12 @@ export function useUpload(uploader) {
return [res, resAvg];
}, [progress, lastTimeRef, startTimeRef]);
return { status, error, progress, speed, speedAvg };
const retry = () => {
uploader.reset();
lastTimeRef.current = Date.now();
startTimeRef.current = Date.now();
uploader.start();
};
return { status, error, progress, speed, speedAvg, retry };
}

View File

@ -10,11 +10,13 @@ import { Progress } from "../uploader/base";
import { CancelToken } from "axios";
export async function createUploadSession(
req: UploadSessionRequest
req: UploadSessionRequest,
cancel: CancelToken
): Promise<UploadCredential> {
const res = await requestAPI<UploadCredential>("file/upload", {
method: "put",
data: req,
cancelToken: cancel,
});
if (res.data.code !== 0) {

View File

@ -4,7 +4,7 @@ import UploadManager from "../index";
import Logger from "../logger";
import { validate } from "../utils/validator";
import { CancelToken } from "../utils/request";
import { CancelTokenSource } from "axios";
import axios, { CancelTokenSource } from "axios";
import { createUploadSession, deleteUploadSession } from "../api";
import * as utils from "../utils";
import { RequestCanceledError, UploaderError } from "../errors";
@ -109,13 +109,16 @@ export default abstract class Base {
this.transit(Status.preparing);
const cachedInfo = utils.getResumeCtx(this.task, this.logger);
if (cachedInfo == null) {
this.task.session = await createUploadSession({
path: this.task.dst,
size: this.task.file.size,
name: this.task.file.name,
policy_id: this.task.policy.id,
last_modified: this.task.file.lastModified,
});
this.task.session = await createUploadSession(
{
path: this.task.dst,
size: this.task.file.size,
name: this.task.file.name,
policy_id: this.task.policy.id,
last_modified: this.task.file.lastModified,
},
this.cancelToken.token
);
this.logger.info("Upload session created:", this.task.session);
} else {
this.task.session = cachedInfo.session;
@ -136,6 +139,17 @@ export default abstract class Base {
this.transit(Status.canceled);
};
public reset = () => {
this.cancelToken = axios.CancelToken.source();
this.progress = {
total: {
size: 0,
loaded: 0,
percent: 0,
},
};
};
protected setError(e: Error) {
if (
!(e instanceof UploaderError && e.Retryable()) ||
@ -155,9 +169,9 @@ export default abstract class Base {
protected cancelUploadSession = (): Promise<void> => {
return new Promise<void>((resolve) => {
utils.removeResumeCtx(this.task, this.logger);
setTimeout(() => {
if (this.task.session) {
deleteUploadSession(this.task.session?.sessionID)
if (this.task.session) {
setTimeout(() => {
deleteUploadSession(this.task.session!?.sessionID)
.catch((e) => {
this.logger.warn(
"Failed to cancel upload session: ",
@ -167,10 +181,10 @@ export default abstract class Base {
.finally(() => {
resolve();
});
} else {
resolve();
}
}, deleteUploadSessionDelay);
}, deleteUploadSessionDelay);
} else {
resolve();
}
});
};