Skip to content

Commit

Permalink
feat: video list.
Browse files Browse the repository at this point in the history
  • Loading branch information
caorushizi committed Jan 12, 2024
1 parent 2d4e9d7 commit 48158eb
Show file tree
Hide file tree
Showing 16 changed files with 2,983 additions and 3,056 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"license": "MIT",
"pnpm": {
"patchedDependencies": {
"@cliqz/[email protected].6": "patches/@[email protected].6.patch"
"@cliqz/[email protected].15": "patches/@[email protected].15.patch"
}
},
"devDependencies": {
Expand Down
18 changes: 17 additions & 1 deletion packages/main/src/controller/DownloadController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import MainWindow from "../windows/MainWindow";
import StoreService from "../services/StoreService";
import DownloadService from "../services/DownloadService";
import VideoRepository from "../repository/VideoRepository";
import { existsSync } from "fs-extra";

@injectable()
export default class DownloadController implements Controller {
Expand Down Expand Up @@ -61,7 +62,22 @@ export default class DownloadController implements Controller {

@handle("get-download-items")
async getDownloadItems(e: IpcMainEvent, pagination: DownloadItemPagination) {
return await this.videoRepository.findVideos(pagination);
const localDir = this.storeService.get("local");
const videos = await this.videoRepository.findVideos(pagination);
const newVideos = videos.list.map((video) => {
if (video.status === DownloadStatus.Success) {
return {
...video,
exist: existsSync(`${localDir}/${video.name}`),
};
}
return video;
});

return {
total: videos.total,
list: newVideos,
};
}

@handle("start-download")
Expand Down
2 changes: 1 addition & 1 deletion packages/renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@ant-design/pro-components": "^2.6.2",
"@reduxjs/toolkit": "^1.9.5",
"ahooks": "^3.7.7",
"antd": "^5.6.2",
"antd": "^5.12.8",
"axios": "^1.4.0",
"classnames": "^2.3.2",
"dayjs": "^1.11.8",
Expand Down
42 changes: 26 additions & 16 deletions packages/renderer/src/App.scss
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
.container {
html,
body {
height: 100vh;
width: 100vw;
overflow: hidden;
.container-sider {
.like-item {
display: flex;
flex-direction: row;
align-items: center;
}
}

#root {
height: 100vh;
width: 100vw;
}

@mixin scrollbar() {
&::-webkit-scrollbar {
height: 8px;
width: 8px;
}

&::-webkit-scrollbar-track {
background: transparent;
}
.container-footer {
padding: 5px;
background: #fff;
text-align: right;
border-top: #f0f0f0 solid 1px;

&::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.15);
}
@media (prefers-color-scheme: dark) {
.container-footer {
background: #141414;
border-top: #313131 solid 1px;
&::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.15);
}
}
}

* {
@include scrollbar();
}
204 changes: 77 additions & 127 deletions packages/renderer/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,144 +1,94 @@
import React, { FC, useState } from "react";
import { Link, Outlet, useLocation, useNavigate } from "react-router-dom";
import { Badge, Button, Layout, Menu, MenuProps } from "antd";
import { ConfigProvider, theme } from "antd";
import "antd/dist/reset.css";
import React, { FC, useEffect } from "react";
import { useDispatch } from "react-redux";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import AppLayout from "./layout/App";
import HomePage, { DownloadFilter } from "./nodes/HomePage";
import SettingPage from "./nodes/SettingPage";
import PlayerPage from "./nodes/PlayerPage";
import SourceExtract from "./nodes/SourceExtract";
import { setAppStore, increase } from "./store";
import "dayjs/locale/zh-cn";
import zhCN from "antd/locale/zh_CN";
import "./App.scss";
import {
DownloadOutlined,
ExportOutlined,
ProfileOutlined,
QuestionCircleOutlined,
SettingOutlined,
} from "@ant-design/icons";
import useElectron from "./hooks/electron";
import { useDispatch, useSelector } from "react-redux";
import { selectAppStore, setAppStore, clearCount, selectCount } from "./store";
import { useAsyncEffect } from "ahooks";
import { tdApp } from "./utils";

const { Footer, Sider, Content } = Layout;

type MenuItem = Required<MenuProps>["items"][number];
function getAlgorithm(appTheme: "dark" | "light") {
return appTheme === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm;
}

const App: FC = () => {
const {
getAppStore: ipcGetAppStore,
openUrl,
setAppStore: ipcSetAppStore,
showBrowserWindow,
} = useElectron();
const location = useLocation();
const navigate = useNavigate();
const dispatch = useDispatch();
const [showExport, setShowExport] = useState(false);
const count = useSelector(selectCount);
const appStore = useSelector(selectAppStore);

const items: MenuItem[] = [
{
label: (
<Link
to="/"
className="like-item"
onClick={() => {
dispatch(clearCount());
}}
>
<DownloadOutlined />
<span>下载列表</span>
{count > 0 && (
<Badge count={count} offset={[5, 1]} size="small"></Badge>
)}
</Link>
),
key: "home",
},
{
label: (
<Link to="/source-extract" className="like-item">
<ProfileOutlined />
<span>素材提取</span>
{showExport && (
<Button
title="在新窗口中打开"
type="text"
style={{ marginLeft: "auto" }}
icon={<ExportOutlined />}
onClick={async (e) => {
e.stopPropagation();
e.preventDefault();
const [appTheme, setAppTheme] = React.useState<"dark" | "light">("light");
const { addIpcListener, removeIpcListener } = useElectron();

dispatch(setAppStore({ openInNewWindow: true }));
if (location.pathname === "/source-extract") {
navigate("/");
}
// FIXME: 有可能 webview 还没有完全隐藏
await ipcSetAppStore("openInNewWindow", true);
await showBrowserWindow();
}}
/>
)}
</Link>
),
key: "source",
onMouseEnter: () => {
setShowExport(true);
},
onMouseLeave: () => {
setShowExport(false);
},
},
{
label: (
<Link to="/settings" className="like-item">
<SettingOutlined />
<span>设置</span>
</Link>
),
key: "settings",
},
];
const themeChange = (event: MediaQueryListEvent) => {
if (event.matches) {
setAppTheme("dark");
} else {
setAppTheme("light");
}
};

const finalItems = items.filter((item) =>
appStore.openInNewWindow ? item?.key !== "source" : true
);
// 监听store变化
const onAppStoreChange = (event: any, store: AppStore) => {
dispatch(setAppStore(store));
};

const openHelpUrl = () => {
tdApp.openHelpPage();
const url = "https://downloader.caorushizi.cn/guides.html?form=client";
openUrl(url);
const onReceiveDownloadItem = () => {
console.log("onReceiveDownloadItem");
dispatch(increase());
};

useAsyncEffect(async () => {
const store = await ipcGetAppStore();
dispatch(setAppStore(store));
useEffect(() => {
addIpcListener("store-change", onAppStoreChange);
addIpcListener("download-item-notifier", onReceiveDownloadItem);

return () => {
removeIpcListener("store-change", onAppStoreChange);
removeIpcListener("download-item-notifier", onReceiveDownloadItem);
};
}, []);

useEffect(() => {
const isDarkTheme = matchMedia("(prefers-color-scheme: dark)");
isDarkTheme.addEventListener("change", themeChange);

if (isDarkTheme.matches) {
setAppTheme("dark");
} else {
setAppTheme("light");
}

return () => {
isDarkTheme.removeEventListener("change", themeChange);
};
}, []);

return (
<Layout className="container">
<Sider className="container-sider" theme="light">
<Menu
style={{ height: "100%" }}
defaultSelectedKeys={["home"]}
mode="vertical"
theme="light"
items={finalItems}
/>
</Sider>
<Layout>
<Content className="container-inner">
<Outlet />
</Content>
<Footer className="container-footer">
<Button
type={"link"}
onClick={openHelpUrl}
icon={<QuestionCircleOutlined />}
>
使用帮助
</Button>
</Footer>
</Layout>
</Layout>
<ConfigProvider
locale={zhCN}
componentSize="small"
theme={{ algorithm: getAlgorithm(appTheme) }}
>
<BrowserRouter>
<Routes>
<Route path="/" element={<AppLayout />}>
<Route index element={<HomePage />} />
<Route
path="done"
element={<HomePage filter={DownloadFilter.done} />}
/>
<Route path="source" element={<SourceExtract />} />
<Route path="settings" element={<SettingPage />} />
<Route path="*" element={<div>404</div>} />
</Route>
<Route path="/browser" element={<SourceExtract page={true} />} />
<Route path="/player" element={<PlayerPage />} />
</Routes>
</BrowserRouter>
</ConfigProvider>
);
};

Expand Down
6 changes: 4 additions & 2 deletions packages/renderer/src/components/DownloadForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ const DownloadFrom: FC<DownloadFormProps> = ({
}}
modalProps={{
destroyOnClose: true,
bodyStyle: {
paddingTop: 5,
styles: {
body: {
paddingTop: 5,
},
},
}}
submitTimeout={2000}
Expand Down
34 changes: 0 additions & 34 deletions packages/renderer/src/index.scss

This file was deleted.

24 changes: 24 additions & 0 deletions packages/renderer/src/layout/App/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.container {
height: 100vh;
width: 100vw;
overflow: hidden;
.container-sider {
.like-item {
display: flex;
flex-direction: row;
align-items: center;
}
}
.container-footer {
padding: 5px;
background: #fff;
text-align: right;
border-top: #f0f0f0 solid 1px;
}
@media (prefers-color-scheme: dark) {
.container-footer {
background: #141414;
border-top: #313131 solid 1px;
}
}
}
Loading

0 comments on commit 48158eb

Please sign in to comment.