diff --git a/src/activitys/ModuleViewActivity/index.tsx b/src/activitys/ModuleViewActivity/index.tsx index 91251361..d7e17525 100644 --- a/src/activitys/ModuleViewActivity/index.tsx +++ b/src/activitys/ModuleViewActivity/index.tsx @@ -34,6 +34,8 @@ import { useFormatBytes } from "@Hooks/useFormatBytes"; import LinearProgress from "@mui/material/LinearProgress"; import { Download } from "@Native/Download"; import { Environment } from "@Native/Environment"; +import { useDownloadModule } from "@Hooks/useDownloadModule"; +import { AvatarWithProgress } from "@Components/AvatarWithProgress"; function a11yProps(index: number) { return { @@ -137,7 +139,7 @@ const ModuleViewActivity = () => { const cconfirm = useConfirm(); - const [downloadProgress, setDownloadProgress] = React.useState(0); + const [startDL, progress] = useDownloadModule(); return ( { width: "100%", }} > - ({ bgcolor: theme.palette.primary.dark, @@ -225,15 +228,15 @@ const ModuleViewActivity = () => { height: 100, boxShadow: "0 -1px 5px rgba(0,0,0,.09), 0 3px 5px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.3), 0 1px 3px rgba(0,0,0,.15)", borderRadius: "20%", - mr: 1.5, fontSize: 50, })} src={icon} + progressTextVariant="body2" > {name.charAt(0).toUpperCase()} - + - + setIsNameVisible(!visible)}> {name} @@ -344,17 +347,6 @@ const ModuleViewActivity = () => { - {downloadProgress !== 0 && ( - - - - - - {`${Math.round(downloadProgress)}%`} - - - )} - { onClick: () => { const lasSeg = new URL(latestVersion.zipUrl).pathname.split("/").pop(); const dlPath = Environment.getPublicDir(Environment.DIRECTORY_DOWNLOADS) + "/" + lasSeg; - const dl = new Download(latestVersion.zipUrl, dlPath); - - dl.onChange = (obj) => { - switch (obj.type) { - case "downloading": - setDownloadProgress(obj.state); - break; - case "finished": - setDownloadProgress(0); - cconfirm({ - title: strings("download"), - description: strings("file_downloaded", { path: dlPath }), - }) - .then(() => {}) - .catch(() => {}); - - break; - } - }; - - dl.onError = (err) => { - setDownloadProgress(0); - os.toast("finsish: " + err, Toast.LENGTH_SHORT); - }; - - dl.start(); - - // os.open(latestVersion.zipUrl, { - // target: "_blank", - // features: { - // color: theme.palette.primary.main, - // }, - // }); + startDL(latestVersion.zipUrl, dlPath); }, }, { diff --git a/src/activitys/ModuleViewActivity/tabs/VersionsTab.tsx b/src/activitys/ModuleViewActivity/tabs/VersionsTab.tsx index bd3d51c1..90e60772 100644 --- a/src/activitys/ModuleViewActivity/tabs/VersionsTab.tsx +++ b/src/activitys/ModuleViewActivity/tabs/VersionsTab.tsx @@ -2,9 +2,11 @@ import FetchTextActivity from "@Activitys/FetchTextActivity"; import InstallTerminalActivity from "@Activitys/InstallTerminalActivity"; import InstallTerminalV2Activity from "@Activitys/InstallTerminalV2Activity"; import { useActivity } from "@Hooks/useActivity"; +import { useDownloadModule } from "@Hooks/useDownloadModule"; import { useFormatDate } from "@Hooks/useFormatDate"; import { useStrings } from "@Hooks/useStrings"; import { useTheme } from "@Hooks/useTheme"; +import { Environment } from "@Native/Environment"; import { os } from "@Native/Os"; import { Shell } from "@Native/Shell"; import DownloadIcon from "@mui/icons-material/Download"; @@ -12,6 +14,7 @@ import InstallMobileIcon from "@mui/icons-material/InstallMobile"; import ManageHistoryIcon from "@mui/icons-material/ManageHistory"; import Chip from "@mui/material/Chip"; import IconButton from "@mui/material/IconButton"; +import LinearProgress from "@mui/material/LinearProgress"; import List from "@mui/material/List"; import ListItem from "@mui/material/ListItem"; import ListItemText from "@mui/material/ListItemText"; @@ -46,6 +49,8 @@ const VersionItem = React.memo(({ id, version, index }) => { const { strings } = useStrings(); const { theme } = useTheme(); + const [startDL, progress] = useDownloadModule(); + const { track, support } = extra; const versionName = `${version.version} (${version.versionCode})`; @@ -71,6 +76,11 @@ const VersionItem = React.memo(({ id, version, index }) => { return ( {version.changelog && ( @@ -102,12 +112,9 @@ const VersionItem = React.memo(({ id, version, index }) => { { - os.open(version.zipUrl, { - target: "_blank", - features: { - color: theme.palette.primary.main, - }, - }); + const lasSeg = new URL(version.zipUrl).pathname.split("/").pop(); + const dlPath = Environment.getPublicDir(Environment.DIRECTORY_DOWNLOADS) + "/" + lasSeg; + startDL(version.zipUrl, dlPath); }} edge="end" aria-label="download" @@ -126,6 +133,9 @@ const VersionItem = React.memo(({ id, version, index }) => { } secondary={ts} /> + {progress !== 0 && ( + + )} ); }); diff --git a/src/components/AvatarWithProgress.tsx b/src/components/AvatarWithProgress.tsx new file mode 100644 index 00000000..15a551cc --- /dev/null +++ b/src/components/AvatarWithProgress.tsx @@ -0,0 +1,75 @@ +import { Avatar, Box, CircularProgress, SxProps, Typography, TypographyProps } from "@mui/material"; +import React from "react"; + +interface AvatarWithProgressProps extends React.PropsWithChildren { + value: number; + src?: string; + sx?: SxProps; + alt?: string; + progressTextVariant?: TypographyProps["variant"]; +} + +const AvatarWithProgress = (props: AvatarWithProgressProps) => { + const isActive = React.useMemo(() => props.value > 0, [props.value]); + + return ( + + + {isActive && ( + <> + ({ + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: theme.palette.background.paper, + opacity: isActive ? 0.6 : 0, + zIndex: 0, + // @ts-ignore + borderRadius: props.sx.borderRadius, + })} + /> + + + {`${Math.round(props.value)}%`} + + )} + + ); +}; + +export { AvatarWithProgress }; diff --git a/src/hooks/useDownloadModule.ts b/src/hooks/useDownloadModule.ts new file mode 100644 index 00000000..1f35e805 --- /dev/null +++ b/src/hooks/useDownloadModule.ts @@ -0,0 +1,47 @@ +import React from "react"; +import { useStrings } from "./useStrings"; +import { useConfirm } from "material-ui-confirm"; +import { os } from "@Native/Os"; +import { Download } from "@Native/Download"; + +const useDownloadModule = (): [(url?: string, dest?: string) => void, number] => { + const { strings } = useStrings(); + const konfirm = useConfirm(); + + const [progress, setProgress] = React.useState(0); + + const start = (url?: string, dest?: string) => { + if (!url || !dest) return; + + const dl = new Download(url, dest); + + dl.onChange = (obj) => { + switch (obj.type) { + case "downloading": + setProgress(obj.state); + break; + case "finished": + setProgress(0); + konfirm({ + title: strings("download"), + description: strings("file_downloaded", { path: dest }), + }) + .then(() => {}) + .catch(() => {}); + + break; + } + }; + + dl.onError = (err) => { + setProgress(0); + os.toast(err, Toast.LENGTH_SHORT); + }; + + dl.start(); + }; + + return [start, progress]; +}; + +export { useDownloadModule }; diff --git a/src/native/Download.ts b/src/native/Download.ts index c4aa4454..14de8205 100644 --- a/src/native/Download.ts +++ b/src/native/Download.ts @@ -1,4 +1,5 @@ import { Native } from "./Native"; +import { os } from "./Os"; type DownloadState = { type: "downloading"; state: number } | { type: "finished"; state: null }; @@ -43,6 +44,8 @@ class Download extends Native { onChange: this._onChange, onError: this._onError, }); + } else { + os.openURL(this._url, "_blank"); } } } diff --git a/src/native/Environment.ts b/src/native/Environment.ts index 611e61d9..0622e970 100644 --- a/src/native/Environment.ts +++ b/src/native/Environment.ts @@ -30,19 +30,31 @@ class EnvironmentClass extends Native { public readonly DIRECTORY_RECORDINGS: string = "Recordings"; public getExternalStorageDir(): string { - return this.interface.getExternalStorageDir(); + if (this.isAndroid) { + return this.interface.getExternalStorageDir(); + } + return ""; } public getPackageDataDir(): string { - return this.interface.getPackageDataDir(); + if (this.isAndroid) { + return this.interface.getPackageDataDir(); + } + return ""; } public getPublicDir(type: string): string { - return this.interface.getPublicDir(type); + if (this.isAndroid) { + return this.interface.getPublicDir(type); + } + return ""; } public getDataDir(): string { - return this.interface.getDataDir(); + if (this.isAndroid) { + return this.interface.getDataDir(); + } + return ""; } } diff --git a/src/native/IsolatedEval/index.ts b/src/native/IsolatedEval/index.ts index 259bd0b7..0e0f8f3b 100644 --- a/src/native/IsolatedEval/index.ts +++ b/src/native/IsolatedEval/index.ts @@ -72,6 +72,10 @@ class IsolatedEval { Build: Build, Native: Native, React: React, + setInterval: setInterval, + clearInterval: clearInterval, + clearTimeout: clearTimeout, + setTimeout: setTimeout, eval() { throw new IsolatedFunctionBlockError("eval()"); },