Bump dependencies (#6358)
This commit is contained in:
parent
042193908b
commit
0a606739d1
@ -37,49 +37,107 @@
|
||||
"ignore": "paint-properties"
|
||||
}
|
||||
],
|
||||
"plugin/stylelint-group-selectors": [true, { "severity": "warning" }],
|
||||
"plugin/whole-pixel": [true, { "ignoreList": ["letter-spacing"] }],
|
||||
"plugin/stylelint-group-selectors": [
|
||||
true,
|
||||
{
|
||||
"severity": "warning"
|
||||
}
|
||||
],
|
||||
"plugin/whole-pixel": [
|
||||
true,
|
||||
{
|
||||
"ignoreList": [
|
||||
"letter-spacing"
|
||||
]
|
||||
}
|
||||
],
|
||||
"selector-pseudo-class-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignorePseudoClasses": ["global", "local"]
|
||||
"ignorePseudoClasses": [
|
||||
"global",
|
||||
"local"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-invalid-position-declaration": [
|
||||
true,
|
||||
{ "ignoreAtRules": ["mixin"] }
|
||||
],
|
||||
"nesting-selector-no-missing-scoping-root": [
|
||||
true,
|
||||
{ "ignoreAtRules": ["include", "mixin"] }
|
||||
],
|
||||
"plugin/selector-tag-no-without-class": [
|
||||
"/^(?!body|html)([^_-]*)$/",
|
||||
{
|
||||
"severity": "warning"
|
||||
}
|
||||
],
|
||||
"plugin/use-baseline": [
|
||||
true,
|
||||
{
|
||||
"severity": "warning",
|
||||
"ignoreSelectors": [
|
||||
"nesting",
|
||||
"dir",
|
||||
"selection",
|
||||
"view-transition",
|
||||
"view-transition-group",
|
||||
"view-transition-image-pair",
|
||||
"view-transition-old",
|
||||
"view-transition-new"
|
||||
],
|
||||
"ignoreProperties": {
|
||||
"property-name": [
|
||||
"text-wrap",
|
||||
"outline",
|
||||
"backdrop-filter",
|
||||
"user-select",
|
||||
"scrollbar-gutter",
|
||||
"scrollbar-width",
|
||||
"scrollbar-color",
|
||||
"box-decoration-break",
|
||||
"offset-anchor"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"plugin/selector-tag-no-without-class": ["/^(?!body|html)([^_-]*)$/", { "severity": "warning" }],
|
||||
"plugin/use-baseline": [true, {
|
||||
"severity": "warning",
|
||||
"ignoreSelectors": [
|
||||
"nesting",
|
||||
"dir",
|
||||
"selection",
|
||||
"view-transition",
|
||||
"view-transition-group",
|
||||
"view-transition-image-pair",
|
||||
"view-transition-old",
|
||||
"view-transition-new"
|
||||
],
|
||||
"ignoreProperties": [
|
||||
"text-wrap",
|
||||
"outline",
|
||||
"backdrop-filter",
|
||||
"user-select",
|
||||
"scrollbar-gutter",
|
||||
"scrollbar-width",
|
||||
"scrollbar-color",
|
||||
"box-decoration-break",
|
||||
"offset-anchor"
|
||||
]
|
||||
}],
|
||||
"@stylistic/number-leading-zero": "always",
|
||||
"@stylistic/string-quotes": null,
|
||||
"@stylistic/color-hex-case": null,
|
||||
"@stylistic/selector-list-comma-newline-after": null,
|
||||
"@stylistic/block-closing-brace-newline-after": null,
|
||||
"@stylistic/indentation": [2, { "ignore": ["value"] }],
|
||||
"at-rule-empty-line-before": ["always", { "ignore": ["first-nested", "after-comment", "blockless-after-blockless"] }],
|
||||
"rule-empty-line-before": ["always", {
|
||||
"except": ["after-single-line-comment", "first-nested"],
|
||||
"ignore": ["after-comment", "inside-block"]
|
||||
}]
|
||||
"@stylistic/indentation": [
|
||||
2,
|
||||
{
|
||||
"ignore": [
|
||||
"value"
|
||||
]
|
||||
}
|
||||
],
|
||||
"at-rule-empty-line-before": [
|
||||
"always",
|
||||
{
|
||||
"ignore": [
|
||||
"first-nested",
|
||||
"after-comment",
|
||||
"blockless-after-blockless"
|
||||
]
|
||||
}
|
||||
],
|
||||
"rule-empty-line-before": [
|
||||
"always",
|
||||
{
|
||||
"except": [
|
||||
"after-single-line-comment",
|
||||
"first-nested"
|
||||
],
|
||||
"ignore": [
|
||||
"after-comment",
|
||||
"inside-block"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +69,7 @@ export default tseslint.config(
|
||||
'no-undef': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'@stylistic/multiline-ternary': 'off',
|
||||
'@stylistic/operator-linebreak': 'off',
|
||||
'@stylistic/max-len': ['error', {
|
||||
code: 120,
|
||||
ignoreComments: true,
|
||||
@ -202,6 +203,7 @@ export default tseslint.config(
|
||||
'react-x/no-array-index-key': 'off',
|
||||
'react-x/no-missing-key': 'off',
|
||||
'react-x/no-nested-component-definitions': 'off',
|
||||
'react-x/no-unused-props': 'off',
|
||||
'react-x/no-leaked-conditional-rendering': 'error',
|
||||
'jsx-a11y/click-events-have-key-events': 'off',
|
||||
'jsx-a11y/mouse-events-have-key-events': 'off',
|
||||
|
||||
4228
package-lock.json
generated
4228
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
108
package.json
108
package.json
@ -40,88 +40,87 @@
|
||||
"*.{css,scss}": "stylelint --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.27.4",
|
||||
"@babel/preset-env": "^7.27.2",
|
||||
"@babel/core": "^7.28.4",
|
||||
"@babel/preset-env": "^7.28.3",
|
||||
"@babel/preset-react": "^7.27.1",
|
||||
"@babel/preset-typescript": "^7.27.1",
|
||||
"@babel/register": "^7.27.1",
|
||||
"@eslint/js": "^9.29.0",
|
||||
"@babel/register": "^7.28.3",
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@glen/jest-raw-loader": "^2.0.0",
|
||||
"@mytonwallet/stylelint-whole-pixel": "github:mytonwallet-org/stylelint-whole-pixel#fd07e44d786460f7d469076b1d2cb1b05297896c",
|
||||
"@mytonwallet/webpack-watch-file-plugin": "github:mytonwallet-org/webpack-watch-file-plugin#747b7fd29da9a928aa8b63299adfba461d2f1231",
|
||||
"@playwright/test": "^1.53.0",
|
||||
"@mytonwallet/stylelint-whole-pixel": "github:mytonwallet-org/stylelint-whole-pixel#6208102",
|
||||
"@mytonwallet/webpack-watch-file-plugin": "github:mytonwallet-org/webpack-watch-file-plugin#6c9386b",
|
||||
"@playwright/test": "^1.56.0",
|
||||
"@statoscope/cli": "5.29.0",
|
||||
"@statoscope/webpack-plugin": "5.29.0",
|
||||
"@stylistic/eslint-plugin": "^4.4.1",
|
||||
"@stylistic/stylelint-config": "^2.0.0",
|
||||
"@stylistic/stylelint-plugin": "^3.1.2",
|
||||
"@tauri-apps/cli": "^2.8.0",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@stylistic/eslint-plugin": "^5.4.0",
|
||||
"@stylistic/stylelint-config": "^3.0.1",
|
||||
"@stylistic/stylelint-plugin": "^4.0.0",
|
||||
"@tauri-apps/cli": "^2.8.4",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@twbs/fantasticon": "^3.1.0",
|
||||
"@types/dom-view-transitions": "^1.0.6",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/node": "^24.0.3",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/node": "^24.7.2",
|
||||
"@types/react": "^19.2.2",
|
||||
"@types/react-dom": "^19.2.1",
|
||||
"@types/webpack": "^5.28.5",
|
||||
"@typescript-eslint/eslint-plugin": "^8.34.1",
|
||||
"@typescript-eslint/parser": "^8.34.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||
"@typescript-eslint/parser": "^8.46.0",
|
||||
"@webpack-cli/serve": "^3.0.1",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"babel-loader": "^10.0.0",
|
||||
"babel-plugin-transform-import-meta": "^2.3.3",
|
||||
"browserslist-config-baseline": "^0.5.0",
|
||||
"buffer": "^6.0.3",
|
||||
"concurrently": "^9.1.2",
|
||||
"copy-webpack-plugin": "^13.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"concurrently": "^9.2.1",
|
||||
"copy-webpack-plugin": "^13.0.1",
|
||||
"cross-env": "^10.1.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"dotenv": "^16.5.0",
|
||||
"eslint": "^9.29.0",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jest": "^28.14.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"eslint": "^9.37.0",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-jest": "^29.0.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-no-null": "^1.0.2",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks-static-deps": "git+https://github.com/zubiden/eslint-plugin-react-hooks-static-deps#c16f35bf2e6e364cbc692c73cc350c1c5d46cc6e",
|
||||
"eslint-plugin-react-x": "^1.52.2",
|
||||
"eslint-plugin-react-hooks-static-deps": "git+https://github.com/zubiden/eslint-plugin-react-hooks-static-deps#c16f35b",
|
||||
"eslint-plugin-react-x": "^2.0.6",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"eslint-plugin-tt-multitab": "git+https://github.com/zubiden/eslint-plugin-tt-multitab#15d542004d39ec7c29d50385484511bab0b77ea9",
|
||||
"eslint-plugin-unused-imports": "^4.1.4",
|
||||
"fake-indexeddb": "^6.0.1",
|
||||
"eslint-plugin-tt-multitab": "git+https://github.com/zubiden/eslint-plugin-tt-multitab#137cf50",
|
||||
"eslint-plugin-unused-imports": "^4.2.0",
|
||||
"fake-indexeddb": "^6.2.3",
|
||||
"git-revision-webpack-plugin": "^5.0.0",
|
||||
"gitlog": "^5.1.0",
|
||||
"glob": "^11.0.3",
|
||||
"html-webpack-plugin": "^5.6.3",
|
||||
"html-webpack-plugin": "^5.6.4",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^30.0.0",
|
||||
"jest-environment-jsdom": "^30.0.0",
|
||||
"lint-staged": "^16.1.2",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
"jest": "^30.2.0",
|
||||
"jest-environment-jsdom": "^30.2.0",
|
||||
"lint-staged": "^16.2.4",
|
||||
"mini-css-extract-plugin": "^2.9.4",
|
||||
"minimatch": "^10.0.3",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-load-config": "^6.0.1",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"postcss-loader": "^8.2.0",
|
||||
"postcss-modules": "^6.0.1",
|
||||
"react": "^19.1.0",
|
||||
"sass": "^1.89.2",
|
||||
"react": "^19.2.0",
|
||||
"sass": "^1.93.2",
|
||||
"sass-loader": "^16.0.5",
|
||||
"script-loader": "^0.7.2",
|
||||
"serve": "^14.2.4",
|
||||
"stylelint": "^16.20.0",
|
||||
"serve": "^14.2.5",
|
||||
"stylelint": "^16.25.0",
|
||||
"stylelint-config-clean-order": "^7.0.0",
|
||||
"stylelint-config-recommended-scss": "^15.0.1",
|
||||
"stylelint-config-recommended-scss": "^16.0.2",
|
||||
"stylelint-declaration-block-no-ignored-properties": "^2.8.0",
|
||||
"stylelint-group-selectors": "^1.0.10",
|
||||
"stylelint-high-performance-animation": "^1.11.0",
|
||||
"stylelint-plugin-use-baseline": "^0.9.1",
|
||||
"stylelint-plugin-use-baseline": "^1.0.2",
|
||||
"stylelint-selector-tag-no-without-class": "^3.0.1",
|
||||
"telegraph-node": "^1.0.4",
|
||||
"tsx": "^4.20.3",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.34.1",
|
||||
"webpack": "^5.99.9",
|
||||
"tsx": "^4.20.6",
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "^8.46.0",
|
||||
"webpack": "^5.102.1",
|
||||
"webpack-dev-server": "^5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -132,13 +131,12 @@
|
||||
"@tauri-apps/plugin-shell": "^2.3.1",
|
||||
"@tauri-apps/plugin-updater": "^2.9.0",
|
||||
"async-mutex": "^0.5.0",
|
||||
"browserslist-config-baseline": "^0.5.0",
|
||||
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#443f1c9d7b16a82e7ee53f7f226d7d9a9920a105",
|
||||
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#443f1c9",
|
||||
"idb-keyval": "^6.2.2",
|
||||
"lowlight": "^3.3.0",
|
||||
"mp4box": "^0.5.4",
|
||||
"music-metadata": "^11.3.0",
|
||||
"opus-recorder": "github:Ajaxy/opus-recorder",
|
||||
"music-metadata": "^11.9.0",
|
||||
"opus-recorder": "github:Ajaxy/opus-recorder#116830a",
|
||||
"os-browserify": "^0.3.0",
|
||||
"pako": "^2.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
@ -148,10 +146,10 @@
|
||||
"dmg-license": "^1.0.11",
|
||||
"fsevents": "^2.3.3"
|
||||
},
|
||||
"overrides": {
|
||||
"@borewit/text-codec": "0.2.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"extends browserslist-config-baseline"
|
||||
],
|
||||
"browserslist-config-baseline": {
|
||||
"logConfigToConsole": false
|
||||
}
|
||||
"baseline widely available"
|
||||
]
|
||||
}
|
||||
|
||||
2
src/@types/global.d.ts
vendored
2
src/@types/global.d.ts
vendored
@ -116,7 +116,7 @@ declare module 'opus-recorder' {
|
||||
|
||||
sourceNode: MediaStreamAudioSourceNode;
|
||||
|
||||
ondataavailable: (typedArray: Uint8Array) => void;
|
||||
ondataavailable: (typedArray: Uint8Array<ArrayBuffer>) => void;
|
||||
}
|
||||
|
||||
const recorder: IOpusRecorder;
|
||||
|
||||
@ -194,11 +194,11 @@ export async function destroy(noLogOut = false, noClearLocalDb = false) {
|
||||
resetUpdatesManager();
|
||||
}
|
||||
|
||||
await client.destroy();
|
||||
client.destroy();
|
||||
}
|
||||
|
||||
export async function disconnect() {
|
||||
await client.disconnect();
|
||||
export function disconnect() {
|
||||
client.disconnect();
|
||||
}
|
||||
|
||||
export function getClient() {
|
||||
|
||||
@ -185,7 +185,7 @@ async function download(
|
||||
}
|
||||
|
||||
function parseMedia(
|
||||
data: Buffer | File, mediaFormat: ApiMediaFormat, mimeType?: string,
|
||||
data: Buffer<ArrayBuffer> | File, mediaFormat: ApiMediaFormat, mimeType?: string,
|
||||
): ApiParsedMedia | undefined {
|
||||
if (data instanceof File) {
|
||||
return data;
|
||||
|
||||
@ -80,7 +80,7 @@ export async function fetchStarGifts() {
|
||||
|
||||
// Right now, only regular star gifts can be bought, but API are not specific
|
||||
const gifts
|
||||
= result.gifts.map(buildApiStarGift).filter((gift): gift is ApiStarGiftRegular => gift.type === 'starGift');
|
||||
= result.gifts.map(buildApiStarGift).filter((gift): gift is ApiStarGiftRegular => gift.type === 'starGift');
|
||||
|
||||
return {
|
||||
gifts,
|
||||
@ -102,33 +102,33 @@ export async function fetchResaleGifts({
|
||||
attributesHash?: string;
|
||||
filter?: ResaleGiftsFilterOptions;
|
||||
}) {
|
||||
type GetResaleStarGifts = ConstructorParameters<typeof GramJs.payments.GetResaleStarGifts>[0];
|
||||
type GetResaleStarGifts = ConstructorParameters<typeof GramJs.payments.GetResaleStarGifts>[0];
|
||||
|
||||
const attributes: ApiStarGiftAttributeId[] = [
|
||||
...(filter?.backdropAttributes ?? []),
|
||||
...(filter?.modelAttributes ?? []),
|
||||
...(filter?.patternAttributes ?? []),
|
||||
];
|
||||
const attributes: ApiStarGiftAttributeId[] = [
|
||||
...(filter?.backdropAttributes ?? []),
|
||||
...(filter?.modelAttributes ?? []),
|
||||
...(filter?.patternAttributes ?? []),
|
||||
];
|
||||
|
||||
const params: GetResaleStarGifts = {
|
||||
giftId: BigInt(giftId),
|
||||
offset,
|
||||
limit,
|
||||
attributesHash: attributesHash ? BigInt(attributesHash) : DEFAULT_PRIMITIVES.BIGINT,
|
||||
attributes: buildInputResaleGiftsAttributes(attributes),
|
||||
...(filter && {
|
||||
sortByPrice: filter.sortType === 'byPrice' || undefined,
|
||||
sortByNum: filter.sortType === 'byNumber' || undefined,
|
||||
} satisfies Partial<GetResaleStarGifts>),
|
||||
};
|
||||
const params: GetResaleStarGifts = {
|
||||
giftId: BigInt(giftId),
|
||||
offset,
|
||||
limit,
|
||||
attributesHash: attributesHash ? BigInt(attributesHash) : DEFAULT_PRIMITIVES.BIGINT,
|
||||
attributes: buildInputResaleGiftsAttributes(attributes),
|
||||
...(filter && {
|
||||
sortByPrice: filter.sortType === 'byPrice' || undefined,
|
||||
sortByNum: filter.sortType === 'byNumber' || undefined,
|
||||
} satisfies Partial<GetResaleStarGifts>),
|
||||
};
|
||||
|
||||
const result = await invokeRequest(new GramJs.payments.GetResaleStarGifts(params));
|
||||
const result = await invokeRequest(new GramJs.payments.GetResaleStarGifts(params));
|
||||
|
||||
if (!result) {
|
||||
return undefined;
|
||||
}
|
||||
if (!result) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return buildApiResaleGifts(result);
|
||||
return buildApiResaleGifts(result);
|
||||
}
|
||||
|
||||
export async function fetchSavedStarGifts({
|
||||
|
||||
@ -36,7 +36,7 @@ function AnimatedIcon(props: OwnProps) {
|
||||
onLoad?.();
|
||||
});
|
||||
|
||||
const [playKey, setPlayKey] = useState(String(Math.random()));
|
||||
const [playKey, setPlayKey] = useState(() => String(Math.random()));
|
||||
|
||||
const handleClick = useLastCallback(() => {
|
||||
if (play === true) {
|
||||
|
||||
@ -83,15 +83,15 @@ const CalendarModal: FC<OwnProps> = ({
|
||||
const [isTimeInputFocused, markTimeInputAsFocused] = useFlag(false);
|
||||
|
||||
const [selectedDate, setSelectedDate] = useState<Date>(passedSelectedDate);
|
||||
const [currentMonthAndYear, setCurrentMonthAndYear] = useState<Date>(
|
||||
new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1),
|
||||
);
|
||||
const [selectedHours, setSelectedHours] = useState<string>(
|
||||
formatInputTime(passedSelectedDate.getHours()),
|
||||
);
|
||||
const [selectedMinutes, setSelectedMinutes] = useState<string>(
|
||||
formatInputTime(passedSelectedDate.getMinutes()),
|
||||
);
|
||||
const [currentMonthAndYear, setCurrentMonthAndYear] = useState<Date>(() => (
|
||||
new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1)
|
||||
));
|
||||
const [selectedHours, setSelectedHours] = useState<string>(() => (
|
||||
formatInputTime(passedSelectedDate.getHours())
|
||||
));
|
||||
const [selectedMinutes, setSelectedMinutes] = useState<string>(() => (
|
||||
formatInputTime(passedSelectedDate.getMinutes())
|
||||
));
|
||||
|
||||
const selectedDay = formatDay(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
|
||||
const currentYear = currentMonthAndYear.getFullYear();
|
||||
|
||||
@ -143,7 +143,7 @@ const StickerSet: FC<OwnProps & StateProps> = ({
|
||||
const [isConfirmModalOpen, openConfirmModal, closeConfirmModal] = useFlag();
|
||||
const { isMobile } = useAppLayout();
|
||||
|
||||
const [itemsPerRow, setItemsPerRow] = useState(getItemsPerRowFallback(windowWidth));
|
||||
const [itemsPerRow, setItemsPerRow] = useState(() => getItemsPerRowFallback(windowWidth));
|
||||
|
||||
const isIntersecting = useIsIntersecting(ref, observeIntersection ?? observeIntersectionForShowingItems);
|
||||
const transitionClassNames = useMediaTransitionDeprecated(isIntersecting);
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
text-align: initial;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
grid-gap: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ function preloadAvatars() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return Promise.all(listIds.active.slice(0, AVATARS_TO_PRELOAD).map((chatId) => {
|
||||
return Promise.all(listIds.active.slice(0, AVATARS_TO_PRELOAD).map(async (chatId) => {
|
||||
const chat = byId[chatId];
|
||||
if (!chat) {
|
||||
return undefined;
|
||||
|
||||
@ -43,11 +43,11 @@ const GiftRibbon = ({
|
||||
const isDarkTheme = theme === 'dark';
|
||||
|
||||
const gradientColor: GradientColor | undefined
|
||||
= Array.isArray(color)
|
||||
? color as GradientColor
|
||||
: colorKey
|
||||
? COLORS[colorKey][isDarkTheme ? 1 : 0]
|
||||
: undefined;
|
||||
= Array.isArray(color)
|
||||
? color as GradientColor
|
||||
: colorKey
|
||||
? COLORS[colorKey][isDarkTheme ? 1 : 0]
|
||||
: undefined;
|
||||
|
||||
const startColor = gradientColor ? gradientColor[0] : color;
|
||||
const endColor = gradientColor ? gradientColor[1] : color;
|
||||
|
||||
@ -21,7 +21,7 @@ import SafeLink from '../SafeLink';
|
||||
export type TextFilter = (
|
||||
'escape_html' | 'hq_emoji' | 'emoji' | 'emoji_html' | 'br' | 'br_html' | 'highlight' | 'links' |
|
||||
'simple_markdown' | 'simple_markdown_html' | 'tg_links'
|
||||
);
|
||||
);
|
||||
|
||||
const SIMPLE_MARKDOWN_REGEX = /(\*\*|__).+?\1/g;
|
||||
|
||||
|
||||
@ -6,17 +6,15 @@ import type { GlobalState } from '../../../global/types';
|
||||
|
||||
import { selectCanPlayAnimatedEmojis, selectCustomEmoji } from '../../../global/selectors';
|
||||
import { addCustomEmojiCallback, removeCustomEmojiCallback } from '../../../util/emoji/customEmojiManager';
|
||||
import ensureCustomEmoji from '../../../util/emoji/ensureCustomEmoji';
|
||||
|
||||
import useEnsureCustomEmoji from '../../../hooks/useEnsureCustomEmoji';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
|
||||
export default function useCustomEmoji(documentId?: string) {
|
||||
const [customEmoji, setCustomEmoji] = useState<ApiSticker | undefined>(
|
||||
documentId ? selectCustomEmoji(getGlobal(), documentId) : undefined,
|
||||
);
|
||||
const [canPlay, setCanPlay] = useState(selectCanPlayAnimatedEmojis(getGlobal()));
|
||||
|
||||
useEnsureCustomEmoji(documentId);
|
||||
const [customEmoji, setCustomEmoji] = useState<ApiSticker | undefined>(() => (
|
||||
documentId ? selectCustomEmoji(getGlobal(), documentId) : undefined
|
||||
));
|
||||
const [canPlay, setCanPlay] = useState(() => selectCanPlayAnimatedEmojis(getGlobal()));
|
||||
|
||||
const handleGlobalChange = useLastCallback((customEmojis?: GlobalState['customEmojis']) => {
|
||||
if (!documentId) return;
|
||||
@ -26,7 +24,11 @@ export default function useCustomEmoji(documentId?: string) {
|
||||
setCanPlay(selectCanPlayAnimatedEmojis(newGlobal));
|
||||
});
|
||||
|
||||
useEffect(handleGlobalChange, [documentId, handleGlobalChange]);
|
||||
useEffect(() => {
|
||||
ensureCustomEmoji(documentId);
|
||||
}, [documentId]);
|
||||
|
||||
useEffect(() => handleGlobalChange(), [documentId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!documentId) return undefined;
|
||||
|
||||
@ -108,8 +108,8 @@
|
||||
.media-list {
|
||||
display: grid;
|
||||
grid-auto-rows: 1fr;
|
||||
grid-gap: 0.25rem;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.25rem;
|
||||
|
||||
padding: 0.5rem;
|
||||
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
.settings-wallpapers {
|
||||
display: grid;
|
||||
grid-auto-rows: 1fr;
|
||||
grid-gap: 0.0625rem;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.0625rem;
|
||||
|
||||
@include mixins.side-panel-section;
|
||||
}
|
||||
|
||||
@ -73,8 +73,8 @@
|
||||
.predefined-colors {
|
||||
display: grid;
|
||||
grid-auto-rows: 1fr;
|
||||
grid-gap: 0.0625rem;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.0625rem;
|
||||
|
||||
@include mixins.side-panel-section;
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ const SettingsGeneralBackground: FC<OwnProps & StateProps> = ({
|
||||
const huePickerRef = useRef<HTMLDivElement>();
|
||||
const isFirstRunRef = useRef(true);
|
||||
|
||||
const [hsv, setHsv] = useState(getInitialHsv(backgroundColor));
|
||||
const [hsv, setHsv] = useState(() => getInitialHsv(backgroundColor));
|
||||
// Cache for drag handlers
|
||||
const hsvRef = useRef(hsv);
|
||||
useEffect(() => {
|
||||
|
||||
@ -158,7 +158,7 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
const [customExpireDate, setCustomExpireDate] = useState<number>(Date.now() + DEFAULT_CUSTOM_EXPIRE_DATE);
|
||||
const [customExpireDate, setCustomExpireDate] = useState<number>(() => Date.now() + DEFAULT_CUSTOM_EXPIRE_DATE);
|
||||
const [isHeaderHidden, setHeaderHidden] = useState(true);
|
||||
const [selectedRandomUserCount, setSelectedRandomUserCount] = useState<number>(DEFAULT_BOOST_COUNT);
|
||||
const [selectedGiveawayOption, setGiveawayOption] = useState<ApiGiveawayType>(TYPE_OPTIONS[0].value);
|
||||
|
||||
@ -38,11 +38,6 @@
|
||||
|
||||
.frame {
|
||||
aspect-ratio: 1;
|
||||
|
||||
@supports not (aspect-ratio: 1) {
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.slide {
|
||||
@ -104,11 +99,6 @@
|
||||
border-top-right-radius: var(--border-radius-default);
|
||||
|
||||
background: var(--premium-feature-background);
|
||||
|
||||
@supports not (aspect-ratio: 1) {
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
|
||||
@ -6,11 +6,6 @@
|
||||
justify-content: center;
|
||||
|
||||
aspect-ratio: 1;
|
||||
|
||||
@supports not (aspect-ratio: 1) {
|
||||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
@ -37,10 +32,6 @@
|
||||
width: 70%;
|
||||
|
||||
opacity: calc(1 - var(--abs-scroll-progress-converted) * 0.4);
|
||||
|
||||
@supports not (aspect-ratio: 1) {
|
||||
transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0.005, 0, -342.2, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.down {
|
||||
@ -71,10 +62,8 @@
|
||||
border-radius: 0 0 10% 10%;
|
||||
}
|
||||
|
||||
@supports (aspect-ratio: 1) {
|
||||
.down .video {
|
||||
top: 0;
|
||||
bottom: initial;
|
||||
border-radius: 10% 10% 0 0;
|
||||
}
|
||||
.down .video {
|
||||
top: 0;
|
||||
bottom: initial;
|
||||
border-radius: 10% 10% 0 0;
|
||||
}
|
||||
|
||||
@ -5,10 +5,10 @@
|
||||
left: 0;
|
||||
|
||||
display: grid;
|
||||
grid-column-gap: 0;
|
||||
grid-row-gap: 0;
|
||||
grid-template-columns: auto;
|
||||
grid-template-rows: auto 1fr;
|
||||
row-gap: 0;
|
||||
column-gap: 0;
|
||||
align-items: center;
|
||||
justify-items: stretch;
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ import useFlag from '../../hooks/useFlag';
|
||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||
import useLastCallback from '../../hooks/useLastCallback';
|
||||
import useOldLang from '../../hooks/useOldLang';
|
||||
import { exitPictureInPictureIfNeeded, usePictureInPictureSignal } from '../../hooks/usePictureInPicture';
|
||||
import { exitPictureInPictureIfNeeded, PICTURE_IN_PICTURE_SIGNAL } from '../../hooks/usePictureInPicture';
|
||||
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
|
||||
import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck';
|
||||
import { useMediaProps } from './hooks/useMediaProps';
|
||||
@ -181,7 +181,7 @@ const MediaViewer = ({
|
||||
animationKey.current = isSingle ? 0 : (messageId || mediaIndex);
|
||||
}
|
||||
|
||||
const [getIsPictureInPicture] = usePictureInPictureSignal();
|
||||
const [getIsPictureInPicture] = PICTURE_IN_PICTURE_SIGNAL;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen || getIsPictureInPicture()) {
|
||||
|
||||
@ -30,6 +30,6 @@
|
||||
display: grid;
|
||||
grid-auto-flow: dense;
|
||||
grid-auto-rows: 6.25rem;
|
||||
grid-gap: 0.125rem;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 0.125rem;
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
|
||||
display: grid;
|
||||
grid-auto-flow: dense;
|
||||
grid-gap: 1px;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 1px;
|
||||
|
||||
padding: 0;
|
||||
|
||||
|
||||
@ -314,6 +314,6 @@
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
grid-gap: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ const ToDoListModal = ({
|
||||
const itemsListRef = useRef<HTMLDivElement>();
|
||||
|
||||
const [title, setTitle] = useState<string>('');
|
||||
const [items, setItems] = useState<Item[]>([{ id: generateUniqueNumberId(), text: '' }]);
|
||||
const [items, setItems] = useState<Item[]>(() => [{ id: generateUniqueNumberId(), text: '' }]);
|
||||
const [isOthersCanAppend, setIsOthersCanAppend] = useState(true);
|
||||
const [isOthersCanComplete, setIsOthersCanComplete] = useState(true);
|
||||
const [hasErrors, setHasErrors] = useState<boolean>(false);
|
||||
|
||||
@ -33,11 +33,6 @@
|
||||
}
|
||||
|
||||
.skeleton {
|
||||
aspect-ratio: 16/9;
|
||||
|
||||
@supports not (aspect-ratio: 16/9) {
|
||||
height: 0 !important;
|
||||
padding-bottom: 56.25%;
|
||||
}
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,11 +65,11 @@ const Poll: FC<OwnProps> = ({
|
||||
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
||||
const [chosenOptions, setChosenOptions] = useState<string[]>([]);
|
||||
const [wasSubmitted, setWasSubmitted] = useState<boolean>(false);
|
||||
const [closePeriod, setClosePeriod] = useState<number>(
|
||||
const [closePeriod, setClosePeriod] = useState<number>(() => (
|
||||
!summary.closed && summary.closeDate && summary.closeDate > 0
|
||||
? Math.min(summary.closeDate - getServerTime(), summary.closePeriod!)
|
||||
: 0,
|
||||
);
|
||||
: 0
|
||||
));
|
||||
const countdownRef = useRef<HTMLDivElement>();
|
||||
const timerCircleRef = useRef<SVGCircleElement>();
|
||||
const { results: voteResults, totalVoters } = results;
|
||||
|
||||
@ -51,14 +51,14 @@ type OwnProps =
|
||||
canPost?: boolean;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
sender?: ApiPeer;
|
||||
canShowSender: boolean;
|
||||
originSender?: ApiPeer;
|
||||
isChatWithSelf?: boolean;
|
||||
isRepliesChat?: boolean;
|
||||
isAnonymousForwards?: boolean;
|
||||
};
|
||||
type StateProps = {
|
||||
sender?: ApiPeer;
|
||||
canShowSender: boolean;
|
||||
originSender?: ApiPeer;
|
||||
isChatWithSelf?: boolean;
|
||||
isRepliesChat?: boolean;
|
||||
isAnonymousForwards?: boolean;
|
||||
};
|
||||
|
||||
const SenderGroupContainer: FC<OwnProps & StateProps> = ({
|
||||
message,
|
||||
|
||||
@ -173,80 +173,80 @@ const GiftResaleFilters: FC<StateProps & OwnProps> = ({
|
||||
const getPatternMenuElement = useLastCallback(() => patternMenuRef.current!);
|
||||
|
||||
const SortMenuButton: FC<{ onTrigger: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => void; isOpen?: boolean }>
|
||||
= useMemo(() => {
|
||||
const sortType = filter.sortType;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{sortType === 'byDate' && lang('ValueGiftSortByDate')}
|
||||
{sortType === 'byNumber' && lang('ValueGiftSortByNumber')}
|
||||
{sortType === 'byPrice' && lang('ValueGiftSortByPrice')}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
= useMemo(() => {
|
||||
const sortType = filter.sortType;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{sortType === 'byDate' && lang('ValueGiftSortByDate')}
|
||||
{sortType === 'byNumber' && lang('ValueGiftSortByNumber')}
|
||||
{sortType === 'byPrice' && lang('ValueGiftSortByPrice')}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
|
||||
const ModelMenuButton:
|
||||
FC<{ onTrigger: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => void; isOpen?: boolean }>
|
||||
= useMemo(() => {
|
||||
const attributesCount = filter?.modelAttributes?.length || 0;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{attributesCount === 0 && lang('GiftAttributeModel')}
|
||||
{attributesCount > 0
|
||||
&& lang('GiftAttributeModelPlural', { count: attributesCount }, { pluralValue: attributesCount })}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
= useMemo(() => {
|
||||
const attributesCount = filter?.modelAttributes?.length || 0;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{attributesCount === 0 && lang('GiftAttributeModel')}
|
||||
{attributesCount > 0
|
||||
&& lang('GiftAttributeModelPlural', { count: attributesCount }, { pluralValue: attributesCount })}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
const BackdropMenuButton:
|
||||
FC<{ onTrigger: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => void; isOpen?: boolean }>
|
||||
= useMemo(() => {
|
||||
const attributesCount = filter?.backdropAttributes?.length || 0;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{attributesCount === 0 && lang('GiftAttributeBackdrop')}
|
||||
{attributesCount > 0
|
||||
&& lang('GiftAttributeBackdropPlural', { count: attributesCount }, { pluralValue: attributesCount })}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
= useMemo(() => {
|
||||
const attributesCount = filter?.backdropAttributes?.length || 0;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{attributesCount === 0 && lang('GiftAttributeBackdrop')}
|
||||
{attributesCount > 0
|
||||
&& lang('GiftAttributeBackdropPlural', { count: attributesCount }, { pluralValue: attributesCount })}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
const PatternMenuButton: FC<{ onTrigger: (e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => void; isOpen?: boolean }>
|
||||
= useMemo(() => {
|
||||
const attributesCount = filter?.patternAttributes?.length || 0;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{attributesCount === 0 && lang('GiftAttributeSymbol')}
|
||||
{attributesCount > 0
|
||||
&& lang('GiftAttributeSymbolPlural', { count: attributesCount }, { pluralValue: attributesCount })}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
= useMemo(() => {
|
||||
const attributesCount = filter?.patternAttributes?.length || 0;
|
||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||
<div
|
||||
className={styles.item}
|
||||
onClick={onTrigger}
|
||||
>
|
||||
{attributesCount === 0 && lang('GiftAttributeSymbol')}
|
||||
{attributesCount > 0
|
||||
&& lang('GiftAttributeSymbolPlural', { count: attributesCount }, { pluralValue: attributesCount })}
|
||||
<Icon
|
||||
name="dropdown-arrows"
|
||||
className={styles.itemIcon}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}, [lang, filter]);
|
||||
|
||||
const handleSortMenuItemClick = useLastCallback((type: ResaleGiftsSortType) => {
|
||||
updateResaleGiftsFilter({ filter: {
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
.optionText {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
|
||||
@ -145,7 +145,7 @@ const SuggestedPostApprovalModal = ({
|
||||
const time = formatScheduledDateTime(scheduleDate, lang, oldLang);
|
||||
|
||||
const key
|
||||
= isAdmin ? 'SuggestedPostConfirmDetailsWithTimeAdmin' : 'SuggestedPostConfirmDetailsWithTimeUser';
|
||||
= isAdmin ? 'SuggestedPostConfirmDetailsWithTimeAdmin' : 'SuggestedPostConfirmDetailsWithTimeUser';
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
display: grid;
|
||||
grid-auto-flow: dense;
|
||||
grid-auto-rows: 6.25rem;
|
||||
grid-gap: 0.25rem;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
|
||||
const [isCalendarOpened, openCalendar, closeCalendar] = useFlag();
|
||||
const [isRequestNeeded, setIsRequestNeeded] = useState(false);
|
||||
const [title, setTitle] = useState('');
|
||||
const [customExpireDate, setCustomExpireDate] = useState<number>(Date.now() + DEFAULT_CUSTOM_EXPIRE_DATE);
|
||||
const [customExpireDate, setCustomExpireDate] = useState<number>(() => Date.now() + DEFAULT_CUSTOM_EXPIRE_DATE);
|
||||
const [selectedExpireOption, setSelectedExpireOption] = useState('unlimited');
|
||||
const [customUsageLimit, setCustomUsageLimit] = useState<number | undefined>(10);
|
||||
const [selectedUsageOption, setSelectedUsageOption] = useState('0');
|
||||
|
||||
@ -48,7 +48,7 @@ const NewDiscussionGroup: FC<OwnProps & StateProps> = ({
|
||||
onBack: onClose,
|
||||
});
|
||||
|
||||
const [title, setTitle] = useState(lang('NewDiscussionChatTitle', { name: chat?.title }));
|
||||
const [title, setTitle] = useState(() => lang('NewDiscussionChatTitle', { name: chat?.title }));
|
||||
const [photo, setPhoto] = useState<File | undefined>();
|
||||
const [error, setError] = useState<string | undefined>();
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ type AnimationName = (
|
||||
'none' | 'slide' | 'slideRtl' | 'slideFade' | 'zoomFade' | 'zoomBounceSemiFade' | 'slideLayers'
|
||||
| 'fade' | 'pushSlide' | 'reveal' | 'slideOptimized' | 'slideOptimizedRtl' | 'semiFade'
|
||||
| 'slideVertical' | 'slideVerticalFade' | 'slideFadeAndroid'
|
||||
);
|
||||
);
|
||||
export type ChildrenFn = (isActive: boolean, isFrom: boolean, currentKey: number, activeKey: number) => React.ReactNode;
|
||||
export type TransitionProps = {
|
||||
ref?: ElementRef<HTMLDivElement>;
|
||||
|
||||
@ -559,7 +559,7 @@ addActionHandler('sendInviteMessages', async (global, actions, payload): Promise
|
||||
await Promise.all(userIds.map((userId) => {
|
||||
const chat = selectChat(global, userId);
|
||||
if (!chat) {
|
||||
return undefined;
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
const userFullName = getUserFullName(selectUser(global, userId));
|
||||
if (userFullName) {
|
||||
|
||||
@ -117,7 +117,7 @@ export type FoldersActions = (
|
||||
'setTitle' | 'saveFilters' | 'editFolder' | 'reset' | 'setChatFilter' | 'setIsLoading' | 'setError' |
|
||||
'editIncludeFilters' | 'editExcludeFilters' | 'setIncludeFilters' | 'setExcludeFilters' | 'setIsTouched' |
|
||||
'setFolderId' | 'setIsChatlist' | 'setColor'
|
||||
);
|
||||
);
|
||||
export type FolderEditDispatch = Dispatch<FoldersState, FoldersActions>;
|
||||
|
||||
const INITIAL_STATE: FoldersState = {
|
||||
|
||||
@ -23,7 +23,7 @@ export default function useMultiaccountInfo(currentUser?: ApiUser) {
|
||||
const isUpdater = Boolean(currentUser) && getGlobal().authRememberMe;
|
||||
const isSynced = useSelector(selectIsSynced);
|
||||
|
||||
const [accountsInfo, setAccountsInfo] = useState(getAccountsInfo());
|
||||
const [accountsInfo, setAccountsInfo] = useState(() => getAccountsInfo());
|
||||
|
||||
const avatarHash = currentUser && getChatAvatarHash(currentUser);
|
||||
const avatarUrl = useMedia(avatarHash, !isUpdater);
|
||||
|
||||
@ -12,9 +12,7 @@ type CallbackType = () => void;
|
||||
const signal = createSignal(false);
|
||||
const setIsPictureInPicture = signal[1];
|
||||
|
||||
export function usePictureInPictureSignal() {
|
||||
return signal;
|
||||
}
|
||||
export const PICTURE_IN_PICTURE_SIGNAL = signal;
|
||||
|
||||
export default function usePictureInPicture(
|
||||
elRef: ElementRef<HTMLVideoElement>,
|
||||
|
||||
@ -51,7 +51,7 @@ export function readBufferFromBigInt(
|
||||
bytesNumber: number,
|
||||
little = true,
|
||||
signed = false,
|
||||
): Buffer {
|
||||
): Buffer<ArrayBuffer> {
|
||||
if (!Number.isInteger(bytesNumber) || bytesNumber <= 0) {
|
||||
throw new RangeError('bytesNumber must be a positive integer');
|
||||
}
|
||||
@ -138,13 +138,13 @@ export function convertToLittle(buf: Uint32Array) {
|
||||
return correct;
|
||||
}
|
||||
|
||||
export function sha1(data: Buffer): Promise<Buffer> {
|
||||
export function sha1(data: Buffer): Promise<Buffer<ArrayBuffer>> {
|
||||
const shaSum = createHash('sha1');
|
||||
shaSum.update(data);
|
||||
return shaSum.digest();
|
||||
}
|
||||
|
||||
export function sha256(data: Buffer): Promise<Buffer> {
|
||||
export function sha256(data: Buffer): Promise<Buffer<ArrayBuffer>> {
|
||||
const shaSum = createHash('sha256');
|
||||
shaSum.update(data);
|
||||
return shaSum.digest();
|
||||
@ -171,7 +171,7 @@ export function modExp(
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getByteArray(integer: bigint, signed = false): Buffer {
|
||||
export function getByteArray(integer: bigint, signed = false): Buffer<ArrayBuffer> {
|
||||
if (!signed && integer < 0n) {
|
||||
throw new RangeError('Cannot convert negative to unsigned');
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ function isGoodLarge(number: bigint, p: bigint): boolean {
|
||||
return number > 0n && number < p;
|
||||
}
|
||||
|
||||
function numBytesForHash(number: Buffer): Buffer {
|
||||
function numBytesForHash(number: Buffer): Buffer<ArrayBuffer> {
|
||||
return Buffer.concat([Buffer.alloc(SIZE_FOR_HASH - number.length), number]);
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ function xor(a: Buffer, b: Buffer) {
|
||||
return a;
|
||||
}
|
||||
|
||||
function pbkdf2sha512(password: Buffer, salt: Buffer, iterations: number): any {
|
||||
function pbkdf2sha512(password: Buffer<ArrayBuffer>, salt: Buffer<ArrayBuffer>, iterations: number): any {
|
||||
return pbkdf2(password, salt, iterations);
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ async function computeHash(
|
||||
) {
|
||||
const hash1 = await sha256(Buffer.concat([algo.salt1, Buffer.from(password, 'utf-8'), algo.salt1]));
|
||||
const hash2 = await sha256(Buffer.concat([algo.salt2, hash1, algo.salt2]));
|
||||
const hash3 = await pbkdf2sha512(hash2, algo.salt1, 100000);
|
||||
const hash3 = await pbkdf2sha512(hash2, algo.salt1 as Buffer<ArrayBuffer>, 100000);
|
||||
return sha256(Buffer.concat([algo.salt2, hash3, algo.salt2]));
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ export function getInputPeer(
|
||||
* @param stripped{Buffer}
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
export function strippedPhotoToJpg(stripped: Buffer) {
|
||||
export function strippedPhotoToJpg(stripped: Buffer<ArrayBuffer>): Buffer<ArrayBuffer> {
|
||||
// Note: Changes here should update _stripped_real_length
|
||||
if (stripped.length < 3 || stripped[0] !== 1) {
|
||||
return stripped;
|
||||
|
||||
@ -370,14 +370,14 @@ class TelegramClient {
|
||||
|
||||
async setForceHttpTransport(forceHttpTransport: boolean) {
|
||||
this._shouldForceHttpTransport = forceHttpTransport;
|
||||
await this.disconnect();
|
||||
this.disconnect();
|
||||
this._sender = undefined;
|
||||
await this.connect();
|
||||
}
|
||||
|
||||
async setAllowHttpTransport(allowHttpTransport: boolean) {
|
||||
this._shouldAllowHttpTransport = allowHttpTransport;
|
||||
await this.disconnect();
|
||||
this.disconnect();
|
||||
this._sender = undefined;
|
||||
await this.connect();
|
||||
}
|
||||
@ -467,26 +467,22 @@ class TelegramClient {
|
||||
lastPongAt = undefined;
|
||||
}
|
||||
}
|
||||
await this.disconnect();
|
||||
this.disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects from the Telegram server
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async disconnect() {
|
||||
disconnect() {
|
||||
this._sender?.disconnect();
|
||||
|
||||
await Promise.all(
|
||||
Object.values(this._exportedSenderPromises)
|
||||
.map((promises) => {
|
||||
return Object.values(promises).map((promise) => {
|
||||
return promise?.then((sender) => {
|
||||
return sender?.disconnect();
|
||||
});
|
||||
});
|
||||
}).flat(),
|
||||
);
|
||||
Object.values(this._exportedSenderPromises)
|
||||
.forEach((promises) => {
|
||||
Object.values(promises).forEach((promise) => {
|
||||
promise?.then((sender) => sender?.disconnect());
|
||||
});
|
||||
});
|
||||
|
||||
Object.values(this._exportedSenderReleaseTimeouts).forEach((timeouts) => {
|
||||
Object.values(timeouts).forEach((releaseTimeout) => {
|
||||
@ -503,11 +499,11 @@ class TelegramClient {
|
||||
* Disconnects all senders and removes all handlers
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async destroy() {
|
||||
destroy() {
|
||||
this._destroyed = true;
|
||||
|
||||
try {
|
||||
await this.disconnect();
|
||||
this.disconnect();
|
||||
this._sender?.destroy();
|
||||
} catch (err) {
|
||||
// Do nothing
|
||||
@ -531,7 +527,7 @@ class TelegramClient {
|
||||
await this._sender.authKey.setKey(undefined);
|
||||
this.session.setAuthKey(undefined);
|
||||
this._isSwitchingDc = true;
|
||||
await this.disconnect();
|
||||
this.disconnect();
|
||||
this._sender = undefined;
|
||||
return this.connect();
|
||||
}
|
||||
@ -839,7 +835,7 @@ class TelegramClient {
|
||||
return this.downloadFile(loc, {
|
||||
dcId,
|
||||
isPriority: true,
|
||||
}) as Promise<Buffer | undefined>; // Profile photo cannot be larger than 2GB, right?
|
||||
}) as Promise<Buffer<ArrayBuffer> | undefined>; // Profile photo cannot be larger than 2GB, right?
|
||||
}
|
||||
|
||||
downloadStickerSetThumb(stickerSet: Api.StickerSet) {
|
||||
@ -859,7 +855,7 @@ class TelegramClient {
|
||||
thumbVersion,
|
||||
}),
|
||||
{ dcId: stickerSet.thumbDcId! },
|
||||
) as Promise<Buffer | undefined>; // Sticker thumb cannot be larger than 2GB, right?
|
||||
) as Promise<Buffer<ArrayBuffer> | undefined>; // Sticker thumb cannot be larger than 2GB, right?
|
||||
}
|
||||
|
||||
return this.invoke(new Api.messages.GetCustomEmojiDocuments({
|
||||
@ -879,7 +875,7 @@ class TelegramClient {
|
||||
{
|
||||
fileSize: toJSNumber(doc.size),
|
||||
dcId: doc.dcId,
|
||||
}) as Promise<Buffer | undefined>; // Sticker thumb cannot be larger than 2GB, right?
|
||||
}) as Promise<Buffer<ArrayBuffer> | undefined>; // Sticker thumb cannot be larger than 2GB, right?
|
||||
});
|
||||
}
|
||||
|
||||
@ -905,7 +901,7 @@ class TelegramClient {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
_downloadCachedPhotoSize(size: Api.PhotoCachedSize | Api.PhotoStrippedSize) {
|
||||
_downloadCachedPhotoSize(size: Api.PhotoCachedSize | Api.PhotoStrippedSize): Buffer<ArrayBuffer> {
|
||||
// No need to download anything, simply write the bytes
|
||||
let data;
|
||||
if (size instanceof Api.PhotoStrippedSize) {
|
||||
@ -1191,7 +1187,7 @@ class TelegramClient {
|
||||
|
||||
state.after = undefined;
|
||||
} else if (e instanceof RPCError && e.errorMessage === 'CONNECTION_NOT_INITED') {
|
||||
await this.disconnect();
|
||||
this.disconnect();
|
||||
await sleep(2000);
|
||||
await this.connect();
|
||||
} else if (e instanceof TimedOutError) {
|
||||
@ -1340,7 +1336,7 @@ class TelegramClient {
|
||||
}
|
||||
}
|
||||
|
||||
function timeout(cb: () => void, ms: number) {
|
||||
function timeout(cb: () => void | Promise<unknown>, ms: number) {
|
||||
let isResolved = false;
|
||||
|
||||
return Promise.race([
|
||||
@ -1351,7 +1347,7 @@ function timeout(cb: () => void, ms: number) {
|
||||
});
|
||||
}
|
||||
|
||||
async function attempts(cb: () => Promise<void> | void, times: number, pause: number) {
|
||||
async function attempts(cb: () => Promise<unknown> | void, times: number, pause: number) {
|
||||
for (let i = 0; i < times; i++) {
|
||||
try {
|
||||
// We need to `return await` here so it can be caught locally
|
||||
|
||||
@ -318,9 +318,9 @@ async function signInUserWithQrCode(
|
||||
async function sendCode(
|
||||
client: TelegramClient, apiCredentials: ApiCredentials, phoneNumber: string, forceSMS = false,
|
||||
): Promise<{
|
||||
phoneCodeHash: string;
|
||||
isCodeViaApp: boolean;
|
||||
}> {
|
||||
phoneCodeHash: string;
|
||||
isCodeViaApp: boolean;
|
||||
}> {
|
||||
try {
|
||||
const { apiId, apiHash } = apiCredentials;
|
||||
const sendResult = await client.invoke(new Api.auth.SendCode({
|
||||
|
||||
@ -53,7 +53,7 @@ class FileView {
|
||||
|
||||
private size?: number;
|
||||
|
||||
private buffer?: Buffer;
|
||||
private buffer?: Buffer<ArrayBuffer>;
|
||||
|
||||
private largeFile?: FileSystemFileHandle;
|
||||
|
||||
@ -92,7 +92,7 @@ class FileView {
|
||||
}
|
||||
}
|
||||
|
||||
async getData(): Promise<Buffer | File> {
|
||||
async getData(): Promise<Buffer<ArrayBuffer> | File> {
|
||||
if (this.type === 'opfs') {
|
||||
return this.largeFile!.getFile();
|
||||
} else {
|
||||
|
||||
@ -9,15 +9,15 @@ import {
|
||||
} from '../Helpers';
|
||||
|
||||
export class AuthKey {
|
||||
_key?: Buffer;
|
||||
_key?: Buffer<ArrayBuffer>;
|
||||
|
||||
_hash?: Buffer;
|
||||
_hash?: Buffer<ArrayBuffer>;
|
||||
|
||||
private auxHash?: bigint;
|
||||
|
||||
keyId?: bigint;
|
||||
|
||||
constructor(value?: Buffer, hash?: Buffer) {
|
||||
constructor(value?: Buffer<ArrayBuffer>, hash?: Buffer<ArrayBuffer>) {
|
||||
if (!hash || !value) {
|
||||
return;
|
||||
}
|
||||
@ -29,7 +29,7 @@ export class AuthKey {
|
||||
this.keyId = reader.readLong(false);
|
||||
}
|
||||
|
||||
async setKey(value?: Buffer | AuthKey) {
|
||||
async setKey(value?: Buffer<ArrayBuffer> | AuthKey) {
|
||||
if (!value) {
|
||||
this._key = undefined;
|
||||
this.auxHash = undefined;
|
||||
|
||||
@ -13,11 +13,11 @@ export class CTR {
|
||||
this.decipher = createDecipheriv('AES-256-CTR', key, iv);
|
||||
}
|
||||
|
||||
encrypt(data: Buffer) {
|
||||
encrypt(data: Buffer<ArrayBuffer>) {
|
||||
return Buffer.from(this.cipher.update(data));
|
||||
}
|
||||
|
||||
decrypt(data: Buffer) {
|
||||
decrypt(data: Buffer<ArrayBuffer>) {
|
||||
return Buffer.from(this.decipher.update(data));
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ class IGENEW {
|
||||
* @param cipherText {Buffer}
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
decryptIge(cipherText: Buffer): Buffer {
|
||||
decryptIge(cipherText: Buffer): Buffer<ArrayBuffer> {
|
||||
return convertToLittle(this.ige.decrypt(cipherText));
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ class IGENEW {
|
||||
* @param plainText {Buffer}
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
encryptIge(plainText: Buffer): Buffer {
|
||||
encryptIge(plainText: Buffer): Buffer<ArrayBuffer> {
|
||||
const padding = plainText.length % 16;
|
||||
if (padding) {
|
||||
plainText = Buffer.concat([
|
||||
|
||||
@ -20,14 +20,14 @@ export function i2abLow(buf: Uint32Array): ArrayBuffer {
|
||||
/**
|
||||
* Uint32Array -> ArrayBuffer (big-endian os)
|
||||
*/
|
||||
export function i2abBig(buf: Uint32Array): ArrayBuffer {
|
||||
export function i2abBig(buf: Uint32Array<ArrayBuffer>): ArrayBuffer {
|
||||
return buf.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayBuffer -> Uint32Array (low-endian os)
|
||||
*/
|
||||
export function ab2iLow(ab: ArrayBuffer | SharedArrayBuffer | Uint8Array): Uint32Array {
|
||||
export function ab2iLow(ab: ArrayBuffer | Uint8Array): Uint32Array {
|
||||
const uint8 = new Uint8Array(ab);
|
||||
const buf = new Uint32Array(uint8.length / 4);
|
||||
|
||||
@ -46,7 +46,7 @@ export function ab2iLow(ab: ArrayBuffer | SharedArrayBuffer | Uint8Array): Uint3
|
||||
/**
|
||||
* ArrayBuffer -> Uint32Array (big-endian os)
|
||||
*/
|
||||
export function ab2iBig(ab: ArrayBuffer | SharedArrayBuffer | Uint8Array): Uint32Array {
|
||||
export function ab2iBig(ab: ArrayBuffer | Uint8Array): Uint32Array {
|
||||
return new Uint32Array(ab);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import { ab2i, i2ab } from './converters';
|
||||
import { getWords } from './words';
|
||||
|
||||
class Counter {
|
||||
_counter: Buffer;
|
||||
_counter: Buffer<ArrayBuffer>;
|
||||
|
||||
constructor(initialValue: Buffer) {
|
||||
this._counter = Buffer.from(initialValue);
|
||||
@ -44,16 +44,22 @@ class CTR {
|
||||
this._aes = new AES(getWords(key));
|
||||
}
|
||||
|
||||
update(plainText: Buffer) {
|
||||
update(plainText: Buffer<ArrayBuffer>) {
|
||||
return this.encrypt(plainText);
|
||||
}
|
||||
|
||||
encrypt(plainText: Buffer) {
|
||||
encrypt(plainText: Buffer<ArrayBuffer>) {
|
||||
const encrypted = Buffer.from(plainText);
|
||||
|
||||
for (let i = 0; i < encrypted.length; i++) {
|
||||
if (this._remainingCounterIndex === 16) {
|
||||
this._remainingCounter = Buffer.from(i2ab(this._aes.encrypt(ab2i(this._counter._counter))));
|
||||
this._remainingCounter = Buffer.from(
|
||||
i2ab(
|
||||
this._aes.encrypt(
|
||||
ab2i(this._counter._counter),
|
||||
) as Uint32Array<ArrayBuffer>,
|
||||
),
|
||||
);
|
||||
this._remainingCounterIndex = 0;
|
||||
this._counter.increment();
|
||||
}
|
||||
@ -111,7 +117,7 @@ class Hash {
|
||||
}
|
||||
}
|
||||
|
||||
export async function pbkdf2(password: Buffer, salt: Buffer, iterations: number) {
|
||||
export async function pbkdf2(password: Buffer<ArrayBuffer>, salt: Buffer<ArrayBuffer>, iterations: number) {
|
||||
const passwordKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveBits']);
|
||||
return Buffer.from(await crypto.subtle.deriveBits({
|
||||
name: 'PBKDF2',
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
export default class BinaryWriter {
|
||||
private readonly _buffers: Buffer[];
|
||||
private readonly _buffers: Buffer<ArrayBuffer>[];
|
||||
|
||||
constructor(stream: Buffer) {
|
||||
constructor(stream: Buffer<ArrayBuffer>) {
|
||||
this._buffers = [stream];
|
||||
}
|
||||
|
||||
write(buffer: Buffer) {
|
||||
write(buffer: Buffer<ArrayBuffer>) {
|
||||
this._buffers.push(buffer);
|
||||
}
|
||||
|
||||
getValue(): Buffer {
|
||||
getValue(): Buffer<ArrayBuffer> {
|
||||
return Buffer.concat(this._buffers);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ export default class HttpStream {
|
||||
|
||||
private isClosed: boolean;
|
||||
|
||||
private stream: Buffer[] = [];
|
||||
private stream: Buffer<ArrayBuffer>[] = [];
|
||||
|
||||
private canRead: Promise<void> = Promise.resolve();
|
||||
|
||||
@ -80,7 +80,7 @@ export default class HttpStream {
|
||||
this.isClosed = false;
|
||||
}
|
||||
|
||||
write(data: Buffer) {
|
||||
write(data: Buffer<ArrayBuffer>) {
|
||||
if (this.isClosed || !this.url) {
|
||||
this.handleDisconnect();
|
||||
throw closeError;
|
||||
|
||||
@ -150,7 +150,7 @@ export default class PromisedWebSockets {
|
||||
});
|
||||
}
|
||||
|
||||
write(data: Buffer) {
|
||||
write(data: Buffer<ArrayBuffer>) {
|
||||
if (this.closed) {
|
||||
throw closeError;
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ export default class MTProtoState {
|
||||
* @param afterId
|
||||
*/
|
||||
async writeDataAsMessage(
|
||||
buffer: BinaryWriter, data: Buffer, contentRelated: boolean, afterId?: bigint,
|
||||
buffer: BinaryWriter, data: Buffer<ArrayBuffer>, contentRelated: boolean, afterId?: bigint,
|
||||
): Promise<bigint> {
|
||||
const msgId = this._getNewMsgId();
|
||||
const seqNo = this._getSeqNo(contentRelated);
|
||||
@ -174,7 +174,7 @@ export default class MTProtoState {
|
||||
* following MTProto 2.0 guidelines core.telegram.org/mtproto/description.
|
||||
* @param data
|
||||
*/
|
||||
async encryptMessageData(data: Buffer) {
|
||||
async encryptMessageData(data: Buffer<ArrayBuffer>): Promise<Buffer<ArrayBuffer>> {
|
||||
if (!this.authKey) {
|
||||
throw new Error('Auth key unset');
|
||||
}
|
||||
@ -237,7 +237,7 @@ export default class MTProtoState {
|
||||
* Inverse of `encrypt_message_data` for incoming server messages.
|
||||
* @param body
|
||||
*/
|
||||
async decryptMessageData(body: Buffer) {
|
||||
async decryptMessageData(body: Buffer<ArrayBuffer>) {
|
||||
if (!this.authKey) {
|
||||
throw new Error('Auth key unset');
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ export default class RequestState<T extends CallableRequest = CallableRequest> {
|
||||
|
||||
public request: any;
|
||||
|
||||
public data: Buffer;
|
||||
public data: Buffer<ArrayBuffer>;
|
||||
|
||||
public after: any;
|
||||
|
||||
|
||||
@ -50,9 +50,9 @@ export class Connection {
|
||||
|
||||
protected _obfuscation: any;
|
||||
|
||||
_sendArray: AsyncQueue<Buffer>;
|
||||
_sendArray: AsyncQueue<Buffer<ArrayBuffer>>;
|
||||
|
||||
_recvArray: AsyncQueue<Buffer | undefined>;
|
||||
_recvArray: AsyncQueue<Buffer<ArrayBuffer> | undefined>;
|
||||
|
||||
socket: PromisedWebSockets | HttpStream;
|
||||
|
||||
@ -73,8 +73,8 @@ export class Connection {
|
||||
this._recvTask = undefined;
|
||||
this._codec = undefined;
|
||||
this._obfuscation = undefined; // TcpObfuscated and MTProxy
|
||||
this._sendArray = new AsyncQueue<Buffer>();
|
||||
this._recvArray = new AsyncQueue<Buffer>();
|
||||
this._sendArray = new AsyncQueue<Buffer<ArrayBuffer>>();
|
||||
this._recvArray = new AsyncQueue<Buffer<ArrayBuffer>>();
|
||||
// this.socket = new PromiseSocket(new Socket())
|
||||
|
||||
this.shouldLongPoll = false;
|
||||
@ -120,7 +120,7 @@ export class Connection {
|
||||
}
|
||||
}
|
||||
|
||||
async send(data: Buffer) {
|
||||
async send(data: Buffer<ArrayBuffer>) {
|
||||
if (!this._connected) {
|
||||
throw new Error('Not connected');
|
||||
}
|
||||
@ -241,7 +241,7 @@ export class HttpConnection extends Connection {
|
||||
this.href = HttpStream.getURL(this._ip, this._port, this._isTestServer, this._isPremium);
|
||||
}
|
||||
|
||||
send(data: Buffer) {
|
||||
send(data: Buffer<ArrayBuffer>) {
|
||||
return this.socket.write(data);
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ class ObfuscatedIO {
|
||||
return this._decrypt.encrypt(data);
|
||||
}
|
||||
|
||||
write(data: Buffer) {
|
||||
write(data: Buffer<ArrayBuffer>) {
|
||||
this.connection.write(this._encrypt.encrypt(data));
|
||||
}
|
||||
}
|
||||
|
||||
8
src/lib/gramjs/tl/api.d.ts
vendored
8
src/lib/gramjs/tl/api.d.ts
vendored
@ -22,7 +22,7 @@ namespace Api {
|
||||
type int128 = bigint;
|
||||
type int256 = bigint;
|
||||
type long = bigint;
|
||||
type bytes = Buffer;
|
||||
type bytes = Buffer<ArrayBuffer>;
|
||||
|
||||
class VirtualClass<Args extends AnyLiteral> {
|
||||
static CONSTRUCTOR_ID: number;
|
||||
@ -30,9 +30,9 @@ namespace Api {
|
||||
static className: string;
|
||||
static classType: 'constructor' | 'request';
|
||||
|
||||
static serializeBytes(data: Buffer | string): Buffer;
|
||||
static serializeBytes(data: Buffer<ArrayBuffer> | string): Buffer<ArrayBuffer>;
|
||||
|
||||
getBytes(): Buffer;
|
||||
getBytes(): Buffer<ArrayBuffer>;
|
||||
CONSTRUCTOR_ID: number;
|
||||
SUBCLASS_OF_ID: number;
|
||||
className: string;
|
||||
@ -42,7 +42,7 @@ namespace Api {
|
||||
}
|
||||
|
||||
class Request<Args, Response> extends VirtualClass<Args> {
|
||||
static readResult(reader: Reader): Buffer;
|
||||
static readResult(reader: Reader): Buffer<ArrayBuffer>;
|
||||
|
||||
__response: Response;
|
||||
}
|
||||
|
||||
@ -9,19 +9,19 @@ export default class GZIPPacked {
|
||||
|
||||
static classType = 'constructor';
|
||||
|
||||
data: Buffer;
|
||||
data: Buffer<ArrayBuffer>;
|
||||
|
||||
private CONSTRUCTOR_ID: number;
|
||||
|
||||
private classType: string;
|
||||
|
||||
constructor(data: Buffer) {
|
||||
constructor(data: Buffer<ArrayBuffer>) {
|
||||
this.data = data;
|
||||
this.CONSTRUCTOR_ID = 0x3072cfa1;
|
||||
this.classType = 'constructor';
|
||||
}
|
||||
|
||||
static async gzipIfSmaller(contentRelated: boolean, data: Buffer) {
|
||||
static async gzipIfSmaller(contentRelated: boolean, data: Buffer<ArrayBuffer>) {
|
||||
if (contentRelated && data.length > 512) {
|
||||
const gzipped = await new GZIPPacked(data).toBytes();
|
||||
if (gzipped.length < data.length) {
|
||||
@ -31,7 +31,7 @@ export default class GZIPPacked {
|
||||
return data;
|
||||
}
|
||||
|
||||
static gzip(input: Buffer) {
|
||||
static gzip(input: Buffer<ArrayBuffer>) {
|
||||
return Buffer.from(input);
|
||||
// TODO this usually makes it faster for large requests
|
||||
// return Buffer.from(deflate(input, { level: 9, gzip: true }))
|
||||
|
||||
@ -179,7 +179,7 @@ namespace Api {
|
||||
type int128 = bigint;
|
||||
type int256 = bigint;
|
||||
type long = bigint;
|
||||
type bytes = Buffer;
|
||||
type bytes = Buffer<ArrayBuffer>;
|
||||
|
||||
class VirtualClass<Args extends AnyLiteral> {
|
||||
static CONSTRUCTOR_ID: number;
|
||||
@ -187,9 +187,9 @@ namespace Api {
|
||||
static className: string;
|
||||
static classType: 'constructor' | 'request';
|
||||
|
||||
static serializeBytes(data: Buffer | string): Buffer;
|
||||
static serializeBytes(data: Buffer<ArrayBuffer> | string): Buffer<ArrayBuffer>;
|
||||
|
||||
getBytes(): Buffer;
|
||||
getBytes(): Buffer<ArrayBuffer>;
|
||||
CONSTRUCTOR_ID: number;
|
||||
SUBCLASS_OF_ID: number;
|
||||
className: string;
|
||||
@ -199,7 +199,7 @@ namespace Api {
|
||||
}
|
||||
|
||||
class Request<Args, Response> extends VirtualClass<Args> {
|
||||
static readResult(reader: Reader): Buffer;
|
||||
static readResult(reader: Reader): Buffer<ArrayBuffer>;
|
||||
|
||||
__response: Response;
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-x/no-unnecessary-use-prefix */
|
||||
import type { ReactElement } from 'react';
|
||||
|
||||
import { DEBUG, DEBUG_MORE } from '../../config';
|
||||
|
||||
@ -147,7 +147,7 @@
|
||||
max-width: 0 !important;
|
||||
|
||||
opacity: 0;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
clip-path: inset(50%);
|
||||
}
|
||||
|
||||
&::-ms-clear,
|
||||
|
||||
@ -172,7 +172,7 @@ body.cursor-ew-resize {
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
||||
clip: rect(0, 0, 0, 0);
|
||||
clip-path: inset(50%);
|
||||
}
|
||||
|
||||
.custom-scroll,
|
||||
|
||||
@ -650,11 +650,11 @@ export type ConfettiParams = OptionalCombine<{
|
||||
style?: ConfettiStyle;
|
||||
withStars?: boolean;
|
||||
}, {
|
||||
top?: number;
|
||||
left?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
}>;
|
||||
top?: number;
|
||||
left?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
}>;
|
||||
|
||||
export interface Size {
|
||||
width: number;
|
||||
|
||||
@ -328,11 +328,11 @@ interface WebAppOutboundEventMap {
|
||||
}
|
||||
|
||||
export type WebAppInboundEvent =
|
||||
{ [K in keyof WebAppInboundEventMap]:
|
||||
WebAppEvent<K, WebAppInboundEventMap[K]>
|
||||
}[keyof WebAppInboundEventMap];
|
||||
{ [K in keyof WebAppInboundEventMap]:
|
||||
WebAppEvent<K, WebAppInboundEventMap[K]>
|
||||
}[keyof WebAppInboundEventMap];
|
||||
|
||||
export type WebAppOutboundEvent =
|
||||
{ [K in keyof WebAppOutboundEventMap]:
|
||||
WebAppEvent<K, WebAppOutboundEventMap[K]>
|
||||
}[keyof WebAppOutboundEventMap];
|
||||
{ [K in keyof WebAppOutboundEventMap]:
|
||||
WebAppEvent<K, WebAppOutboundEventMap[K]>
|
||||
}[keyof WebAppOutboundEventMap];
|
||||
|
||||
@ -14,7 +14,7 @@ export async function parseAudioMetadata(url: string): Promise<AudioMetadata> {
|
||||
const { common: { title, artist, picture }, format: { duration } } = metadata;
|
||||
|
||||
const cover = selectCover(picture);
|
||||
const coverBlob = cover ? new Blob([cover.data], { type: cover.format }) : undefined;
|
||||
const coverBlob = cover ? new Blob([cover.data as Uint8Array<ArrayBuffer>], { type: cover.format }) : undefined;
|
||||
const coverUrl = coverBlob ? URL.createObjectURL(coverBlob) : undefined;
|
||||
|
||||
return {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { getActions, getGlobal } from '../global';
|
||||
import { getActions, getGlobal } from '../../global';
|
||||
|
||||
import { selectCustomEmoji } from '../global/selectors';
|
||||
import { addCustomEmojiInputRenderCallback } from '../util/emoji/customEmojiManager';
|
||||
import { throttle } from '../util/schedulers';
|
||||
import { selectCustomEmoji } from '../../global/selectors';
|
||||
import { throttle } from '../schedulers';
|
||||
import { addCustomEmojiInputRenderCallback } from './customEmojiManager';
|
||||
|
||||
let LOAD_QUEUE = new Set<string>();
|
||||
const RENDER_HISTORY = new Set<string>();
|
||||
@ -42,7 +42,7 @@ function notifyCustomEmojiRender(emojiId: string) {
|
||||
|
||||
addCustomEmojiInputRenderCallback(notifyCustomEmojiRender);
|
||||
|
||||
export default function useEnsureCustomEmoji(id?: string) {
|
||||
export default function ensureCustomEmoji(id?: string) {
|
||||
if (!id) return;
|
||||
notifyCustomEmojiRender(id);
|
||||
|
||||
@ -31,7 +31,7 @@ export async function start(analyzerCallback: (volume: number) => void) {
|
||||
|
||||
const startedAt = Date.now();
|
||||
let pausedAt: number;
|
||||
const chunks: Uint8Array[] = [];
|
||||
const chunks: Uint8Array<ArrayBuffer>[] = [];
|
||||
const waveform: number[] = [];
|
||||
|
||||
mediaRecorder.ondataavailable = (typedArray) => {
|
||||
|
||||
1042
tauri/Cargo.lock
generated
1042
tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "telegram_air"
|
||||
version = "2.8.13"
|
||||
version = "2.8.14"
|
||||
description = "Telegram Air"
|
||||
authors = ["Alexander Zinchuk"]
|
||||
license = "GPLv3"
|
||||
@ -14,8 +14,8 @@ rust-version = "1.85"
|
||||
tauri-build = { version = "2.4.1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde_json = "1.0.143"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
serde_json = "1.0.145"
|
||||
tauri = { version = "2.8.5", features = [ "devtools", "unstable", "config-json5", "tray-icon", "image-png"] }
|
||||
tauri-plugin-window-state = "2.4.0"
|
||||
tauri-plugin-shell = "2.3.1"
|
||||
@ -24,17 +24,17 @@ tauri-plugin-notification = "2.3.1"
|
||||
tauri-plugin-updater = "2.9.0"
|
||||
tauri-plugin-process = "2.3.0"
|
||||
tauri-plugin-fs = "2.4.2"
|
||||
tauri-plugin-deep-link = "2.4.2"
|
||||
log = "0.4.27"
|
||||
uuid = { version = "1.18.0", features = ["v4"] }
|
||||
tauri-plugin-deep-link = "2.4.3"
|
||||
log = "0.4.28"
|
||||
uuid = { version = "1.18.1", features = ["v4"] }
|
||||
url = "2.5.7"
|
||||
image = "0.25.6"
|
||||
image = "0.25.8"
|
||||
imageproc = "0.25.0"
|
||||
ab_glyph = "0.2.31"
|
||||
tauri-plugin-os = "2"
|
||||
ab_glyph = "0.2.32"
|
||||
tauri-plugin-os = "2.3.1"
|
||||
|
||||
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\"))".dependencies]
|
||||
tauri-plugin-single-instance = { version = "2.3.3", features = ["deep-link"] }
|
||||
tauri-plugin-single-instance = { version = "2.3.4", features = ["deep-link"] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = "0.26.1"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user