update
parent
473d3e55c7
commit
be3da0a45d
|
@ -94,6 +94,6 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.receiveInputClose {
|
.receiveInputClose {
|
||||||
position: absolute;
|
position: absolute !important;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@ function CountriesInput(props: {
|
||||||
let [countriesList, setCountriesList] = useState([] as Country[]);
|
let [countriesList, setCountriesList] = useState([] as Country[]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Telegram.call("help.getCountriesList").then((result: any) => {
|
Telegram.call("help.getCountriesList", undefined, undefined, true).then(
|
||||||
console.log("country:", result);
|
(result: any) => {
|
||||||
let resp: Country[] = [];
|
let resp: Country[] = [];
|
||||||
result.countries.map((country: any) => {
|
result.countries.map((country: any) => {
|
||||||
resp.push({
|
resp.push({
|
||||||
|
@ -31,7 +31,8 @@ function CountriesInput(props: {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
setCountriesList(resp);
|
setCountriesList(resp);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,2 +1,9 @@
|
||||||
declare module "mtproton/envs/browser";
|
declare module "mtproton/envs/browser";
|
||||||
declare module "mtproton/src/utils/common";
|
declare module "mtproton/src/utils/common";
|
||||||
|
declare module "mtproton/src/index";
|
||||||
|
declare module "mtproton/envs/browser/sha1";
|
||||||
|
declare module "mtproton/envs/browser/sha256";
|
||||||
|
declare module "mtproton/envs/browser/pbkdf2";
|
||||||
|
declare module "mtproton/envs/browser/transport";
|
||||||
|
declare module "mtproton/envs/browser/get-random-bytes";
|
||||||
|
declare module "mtproton/envs/browser/get-local-storage";
|
||||||
|
|
|
@ -4,15 +4,19 @@ import reportWebVitals from "./reportWebVitals";
|
||||||
import Dashboard from "./pages/dashboard";
|
import Dashboard from "./pages/dashboard";
|
||||||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||||
import Home from "./pages/home";
|
import Home from "./pages/home";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import store from "./store";
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
<Provider store={store}>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
<Route path="/dashboard" element={<Dashboard />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
</Provider>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById("root")
|
document.getElementById("root")
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,31 @@
|
||||||
import style from "./style.module.css";
|
import style from "./style.module.css";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
Divider,
|
||||||
|
IconButton,
|
||||||
|
Menu,
|
||||||
|
MenuItem,
|
||||||
|
Paper,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
} from "@mui/material";
|
||||||
|
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
|
||||||
|
|
||||||
|
enum ContentType {
|
||||||
|
File,
|
||||||
|
Share,
|
||||||
|
SafeBox,
|
||||||
|
Recycled,
|
||||||
|
}
|
||||||
|
|
||||||
function Login() {
|
function Login() {
|
||||||
|
let [type, setType] = useState(ContentType.File);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
@ -11,17 +36,100 @@ function Login() {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={style.menu}>
|
<div className={style.menu}>
|
||||||
<li>文件</li>
|
<li onClick={() => setType(ContentType.File)}>文件</li>
|
||||||
<li>分享</li>
|
<li onClick={() => setType(ContentType.Share)}>分享</li>
|
||||||
<li>保险箱</li>
|
<li onClick={() => setType(ContentType.SafeBox)}>保险箱</li>
|
||||||
<li>回收站</li>
|
<li onClick={() => setType(ContentType.Recycled)}>回收站</li>
|
||||||
<Link to={`/`}>
|
<Link to={`/`}>
|
||||||
<div className={style.logo}>LOGO</div>
|
<div className={style.logo}>LOGO</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div></div>
|
<div className={style.content}>
|
||||||
|
{type === ContentType.File && <File />}
|
||||||
|
{type === ContentType.Share && <Share />}
|
||||||
|
{type === ContentType.SafeBox && <SafeBox />}
|
||||||
|
{type === ContentType.Recycled && <Recycled />}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function File() {
|
||||||
|
let [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||||
|
const open = Boolean(anchorEl);
|
||||||
|
|
||||||
|
let handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
let handleClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Paper sx={{ padding: "100px", width: "100%" }}>
|
||||||
|
<TableContainer sx={{ backgroundColor: "#f2f2f2" }}>
|
||||||
|
<Table aria-label={"文件列表"}>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell sx={{ width: "70%" }}>名称</TableCell>
|
||||||
|
<TableCell>修改时间</TableCell>
|
||||||
|
<TableCell>大小</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell sx={{ position: "relative" }}>
|
||||||
|
xxx
|
||||||
|
<IconButton
|
||||||
|
sx={{ position: "absolute", right: 20 }}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<MoreHorizIcon />
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>2020-01-01 12:12:12</TableCell>
|
||||||
|
<TableCell>128MB</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Paper>
|
||||||
|
<Menu
|
||||||
|
open={open}
|
||||||
|
id="basic-menu"
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
onClose={handleClose}
|
||||||
|
>
|
||||||
|
<MenuItem onClick={handleClose}>下载</MenuItem>
|
||||||
|
<MenuItem onClick={handleClose}>分享</MenuItem>
|
||||||
|
<Divider />
|
||||||
|
<MenuItem onClick={handleClose}>重命名</MenuItem>
|
||||||
|
<MenuItem onClick={handleClose}>移动</MenuItem>
|
||||||
|
<MenuItem onClick={handleClose}>移至保险箱</MenuItem>
|
||||||
|
<MenuItem onClick={handleClose}>查看详细信息</MenuItem>
|
||||||
|
<MenuItem onClick={handleClose}>删除</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Share() {
|
||||||
|
return <div>分享</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SafeBox() {
|
||||||
|
return <div>保险箱</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Recycled() {
|
||||||
|
return <div>回收站</div>;
|
||||||
|
}
|
||||||
|
|
||||||
export default Login;
|
export default Login;
|
||||||
|
|
|
@ -32,3 +32,10 @@
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
|
@ -5,16 +5,23 @@ import style from "./style.module.css";
|
||||||
import { Box, Drawer } from "@mui/material";
|
import { Box, Drawer } from "@mui/material";
|
||||||
import { HomeMenu } from "../../component/homeMenu";
|
import { HomeMenu } from "../../component/homeMenu";
|
||||||
import { HomeSignIn } from "../../component/homeSignIn";
|
import { HomeSignIn } from "../../component/homeSignIn";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { useSelectorIsLoggedIn, useSelectorUser } from "../../store/user";
|
||||||
|
import { login } from "../../store/user";
|
||||||
|
|
||||||
function Home() {
|
function Home() {
|
||||||
let [isSignIn, setIsSignIn] = useState(false);
|
// let [isSignIn, setIsSignIn] = useState(false);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
let isSignIn = useSelectorIsLoggedIn();
|
||||||
let [isOpenSignIn, setIsOpenSignIn] = useState(false);
|
let [isOpenSignIn, setIsOpenSignIn] = useState(false);
|
||||||
|
let user = useSelectorUser();
|
||||||
|
|
||||||
useEffect(function () {
|
useEffect(
|
||||||
|
function () {
|
||||||
getMe()
|
getMe()
|
||||||
.then(function (user) {
|
.then(function (user) {
|
||||||
// 已登录
|
// 已登录
|
||||||
setIsSignIn(true);
|
dispatch(login(user));
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
if (error.code === 401) {
|
if (error.code === 401) {
|
||||||
|
@ -22,7 +29,9 @@ function Home() {
|
||||||
}
|
}
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
}, []);
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.box}>
|
<div className={style.box}>
|
||||||
|
@ -34,7 +43,6 @@ function Home() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<HomeMenu
|
<HomeMenu
|
||||||
className={style.homeMenu}
|
className={style.homeMenu}
|
||||||
isSignIn={isSignIn}
|
isSignIn={isSignIn}
|
||||||
|
@ -42,7 +50,7 @@ function Home() {
|
||||||
setIsOpenSignIn(true);
|
setIsOpenSignIn(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{user.user && <div>{user.user.username}</div>}
|
||||||
<Drawer
|
<Drawer
|
||||||
anchor={"right"}
|
anchor={"right"}
|
||||||
open={isOpenSignIn && !isSignIn}
|
open={isOpenSignIn && !isSignIn}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
function getLocalStorage() {
|
||||||
|
return {
|
||||||
|
set(key: string, value: string) {
|
||||||
|
return window.localStorage.setItem(key, value);
|
||||||
|
},
|
||||||
|
|
||||||
|
get(key: string) {
|
||||||
|
return window.localStorage.getItem(key);
|
||||||
|
},
|
||||||
|
|
||||||
|
setObject(key: string, value: any) {
|
||||||
|
return window.localStorage.setItem(key, JSON.stringify(value));
|
||||||
|
},
|
||||||
|
|
||||||
|
getObject(key: string) {
|
||||||
|
return JSON.parse(window.localStorage.getItem(key)?.toString() || "{}");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getLocalStorage;
|
|
@ -1,7 +1,8 @@
|
||||||
import { configureStore } from "@reduxjs/toolkit";
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
import userReducer from "./store/user";
|
||||||
|
|
||||||
export default configureStore({
|
export default configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
user: (state) => {},
|
user: userReducer,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import storage from "../storage";
|
||||||
|
|
||||||
|
const FileList = createSlice({
|
||||||
|
name: "fileList",
|
||||||
|
initialState: {
|
||||||
|
fileList: [],
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
updateOfStorage: (state) => {
|
||||||
|
state.fileList = storage().getObject("fileList");
|
||||||
|
},
|
||||||
|
|
||||||
|
addFileOfStorage: (state, action) => {
|
||||||
|
// @ts-ignore
|
||||||
|
state.fileList.push(action.payload);
|
||||||
|
storage().setObject("fileList", state.fileList);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function useSelectorFileList() {
|
||||||
|
return useSelector((state: any) => state.fileList);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const { updateOfStorage } = FileList.actions;
|
||||||
|
|
||||||
|
export default FileList.reducer;
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
const User = createSlice({
|
||||||
|
name: "user",
|
||||||
|
initialState: {
|
||||||
|
isLoggedIn: false,
|
||||||
|
user: {},
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
login: (state, action) => {
|
||||||
|
state.isLoggedIn = true;
|
||||||
|
state.user = action.payload;
|
||||||
|
},
|
||||||
|
logout: (state) => {
|
||||||
|
state.isLoggedIn = false;
|
||||||
|
state.user = {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function useSelectorUser() {
|
||||||
|
return useSelector((state: any) => state.user.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSelectorIsLoggedIn() {
|
||||||
|
return useSelector((state: any) => state.user.isLoggedIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const { login, logout } = User.actions;
|
||||||
|
|
||||||
|
export default User.reducer;
|
|
@ -1,26 +1,59 @@
|
||||||
import Client from "mtproton/envs/browser";
|
import Client from "mtproton/envs/browser";
|
||||||
import { rand_id } from "../utils/rand";
|
import { rand_id } from "../utils/rand";
|
||||||
import { obj } from "../utils/log";
|
import { obj } from "../utils/log";
|
||||||
|
import makeMTProto from "mtproton/src/index";
|
||||||
|
import SHA1 from "mtproton/envs/browser/sha1";
|
||||||
|
import SHA256 from "mtproton/envs/browser/sha256";
|
||||||
|
import PBKDF2 from "mtproton/envs/browser/pbkdf2";
|
||||||
|
import Transport from "mtproton/envs/browser/transport";
|
||||||
|
import getRandomBytes from "mtproton/envs/browser/get-random-bytes";
|
||||||
|
import getLocalStorage from "mtproton/envs/browser/get-local-storage";
|
||||||
|
|
||||||
class TelegramHelper {
|
class TelegramHelper {
|
||||||
private client: any;
|
private client: any;
|
||||||
constructor(appID: number, appHash: string) {
|
constructor(appID: number, appHash: string, custom: boolean = false) {
|
||||||
|
if (custom) {
|
||||||
this.client = new Client({
|
this.client = new Client({
|
||||||
api_id: appID,
|
api_id: appID,
|
||||||
api_hash: appHash,
|
api_hash: appHash,
|
||||||
test: true,
|
test: true,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
let createTransport = function (dc: any, crypto: any) {
|
||||||
|
return new Transport(dc, crypto);
|
||||||
|
};
|
||||||
|
|
||||||
|
const MTProto = makeMTProto({
|
||||||
|
SHA1,
|
||||||
|
SHA256,
|
||||||
|
PBKDF2,
|
||||||
|
getRandomBytes,
|
||||||
|
getLocalStorage,
|
||||||
|
createTransport,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.client = new MTProto({
|
||||||
|
api_id: appID,
|
||||||
|
api_hash: appHash,
|
||||||
|
test: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
this.client.setDefaultDc(1);
|
this.client.setDefaultDc(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
async call(method: string, params?: object, options?: object): Promise<any> {
|
async call(
|
||||||
|
method: string,
|
||||||
|
params?: object,
|
||||||
|
options?: object,
|
||||||
|
hideLog: boolean = false
|
||||||
|
): Promise<any> {
|
||||||
try {
|
try {
|
||||||
console.dir(`${method} req\n${obj(params)}`);
|
!hideLog && console.dir(`${method} req\n${obj(params)}`);
|
||||||
let resp = await this.client.call(method, params, options);
|
let resp = await this.client.call(method, params, options);
|
||||||
console.dir(`${method} resp\n${obj(resp)}`);
|
!hideLog && console.dir(`${method} resp\n${obj(resp)}`);
|
||||||
return resp;
|
return resp;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`${method} error:`, error);
|
!hideLog && console.log(`${method} error:`, error);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { error_code, error_message } = error;
|
const { error_code, error_message } = error;
|
||||||
|
|
Loading…
Reference in New Issue