demo compile
parent
78b2b4b753
commit
26cb0eaef1
File diff suppressed because it is too large
Load Diff
37
src/App.tsx
37
src/App.tsx
|
@ -9,10 +9,15 @@ import {
|
|||
TextField,
|
||||
} from "@mui/material";
|
||||
import CountriesInput, { Country } from "./component/countriesInput";
|
||||
import Telegram, { uploadBigFile } from "./telegram";
|
||||
import Telegram, {
|
||||
inputFile,
|
||||
uploadBigFile,
|
||||
sendFile,
|
||||
downloadFile,
|
||||
} from "./telegram";
|
||||
import SendIcon from "@mui/icons-material/Send";
|
||||
import { User } from "./user";
|
||||
import { Upload } from "@mui/icons-material";
|
||||
import { Download, Upload } from "@mui/icons-material";
|
||||
import ab2str from "./utils/arraybuffer2str";
|
||||
|
||||
function App() {
|
||||
|
@ -21,6 +26,7 @@ function App() {
|
|||
let [phoneCodeHash, setPhoneCodeHash] = useState("");
|
||||
let [country, setCountry] = useState({} as Country | null);
|
||||
let [user, setUser] = useState({} as User);
|
||||
let [fileDocument, setFileDocument] = useState({} as any);
|
||||
const [fileList, setFileList] = useState([]);
|
||||
|
||||
let sendCode = () => {
|
||||
|
@ -62,7 +68,6 @@ function App() {
|
|||
Telegram.call("messages.sendMessage", {
|
||||
peer: {
|
||||
_: "inputPeerSelf",
|
||||
user_id: user.id,
|
||||
},
|
||||
message: "ice",
|
||||
random_id: (10000 + Math.random() * (100000 - 10000))
|
||||
|
@ -81,7 +86,18 @@ function App() {
|
|||
console.log("uploadFile:", fileList);
|
||||
// @ts-ignore
|
||||
uploadBigFile(fileList[0]?.bytes)
|
||||
.then((file_id) => console.log("uploadFile ret:", file_id))
|
||||
.then((file) => {
|
||||
console.log("uploadFile ret:", file);
|
||||
sendFile(
|
||||
// @ts-ignore
|
||||
inputFile(file.file_id, file.total_part, fileList[0].name),
|
||||
// @ts-ignore
|
||||
fileList[0].type
|
||||
).then((result) => {
|
||||
console.log("sendFile ret:", result);
|
||||
setFileDocument(result.updates[1].message.media);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("uploadFile error:", error);
|
||||
alert(error);
|
||||
|
@ -93,7 +109,7 @@ function App() {
|
|||
const reader = new FileReader();
|
||||
reader.onload = function (event) {
|
||||
if (event.target && event.target.result) {
|
||||
let bytes = ab2str(event.target.result as ArrayBuffer);
|
||||
let bytes = event.target.result;
|
||||
console.log(bytes);
|
||||
e.target.files[0].bytes = bytes;
|
||||
setFileList(e.target.files);
|
||||
|
@ -102,6 +118,14 @@ function App() {
|
|||
reader.readAsArrayBuffer(e.target.files[0]);
|
||||
};
|
||||
|
||||
let download = () => {
|
||||
console.log("download:", fileDocument);
|
||||
downloadFile(fileDocument).catch((error) => {
|
||||
console.log("download error:", error);
|
||||
alert(error);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Container maxWidth="sm">
|
||||
<Paper
|
||||
|
@ -160,6 +184,9 @@ function App() {
|
|||
<Button variant={"contained"} onClick={uploadFile} endIcon={<Upload />}>
|
||||
上传
|
||||
</Button>
|
||||
<Button variant={"contained"} onClick={download} endIcon={<Download />}>
|
||||
下载
|
||||
</Button>
|
||||
</Paper>
|
||||
</Container>
|
||||
);
|
||||
|
|
|
@ -54,7 +54,7 @@ function CountriesInput(props: {
|
|||
})}
|
||||
sx={{ width: 300 }}
|
||||
onChange={(_event, value) => {
|
||||
props.onChange(value);
|
||||
props.onChange(value as Country);
|
||||
}}
|
||||
getOptionLabel={(option) => option.default_name}
|
||||
renderOption={(props, option) => (
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
declare module "mtproton/envs/browser";
|
||||
declare module "mtproton/src/utils/common";
|
||||
|
|
163
src/telegram.ts
163
src/telegram.ts
|
@ -1,6 +1,5 @@
|
|||
import Client from "mtproton/envs/browser";
|
||||
import between from "./utils/rand";
|
||||
import exp from "constants";
|
||||
|
||||
class TelegramHelper {
|
||||
private client: any;
|
||||
|
@ -8,12 +7,12 @@ class TelegramHelper {
|
|||
this.client = new Client({
|
||||
api_id: appID,
|
||||
api_hash: appHash,
|
||||
test: true,
|
||||
test: false,
|
||||
});
|
||||
this.client.setDefaultDc(1);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
async call(method: string, params?: object, options?: object) {
|
||||
async call(method: string, params?: object, options?: object): Promise<any> {
|
||||
try {
|
||||
return await this.client.call(method, params, options);
|
||||
} catch (error) {
|
||||
|
@ -36,34 +35,42 @@ class TelegramHelper {
|
|||
|
||||
const dcId = Number(dcIdAsString);
|
||||
|
||||
if (type === "PHONE") {
|
||||
await this.client.setDefaultDc(dcId);
|
||||
} else {
|
||||
Object.assign(options, { dcId });
|
||||
}
|
||||
// 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: string): Promise<number> {
|
||||
async function uploadBigFile(
|
||||
bytes: ArrayBuffer
|
||||
): Promise<{ file_id: number; total_part: number }> {
|
||||
let file_id = between(10000, 99999);
|
||||
console.log("file_id", file_id);
|
||||
|
||||
const file_total_parts = Math.ceil(bytes.length / 524288);
|
||||
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: bytes.slice(i * 524288, (i + 1) * 524288),
|
||||
bytes: tempBytes,
|
||||
});
|
||||
if (finished) {
|
||||
console.log("finished");
|
||||
|
@ -76,12 +83,138 @@ async function uploadBigFile(bytes: string): Promise<number> {
|
|||
}
|
||||
|
||||
console.log("uploaded");
|
||||
return file_id;
|
||||
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 = between(10000, 99999);
|
||||
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: between(10000, 99999),
|
||||
message: "test",
|
||||
});
|
||||
}
|
||||
|
||||
async function downloadFile(fileDocument: any) {
|
||||
let partSize = 1024 * 1024;
|
||||
const file_total_parts = Math.ceil(fileDocument.document.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.document.id,
|
||||
access_hash: fileDocument.document.access_hash,
|
||||
file_reference: fileDocument.document.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.document.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.document.mime_type,
|
||||
});
|
||||
let url = window.URL.createObjectURL(blob);
|
||||
let a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = fileDocument.document.attributes[0].file_name;
|
||||
a.click();
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
const appID = 18987971;
|
||||
const appHash = "fcfd9e6ed3f9e48a360bb57cc0d59d98";
|
||||
let Telegram = new TelegramHelper(appID, appHash);
|
||||
|
||||
function hexStringToArrayBuffer(hexString: string) {
|
||||
// remove the leading 0x
|
||||
hexString = hexString.replace(/^0x/, "");
|
||||
|
||||
// ensure even number of characters
|
||||
if (hexString.length % 2 != 0) {
|
||||
console.log(
|
||||
"WARNING: expecting an even number of characters in the hexString"
|
||||
);
|
||||
}
|
||||
|
||||
// check for some non-hex characters
|
||||
let bad = hexString.match(/[G-Z\s]/i);
|
||||
if (bad) {
|
||||
console.log("WARNING: found non-hex characters", bad);
|
||||
}
|
||||
|
||||
// split the string into pairs of octets
|
||||
let pairs = hexString.match(/[\dA-F]{2}/gi);
|
||||
|
||||
// convert the octets to integers
|
||||
// @ts-ignore
|
||||
let integers = pairs.map(function (s: string) {
|
||||
return parseInt(s, 16);
|
||||
});
|
||||
|
||||
let array = new Uint8Array(integers);
|
||||
console.log(array);
|
||||
|
||||
return array.buffer;
|
||||
}
|
||||
|
||||
function arrayBufferToHex(arrayBuffer: ArrayBuffer) {
|
||||
if (typeof arrayBuffer !== "object" || arrayBuffer === null) {
|
||||
throw new TypeError("Expected input to be an ArrayBuffer");
|
||||
}
|
||||
|
||||
let view = new Uint8Array(arrayBuffer);
|
||||
let result = "";
|
||||
let value;
|
||||
|
||||
for (let i = 0; i < view.length; i++) {
|
||||
value = view[i].toString(16);
|
||||
result += value.length === 1 ? "0" + value : value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export default Telegram;
|
||||
export { uploadBigFile };
|
||||
export { uploadBigFile, inputFile, sendFile, downloadFile };
|
||||
|
|
|
@ -5,4 +5,16 @@ function ArraybufferToStr(buffer: ArrayBuffer) {
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue