master
icechen 2022-03-11 04:39:30 +08:00
parent 85b3a01805
commit a80d8c68d8
17 changed files with 1195 additions and 169 deletions

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title> <title>fileset</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@ -1,21 +1,34 @@
{ {
"name": "tbeg-web", "name": "tbeg-web",
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.1",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc && vite build", "build": "tsc && vite build",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@reduxjs/toolkit": "^1.8.0",
"autoprefixer": "^10.4.2",
"axios": "^0.26.1",
"filesize": "^8.0.7",
"mtproton": "^6.0.0",
"postcss": "^8.4.8",
"prettier-plugin-tailwindcss": "^0.1.8",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2" "react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.2.2",
"redux": "^4.1.2",
"tailwindcss": "^3.0.23"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^17.0.33", "@redux-devtools/core": "^3.11.0",
"@types/react-dom": "^17.0.10", "@types/react": "^17.0.40",
"@vitejs/plugin-react": "^1.0.7", "@types/react-dom": "^17.0.13",
"typescript": "^4.5.4", "@vitejs/plugin-react": "^1.2.0",
"vite": "^2.8.0" "prettier": "^2.5.1",
"typescript": "^4.6.2",
"vite": "^2.8.6"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
module.exports = {
plugins: [require("prettier-plugin-tailwindcss")],
};

View File

@ -1,42 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
button {
font-size: calc(10px + 2vmin);
}

View File

@ -1,45 +1,16 @@
import { useState } from 'react' import { BrowserRouter, Route, Routes } from "react-router-dom";
import logo from './logo.svg' import Home from "./pages/home";
import './App.css' import Dashboard from "./pages/dashboard";
function App() { function App() {
const [count, setCount] = useState(0)
return ( return (
<div className="App"> <BrowserRouter>
<header className="App-header"> <Routes>
<img src={logo} className="App-logo" alt="logo" /> <Route path="/" element={<Home />} />
<p>Hello Vite + React!</p> <Route path="/dashboard" element={<Dashboard />} />
<p> </Routes>
<button type="button" onClick={() => setCount((count) => count + 1)}> </BrowserRouter>
count is: {count} );
</button>
</p>
<p>
Edit <code>App.tsx</code> and save to test HMR updates.
</p>
<p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{' | '}
<a
className="App-link"
href="https://vitejs.dev/guide/features.html"
target="_blank"
rel="noopener noreferrer"
>
Vite Docs
</a>
</p>
</header>
</div>
)
} }
export default App export default App;

View File

@ -1,15 +0,0 @@
<svg width="410" height="404" viewBox="0 0 410 404" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M399.641 59.5246L215.643 388.545C211.844 395.338 202.084 395.378 198.228 388.618L10.5817 59.5563C6.38087 52.1896 12.6802 43.2665 21.0281 44.7586L205.223 77.6824C206.398 77.8924 207.601 77.8904 208.776 77.6763L389.119 44.8058C397.439 43.2894 403.768 52.1434 399.641 59.5246Z" fill="url(#paint0_linear)"/>
<path d="M292.965 1.5744L156.801 28.2552C154.563 28.6937 152.906 30.5903 152.771 32.8664L144.395 174.33C144.198 177.662 147.258 180.248 150.51 179.498L188.42 170.749C191.967 169.931 195.172 173.055 194.443 176.622L183.18 231.775C182.422 235.487 185.907 238.661 189.532 237.56L212.947 230.446C216.577 229.344 220.065 232.527 219.297 236.242L201.398 322.875C200.278 328.294 207.486 331.249 210.492 326.603L212.5 323.5L323.454 102.072C325.312 98.3645 322.108 94.137 318.036 94.9228L279.014 102.454C275.347 103.161 272.227 99.746 273.262 96.1583L298.731 7.86689C299.767 4.27314 296.636 0.855181 292.965 1.5744Z" fill="url(#paint1_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="6.00017" y1="32.9999" x2="235" y2="344" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="194.651" y1="8.81818" x2="236.076" y2="292.989" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

9
src/global.d.ts vendored 100644
View File

@ -0,0 +1,9 @@
declare module "mtproton/envs/browser";
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";

View File

@ -1,13 +1,7 @@
body { @tailwind base;
margin: 0; @tailwind components;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', @tailwind utilities;
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code { body {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', background-color: #eae4de;
monospace;
} }

View File

@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,3 @@
export default function Dashboard() {
return <div>Dashboard</div>;
}

View File

@ -0,0 +1,24 @@
export default function Home() {
return (
<div>
<div
className={
"m-4 box-border w-16 cursor-pointer select-none border border-4 border-red-900 text-center"
}
>
LOGO
</div>
<Menu></Menu>
</div>
);
}
function Menu() {
return (
<div className={"container absolute top-2 right-2 flex gap-2"}>
<div></div>
<div>/</div>
</div>
);
}

View File

@ -0,0 +1,244 @@
import Client from "mtproton/envs/browser";
import { rand_id } from "../utils/rand";
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 {
private client: any;
constructor(appID: number, appHash: string, custom: boolean = false) {
if (!custom) {
this.client = new Client({
api_id: appID,
api_hash: appHash,
test: false,
});
} 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(2);
}
async call(
method: string,
params?: object,
options?: object,
hideLog: boolean = false
): Promise<any> {
try {
!hideLog && console.log(`${method} req\n${params}`);
options = {
...options,
};
let resp = await this.client.call(method, params, options);
!hideLog && console.log(`${method} resp\n${resp}`);
return resp;
} catch (error) {
!hideLog && console.log(`${method} error:`, error);
// @ts-ignore
const { error_code, error_message } = error;
// if (error_code === 420) {
// const seconds = Number(error_message.split('FLOOD_WAIT_')[1]);
// const ms = seconds * 1000;
//
// await sleep(ms);
//
// return this.call(method, params, options);
// }
if (error_code === 303) {
const [, dcIdAsString] = error_message.split("_MIGRATE_");
const dcId = Number(dcIdAsString);
// if (type === "PHONE") {
await this.client.setDefaultDc(dcId);
// } else {
// Object.assign(options, { dcId });
// }
return this.call(method, params, options);
}
return Promise.reject(error);
}
}
}
async function uploadBigFile(
bytes: ArrayBuffer,
callback?: (ratio: number) => void
): Promise<{ file_id: number; total_part: number }> {
let file_id = rand_id();
console.log("file_id", file_id);
let uploadBytes = new Uint8Array(bytes);
console.log("uploading file", bytes);
const file_total_parts = Math.ceil(uploadBytes.length / 524288);
console.log("file_total_parts", file_total_parts);
for (let i = 0; i < file_total_parts; i++) {
console.log("push part: ", i);
try {
let tempBytes = uploadBytes.slice(i * 524288, (i + 1) * 524288);
if (i === file_total_parts - 1) {
tempBytes = uploadBytes.slice(i * 524288);
}
console.log("tempBytes", tempBytes);
let finished = await Telegram.call("upload.saveBigFilePart", {
file_id: file_id,
file_part: i,
file_total_parts: file_total_parts,
bytes: tempBytes,
});
console.log("finished", finished);
if (callback) {
callback(((i + 1) / file_total_parts) * 100);
}
} catch (error) {
return Promise.reject(error);
}
}
console.log("uploaded");
return { file_id: file_id, total_part: file_total_parts };
}
function inputFile(file_id: number, part_number: number, file_name: string) {
return {
_: "inputFileBig",
id: file_id,
parts: part_number,
name: file_name,
};
}
function sendFile(inputFile: any, type: string) {
let random_id = rand_id();
console.log("random_id", random_id);
return Telegram.call("messages.sendMedia", {
peer: {
_: "inputPeerSelf",
},
media: {
_: "inputMediaUploadedDocument",
file: inputFile,
mime_type: type,
attributes: [
{
_: "documentAttributeFilename",
file_name: inputFile.name,
},
],
},
random_id: rand_id(),
message: "test",
});
}
async function downloadFile(fileDocument: any) {
let partSize = 1024 * 1024;
const file_total_parts = Math.ceil(fileDocument.size / partSize);
let results = [];
for (let i = 0; i < file_total_parts; i++) {
try {
let result = await Telegram.call("upload.getFile", {
location: {
_: "inputDocumentFileLocation",
id: fileDocument.id,
access_hash: fileDocument.access_hash,
file_reference: fileDocument.file_reference,
thumb_size: "",
},
limit: partSize,
offset: partSize * i,
});
console.log("result", result);
results.push(result);
} catch (error) {
return Promise.reject(error);
}
}
console.log("messages.getDocument:", results);
let bytes = new Uint8Array(fileDocument.size);
for (let i = 0; i < results.length; i++) {
for (let j = 0; j < results[i].bytes.length; j++) {
bytes[i * partSize + j] = results[i].bytes[j];
}
}
let downloadBytes = bytes;
console.log("downloadBytes", downloadBytes);
let blob = new Blob([downloadBytes], {
type: fileDocument.mime_type,
});
let url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = fileDocument.file_name;
a.click();
return Promise.resolve(true);
}
async function sendSignInCode(phone: string): Promise<string> {
try {
let result = await Telegram.call("auth.sendCode", {
phone_number: phone,
settings: {
_: "codeSettings",
},
});
return Promise.resolve(result.phone_code_hash);
} catch (error: any) {
return Promise.reject(error);
}
}
async function signIn(phone: string, code: string, phone_code_hash: string) {
try {
let result = await Telegram.call("auth.signIn", {
phone_number: phone,
phone_code_hash: phone_code_hash,
phone_code: code,
});
return Promise.resolve(result);
} catch (error: any) {
return Promise.reject(error);
}
}
const appID = 18987971;
const appHash = "fcfd9e6ed3f9e48a360bb57cc0d59d98";
let Telegram = new TelegramHelper(appID, appHash);
export default Telegram;
export {
uploadBigFile,
inputFile,
sendFile,
downloadFile,
sendSignInCode,
signIn,
};

View File

@ -0,0 +1,9 @@
import Telegram from "./telegram";
async function getMe() {
return await Telegram.call("users.getFullUser", {
id: { _: "inputUserSelf" },
});
}
export { getMe };

View File

@ -0,0 +1,20 @@
function ArraybufferToStr(buffer: ArrayBuffer) {
let uint8 = new Uint8Array(buffer);
let decoder = new TextDecoder("utf8");
return decoder.decode(uint8);
}
// function ab2str(buf: ArrayBuffer) {
// return String.fromCharCode.apply(null, buf as Uint16Array);
// }
// function str2ab(str: string) {
// let buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
// let bufView = new Uint16Array(buf);
// for (let i = 0, strLen = str.length; i < strLen; i++) {
// bufView[i] = str.charCodeAt(i);
// }
// return buf;
// }
//
export default ArraybufferToStr;

12
src/utils/log.ts 100644
View File

@ -0,0 +1,12 @@
const maxToLog = 10240;
export function obj(obj: any): string {
if (!obj) {
return "null";
}
let s = JSON.stringify(obj, null, 2);
if (s.length > maxToLog) {
s = s.substr(0, maxToLog) + "...";
}
return s;
}

View File

@ -0,0 +1,9 @@
function between(min: number, max: number): number {
return Math.floor(Math.random() * (max - min) + min);
}
function rand_id(): number {
return between(100000, 999999);
}
export { between, rand_id };