Merge remote-tracking branch 'tdesktop/dev' into dev

This commit is contained in:
Eric Kotato 2020-01-18 18:26:29 +03:00
commit 2b77ec69f0
435 changed files with 19946 additions and 7255 deletions

432
.github/workflows/mac.yml vendored Normal file
View file

@ -0,0 +1,432 @@
name: MacOS.
on:
push:
paths-ignore:
- 'docs/**'
- '*.md'
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'
jobs:
macos:
name: MacOS
runs-on: macos-latest
strategy:
matrix:
defines:
- ""
env:
MIN_MAC: "-mmacosx-version-min=10.12"
UNGUARDED: "-Werror=unguarded-availability-new"
GIT: "https://github.com"
PREFIX: "/usr/local/macos"
MACOSX_DEPLOYMENT_TARGET: "10.12"
XZ: "xz-5.0.5"
QT: "5_12_5"
OPENSSL_VER: "1_1_1"
QT_PREFIX: "/usr/local/desktop-app/Qt-5.12.5"
LIBICONV_VER: "libiconv-1.15"
UPLOAD_ARTIFACT: "false"
MANUAL_CACHING: "1"
DOC_PATH: "docs/building-xcode.md"
steps:
- name: Get repository name.
run: echo ::set-env name=REPO_NAME::${GITHUB_REPOSITORY##*/}
- name: Clone.
uses: actions/checkout@v1
with:
submodules: recursive
- name: First set up.
run: |
cd ..
mv $REPO_NAME temp
mkdir $REPO_NAME
mv temp $REPO_NAME/$REPO_NAME
cd $REPO_NAME
brew install automake fdk-aac lame libass libtool libvorbis libvpx \
ninja opus sdl shtool texi2html theora x264 xvid yasm pkg-config
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version > CACHE_KEY.txt
echo $MIN_MAC >> CACHE_KEY.txt
echo $PREFIX >> CACHE_KEY.txt
echo $MANUAL_CACHING >> CACHE_KEY.txt
echo ::set-env name=CACHE_KEY::`md5 -q CACHE_KEY.txt`
echo ::add-path::$PWD/Libraries/depot_tools
mkdir -p Libraries/macos
cd Libraries/macos
echo ::set-env name=LibrariesPath::`pwd`
- name: Range-v3.
run: |
echo "Find necessary branch from doc."
cloneRange=$(grep -A 1 "range-v3" $REPO_NAME/$DOC_PATH | sed -n 1p)
cd $LibrariesPath
echo $cloneRange
eval $cloneRange
- name: Patches.
run: |
echo "Find necessary commit from doc."
checkoutCommit=$(grep -A 1 "cd patches" $REPO_NAME/$DOC_PATH | sed -n 2p)
cd $LibrariesPath
git clone $GIT/desktop-app/patches.git
cd Patches
eval $checkoutCommit
- name: XZ.
run: |
cd $LibrariesPath
wget https://tukaani.org/xz/$XZ.tar.gz
tar -xvzf $XZ.tar.gz
cd $XZ
CFLAGS="$MIN_MAC" LDFLAGS="$MIN_MAC" ./configure --prefix=$PREFIX
make -j$(nproc)
sudo make install
- name: Zlib.
run: |
cd $LibrariesPath
git clone $GIT/desktop-app/zlib.git
cd zlib
CFLAGS="$MIN_MAC $UNGUARDED" LDFLAGS="$MIN_MAC" ./configure
make -j$(nproc)
sudo make install
- name: OpenSSL cache.
id: cache-openssl
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/openssl_${{ env.OPENSSL_VER }}
key: ${{ runner.OS }}-${{ env.OPENSSL_VER }}-${{ env.CACHE_KEY }}
- name: OpenSSL.
if: steps.cache-openssl.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone $GIT/openssl/openssl openssl_$OPENSSL_VER
cd openssl_$OPENSSL_VER
git checkout OpenSSL_"$OPENSSL_VER"-stable
./Configure \
--prefix=$PREFIX \
darwin64-x86_64-cc \
-static \
$MIN_MAC
make build_libs -j$(nproc)
- name: Opus cache.
id: cache-opus
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/opus
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
- name: Opus.
if: steps.cache-opus.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone $GIT/xiph/opus
cd opus
git checkout v1.3
./autogen.sh
CFLAGS="$MIN_MAC $UNGUARDED" CPPFLAGS="$MIN_MAC $UNGUARDED" LDFLAGS="$MIN_MAC" ./configure --prefix=$PREFIX
make -j$(nproc)
- name: Opus install.
run: |
cd $LibrariesPath/opus
sudo make install
- name: Libiconv cache.
id: cache-libiconv
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/${{ env.LIBICONV_VER }}
key: ${{ runner.OS }}-${{ env.LIBICONV_VER }}-${{ env.CACHE_KEY }}
- name: Libiconv.
if: steps.cache-libiconv.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
wget https://ftp.gnu.org/pub/gnu/libiconv/"$LIBICONV_VER".tar.gz
tar -xvzf "$LIBICONV_VER".tar.gz
cd $LIBICONV_VER
CFLAGS="$MIN_MAC $UNGUARDED" CPPFLAGS="$MIN_MAC $UNGUARDED" LDFLAGS="$MIN_MAC" ./configure --enable-static --prefix=$PREFIX
make -j$(nproc)
- name: Libiconv install.
run: |
cd $LibrariesPath/$LIBICONV_VER
sudo make install
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/ffmpeg
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}
- name: FFmpeg.
if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone $GIT/FFmpeg/FFmpeg.git ffmpeg
cd ffmpeg
git checkout release/3.4
CFLAGS=`freetype-config --cflags`
LDFLAGS=`freetype-config --libs`
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig:/usr/X11/lib/pkgconfig
./configure --prefix=/usr/local \
--extra-cflags="$MIN_MAC $UNGUARDED" \
--extra-cxxflags="$MIN_MAC $UNGUARDED" \
--extra-ldflags="$MIN_MAC" \
--enable-protocol=file --enable-libopus \
--disable-programs \
--disable-doc \
--disable-network \
--disable-everything \
--enable-hwaccel=h264_videotoolbox \
--enable-hwaccel=hevc_videotoolbox \
--enable-hwaccel=mpeg1_videotoolbox \
--enable-hwaccel=mpeg2_videotoolbox \
--enable-hwaccel=mpeg4_videotoolbox \
--enable-decoder=aac \
--enable-decoder=aac_at \
--enable-decoder=aac_fixed \
--enable-decoder=aac_latm \
--enable-decoder=aasc \
--enable-decoder=alac \
--enable-decoder=alac_at \
--enable-decoder=flac \
--enable-decoder=gif \
--enable-decoder=h264 \
--enable-decoder=hevc \
--enable-decoder=mp1 \
--enable-decoder=mp1float \
--enable-decoder=mp2 \
--enable-decoder=mp2float \
--enable-decoder=mp3 \
--enable-decoder=mp3adu \
--enable-decoder=mp3adufloat \
--enable-decoder=mp3float \
--enable-decoder=mp3on4 \
--enable-decoder=mp3on4float \
--enable-decoder=mpeg4 \
--enable-decoder=msmpeg4v2 \
--enable-decoder=msmpeg4v3 \
--enable-decoder=opus \
--enable-decoder=pcm_alaw \
--enable-decoder=pcm_alaw_at \
--enable-decoder=pcm_f32be \
--enable-decoder=pcm_f32le \
--enable-decoder=pcm_f64be \
--enable-decoder=pcm_f64le \
--enable-decoder=pcm_lxf \
--enable-decoder=pcm_mulaw \
--enable-decoder=pcm_mulaw_at \
--enable-decoder=pcm_s16be \
--enable-decoder=pcm_s16be_planar \
--enable-decoder=pcm_s16le \
--enable-decoder=pcm_s16le_planar \
--enable-decoder=pcm_s24be \
--enable-decoder=pcm_s24daud \
--enable-decoder=pcm_s24le \
--enable-decoder=pcm_s24le_planar \
--enable-decoder=pcm_s32be \
--enable-decoder=pcm_s32le \
--enable-decoder=pcm_s32le_planar \
--enable-decoder=pcm_s64be \
--enable-decoder=pcm_s64le \
--enable-decoder=pcm_s8 \
--enable-decoder=pcm_s8_planar \
--enable-decoder=pcm_u16be \
--enable-decoder=pcm_u16le \
--enable-decoder=pcm_u24be \
--enable-decoder=pcm_u24le \
--enable-decoder=pcm_u32be \
--enable-decoder=pcm_u32le \
--enable-decoder=pcm_u8 \
--enable-decoder=pcm_zork \
--enable-decoder=vorbis \
--enable-decoder=wavpack \
--enable-decoder=wmalossless \
--enable-decoder=wmapro \
--enable-decoder=wmav1 \
--enable-decoder=wmav2 \
--enable-decoder=wmavoice \
--enable-encoder=libopus \
--enable-parser=aac \
--enable-parser=aac_latm \
--enable-parser=flac \
--enable-parser=h264 \
--enable-parser=hevc \
--enable-parser=mpeg4video \
--enable-parser=mpegaudio \
--enable-parser=opus \
--enable-parser=vorbis \
--enable-demuxer=aac \
--enable-demuxer=flac \
--enable-demuxer=gif \
--enable-demuxer=h264 \
--enable-demuxer=hevc \
--enable-demuxer=m4v \
--enable-demuxer=mov \
--enable-demuxer=mp3 \
--enable-demuxer=ogg \
--enable-demuxer=wav \
--enable-muxer=ogg \
--enable-muxer=opus
make -j$(nproc)
- name: FFmpeg install.
run: |
cd $LibrariesPath/ffmpeg
sudo make install
- name: OpenAL Soft.
run: |
cd $LibrariesPath
git clone $GIT/kcat/openal-soft.git
cd openal-soft
git checkout openal-soft-1.19.1
cd build
CFLAGS="$UNGUARDED" CPPFLAGS="$UNGUARDED" cmake \
-D CMAKE_INSTALL_PREFIX:PATH=$PREFIX \
-D ALSOFT_EXAMPLES=OFF \
-D LIBTYPE:STRING=STATIC \
-D CMAKE_OSX_DEPLOYMENT_TARGET:STRING=$MACOSX_DEPLOYMENT_TARGET ..
make -j$(nproc)
sudo make install
- name: Crashpad cache.
id: cache-crashpad
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/crashpad
key: ${{ runner.OS }}-crashpad-${{ env.CACHE_KEY }}-${{ hashFiles('**/crashpad.diff') }}-${{ hashFiles('**/mini_chromium.diff') }}
- name: Crashpad.
if: steps.cache-crashpad.outputs.cache-hit != 'true'
run: |
cd Libraries
echo Install GYP for Crashpad.
git clone https://chromium.googlesource.com/external/gyp
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
cd gyp
git checkout 9f2a7bb1
git apply $LibrariesPath/patches/gyp.diff
./setup.py build
sudo ./setup.py install
cd $LibrariesPath
git clone https://chromium.googlesource.com/crashpad/crashpad.git
cd crashpad
git checkout feb3aa3923
git apply ../patches/crashpad.diff
cd third_party/mini_chromium
git clone https://chromium.googlesource.com/chromium/mini_chromium
cd mini_chromium
git checkout 7c5b0c1ab4
git apply ../../../../patches/mini_chromium.diff
cd ../../gtest
git clone https://chromium.googlesource.com/external/github.com/google/googletest gtest
cd gtest
git checkout d62d6c6556
cd ../../..
build/gyp_crashpad.py -Dmac_deployment_target=10.10
ninja -C out/Debug
- name: Qt 5.12.5 cache.
id: cache-qt
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/qt-cache
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_5.diff') }}
- name: Use cached Qt 5.12.5.
if: steps.cache-qt.outputs.cache-hit == 'true'
run: |
cd $LibrariesPath
mv qt-cache Qt-5.12.5
sudo mkdir -p $QT_PREFIX
sudo mv -f Qt-5.12.5 /usr/local/desktop-app/
- name: Build Qt 5.12.5.
if: steps.cache-qt.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone git://code.qt.io/qt/qt5.git qt$QT
cd qt$QT
perl init-repository --module-subset=qtbase,qtimageformats
git checkout v5.12.5
git submodule update qtbase
git submodule update qtimageformats
cd qtbase
git apply ../../patches/qtbase_$QT.diff
cd ..
./configure \
-prefix "$QT_PREFIX" \
-debug \
-force-debug-info \
-opensource \
-confirm-license \
-static \
-opengl desktop \
-no-openssl \
-securetransport \
-nomake examples \
-nomake tests \
-platform macx-clang
make -j$(nproc)
sudo make install
make clean
cp -r $QT_PREFIX $LibrariesPath/qt-cache
- name: Build Telegram Desktop.
run: |
cd $REPO_NAME/Telegram
DEFINE=""
if [ -n "${{ matrix.defines }}" ]; then
DEFINE="-D ${{ matrix.defines }}=ON"
echo Define from matrix: $DEFINE
fi
./configure.sh -D TDESKTOP_API_TEST=ON -D DESKTOP_APP_USE_PACKAGED=OFF $DEFINE
cd ../out
xcoderun='xcodebuild build -project Telegram.xcodeproj -scheme Telegram -destination "platform=macOS,arch=x86_64" -configuration Debug'
bash -c "$xcoderun" || bash -c "$xcoderun" || bash -c "$xcoderun"
- name: Move artifact.
if: env.UPLOAD_ARTIFACT == 'true'
run: |
cd $REPO_NAME/out/Debug
mkdir artifact
mv Telegram.app artifact/
mv Updater artifact/
- uses: actions/upload-artifact@master
if: env.UPLOAD_ARTIFACT == 'true'
name: Upload artifact.
with:
name: Telegram
path: $REPO_NAME\out\Debug\artifact\

342
.github/workflows/win.yml vendored Normal file
View file

@ -0,0 +1,342 @@
name: Windows.
on:
push:
paths-ignore:
- 'docs/**'
- '*.md'
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'
jobs:
windows:
name: Windows
runs-on: windows-latest
strategy:
matrix:
defines:
- ""
env:
SDK: "10.0.18362.0"
VC: "call vcvars32.bat && cd Libraries"
PY2: 'C:\hostedtoolcache\windows\Python\2.7.16\x64'
GIT: "https://github.com"
QT: "5_12_5"
OPENSSL_VER: "1_1_1"
UPLOAD_ARTIFACT: "false"
MANUAL_CACHING: "1"
DOC_PATH: "docs/building-msvc.md"
steps:
- name: Get repository name.
shell: bash
run: echo ::set-env name=REPO_NAME::${GITHUB_REPOSITORY##*/}
- name: Clone.
uses: actions/checkout@v1
with:
submodules: recursive
- name: Set up environment variables.
shell: cmd
run: |
cd ..
move %REPO_NAME% temp
mkdir %REPO_NAME%
move temp %REPO_NAME%/%REPO_NAME%
cd %REPO_NAME%
echo ::add-path::C:\Strawberry\perl\bin\
echo ::add-path::"%programfiles%\NASM"
C:
cd "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\"
echo ::add-path::%cd%
call vcvars32.bat
D:
cd %GITHUB_WORKSPACE%
msbuild -version > CACHE_KEY.txt
echo %MANUAL_CACHING% >> CACHE_KEY.txt
mkdir Libraries
cd Libraries
echo ::set-env name=LibrariesPath::%cd%
- name: Generate cache key.
shell: bash
run: |
echo ::set-env name=CACHE_KEY::`md5sum CACHE_KEY.txt | awk '{ print $1 }'`
- name: Choco installs.
run: |
choco install --no-progress -y nasm yasm jom ninja
- name: Range-v3.
shell: bash
run: |
echo "Find necessary branch from doc."
cloneRange=$(grep -A 1 "range-v3" $REPO_NAME/$DOC_PATH | sed -n 1p)
cd $LibrariesPath
echo $cloneRange
eval $cloneRange
- name: Patches.
shell: bash
run: |
echo "Find necessary commit from doc."
checkoutCommit=$(grep -A 1 "cd patches" $REPO_NAME/$DOC_PATH | sed -n 2p)
cd $LibrariesPath
git clone $GIT/desktop-app/patches.git
cd Patches
eval $checkoutCommit
- name: LZMA.
shell: cmd
run: |
%VC%
git clone %GIT%/telegramdesktop/lzma.git
cd lzma
cd C\Util\LzmaLib
msbuild -m LzmaLib.sln /property:Configuration=Debug
- name: OpenSSL cache.
id: cache-openssl
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/openssl_${{ env.OPENSSL_VER }}
key: ${{ runner.OS }}-${{ env.CACHE_KEY }}-${{ env.OPENSSL_VER }}
- name: OpenSSL.
if: steps.cache-openssl.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
git clone %GIT%/openssl/openssl.git openssl_%OPENSSL_VER%
cd openssl_%OPENSSL_VER%
git checkout OpenSSL_%OPENSSL_VER%-stable
perl Configure no-shared debug-VC-WIN32
nmake
mkdir out32.dbg
move libcrypto.lib out32.dbg
move libssl.lib out32.dbg
move ossl_static.pdb out32.dbg\ossl_static
nmake clean
move out32.dbg\ossl_static out32.dbg\ossl_static.pdb
perl Configure no-shared VC-WIN32
nmake
mkdir out32
move libcrypto.lib out32
move libssl.lib out32
move ossl_static.pdb out32
rmdir /S /Q test
- name: Zlib.
shell: cmd
run: |
%VC%
git clone %GIT%/telegramdesktop/zlib.git
cd zlib
git checkout tdesktop
cd contrib\vstudio\vc14
msbuild -m zlibstat.vcxproj /property:Configuration=Debug
- name: OpenAL Soft cache.
id: cache-openal
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/openal-soft
key: ${{ runner.OS }}-openal-soft-${{ env.CACHE_KEY }}
- name: OpenAL Soft.
shell: cmd
if: steps.cache-openal.outputs.cache-hit != 'true'
run: |
%VC%
git clone %GIT%/telegramdesktop/openal-soft.git
cd openal-soft
git checkout fix_capture
cd build
cmake ^
-G "Visual Studio 16 2019" ^
-A Win32 ^
-D LIBTYPE:STRING=STATIC ^
-D FORCE_STATIC_VCRT:STRING=ON ..
msbuild -m OpenAL.vcxproj /property:Configuration=Debug
- name: Breakpad cache.
id: cache-breakpad
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/breakpad
key: ${{ runner.OS }}-breakpad-${{ env.CACHE_KEY }}-${{ hashFiles('**/breakpad.diff') }}
- name: Breakpad.
env:
GYP_MSVS_OVERRIDE_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\'
GYP_MSVS_VERSION: 2019
shell: cmd
if: steps.cache-breakpad.outputs.cache-hit != 'true'
run: |
cd %LibrariesPath%
git clone %GIT%/telegramdesktop/gyp.git
cd gyp
SET PATH=%PY2%;%cd%;%PATH%
git checkout tdesktop
cd %LibrariesPath%
git clone %GIT%/google/breakpad
cd breakpad
git checkout a1dbcdcb43
git apply ../patches/breakpad.diff
cd src
git clone %GIT%/google/googletest testing
cd client\windows
call gyp --no-circular-check breakpad_client.gyp --format=ninja
cd ..\..
ninja -C out/Debug common crash_generation_client exception_handler
ninja -C out/Release common crash_generation_client exception_handler
cd tools\windows\dump_syms
call gyp dump_syms.gyp
call vcvars32.bat
msbuild -m dump_syms.vcxproj /property:Configuration=Release
- name: Opus cache.
id: cache-opus
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/opus
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
- name: Opus.
shell: cmd
run: |
%VC%
git clone %GIT%/telegramdesktop/opus.git
cd opus
git checkout tdesktop
cd win32\VS2015
msbuild -m opus.sln /property:Configuration=Debug /property:Platform="Win32"
msbuild -m opus.sln /property:Configuration=Release /property:Platform="Win32"
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/ffmpeg
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}-${{ hashFiles('**/build_ffmpeg_win.sh') }}
- name: FFmpeg.
if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
choco install --no-progress -y msys2
git clone %GIT%/FFmpeg/FFmpeg.git ffmpeg
cd ffmpeg
git checkout release/3.4
set CHERE_INVOKING=enabled_from_arguments
set MSYS2_PATH_TYPE=inherit
call c:\tools\msys64\usr\bin\bash --login ../../%REPO_NAME%/Telegram/Patches/build_ffmpeg_win.sh
- name: Qt 5.12.5 cache.
id: cache-qt
uses: actions/cache@v1
with:
path: ${{ env.LibrariesPath }}/Qt-5.12.5
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_5.diff') }}
- name: Configure Qt 5.12.5.
if: steps.cache-qt.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
git clone git://code.qt.io/qt/qt5.git qt_%QT%
cd qt_%QT%
perl init-repository --module-subset=qtbase,qtimageformats
git checkout v5.12.5
git submodule update qtbase
git submodule update qtimageformats
cd qtbase
git apply ../../patches/qtbase_%QT%.diff
cd ..
SET SSL=%LibrariesPath%\openssl_1_1_1
SET LIBS=libcrypto.lib Ws2_32.lib Gdi32.lib Advapi32.lib Crypt32.lib User32.lib
configure ^
-prefix "%LibrariesPath%\Qt-5.12.5" ^
-debug ^
-force-debug-info ^
-opensource ^
-confirm-license ^
-static ^
-static-runtime -I "%SSL%\include" ^
-no-opengl ^
-openssl-linked ^
OPENSSL_LIBS_DEBUG="%SSL%\out32.dbg\libssl.lib %SSL%\out32.dbg\%LIBS%" ^
OPENSSL_LIBS_RELEASE="%SSL%\out32\libssl.lib %SSL%\out32\%LIBS%" ^
-mp ^
-nomake examples ^
-nomake tests ^
-platform win32-msvc
- name: Build Qt 5.12.5.
if: steps.cache-qt.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
cd qt_%QT%
jom -j%NUMBER_OF_PROCESSORS%
jom -j%NUMBER_OF_PROCESSORS% install
cd ..
rmdir /S /Q qt_%QT%
- name: Read defines.
shell: bash
run: |
DEFINE=""
if [ -n "${{ matrix.defines }}" ]; then
DEFINE="-D ${{ matrix.defines }}=ON"
echo Define from matrix: $DEFINE
fi
echo "::set-env name=TDESKTOP_BUILD_DEFINE::$DEFINE"
- name: Build Telegram Desktop.
shell: cmd
run: |
cd %REPO_NAME%\Telegram
call configure.bat ^
-D TDESKTOP_API_TEST=ON ^
-D DESKTOP_APP_USE_PACKAGED=OFF ^
%TDESKTOP_BUILD_DEFINE% ^
-DCMAKE_SYSTEM_VERSION=%SDK%
call vcvars32.bat
cd ..\out
msbuild -m Telegram.sln /nologo /p:Configuration=Debug,Platform=Win32
- name: Move artifact.
if: env.UPLOAD_ARTIFACT == 'true'
run: |
cd %REPO_NAME%\out\Debug
mkdir artifact
move Telegram.exe artifact/
move Updater.exe artifact/
- uses: actions/upload-artifact@master
name: Upload artifact.
if: env.UPLOAD_ARTIFACT == 'true'
with:
name: Telegram
path: ${{ env.REPO_NAME }}\out\Debug\artifact\

1
.gitignore vendored
View file

@ -43,6 +43,7 @@ stage
/snap/plugins/__pycache__ /snap/plugins/__pycache__
/Telegram/*.user.* /Telegram/*.user.*
*.txt.user
*.pro.user *.pro.user
/Linux/ /Linux/
/Telegram/Makefile /Telegram/Makefile

15
.gitmodules vendored
View file

@ -49,3 +49,18 @@
[submodule "Telegram/lib_spellcheck"] [submodule "Telegram/lib_spellcheck"]
path = Telegram/lib_spellcheck path = Telegram/lib_spellcheck
url = https://github.com/desktop-app/lib_spellcheck url = https://github.com/desktop-app/lib_spellcheck
[submodule "Telegram/lib_storage"]
path = Telegram/lib_storage
url = https://github.com/desktop-app/lib_storage.git
[submodule "cmake"]
path = cmake
url = https://github.com/desktop-app/cmake_helpers.git
[submodule "Telegram/ThirdParty/expected"]
path = Telegram/ThirdParty/expected
url = https://github.com/TartanLlama/expected
[submodule "Telegram/ThirdParty/QR"]
path = Telegram/ThirdParty/QR
url = https://github.com/nayuki/QR-Code-generator
[submodule "Telegram/lib_qr"]
path = Telegram/lib_qr
url = https://github.com/desktop-app/lib_qr.git

View file

@ -43,12 +43,14 @@ addons:
- liblzma-dev - liblzma-dev
- libopus-dev - libopus-dev
- libpulse-dev - libpulse-dev
- libenchant-dev
- libssl-dev - libssl-dev
- libdee-dev - libdee-dev
- libva-dev - libva-dev
- libvdpau-dev - libvdpau-dev
- libxcb-xkb-dev - libxcb-xkb-dev
- libxkbcommon-dev - libxkbcommon-dev
- libatspi2.0-dev
- lintian - lintian
- quilt - quilt
- valac - valac

View file

@ -17,7 +17,7 @@ XKB_PATH="$BUILD/libxkbcommon"
XKB_CACHE_VERSION="3" XKB_CACHE_VERSION="3"
QT_PATH="$BUILD/qt" QT_PATH="$BUILD/qt"
QT_CACHE_VERSION="4" QT_CACHE_VERSION="5"
QT_PATCH="$EXTERNAL/patches/qtbase_${QT_VERSION//\./_}.diff" QT_PATCH="$EXTERNAL/patches/qtbase_${QT_VERSION//\./_}.diff"
BREAKPAD_PATH="$BUILD/breakpad" BREAKPAD_PATH="$BUILD/breakpad"
@ -694,7 +694,6 @@ buildTelegram() {
-Dlinux_path_qt=$QT_PATH \ -Dlinux_path_qt=$QT_PATH \
-Dlinux_path_breakpad=$BREAKPAD_PATH \ -Dlinux_path_breakpad=$BREAKPAD_PATH \
-Dlinux_path_libexif_lib=/usr/local/lib \ -Dlinux_path_libexif_lib=/usr/local/lib \
-Dlinux_path_opus_include=/usr/include/opus \
-Dlinux_lib_ssl=-lssl \ -Dlinux_lib_ssl=-lssl \
-Dlinux_lib_crypto=-lcrypto \ -Dlinux_lib_crypto=-lcrypto \
-Dlinux_lib_icu=-licuuc\ -licutu\ -licui18n \ -Dlinux_lib_icu=-licuuc\ -licutu\ -licui18n \

37
CMakeLists.txt Normal file
View file

@ -0,0 +1,37 @@
# This file is part of Telegram Desktop,
# the official desktop application for the Telegram messaging service.
#
# For license and copyright information please follow this link:
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
cmake_minimum_required(VERSION 3.16)
cmake_policy(SET CMP0076 NEW)
cmake_policy(SET CMP0091 NEW)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
include(cmake/validate_special_target.cmake)
include(cmake/version.cmake)
desktop_app_parse_version(Telegram/build/version)
project(Telegram
LANGUAGES C CXX
VERSION ${desktop_app_version_cmake}
DESCRIPTION "Official Telegram Desktop messenger"
HOMEPAGE_URL "https://desktop.telegram.org"
)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Telegram)
include(cmake/variables.cmake)
include(cmake/nice_target_sources.cmake)
include(cmake/target_link_static_libraries.cmake)
include(cmake/target_link_frameworks.cmake)
include(cmake/init_target.cmake)
include(cmake/generate_target.cmake)
include(cmake/options.cmake)
include(cmake/external/qt/package.cmake)
add_subdirectory(cmake)
add_subdirectory(Telegram)

2
LEGAL
View file

@ -1,7 +1,7 @@
This file is part of Telegram Desktop, This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service. the official desktop application for the Telegram messaging service.
Copyright (c) 2014-2019 John Preston, https://desktop.telegram.org Copyright (c) 2014-2020 The Telegram Desktop Authors.
Telegram Desktop is free software: you can redistribute it and/or modify Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

1187
Telegram/CMakeLists.txt Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -178,8 +178,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_photo_caption" = "Caption"; "lng_photo_caption" = "Caption";
"lng_photos_comment" = "Comment"; "lng_photos_comment" = "Comment";
"lng_intro_qr_title" = "Scan From Mobile Telegram";
"lng_intro_qr_step1" = "Open Telegram on your phone";
"lng_intro_qr_step2" = "Go to Settings > Devices > Scan QR Code";
"lng_intro_qr_step3" = "Scan this image to Log In";
"lng_intro_qr_skip" = "Or log in using your phone number";
"lng_phone_title" = "Your Phone Number"; "lng_phone_title" = "Your Phone Number";
"lng_phone_desc" = "Please confirm your country code and\nenter your mobile phone number."; "lng_phone_desc" = "Please confirm your country code and\nenter your mobile phone number.";
"lng_phone_to_qr" = "Quick log in using QR code";
"lng_country_code" = "Country Code"; "lng_country_code" = "Country Code";
"lng_bad_country_code" = "Invalid Country Code"; "lng_bad_country_code" = "Invalid Country Code";
"lng_country_ph" = "Search"; "lng_country_ph" = "Search";
@ -408,7 +415,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_system_integration" = "System integration"; "lng_settings_system_integration" = "System integration";
"lng_settings_performance" = "Performance"; "lng_settings_performance" = "Performance";
"lng_settings_enable_animations" = "Enable animations"; "lng_settings_enable_animations" = "Enable animations";
"lng_settings_autoplay_gifs" = "Autoplay GIFs"; "lng_settings_sensitive_title" = "Sensitive content";
"lng_settings_sensitive_disable_filtering" = "Disable filtering";
"lng_settings_sensitive_about" = "Display sensitive media in public channels on all your Telegram devices.";
"lng_settings_spellchecker" = "Spell checker"; "lng_settings_spellchecker" = "Spell checker";
"lng_settings_system_spellchecker" = "Use system spell checker"; "lng_settings_system_spellchecker" = "Use system spell checker";
@ -1143,12 +1152,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_media_auto_in_groups" = "In groups"; "lng_media_auto_in_groups" = "In groups";
"lng_media_auto_in_channels" = "In channels"; "lng_media_auto_in_channels" = "In channels";
"lng_media_auto_title" = "Automatically download"; "lng_media_auto_title" = "Automatically download";
"lng_media_auto_play" = "Autoplay";
"lng_media_photo_title" = "Photos"; "lng_media_photo_title" = "Photos";
"lng_media_video_title" = "Video files"; "lng_media_video_title" = "Video files";
"lng_media_audio_title" = "Voice messages";
"lng_media_video_messages_title" = "Round video messages"; "lng_media_video_messages_title" = "Round video messages";
"lng_media_file_title" = "Files"; "lng_media_file_title" = "Files";
"lng_media_music_title" = "Music";
"lng_media_animation_title" = "Animated GIFs"; "lng_media_animation_title" = "Animated GIFs";
"lng_media_size_limit" = "Limit by size"; "lng_media_size_limit" = "Limit by size";
"lng_media_size_up_to" = "up to {size}"; "lng_media_size_up_to" = "up to {size}";
@ -2231,6 +2239,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_mac_menu_new_group" = "New Group"; "lng_mac_menu_new_group" = "New Group";
"lng_mac_menu_new_channel" = "New Channel"; "lng_mac_menu_new_channel" = "New Channel";
"lng_mac_menu_show" = "Show Telegram"; "lng_mac_menu_show" = "Show Telegram";
"lng_mac_menu_emoji_and_symbols" = "Emoji & Symbols";
"lng_mac_touchbar_favorite_stickers" = "Favorite stickers"; "lng_mac_touchbar_favorite_stickers" = "Favorite stickers";

View file

@ -89,6 +89,7 @@ inputDocumentFileLocation#bad07584 id:long access_hash:long file_reference:bytes
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation; inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
inputTakeoutFileLocation#29be5899 = InputFileLocation; inputTakeoutFileLocation#29be5899 = InputFileLocation;
inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation; inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation;
inputPhotoLegacyFileLocation#d83466f3 id:long access_hash:long file_reference:bytes volume_id:long local_id:int secret:long = InputFileLocation;
inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation; inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation;
inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation; inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation;
@ -213,6 +214,7 @@ peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bo
peerSettings#818426cd flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true = PeerSettings; peerSettings#818426cd flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true = PeerSettings;
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper; wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
wallPaperNoFile#8af40b25 flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
inputReportReasonSpam#58dbcab8 = ReportReason; inputReportReasonSpam#58dbcab8 = ReportReason;
inputReportReasonViolence#1e22c78d = ReportReason; inputReportReasonViolence#1e22c78d = ReportReason;
@ -347,6 +349,8 @@ updatePeerLocated#b4afcfb0 peers:Vector<PeerLocated> = Update;
updateNewScheduledMessage#39a51dfb message:Message = Update; updateNewScheduledMessage#39a51dfb message:Message = Update;
updateDeleteScheduledMessages#90866cee peer:Peer messages:Vector<int> = Update; updateDeleteScheduledMessages#90866cee peer:Peer messages:Vector<int> = Update;
updateTheme#8216fba3 theme:Theme = Update; updateTheme#8216fba3 theme:Theme = Update;
updateGeoLiveViewed#871fb939 peer:Peer msg_id:int = Update;
updateLoginToken#564fe691 = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -496,7 +500,7 @@ messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMess
webPageEmpty#eb1477e8 id:long = WebPage; webPageEmpty#eb1477e8 id:long = WebPage;
webPagePending#c586da1c id:long date:int = WebPage; webPagePending#c586da1c id:long date:int = WebPage;
webPage#fa64e172 flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document documents:flags.11?Vector<Document> cached_page:flags.10?Page = WebPage; webPage#e89c45b2 flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector<WebPageAttribute> = WebPage;
webPageNotModified#85849473 = WebPage; webPageNotModified#85849473 = WebPage;
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization; authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
@ -1027,15 +1031,16 @@ chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags
inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper; inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
inputWallPaperSlug#72091c80 slug:string = InputWallPaper; inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
inputWallPaperNoFile#8427bbac = InputWallPaper;
account.wallPapersNotModified#1c199183 = account.WallPapers; account.wallPapersNotModified#1c199183 = account.WallPapers;
account.wallPapers#702b65a9 hash:int wallpapers:Vector<WallPaper> = account.WallPapers; account.wallPapers#702b65a9 hash:int wallpapers:Vector<WallPaper> = account.WallPapers;
codeSettings#debebe83 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true = CodeSettings; codeSettings#debebe83 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true = CodeSettings;
wallPaperSettings#a12f40b8 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int intensity:flags.3?int = WallPaperSettings; wallPaperSettings#5086cf8 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int intensity:flags.3?int rotation:flags.4?int = WallPaperSettings;
autoDownloadSettings#d246fd47 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true photo_size_max:int video_size_max:int file_size_max:int = AutoDownloadSettings; autoDownloadSettings#e04232f3 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true photo_size_max:int video_size_max:int file_size_max:int video_upload_maxbitrate:int = AutoDownloadSettings;
account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings; account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings;
@ -1073,7 +1078,7 @@ inputTheme#3c5693e9 id:long access_hash:long = InputTheme;
inputThemeSlug#f5890df1 slug:string = InputTheme; inputThemeSlug#f5890df1 slug:string = InputTheme;
themeDocumentNotModified#483d270c = Theme; themeDocumentNotModified#483d270c = Theme;
theme#f7d90ce0 flags:# creator:flags.0?true default:flags.1?true id:long access_hash:long slug:string title:string document:flags.2?Document installs_count:int = Theme; theme#28f1114 flags:# creator:flags.0?true default:flags.1?true id:long access_hash:long slug:string title:string document:flags.2?Document settings:flags.3?ThemeSettings installs_count:int = Theme;
account.themesNotModified#f41eb622 = account.Themes; account.themesNotModified#f41eb622 = account.Themes;
account.themes#7f676421 hash:int themes:Vector<Theme> = account.Themes; account.themes#7f676421 hash:int themes:Vector<Theme> = account.Themes;
@ -1082,6 +1087,26 @@ wallet.liteResponse#764386d7 response:bytes = wallet.LiteResponse;
wallet.secretSalt#dd484d64 salt:bytes = wallet.KeySecretSalt; wallet.secretSalt#dd484d64 salt:bytes = wallet.KeySecretSalt;
auth.loginToken#629f1980 expires:int token:bytes = auth.LoginToken;
auth.loginTokenMigrateTo#68e9916 dc_id:int token:bytes = auth.LoginToken;
auth.loginTokenSuccess#390d5c5e authorization:auth.Authorization = auth.LoginToken;
account.contentSettings#57e28221 flags:# sensitive_enabled:flags.0?true sensitive_can_change:flags.1?true = account.ContentSettings;
messages.inactiveChats#a927fec5 dates:Vector<int> chats:Vector<Chat> users:Vector<User> = messages.InactiveChats;
baseThemeClassic#c3a12462 = BaseTheme;
baseThemeDay#fbd81688 = BaseTheme;
baseThemeNight#b7b31ea8 = BaseTheme;
baseThemeTinted#6d5f77ee = BaseTheme;
baseThemeArctic#5b11125a = BaseTheme;
inputThemeSettings#bd507cd1 flags:# base_theme:BaseTheme accent_color:int message_top_color:flags.0?int message_bottom_color:flags.0?int wallpaper:flags.1?InputWallPaper wallpaper_settings:flags.1?WallPaperSettings = InputThemeSettings;
themeSettings#9c14984a flags:# base_theme:BaseTheme accent_color:int message_top_color:flags.0?int message_bottom_color:flags.0?int wallpaper:flags.1?WallPaper = ThemeSettings;
webPageAttributeTheme#54b56617 flags:# documents:flags.0?Vector<Document> settings:flags.1?ThemeSettings = WebPageAttribute;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1107,6 +1132,9 @@ auth.recoverPassword#4ea56e92 code:string = auth.Authorization;
auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentCode; auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentCode;
auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool; auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool; auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
auth.exportLoginToken#b1b41517 api_id:int api_hash:string except_ids:Vector<int> = auth.LoginToken;
auth.importLoginToken#95ac5ce4 token:bytes = auth.LoginToken;
auth.acceptLoginToken#e894ad4d token:bytes = Authorization;
account.registerDevice#68976c6f flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool; account.registerDevice#68976c6f flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool;
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool; account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
@ -1164,12 +1192,15 @@ account.resetWallPapers#bb3b9804 = Bool;
account.getAutoDownloadSettings#56da0b3f = account.AutoDownloadSettings; account.getAutoDownloadSettings#56da0b3f = account.AutoDownloadSettings;
account.saveAutoDownloadSettings#76f36233 flags:# low:flags.0?true high:flags.1?true settings:AutoDownloadSettings = Bool; account.saveAutoDownloadSettings#76f36233 flags:# low:flags.0?true high:flags.1?true settings:AutoDownloadSettings = Bool;
account.uploadTheme#1c3db333 flags:# file:InputFile thumb:flags.0?InputFile file_name:string mime_type:string = Document; account.uploadTheme#1c3db333 flags:# file:InputFile thumb:flags.0?InputFile file_name:string mime_type:string = Document;
account.createTheme#2b7ffd7f slug:string title:string document:InputDocument = Theme; account.createTheme#8432c21f flags:# slug:string title:string document:flags.2?InputDocument settings:flags.3?InputThemeSettings = Theme;
account.updateTheme#3b8ea202 flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument = Theme; account.updateTheme#5cb367d5 flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument settings:flags.3?InputThemeSettings = Theme;
account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool; account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool;
account.installTheme#7ae43737 flags:# dark:flags.0?true format:flags.1?string theme:flags.1?InputTheme = Bool; account.installTheme#7ae43737 flags:# dark:flags.0?true format:flags.1?string theme:flags.1?InputTheme = Bool;
account.getTheme#8d9d742b format:string theme:InputTheme document_id:long = Theme; account.getTheme#8d9d742b format:string theme:InputTheme document_id:long = Theme;
account.getThemes#285946f8 format:string hash:int = account.Themes; account.getThemes#285946f8 format:string hash:int = account.Themes;
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
account.getContentSettings#8b9b4dae = account.ContentSettings;
account.getMultiWallPapers#65ad71dc wallpapers:Vector<InputWallPaper> = Vector<WallPaper>;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>; users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull; users.getFullUser#ca30a5b1 id:InputUser = UserFull;
@ -1385,6 +1416,7 @@ channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel =
channels.editCreator#8f38cd1f channel:InputChannel user_id:InputUser password:InputCheckPasswordSRP = Updates; channels.editCreator#8f38cd1f channel:InputChannel user_id:InputUser password:InputCheckPasswordSRP = Updates;
channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint address:string = Bool; channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint address:string = Bool;
channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates; channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates;
channels.getInactiveChannels#11e831ee = messages.InactiveChats;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
@ -1422,4 +1454,4 @@ folders.deleteFolder#1c295881 folder_id:int = Updates;
wallet.sendLiteRequest#e2c9d33e body:bytes = wallet.LiteResponse; wallet.sendLiteRequest#e2c9d33e body:bytes = wallet.LiteResponse;
wallet.getKeySecretSalt#b57f346 revoke:Bool = wallet.KeySecretSalt; wallet.getKeySecretSalt#b57f346 revoke:Bool = wallet.KeySecretSalt;
// LAYER 106 // LAYER 108

View file

@ -21,6 +21,8 @@ p_q_inner_data_dc#a9f55f95 pq:string p:string q:string nonce:int128 server_nonce
p_q_inner_data_temp#3c6a84d4 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data; p_q_inner_data_temp#3c6a84d4 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data;
p_q_inner_data_temp_dc#56fddf88 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data; p_q_inner_data_temp_dc#56fddf88 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data;
bind_auth_key_inner#75a3f765 nonce:long temp_auth_key_id:long perm_auth_key_id:long temp_session_id:long expires_at:int = BindAuthKeyInner;
server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params; server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params;
server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params; server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;

View file

@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop" <Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE" ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A" Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="1.9.1.0" /> Version="1.9.4.0" />
<Properties> <Properties>
<DisplayName>Telegram Desktop</DisplayName> <DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName> <PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>

View file

@ -0,0 +1,51 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_self_destruct.h"
#include "apiwrap.h"
namespace Api {
SelfDestruct::SelfDestruct(not_null<ApiWrap*> api)
: _api(api->instance()) {
}
void SelfDestruct::reload() {
if (_requestId) {
return;
}
_requestId = _api.request(MTPaccount_GetAccountTTL(
)).done([=](const MTPAccountDaysTTL &result) {
_requestId = 0;
result.match([&](const MTPDaccountDaysTTL &data) {
_days = data.vdays().v;
});
}).fail([=](const RPCError &error) {
_requestId = 0;
}).send();
}
rpl::producer<int> SelfDestruct::days() const {
using namespace rpl::mappers;
return _days.value() | rpl::filter(_1 != 0);
}
void SelfDestruct::update(int days) {
_api.request(_requestId).cancel();
_requestId = _api.request(MTPaccount_SetAccountTTL(
MTP_accountDaysTTL(MTP_int(days))
)).done([=](const MTPBool &result) {
_requestId = 0;
}).fail([=](const RPCError &result) {
_requestId = 0;
}).send();
_days = days;
}
} // namespace Api

View file

@ -0,0 +1,32 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/sender.h"
class ApiWrap;
namespace Api {
class SelfDestruct final {
public:
explicit SelfDestruct(not_null<ApiWrap*> api);
void reload();
void update(int days);
rpl::producer<int> days() const;
private:
MTP::Sender _api;
mtpRequestId _requestId = 0;
rpl::variable<int> _days = 0;
};
} // namespace Api

View file

@ -0,0 +1,74 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_sensitive_content.h"
#include "apiwrap.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
namespace Api {
namespace {
constexpr auto kRefreshAppConfigTimeout = 3 * crl::time(1000);
} // namespace
SensitiveContent::SensitiveContent(not_null<ApiWrap*> api)
: _session(&api->session())
, _api(api->instance())
, _appConfigReloadTimer([=] { _session->account().appConfig().refresh(); }) {
}
void SensitiveContent::reload() {
if (_requestId) {
return;
}
_requestId = _api.request(MTPaccount_GetContentSettings(
)).done([=](const MTPaccount_ContentSettings &result) {
_requestId = 0;
result.match([&](const MTPDaccount_contentSettings &data) {
_enabled = data.is_sensitive_enabled();
_canChange = data.is_sensitive_can_change();
});
}).fail([=](const RPCError &error) {
_requestId = 0;
}).send();
}
bool SensitiveContent::enabledCurrent() const {
return _enabled.current();
}
rpl::producer<bool> SensitiveContent::enabled() const {
return _enabled.value();
}
rpl::producer<bool> SensitiveContent::canChange() const {
return _canChange.value();
}
void SensitiveContent::update(bool enabled) {
if (!_canChange.current()) {
return;
}
using Flag = MTPaccount_SetContentSettings::Flag;
_api.request(_requestId).cancel();
_requestId = _api.request(MTPaccount_SetContentSettings(
MTP_flags(enabled ? Flag::f_sensitive_enabled : Flag(0))
)).done([=](const MTPBool &result) {
_requestId = 0;
}).fail([=](const RPCError &error) {
_requestId = 0;
}).send();
_enabled = enabled;
_appConfigReloadTimer.callOnce(kRefreshAppConfigTimeout);
}
} // namespace Api

View file

@ -0,0 +1,42 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/sender.h"
#include "base/timer.h"
class ApiWrap;
namespace Main {
class Session;
} // namespace Main
namespace Api {
class SensitiveContent final {
public:
explicit SensitiveContent(not_null<ApiWrap*> api);
void reload();
void update(bool enabled);
[[nodiscard]] bool enabledCurrent() const;
[[nodiscard]] rpl::producer<bool> enabled() const;
[[nodiscard]] rpl::producer<bool> canChange() const;
private:
const not_null<Main::Session*> _session;
MTP::Sender _api;
mtpRequestId _requestId = 0;
rpl::variable<bool> _enabled = false;
rpl::variable<bool> _canChange = false;
base::Timer _appConfigReloadTimer;
};
} // namespace Api

View file

@ -8,6 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h" #include "apiwrap.h"
#include "api/api_text_entities.h" #include "api/api_text_entities.h"
#include "api/api_self_destruct.h"
#include "api/api_sensitive_content.h"
#include "data/data_drafts.h" #include "data/data_drafts.h"
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_web_page.h" #include "data/data_web_page.h"
@ -40,6 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
//#include "history/feed/history_feed_section.h" // #feed //#include "history/feed/history_feed_section.h" // #feed
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "main/main_account.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "boxes/stickers_box.h" #include "boxes/stickers_box.h"
#include "boxes/sticker_set_box.h" #include "boxes/sticker_set_box.h"
@ -54,7 +57,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/emoji_config.h" #include "ui/emoji_config.h"
#include "support/support_helper.h" #include "support/support_helper.h"
#include "storage/localimageloader.h" #include "storage/localimageloader.h"
#include "storage/file_download.h" #include "storage/download_manager_mtproto.h"
#include "storage/file_upload.h" #include "storage/file_upload.h"
#include "storage/storage_facade.h" #include "storage/storage_facade.h"
#include "storage/storage_shared_media.h" #include "storage/storage_shared_media.h"
@ -222,7 +225,8 @@ bool ApiWrap::BlockedUsersSlice::operator!=(const BlockedUsersSlice &other) cons
} }
ApiWrap::ApiWrap(not_null<Main::Session*> session) ApiWrap::ApiWrap(not_null<Main::Session*> session)
: _session(session) : MTP::Sender(session->account().mtp())
, _session(session)
, _messageDataResolveDelayed([=] { resolveMessageDatas(); }) , _messageDataResolveDelayed([=] { resolveMessageDatas(); })
, _webPagesTimer([=] { resolveWebPages(); }) , _webPagesTimer([=] { resolveWebPages(); })
, _draftsSaveTimer([=] { saveDraftsToCloud(); }) , _draftsSaveTimer([=] { saveDraftsToCloud(); })
@ -231,7 +235,9 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
, _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout)) , _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout))
//, _feedReadTimer([=] { readFeeds(); }) // #feed //, _feedReadTimer([=] { readFeeds(); }) // #feed
, _proxyPromotionTimer([=] { refreshProxyPromotion(); }) , _proxyPromotionTimer([=] { refreshProxyPromotion(); })
, _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); }) { , _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); })
, _selfDestruct(std::make_unique<Api::SelfDestruct>(this))
, _sensitiveContent(std::make_unique<Api::SensitiveContent>(this)) {
crl::on_main([=] { crl::on_main([=] {
// You can't use _session->lifetime() in the constructor, // You can't use _session->lifetime() in the constructor,
// only queued, because it is not constructed yet. // only queued, because it is not constructed yet.
@ -244,6 +250,8 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
}); });
} }
ApiWrap::~ApiWrap() = default;
Main::Session &ApiWrap::session() const { Main::Session &ApiWrap::session() const {
return *_session; return *_session;
} }
@ -280,11 +288,11 @@ void ApiWrap::refreshProxyPromotion() {
return; return;
} }
const auto key = [&]() -> std::pair<QString, uint32> { const auto key = [&]() -> std::pair<QString, uint32> {
if (Global::ProxySettings() != ProxyData::Settings::Enabled) { if (Global::ProxySettings() != MTP::ProxyData::Settings::Enabled) {
return {}; return {};
} }
const auto &proxy = Global::SelectedProxy(); const auto &proxy = Global::SelectedProxy();
if (proxy.type != ProxyData::Type::Mtproto) { if (proxy.type != MTP::ProxyData::Type::Mtproto) {
return {}; return {};
} }
return { proxy.host, proxy.port }; return { proxy.host, proxy.port };
@ -2971,12 +2979,12 @@ void ApiWrap::requestFileReference(
void ApiWrap::refreshFileReference( void ApiWrap::refreshFileReference(
Data::FileOrigin origin, Data::FileOrigin origin,
not_null<mtpFileLoader*> loader, not_null<Storage::DownloadMtprotoTask*> task,
int requestId, int requestId,
const QByteArray &current) { const QByteArray &current) {
return refreshFileReference(origin, crl::guard(loader, [=]( return refreshFileReference(origin, crl::guard(task, [=](
const UpdatedFileReferences &data) { const UpdatedFileReferences &data) {
loader->refreshFileReferenceFrom(data, requestId, current); task->refreshFileReferenceFrom(data, requestId, current);
})); }));
} }
@ -5798,42 +5806,12 @@ auto ApiWrap::blockedUsersSlice() -> rpl::producer<BlockedUsersSlice> {
: (_blockedUsersChanges.events() | rpl::type_erased()); : (_blockedUsersChanges.events() | rpl::type_erased());
} }
void ApiWrap::reloadSelfDestruct() { Api::SelfDestruct &ApiWrap::selfDestruct() {
if (_selfDestructRequestId) { return *_selfDestruct;
return;
}
_selfDestructRequestId = request(MTPaccount_GetAccountTTL(
)).done([=](const MTPAccountDaysTTL &result) {
_selfDestructRequestId = 0;
result.match([&](const MTPDaccountDaysTTL &data) {
setSelfDestructDays(data.vdays().v);
});
}).fail([=](const RPCError &error) {
_selfDestructRequestId = 0;
}).send();
} }
rpl::producer<int> ApiWrap::selfDestructValue() const { Api::SensitiveContent &ApiWrap::sensitiveContent() {
return _selfDestructDays return *_sensitiveContent;
? _selfDestructChanges.events_starting_with_copy(*_selfDestructDays)
: (_selfDestructChanges.events() | rpl::type_erased());
}
void ApiWrap::saveSelfDestruct(int days) {
request(_selfDestructRequestId).cancel();
_selfDestructRequestId = request(MTPaccount_SetAccountTTL(
MTP_accountDaysTTL(MTP_int(days))
)).done([=](const MTPBool &result) {
_selfDestructRequestId = 0;
}).fail([=](const RPCError &result) {
_selfDestructRequestId = 0;
}).send();
setSelfDestructDays(days);
}
void ApiWrap::setSelfDestructDays(int days) {
_selfDestructDays = days;
_selfDestructChanges.fire_copy(days);
} }
void ApiWrap::createPoll( void ApiWrap::createPoll(
@ -6105,5 +6083,3 @@ void ApiWrap::sendReadRequest(not_null<PeerData*> peer, MsgId upTo) {
}(); }();
_readRequests.emplace(peer, requestId, upTo); _readRequests.emplace(peer, requestId, upTo);
} }
ApiWrap::~ApiWrap() = default;

View file

@ -20,7 +20,6 @@ struct MessageGroupId;
struct SendingAlbum; struct SendingAlbum;
enum class SendMediaType; enum class SendMediaType;
struct FileLoadTo; struct FileLoadTo;
class mtpFileLoader;
namespace Main { namespace Main {
class Session; class Session;
@ -38,6 +37,7 @@ class Result;
namespace Storage { namespace Storage {
enum class SharedMediaType : signed char; enum class SharedMediaType : signed char;
struct PreparedList; struct PreparedList;
class DownloadMtprotoTask;
} // namespace Storage } // namespace Storage
namespace Dialogs { namespace Dialogs {
@ -83,6 +83,9 @@ QString RequestKey(Types &&...values) {
return result; return result;
} }
class SelfDestruct;
class SensitiveContent;
} // namespace Api } // namespace Api
class ApiWrap : public MTP::Sender, private base::Subscriber { class ApiWrap : public MTP::Sender, private base::Subscriber {
@ -131,6 +134,7 @@ public:
}; };
explicit ApiWrap(not_null<Main::Session*> session); explicit ApiWrap(not_null<Main::Session*> session);
~ApiWrap();
Main::Session &session() const; Main::Session &session() const;
@ -201,7 +205,7 @@ public:
FileReferencesHandler &&handler); FileReferencesHandler &&handler);
void refreshFileReference( void refreshFileReference(
Data::FileOrigin origin, Data::FileOrigin origin,
not_null<mtpFileLoader*> loader, not_null<Storage::DownloadMtprotoTask*> task,
int requestId, int requestId,
const QByteArray &current); const QByteArray &current);
@ -465,9 +469,8 @@ public:
void reloadBlockedUsers(); void reloadBlockedUsers();
rpl::producer<BlockedUsersSlice> blockedUsersSlice(); rpl::producer<BlockedUsersSlice> blockedUsersSlice();
void reloadSelfDestruct(); [[nodiscard]] Api::SelfDestruct &selfDestruct();
rpl::producer<int> selfDestructValue() const; [[nodiscard]] Api::SensitiveContent &sensitiveContent();
void saveSelfDestruct(int days);
void createPoll( void createPoll(
const PollData &data, const PollData &data,
@ -480,8 +483,6 @@ public:
void closePoll(not_null<HistoryItem*> item); void closePoll(not_null<HistoryItem*> item);
void reloadPollResults(not_null<HistoryItem*> item); void reloadPollResults(not_null<HistoryItem*> item);
~ApiWrap();
private: private:
struct MessageDataRequest { struct MessageDataRequest {
using Callbacks = QList<RequestMessageDataCallback>; using Callbacks = QList<RequestMessageDataCallback>;
@ -679,8 +680,6 @@ private:
const QVector<MTPPrivacyRule> &rules); const QVector<MTPPrivacyRule> &rules);
void updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules); void updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules);
void setSelfDestructDays(int days);
void migrateDone( void migrateDone(
not_null<PeerData*> peer, not_null<PeerData*> peer,
not_null<ChannelData*> channel); not_null<ChannelData*> channel);
@ -874,9 +873,8 @@ private:
std::optional<BlockedUsersSlice> _blockedUsersSlice; std::optional<BlockedUsersSlice> _blockedUsersSlice;
rpl::event_stream<BlockedUsersSlice> _blockedUsersChanges; rpl::event_stream<BlockedUsersSlice> _blockedUsersChanges;
mtpRequestId _selfDestructRequestId = 0; const std::unique_ptr<Api::SelfDestruct> _selfDestruct;
std::optional<int> _selfDestructDays; const std::unique_ptr<Api::SensitiveContent> _sensitiveContent;
rpl::event_stream<int> _selfDestructChanges;
base::flat_map<FullMsgId, mtpRequestId> _pollVotesRequestIds; base::flat_map<FullMsgId, mtpRequestId> _pollVotesRequestIds;
base::flat_map<FullMsgId, mtpRequestId> _pollCloseRequestIds; base::flat_map<FullMsgId, mtpRequestId> _pollCloseRequestIds;

View file

@ -316,12 +316,12 @@ namespace App {
} }
QImage readImage(QByteArray data, QByteArray *format, bool opaque, bool *animated) { QImage readImage(QByteArray data, QByteArray *format, bool opaque, bool *animated) {
QByteArray tmpFormat; QByteArray tmpFormat;
QImage result; QImage result;
QBuffer buffer(&data); QBuffer buffer(&data);
if (!format) { if (!format) {
format = &tmpFormat; format = &tmpFormat;
} }
{ {
QImageReader reader(&buffer, *format); QImageReader reader(&buffer, *format);
#ifndef OS_MAC_OLD #ifndef OS_MAC_OLD

View file

@ -203,7 +203,7 @@ void ShowAddParticipantsError(
Ui::show(Box<InformBox>(text), Ui::LayerOption::KeepOther); Ui::show(Box<InformBox>(text), Ui::LayerOption::KeepOther);
} }
class RevokePublicLinkBox::Inner : public TWidget, private MTP::Sender { class RevokePublicLinkBox::Inner : public TWidget {
public: public:
Inner( Inner(
QWidget *parent, QWidget *parent,
@ -228,6 +228,7 @@ private:
void updateSelected(); void updateSelected();
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api;
PeerData *_selected = nullptr; PeerData *_selected = nullptr;
PeerData *_pressed = nullptr; PeerData *_pressed = nullptr;
@ -450,6 +451,7 @@ GroupInfoBox::GroupInfoBox(
const QString &title, const QString &title,
Fn<void(not_null<ChannelData*>)> channelDone) Fn<void(not_null<ChannelData*>)> channelDone)
: _navigation(navigation) : _navigation(navigation)
, _api(_navigation->session().api().instance())
, _type(type) , _type(type)
, _initialTitle(title) , _initialTitle(title)
, _channelDone(std::move(channelDone)) { , _channelDone(std::move(channelDone)) {
@ -569,7 +571,7 @@ void GroupInfoBox::createGroup(
if (inputs.empty()) { if (inputs.empty()) {
return; return;
} }
_creationRequestId = request(MTPmessages_CreateChat( _creationRequestId = _api.request(MTPmessages_CreateChat(
MTP_vector<MTPInputUser>(inputs), MTP_vector<MTPInputUser>(inputs),
MTP_string(title) MTP_string(title)
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
@ -645,7 +647,7 @@ void GroupInfoBox::createChannel(const QString &title, const QString &descriptio
const auto flags = (_type == Type::Megagroup) const auto flags = (_type == Type::Megagroup)
? MTPchannels_CreateChannel::Flag::f_megagroup ? MTPchannels_CreateChannel::Flag::f_megagroup
: MTPchannels_CreateChannel::Flag::f_broadcast; : MTPchannels_CreateChannel::Flag::f_broadcast;
_creationRequestId = request(MTPchannels_CreateChannel( _creationRequestId = _api.request(MTPchannels_CreateChannel(
MTP_flags(flags), MTP_flags(flags),
MTP_string(title), MTP_string(title),
MTP_string(description), MTP_string(description),
@ -682,7 +684,7 @@ void GroupInfoBox::createChannel(const QString &title, const QString &descriptio
std::move(image)); std::move(image));
} }
_createdChannel = channel; _createdChannel = channel;
_creationRequestId = request(MTPmessages_ExportChatInvite( _creationRequestId = _api.request(MTPmessages_ExportChatInvite(
_createdChannel->input _createdChannel->input
)).done([=](const MTPExportedChatInvite &result) { )).done([=](const MTPExportedChatInvite &result) {
_creationRequestId = 0; _creationRequestId = 0;
@ -1287,6 +1289,7 @@ RevokePublicLinkBox::Inner::Inner(
Fn<void()> revokeCallback) Fn<void()> revokeCallback)
: TWidget(parent) : TWidget(parent)
, _session(session) , _session(session)
, _api(_session->api().instance())
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _revokeWidth(st::normalFont->width(tr::lng_channels_too_much_public_revoke(tr::now))) , _revokeWidth(st::normalFont->width(tr::lng_channels_too_much_public_revoke(tr::now)))
, _revokeCallback(std::move(revokeCallback)) { , _revokeCallback(std::move(revokeCallback)) {
@ -1294,7 +1297,7 @@ RevokePublicLinkBox::Inner::Inner(
resize(width(), 5 * _rowHeight); resize(width(), 5 * _rowHeight);
request(MTPchannels_GetAdminedPublicChannels( _api.request(MTPchannels_GetAdminedPublicChannels(
MTP_flags(0) MTP_flags(0)
)).done([=](const MTPmessages_Chats &result) { )).done([=](const MTPmessages_Chats &result) {
const auto &chats = result.match([](const auto &data) { const auto &chats = result.match([](const auto &data) {
@ -1401,7 +1404,7 @@ void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
auto confirmText = tr::lng_channels_too_much_public_revoke(tr::now); auto confirmText = tr::lng_channels_too_much_public_revoke(tr::now);
_weakRevokeConfirmBox = Ui::show(Box<ConfirmBox>(text, confirmText, crl::guard(this, [this, pressed]() { _weakRevokeConfirmBox = Ui::show(Box<ConfirmBox>(text, confirmText, crl::guard(this, [this, pressed]() {
if (_revokeRequestId) return; if (_revokeRequestId) return;
_revokeRequestId = request(MTPchannels_UpdateUsername( _revokeRequestId = _api.request(MTPchannels_UpdateUsername(
pressed->asChannel()->inputChannel, pressed->asChannel()->inputChannel,
MTP_string() MTP_string()
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {

View file

@ -94,7 +94,7 @@ private:
}; };
class GroupInfoBox : public Ui::BoxContent, private MTP::Sender { class GroupInfoBox : public Ui::BoxContent {
public: public:
enum class Type { enum class Type {
Group, Group,
@ -124,6 +124,7 @@ private:
void updateMaxHeight(); void updateMaxHeight();
const not_null<Window::SessionNavigation*> _navigation; const not_null<Window::SessionNavigation*> _navigation;
MTP::Sender _api;
Type _type = Type::Group; Type _type = Type::Group;
QString _initialTitle; QString _initialTitle;

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_auto_download.h"
#include "ui/widgets/continuous_sliders.h" #include "ui/widgets/continuous_sliders.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/wrap/vertical_layout.h" #include "ui/wrap/vertical_layout.h"
@ -24,8 +25,53 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace { namespace {
constexpr auto kMegabyte = 1024 * 1024; constexpr auto kMegabyte = 1024 * 1024;
constexpr auto kDefaultLimit = 10 * kMegabyte; constexpr auto kDefaultDownloadLimit = 10 * kMegabyte;
constexpr auto kDefaultAutoPlayLimit = 50 * kMegabyte;
using Type = Data::AutoDownload::Type;
not_null<int*> AddSizeLimitSlider(
not_null<Ui::VerticalLayout*> container,
const base::flat_map<Type, int> &values,
int defaultValue) {
using namespace Settings;
using Pair = base::flat_map<Type, int>::value_type;
const auto limits = Ui::CreateChild<rpl::event_stream<int>>(
container.get());
const auto currentLimit = ranges::max_element(
values,
std::less<>(),
[](Pair pair) { return pair.second; })->second;
const auto initialLimit = currentLimit ? currentLimit : defaultValue;
const auto result = Ui::CreateChild<int>(container.get(), initialLimit);
AddButtonWithLabel(
container,
tr::lng_media_size_limit(),
limits->events_starting_with_copy(
initialLimit
) | rpl::map([](int value) {
return tr::lng_media_size_up_to(
tr::now,
lt_size,
QString::number(value / kMegabyte) + " MB");
}),
st::autoDownloadLimitButton
)->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto slider = container->add(
object_ptr<Ui::MediaSlider>(container, st::autoDownloadLimitSlider),
st::autoDownloadLimitPadding);
slider->resize(st::autoDownloadLimitSlider.seekSize);
slider->setPseudoDiscrete(
Export::View::kSizeValueCount,
Export::View::SizeLimitByIndex,
*result,
[=](int value) {
*result = value;
limits->fire_copy(value);
});
return result;
}
} // namespace } // namespace
AutoDownloadBox::AutoDownloadBox( AutoDownloadBox::AutoDownloadBox(
@ -41,12 +87,13 @@ void AutoDownloadBox::prepare() {
} }
void AutoDownloadBox::setupContent() { void AutoDownloadBox::setupContent() {
using namespace rpl::mappers;
using namespace Settings; using namespace Settings;
using namespace Data::AutoDownload; using namespace Data::AutoDownload;
using namespace rpl::mappers;
using Type = Data::AutoDownload::Type; using Type = Data::AutoDownload::Type;
using Pair = base::flat_map<Type, int>::value_type;
setTitle(tr::lng_media_auto_title()); setTitle(tr::lng_profile_settings_section());
const auto settings = &_session->settings().autoDownload(); const auto settings = &_session->settings().autoDownload();
const auto checked = [=](Source source, Type type) { const auto checked = [=](Source source, Type type) {
@ -59,17 +106,10 @@ void AutoDownloadBox::setupContent() {
this, this,
std::move(wrap))); std::move(wrap)));
static const auto kHidden = { const auto add = [&](
Type::Video, not_null<base::flat_map<Type, int>*> values,
Type::Music, Type type,
Type::VoiceMessage rpl::producer<QString> label) {
};
const auto values = Ui::CreateChild<base::flat_map<Type, int>>(content);
const auto add = [&](Type type, rpl::producer<QString> label) {
if (ranges::find(kHidden, type) != end(kHidden)) {
return;
}
const auto value = settings->bytesLimit(_source, type); const auto value = settings->bytesLimit(_source, type);
AddButton( AddButton(
content, content,
@ -83,77 +123,78 @@ void AutoDownloadBox::setupContent() {
}, content->lifetime()); }, content->lifetime());
values->emplace(type, value); values->emplace(type, value);
}; };
add(Type::Photo, tr::lng_media_photo_title());
add(Type::VoiceMessage, tr::lng_media_audio_title());
add(Type::VideoMessage, tr::lng_media_video_messages_title());
add(Type::Video, tr::lng_media_video_title());
add(Type::File, tr::lng_media_file_title());
add(Type::Music, tr::lng_media_music_title());
add(Type::GIF, tr::lng_media_animation_title());
const auto limits = Ui::CreateChild<rpl::event_stream<int>>(content); AddSubsectionTitle(content, tr::lng_media_auto_title());
using Pair = base::flat_map<Type, int>::value_type;
const auto settingsLimit = ranges::max_element( const auto downloadValues = Ui::CreateChild<base::flat_map<Type, int>>(
*values, content);
std::less<>(), add(downloadValues, Type::Photo, tr::lng_media_photo_title());
[](Pair pair) { return pair.second; })->second; add(downloadValues, Type::File, tr::lng_media_file_title());
const auto initialLimit = settingsLimit ? settingsLimit : kDefaultLimit;
const auto limit = Ui::CreateChild<int>(content, initialLimit); const auto downloadLimit = AddSizeLimitSlider(
AddButtonWithLabel(
content, content,
tr::lng_media_size_limit(), *downloadValues,
limits->events_starting_with_copy( kDefaultDownloadLimit);
initialLimit
) | rpl::map([](int value) { AddSkip(content);
return tr::lng_media_size_up_to( AddSubsectionTitle(content, tr::lng_media_auto_play());
tr::now,
lt_size, const auto autoPlayValues = Ui::CreateChild<base::flat_map<Type, int>>(
QString::number(value / kMegabyte) + " MB"); content);
}), add(
st::autoDownloadLimitButton autoPlayValues,
)->setAttribute(Qt::WA_TransparentForMouseEvents); Type::AutoPlayVideoMessage,
const auto slider = content->add( tr::lng_media_video_messages_title());
object_ptr<Ui::MediaSlider>(content, st::autoDownloadLimitSlider), add(autoPlayValues, Type::AutoPlayVideo, tr::lng_media_video_title());
st::autoDownloadLimitPadding); add(autoPlayValues, Type::AutoPlayGIF, tr::lng_media_animation_title());
slider->resize(st::autoDownloadLimitSlider.seekSize);
slider->setPseudoDiscrete( const auto autoPlayLimit = AddSizeLimitSlider(
Export::View::kSizeValueCount, content,
Export::View::SizeLimitByIndex, *autoPlayValues,
*limit, kDefaultAutoPlayLimit);
[=](int value) {
*limit = value; const auto limitByType = [=](Type type) {
limits->fire_copy(value); return (ranges::find(kAutoPlayTypes, type) != end(kAutoPlayTypes))
}); ? *autoPlayLimit
: *downloadLimit;
};
addButton(tr::lng_connection_save(), [=] { addButton(tr::lng_connection_save(), [=] {
auto allowMore = ranges::view::all( auto &&values = ranges::view::concat(
*values *downloadValues,
) | ranges::view::filter([&](Pair pair) { *autoPlayValues);
auto allowMore = values | ranges::view::filter([&](Pair pair) {
const auto [type, enabled] = pair; const auto [type, enabled] = pair;
const auto value = enabled ? *limit : 0; const auto value = enabled ? limitByType(type) : 0;
const auto old = settings->bytesLimit(_source, type); const auto old = settings->bytesLimit(_source, type);
return (old < value); return (old < value);
}) | ranges::view::transform([](Pair pair) { }) | ranges::view::transform([](Pair pair) {
return pair.first; return pair.first;
}); });
const auto less = ranges::find_if(*autoPlayValues, [&](Pair pair) {
const auto [type, enabled] = pair;
const auto value = enabled ? limitByType(type) : 0;
return value < settings->bytesLimit(_source, type);
}) != end(*autoPlayValues);
const auto allowMoreTypes = base::flat_set<Type>( const auto allowMoreTypes = base::flat_set<Type>(
allowMore.begin(), allowMore.begin(),
allowMore.end()); allowMore.end());
const auto changed = ranges::find_if(*values, [&](Pair pair) { const auto changed = ranges::find_if(values, [&](Pair pair) {
const auto [type, enabled] = pair; const auto [type, enabled] = pair;
const auto value = enabled ? *limit : 0; const auto value = enabled ? limitByType(type) : 0;
return settings->bytesLimit(_source, type) != value; return value != settings->bytesLimit(_source, type);
}) != end(*values); }) != end(values);
const auto &kHidden = kStreamedTypes;
const auto hiddenChanged = ranges::find_if(kHidden, [&](Type type) { const auto hiddenChanged = ranges::find_if(kHidden, [&](Type type) {
const auto now = settings->bytesLimit(_source, type); const auto now = settings->bytesLimit(_source, type);
return (now > 0) && (now != *limit); return (now > 0) && (now != limitByType(type));
}) != end(kHidden); }) != end(kHidden);
if (changed) { if (changed) {
for (const auto [type, enabled] : *values) { for (const auto [type, enabled] : values) {
const auto value = enabled ? *limit : 0; const auto value = enabled ? limitByType(type) : 0;
settings->setBytesLimit(_source, type, value); settings->setBytesLimit(_source, type, value);
} }
} }
@ -161,7 +202,10 @@ void AutoDownloadBox::setupContent() {
for (const auto type : kHidden) { for (const auto type : kHidden) {
const auto now = settings->bytesLimit(_source, type); const auto now = settings->bytesLimit(_source, type);
if (now > 0) { if (now > 0) {
settings->setBytesLimit(_source, type, *limit); settings->setBytesLimit(
_source,
type,
limitByType(type));
} }
} }
} }
@ -175,6 +219,9 @@ void AutoDownloadBox::setupContent() {
!= allowMoreTypes.end()) { != allowMoreTypes.end()) {
_session->data().documentLoadSettingsChanged(); _session->data().documentLoadSettingsChanged();
} }
if (less) {
_session->data().checkPlayingVideoFiles();
}
closeBox(); closeBox();
}); });
addButton(tr::lng_cancel(), [=] { closeBox(); }); addButton(tr::lng_cancel(), [=] { closeBox(); });

View file

@ -53,10 +53,7 @@ QImage TakeMiddleSample(QImage original, QSize size) {
} // namespace } // namespace
class BackgroundBox::Inner class BackgroundBox::Inner : public Ui::RpWidget, private base::Subscriber {
: public Ui::RpWidget
, private MTP::Sender
, private base::Subscriber {
public: public:
Inner( Inner(
QWidget *parent, QWidget *parent,
@ -114,6 +111,7 @@ private:
void validatePaperThumbnail(const Paper &paper) const; void validatePaperThumbnail(const Paper &paper) const;
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api;
std::vector<Paper> _papers; std::vector<Paper> _papers;
@ -185,6 +183,7 @@ BackgroundBox::Inner::Inner(
not_null<Main::Session*> session) not_null<Main::Session*> session)
: RpWidget(parent) : RpWidget(parent)
, _session(session) , _session(session)
, _api(_session->api().instance())
, _check(std::make_unique<Ui::RoundCheckbox>(st::overviewCheck, [=] { update(); })) { , _check(std::make_unique<Ui::RoundCheckbox>(st::overviewCheck, [=] { update(); })) {
_check->setChecked(true, Ui::RoundCheckbox::SetStyle::Fast); _check->setChecked(true, Ui::RoundCheckbox::SetStyle::Fast);
if (_session->data().wallpapers().empty()) { if (_session->data().wallpapers().empty()) {
@ -209,7 +208,7 @@ BackgroundBox::Inner::Inner(
} }
void BackgroundBox::Inner::requestPapers() { void BackgroundBox::Inner::requestPapers() {
request(MTPaccount_GetWallPapers( _api.request(MTPaccount_GetWallPapers(
MTP_int(_session->data().wallpapersHash()) MTP_int(_session->data().wallpapersHash())
)).done([=](const MTPaccount_WallPapers &result) { )).done([=](const MTPaccount_WallPapers &result) {
if (_session->data().updateWallpapers(result)) { if (_session->data().updateWallpapers(result)) {

View file

@ -716,6 +716,9 @@ void BackgroundPreviewBox::checkLoadedDocument() {
return; return;
} }
const auto generateCallback = [=](QImage &&image) { const auto generateCallback = [=](QImage &&image) {
if (image.isNull()) {
return;
}
crl::async([ crl::async([
this, this,
image = std::move(image), image = std::move(image),

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "boxes/calendar_box.h" #include "boxes/calendar_box.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/effects/ripple_animation.h" #include "ui/effects/ripple_animation.h"

View file

@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_file_origin.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "observer_peer.h" #include "observer_peer.h"

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "boxes/abstract_box.h" #include "boxes/abstract_box.h"
#include "mtproto/mtproto_rpc_sender.h"
namespace Main { namespace Main {
class Session; class Session;

View file

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "numbers.h" #include "numbers.h"
#include "app.h" #include "app.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "mtproto/facade.h"
#include "styles/style_layers.h" #include "styles/style_layers.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h" #include "boxes/abstract_box.h"
#include "base/timer.h" #include "base/timer.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
#include "mtproto/mtproto_rpc_sender.h"
namespace Ui { namespace Ui {
class InputField; class InputField;

View file

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/call_delayed.h" #include "base/call_delayed.h"
#include "core/application.h" #include "core/application.h"
#include "main/main_account.h" #include "main/main_account.h"
#include "mtproto/facade.h"
#include "ui/widgets/checkbox.h" #include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
@ -38,6 +39,8 @@ namespace {
constexpr auto kSaveSettingsDelayedTimeout = crl::time(1000); constexpr auto kSaveSettingsDelayedTimeout = crl::time(1000);
using ProxyData = MTP::ProxyData;
class Base64UrlInput : public Ui::MaskedInputField { class Base64UrlInput : public Ui::MaskedInputField {
public: public:
Base64UrlInput( Base64UrlInput(
@ -1057,7 +1060,7 @@ void ProxiesBoxController::refreshChecker(Item &item) {
item.state = ItemState::Checking; item.state = ItemState::Checking;
const auto setup = [&](Checker &checker, const bytes::vector &secret) { const auto setup = [&](Checker &checker, const bytes::vector &secret) {
checker = MTP::internal::AbstractConnection::Create( checker = MTP::details::AbstractConnection::Create(
mtproto, mtproto,
type, type,
QThread::currentThread(), QThread::currentThread(),
@ -1105,7 +1108,7 @@ void ProxiesBoxController::refreshChecker(Item &item) {
} }
void ProxiesBoxController::setupChecker(int id, const Checker &checker) { void ProxiesBoxController::setupChecker(int id, const Checker &checker) {
using Connection = MTP::internal::AbstractConnection; using Connection = MTP::details::AbstractConnection;
const auto pointer = checker.get(); const auto pointer = checker.get();
pointer->connect(pointer, &Connection::connected, [=] { pointer->connect(pointer, &Connection::connected, [=] {
const auto item = findById(id); const auto item = findById(id);
@ -1148,7 +1151,7 @@ object_ptr<Ui::BoxContent> ProxiesBoxController::create() {
for (const auto &item : _list) { for (const auto &item : _list) {
updateView(item); updateView(item);
} }
return std::move(result); return result;
} }
auto ProxiesBoxController::findById(int id) -> std::vector<Item>::iterator { auto ProxiesBoxController::findById(int id) -> std::vector<Item>::iterator {

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h" #include "base/timer.h"
#include "base/object_ptr.h" #include "base/object_ptr.h"
#include "mtproto/connection_abstract.h" #include "mtproto/connection_abstract.h"
#include "mtproto/mtproto_proxy_data.h"
namespace Ui { namespace Ui {
class BoxContent; class BoxContent;
@ -25,6 +26,7 @@ class Radioenum;
class ProxiesBoxController : public base::Subscriber { class ProxiesBoxController : public base::Subscriber {
public: public:
using ProxyData = MTP::ProxyData;
using Type = ProxyData::Type; using Type = ProxyData::Type;
ProxiesBoxController(); ProxiesBoxController();
@ -73,7 +75,7 @@ public:
~ProxiesBoxController(); ~ProxiesBoxController();
private: private:
using Checker = MTP::internal::ConnectionPointer; using Checker = MTP::details::ConnectionPointer;
struct Item { struct Item {
int id = 0; int id = 0;
ProxyData data; ProxyData data;

View file

@ -768,7 +768,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
FocusAtEnd(question); FocusAtEnd(question);
}, lifetime()); }, lifetime());
return std::move(result); return result;
} }
void CreatePollBox::prepare() { void CreatePollBox::prepare() {

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_media_prepare.h" #include "storage/storage_media_prepare.h"
#include "ui/wrap/slide_wrap.h" #include "ui/wrap/slide_wrap.h"
#include "media/clip/media_clip_reader.h" #include "media/clip/media_clip_reader.h"
#include "mtproto/mtproto_rpc_sender.h"
namespace ChatHelpers { namespace ChatHelpers {
class TabbedPanel; class TabbedPanel;

View file

@ -100,7 +100,7 @@ private:
}; };
class EditPrivacyBox : public Ui::BoxContent, private MTP::Sender { class EditPrivacyBox : public Ui::BoxContent {
public: public:
using Value = ApiWrap::Privacy; using Value = ApiWrap::Privacy;
using Option = Value::Option; using Option = Value::Option;

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "boxes/confirm_phone_box.h" #include "boxes/confirm_phone_box.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "apiwrap.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
@ -47,6 +48,7 @@ PasscodeBox::PasscodeBox(
not_null<Main::Session*> session, not_null<Main::Session*> session,
bool turningOff) bool turningOff)
: _session(session) : _session(session)
, _api(_session->api().instance())
, _turningOff(turningOff) , _turningOff(turningOff)
, _about(st::boxWidth - st::boxPadding.left() * 1.5) , _about(st::boxWidth - st::boxPadding.left() * 1.5)
, _oldPasscode(this, st::defaultInputField, tr::lng_passcode_enter_old()) , _oldPasscode(this, st::defaultInputField, tr::lng_passcode_enter_old())
@ -62,6 +64,7 @@ PasscodeBox::PasscodeBox(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const CloudFields &fields) const CloudFields &fields)
: _session(session) : _session(session)
, _api(_session->api().instance())
, _turningOff(fields.turningOff) , _turningOff(fields.turningOff)
, _cloudPwd(true) , _cloudPwd(true)
, _cloudFields(fields) , _cloudFields(fields)
@ -357,7 +360,7 @@ void PasscodeBox::validateEmail(
if (_setRequest) { if (_setRequest) {
return; return;
} }
_setRequest = request(MTPaccount_ConfirmPasswordEmail( _setRequest = _api.request(MTPaccount_ConfirmPasswordEmail(
MTP_string(code) MTP_string(code)
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
*set = true; *set = true;
@ -387,7 +390,7 @@ void PasscodeBox::validateEmail(
if (_setRequest) { if (_setRequest) {
return; return;
} }
_setRequest = request(MTPaccount_ResendPasswordEmail( _setRequest = _api.request(MTPaccount_ResendPasswordEmail(
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
_setRequest = 0; _setRequest = 0;
resent->fire(tr::lng_cloud_password_resent(tr::now)); resent->fire(tr::lng_cloud_password_resent(tr::now));
@ -597,8 +600,8 @@ void PasscodeBox::requestPasswordData() {
return serverError(); return serverError();
} }
request(base::take(_setRequest)).cancel(); _api.request(base::take(_setRequest)).cancel();
_setRequest = request( _setRequest = _api.request(
MTPaccount_GetPassword() MTPaccount_GetPassword()
).done([=](const MTPaccount_Password &result) { ).done([=](const MTPaccount_Password &result) {
_setRequest = 0; _setRequest = 0;
@ -636,7 +639,7 @@ void PasscodeBox::sendClearCloudPassword(
| MTPDaccount_passwordInputSettings::Flag::f_new_password_hash | MTPDaccount_passwordInputSettings::Flag::f_new_password_hash
| MTPDaccount_passwordInputSettings::Flag::f_hint | MTPDaccount_passwordInputSettings::Flag::f_hint
| MTPDaccount_passwordInputSettings::Flag::f_email; | MTPDaccount_passwordInputSettings::Flag::f_email;
_setRequest = request(MTPaccount_UpdatePasswordSettings( _setRequest = _api.request(MTPaccount_UpdatePasswordSettings(
check.result, check.result,
MTP_account_passwordInputSettings( MTP_account_passwordInputSettings(
MTP_flags(flags), MTP_flags(flags),
@ -667,7 +670,7 @@ void PasscodeBox::setNewCloudPassword(const QString &newPassword) {
| MTPDaccount_passwordInputSettings::Flag::f_hint | MTPDaccount_passwordInputSettings::Flag::f_hint
| MTPDaccount_passwordInputSettings::Flag::f_email; | MTPDaccount_passwordInputSettings::Flag::f_email;
_checkPasswordCallback = nullptr; _checkPasswordCallback = nullptr;
_setRequest = request(MTPaccount_UpdatePasswordSettings( _setRequest = _api.request(MTPaccount_UpdatePasswordSettings(
MTP_inputCheckPasswordEmpty(), MTP_inputCheckPasswordEmpty(),
MTP_account_passwordInputSettings( MTP_account_passwordInputSettings(
MTP_flags(flags), MTP_flags(flags),
@ -695,7 +698,7 @@ void PasscodeBox::changeCloudPassword(
const QString &oldPassword, const QString &oldPassword,
const Core::CloudPasswordResult &check, const Core::CloudPasswordResult &check,
const QString &newPassword) { const QString &newPassword) {
_setRequest = request(MTPaccount_GetPasswordSettings( _setRequest = _api.request(MTPaccount_GetPasswordSettings(
check.result check.result
)).done([=](const MTPaccount_PasswordSettings &result) { )).done([=](const MTPaccount_PasswordSettings &result) {
_setRequest = 0; _setRequest = 0;
@ -760,7 +763,7 @@ void PasscodeBox::resetSecret(
const QString &newPassword, const QString &newPassword,
Fn<void()> callback) { Fn<void()> callback) {
using Flag = MTPDaccount_passwordInputSettings::Flag; using Flag = MTPDaccount_passwordInputSettings::Flag;
_setRequest = request(MTPaccount_UpdatePasswordSettings( _setRequest = _api.request(MTPaccount_UpdatePasswordSettings(
check.result, check.result,
MTP_account_passwordInputSettings( MTP_account_passwordInputSettings(
MTP_flags(Flag::f_new_secure_settings), MTP_flags(Flag::f_new_secure_settings),
@ -814,7 +817,7 @@ void PasscodeBox::sendChangeCloudPassword(
_cloudFields.newSecureSecretAlgo, _cloudFields.newSecureSecretAlgo,
bytes::make_span(newPasswordBytes))); bytes::make_span(newPasswordBytes)));
} }
_setRequest = request(MTPaccount_UpdatePasswordSettings( _setRequest = _api.request(MTPaccount_UpdatePasswordSettings(
check.result, check.result,
MTP_account_passwordInputSettings( MTP_account_passwordInputSettings(
MTP_flags(flags), MTP_flags(flags),
@ -873,7 +876,7 @@ void PasscodeBox::emailChanged() {
void PasscodeBox::recoverByEmail() { void PasscodeBox::recoverByEmail() {
if (_pattern.isEmpty()) { if (_pattern.isEmpty()) {
_pattern = "-"; _pattern = "-";
request(MTPauth_RequestPasswordRecovery( _api.request(MTPauth_RequestPasswordRecovery(
)).done([=](const MTPauth_PasswordRecovery &result) { )).done([=](const MTPauth_PasswordRecovery &result) {
recoverStarted(result); recoverStarted(result);
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {

View file

@ -25,7 +25,7 @@ namespace Core {
struct CloudPasswordState; struct CloudPasswordState;
} // namespace Core } // namespace Core
class PasscodeBox : public Ui::BoxContent, private MTP::Sender { class PasscodeBox : public Ui::BoxContent {
public: public:
PasscodeBox(QWidget*, not_null<Main::Session*> session, bool turningOff); PasscodeBox(QWidget*, not_null<Main::Session*> session, bool turningOff);
@ -130,6 +130,7 @@ private:
void serverError(); void serverError();
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api;
QString _pattern; QString _pattern;

View file

@ -1313,7 +1313,6 @@ void PeerListContent::loadProfilePhotos() {
auto yFrom = _visibleTop; auto yFrom = _visibleTop;
auto yTo = _visibleBottom + (_visibleBottom - _visibleTop) * PreloadHeightsCount; auto yTo = _visibleBottom + (_visibleBottom - _visibleTop) * PreloadHeightsCount;
_controller->session().downloader().clearPriorities();
if (yTo < 0) return; if (yTo < 0) return;
if (yFrom < 0) yFrom = 0; if (yFrom < 0) yFrom = 0;

View file

@ -142,7 +142,8 @@ void PeerListRowWithLink::paintAction(
PeerListGlobalSearchController::PeerListGlobalSearchController( PeerListGlobalSearchController::PeerListGlobalSearchController(
not_null<Window::SessionNavigation*> navigation) not_null<Window::SessionNavigation*> navigation)
: _navigation(navigation) { : _navigation(navigation)
, _api(_navigation->session().api().instance()) {
_timer.setCallback([this] { searchOnServer(); }); _timer.setCallback([this] { searchOnServer(); });
} }
@ -169,7 +170,7 @@ bool PeerListGlobalSearchController::searchInCache() {
} }
void PeerListGlobalSearchController::searchOnServer() { void PeerListGlobalSearchController::searchOnServer() {
_requestId = request(MTPcontacts_Search( _requestId = _api.request(MTPcontacts_Search(
MTP_string(_query), MTP_string(_query),
MTP_int(SearchPeopleLimit) MTP_int(SearchPeopleLimit)
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) { )).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {

View file

@ -59,9 +59,7 @@ private:
}; };
class PeerListGlobalSearchController class PeerListGlobalSearchController : public PeerListSearchController {
: public PeerListSearchController
, private MTP::Sender {
public: public:
PeerListGlobalSearchController( PeerListGlobalSearchController(
not_null<Window::SessionNavigation*> navigation); not_null<Window::SessionNavigation*> navigation);
@ -78,6 +76,7 @@ private:
void searchDone(const MTPcontacts_Found &result, mtpRequestId requestId); void searchDone(const MTPcontacts_Found &result, mtpRequestId requestId);
const not_null<Window::SessionNavigation*> _navigation; const not_null<Window::SessionNavigation*> _navigation;
MTP::Sender _api;
base::Timer _timer; base::Timer _timer;
QString _query; QString _query;
mtpRequestId _requestId = 0; mtpRequestId _requestId = 0;

View file

@ -276,6 +276,7 @@ AddSpecialBoxController::AddSpecialBoxController(
peer, peer,
&_additional)) &_additional))
, _peer(peer) , _peer(peer)
, _api(_peer->session().api().instance())
, _role(role) , _role(role)
, _additional(peer, Role::Members) , _additional(peer, Role::Members)
, _adminDoneCallback(std::move(adminDoneCallback)) , _adminDoneCallback(std::move(adminDoneCallback))
@ -408,7 +409,7 @@ void AddSpecialBoxController::loadMoreRows() {
const auto participantsHash = 0; const auto participantsHash = 0;
const auto channel = _peer->asChannel(); const auto channel = _peer->asChannel();
_loadRequestId = request(MTPchannels_GetParticipants( _loadRequestId = _api.request(MTPchannels_GetParticipants(
channel->inputChannel, channel->inputChannel,
MTP_channelParticipantsRecent(), MTP_channelParticipantsRecent(),
MTP_int(_offset), MTP_int(_offset),
@ -464,7 +465,7 @@ bool AddSpecialBoxController::checkInfoLoaded(
// We don't know what this user status is in the group. // We don't know what this user status is in the group.
const auto channel = _peer->asChannel(); const auto channel = _peer->asChannel();
request(MTPchannels_GetParticipant( _api.request(MTPchannels_GetParticipant(
channel->inputChannel, channel->inputChannel,
user->inputUser user->inputUser
)).done([=](const MTPchannels_ChannelParticipant &result) { )).done([=](const MTPchannels_ChannelParticipant &result) {
@ -829,6 +830,7 @@ AddSpecialBoxSearchController::AddSpecialBoxSearchController(
not_null<ParticipantsAdditionalData*> additional) not_null<ParticipantsAdditionalData*> additional)
: _peer(peer) : _peer(peer)
, _additional(additional) , _additional(additional)
, _api(_peer->session().api().instance())
, _timer([=] { searchOnServer(); }) { , _timer([=] { searchOnServer(); }) {
subscribeToMigration(); subscribeToMigration();
} }
@ -924,7 +926,7 @@ void AddSpecialBoxSearchController::requestParticipants() {
const auto participantsHash = 0; const auto participantsHash = 0;
const auto channel = _peer->asChannel(); const auto channel = _peer->asChannel();
_requestId = request(MTPchannels_GetParticipants( _requestId = _api.request(MTPchannels_GetParticipants(
channel->inputChannel, channel->inputChannel,
MTP_channelParticipantsSearch(MTP_string(_query)), MTP_channelParticipantsSearch(MTP_string(_query)),
MTP_int(_offset), MTP_int(_offset),
@ -1012,7 +1014,7 @@ void AddSpecialBoxSearchController::requestGlobal() {
} }
auto perPage = SearchPeopleLimit; auto perPage = SearchPeopleLimit;
_requestId = request(MTPcontacts_Search( _requestId = _api.request(MTPcontacts_Search(
MTP_string(_query), MTP_string(_query),
MTP_int(perPage) MTP_int(perPage)
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) { )).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {

View file

@ -69,7 +69,6 @@ private:
class AddSpecialBoxController class AddSpecialBoxController
: public PeerListController : public PeerListController
, private base::Subscriber , private base::Subscriber
, private MTP::Sender
, public base::has_weak_ptr { , public base::has_weak_ptr {
public: public:
using Role = ParticipantsBoxController::Role; using Role = ParticipantsBoxController::Role;
@ -87,12 +86,12 @@ public:
AdminDoneCallback adminDoneCallback, AdminDoneCallback adminDoneCallback,
BannedDoneCallback bannedDoneCallback); BannedDoneCallback bannedDoneCallback);
Main::Session &session() const override; [[nodiscard]] Main::Session &session() const override;
void prepare() override; void prepare() override;
void rowClicked(not_null<PeerListRow*> row) override; void rowClicked(not_null<PeerListRow*> row) override;
void loadMoreRows() override; void loadMoreRows() override;
std::unique_ptr<PeerListRow> createSearchRow( [[nodiscard]] std::unique_ptr<PeerListRow> createSearchRow(
not_null<PeerData*> peer) override; not_null<PeerData*> peer) override;
private: private:
@ -120,6 +119,7 @@ private:
void migrate(not_null<ChannelData*> channel); void migrate(not_null<ChannelData*> channel);
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
MTP::Sender _api;
Role _role = Role::Admins; Role _role = Role::Admins;
int _offset = 0; int _offset = 0;
mtpRequestId _loadRequestId = 0; mtpRequestId _loadRequestId = 0;
@ -139,7 +139,6 @@ protected:
// Finds chat/channel members, then contacts, then global search results. // Finds chat/channel members, then contacts, then global search results.
class AddSpecialBoxSearchController class AddSpecialBoxSearchController
: public PeerListSearchController : public PeerListSearchController
, private MTP::Sender
, private base::Subscriber { , private base::Subscriber {
public: public:
using Role = ParticipantsBoxController::Role; using Role = ParticipantsBoxController::Role;
@ -181,6 +180,7 @@ private:
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
not_null<ParticipantsAdditionalData*> _additional; not_null<ParticipantsAdditionalData*> _additional;
MTP::Sender _api;
base::Timer _timer; base::Timer _timer;
QString _query; QString _query;

View file

@ -223,7 +223,7 @@ object_ptr<Ui::RpWidget> SetupAbout(
tr::now, tr::now,
Ui::Text::WithEntities); Ui::Text::WithEntities);
}()); }());
return std::move(about); return about;
} }
object_ptr<Ui::RpWidget> SetupFooter( object_ptr<Ui::RpWidget> SetupFooter(

View file

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h" #include "boxes/abstract_box.h"
#include "base/unique_qptr.h" #include "base/unique_qptr.h"
class RPCError;
namespace Ui { namespace Ui {
class FlatLabel; class FlatLabel;
class LinkButton; class LinkButton;

View file

@ -750,6 +750,7 @@ ParticipantsBoxController::ParticipantsBoxController(
: PeerListController(CreateSearchController(peer, role, &_additional)) : PeerListController(CreateSearchController(peer, role, &_additional))
, _navigation(navigation) , _navigation(navigation)
, _peer(peer) , _peer(peer)
, _api(_peer->session().api().instance())
, _role(role) , _role(role)
, _additional(peer, _role) { , _additional(peer, _role) {
subscribeToMigration(); subscribeToMigration();
@ -1029,7 +1030,7 @@ void ParticipantsBoxController::restoreState(
: nullptr; : nullptr;
if (const auto my = dynamic_cast<SavedState*>(typeErasedState)) { if (const auto my = dynamic_cast<SavedState*>(typeErasedState)) {
if (const auto requestId = base::take(_loadRequestId)) { if (const auto requestId = base::take(_loadRequestId)) {
request(requestId).cancel(); _api.request(requestId).cancel();
} }
_additional = std::move(my->additional); _additional = std::move(my->additional);
@ -1260,7 +1261,7 @@ void ParticipantsBoxController::loadMoreRows() {
: kParticipantsFirstPageCount; : kParticipantsFirstPageCount;
const auto participantsHash = 0; const auto participantsHash = 0;
_loadRequestId = request(MTPchannels_GetParticipants( _loadRequestId = _api.request(MTPchannels_GetParticipants(
channel->inputChannel, channel->inputChannel,
filter, filter,
MTP_int(_offset), MTP_int(_offset),
@ -1797,7 +1798,7 @@ std::unique_ptr<PeerListRow> ParticipantsBoxController::createRow(
row->setActionLink(tr::lng_profile_kick(tr::now)); row->setActionLink(tr::lng_profile_kick(tr::now));
} }
} }
return std::move(row); return row;
} }
auto ParticipantsBoxController::computeType( auto ParticipantsBoxController::computeType(
@ -1920,7 +1921,8 @@ ParticipantsBoxSearchController::ParticipantsBoxSearchController(
not_null<ParticipantsAdditionalData*> additional) not_null<ParticipantsAdditionalData*> additional)
: _channel(channel) : _channel(channel)
, _role(role) , _role(role)
, _additional(additional) { , _additional(additional)
, _api(_channel->session().api().instance()) {
_timer.setCallback([=] { searchOnServer(); }); _timer.setCallback([=] { searchOnServer(); });
} }
@ -1945,14 +1947,14 @@ auto ParticipantsBoxSearchController::saveState() const
result->offset = _offset; result->offset = _offset;
result->allLoaded = _allLoaded; result->allLoaded = _allLoaded;
result->wasLoading = (_requestId != 0); result->wasLoading = (_requestId != 0);
return std::move(result); return result;
} }
void ParticipantsBoxSearchController::restoreState( void ParticipantsBoxSearchController::restoreState(
std::unique_ptr<SavedStateBase> state) { std::unique_ptr<SavedStateBase> state) {
if (auto my = dynamic_cast<SavedState*>(state.get())) { if (auto my = dynamic_cast<SavedState*>(state.get())) {
if (auto requestId = base::take(_requestId)) { if (auto requestId = base::take(_requestId)) {
request(requestId).cancel(); _api.request(requestId).cancel();
} }
_cache.clear(); _cache.clear();
_queries.clear(); _queries.clear();
@ -2017,7 +2019,7 @@ bool ParticipantsBoxSearchController::loadMoreRows() {
auto perPage = kParticipantsPerPage; auto perPage = kParticipantsPerPage;
auto participantsHash = 0; auto participantsHash = 0;
_requestId = request(MTPchannels_GetParticipants( _requestId = _api.request(MTPchannels_GetParticipants(
_channel->inputChannel, _channel->inputChannel,
filter, filter,
MTP_int(_offset), MTP_int(_offset),

View file

@ -135,7 +135,6 @@ private:
class ParticipantsBoxController class ParticipantsBoxController
: public PeerListController : public PeerListController
, private base::Subscriber , private base::Subscriber
, private MTP::Sender
, public base::has_weak_ptr { , public base::has_weak_ptr {
public: public:
using Role = ParticipantsRole; using Role = ParticipantsRole;
@ -239,6 +238,7 @@ private:
not_null<Window::SessionNavigation*> _navigation; not_null<Window::SessionNavigation*> _navigation;
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
MTP::Sender _api;
Role _role = Role::Admins; Role _role = Role::Admins;
int _offset = 0; int _offset = 0;
mtpRequestId _loadRequestId = 0; mtpRequestId _loadRequestId = 0;
@ -252,9 +252,7 @@ private:
}; };
// Members, banned and restricted users server side search. // Members, banned and restricted users server side search.
class ParticipantsBoxSearchController class ParticipantsBoxSearchController : public PeerListSearchController {
: public PeerListSearchController
, private MTP::Sender {
public: public:
using Role = ParticipantsBoxController::Role; using Role = ParticipantsBoxController::Role;
@ -296,6 +294,7 @@ private:
not_null<ChannelData*> _channel; not_null<ChannelData*> _channel;
Role _role = Role::Restricted; Role _role = Role::Restricted;
not_null<ParticipantsAdditionalData*> _additional; not_null<ParticipantsAdditionalData*> _additional;
MTP::Sender _api;
base::Timer _timer; base::Timer _timer;
QString _query; QString _query;

View file

@ -240,9 +240,7 @@ namespace {
constexpr auto kMaxGroupChannelTitle = 128; // See also add_contact_box. constexpr auto kMaxGroupChannelTitle = 128; // See also add_contact_box.
constexpr auto kMaxChannelDescription = 255; // See also add_contact_box. constexpr auto kMaxChannelDescription = 255; // See also add_contact_box.
class Controller class Controller : public base::has_weak_ptr {
: public base::has_weak_ptr
, private MTP::Sender {
public: public:
Controller( Controller(
not_null<Window::SessionNavigation*> navigation, not_null<Window::SessionNavigation*> navigation,
@ -334,6 +332,7 @@ private:
const not_null<Window::SessionNavigation*> _navigation; const not_null<Window::SessionNavigation*> _navigation;
const not_null<Ui::BoxContent*> _box; const not_null<Ui::BoxContent*> _box;
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
MTP::Sender _api;
const bool _isGroup = false; const bool _isGroup = false;
base::unique_qptr<Ui::VerticalLayout> _wrap; base::unique_qptr<Ui::VerticalLayout> _wrap;
@ -344,7 +343,6 @@ private:
const rpl::event_stream<Privacy> _privacyTypeUpdates; const rpl::event_stream<Privacy> _privacyTypeUpdates;
const rpl::event_stream<ChannelData*> _linkedChatUpdates; const rpl::event_stream<ChannelData*> _linkedChatUpdates;
MTP::Sender _linkedChatsRequester;
mtpRequestId _linkedChatsRequestId = 0; mtpRequestId _linkedChatsRequestId = 0;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
@ -358,6 +356,7 @@ Controller::Controller(
: _navigation(navigation) : _navigation(navigation)
, _box(box) , _box(box)
, _peer(peer) , _peer(peer)
, _api(_peer->session().api().instance())
, _isGroup(_peer->isChat() || _peer->isMegagroup()) { , _isGroup(_peer->isChat() || _peer->isMegagroup()) {
_box->setTitle(_isGroup _box->setTitle(_isGroup
? tr::lng_edit_group() ? tr::lng_edit_group()
@ -478,7 +477,7 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
[=] { submitTitle(); }); [=] { submitTitle(); });
_controls.title = result->entity(); _controls.title = result->entity();
return std::move(result); return result;
} }
object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() { object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
@ -512,7 +511,7 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
[=] { submitDescription(); }); [=] { submitDescription(); });
_controls.description = result->entity(); _controls.description = result->entity();
return std::move(result); return result;
} }
object_ptr<Ui::RpWidget> Controller::createManageGroupButtons() { object_ptr<Ui::RpWidget> Controller::createManageGroupButtons() {
@ -526,7 +525,7 @@ object_ptr<Ui::RpWidget> Controller::createManageGroupButtons() {
fillManageSection(); fillManageSection();
return std::move(result); return result;
} }
object_ptr<Ui::RpWidget> Controller::createStickersEdit() { object_ptr<Ui::RpWidget> Controller::createStickersEdit() {
@ -564,7 +563,7 @@ object_ptr<Ui::RpWidget> Controller::createStickersEdit() {
Ui::show(Box<StickersBox>(channel), Ui::LayerOption::KeepOther); Ui::show(Box<StickersBox>(channel), Ui::LayerOption::KeepOther);
}); });
return std::move(result); return result;
} }
bool Controller::canEditInformation() const { bool Controller::canEditInformation() const {
@ -644,7 +643,7 @@ void Controller::showEditLinkedChatBox() {
callback(_linkedChatOriginalValue); callback(_linkedChatOriginalValue);
return; return;
} }
_linkedChatsRequestId = _linkedChatsRequester.request( _linkedChatsRequestId = _api.request(
MTPchannels_GetGroupsForDiscussion() MTPchannels_GetGroupsForDiscussion()
).done([=](const MTPmessages_Chats &result) { ).done([=](const MTPmessages_Chats &result) {
_linkedChatsRequestId = 0; _linkedChatsRequestId = 0;
@ -1187,7 +1186,7 @@ void Controller::saveUsername() {
return; return;
} }
request(MTPchannels_UpdateUsername( _api.request(MTPchannels_UpdateUsername(
channel->inputChannel, channel->inputChannel,
MTP_string(*_savingData.username) MTP_string(*_savingData.username)
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
@ -1242,7 +1241,7 @@ void Controller::saveLinkedChat() {
const auto input = *_savingData.linkedChat const auto input = *_savingData.linkedChat
? (*_savingData.linkedChat)->inputChannel ? (*_savingData.linkedChat)->inputChannel
: MTP_inputChannelEmpty(); : MTP_inputChannelEmpty();
request(MTPchannels_SetDiscussionGroup( _api.request(MTPchannels_SetDiscussionGroup(
(channel->isBroadcast() ? channel->inputChannel : input), (channel->isBroadcast() ? channel->inputChannel : input),
(channel->isBroadcast() ? input : channel->inputChannel) (channel->isBroadcast() ? input : channel->inputChannel)
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
@ -1283,14 +1282,14 @@ void Controller::saveTitle() {
}; };
if (const auto channel = _peer->asChannel()) { if (const auto channel = _peer->asChannel()) {
request(MTPchannels_EditTitle( _api.request(MTPchannels_EditTitle(
channel->inputChannel, channel->inputChannel,
MTP_string(*_savingData.title) MTP_string(*_savingData.title)
)).done(std::move(onDone) )).done(std::move(onDone)
).fail(std::move(onFail) ).fail(std::move(onFail)
).send(); ).send();
} else if (const auto chat = _peer->asChat()) { } else if (const auto chat = _peer->asChat()) {
request(MTPmessages_EditChatTitle( _api.request(MTPmessages_EditChatTitle(
chat->inputChat, chat->inputChat,
MTP_string(*_savingData.title) MTP_string(*_savingData.title)
)).done(std::move(onDone) )).done(std::move(onDone)
@ -1311,7 +1310,7 @@ void Controller::saveDescription() {
_peer->setAbout(*_savingData.description); _peer->setAbout(*_savingData.description);
continueSave(); continueSave();
}; };
request(MTPmessages_EditChatAbout( _api.request(MTPmessages_EditChatAbout(
_peer->input, _peer->input,
MTP_string(*_savingData.description) MTP_string(*_savingData.description)
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
@ -1368,7 +1367,7 @@ void Controller::togglePreHistoryHidden(
done(); done();
}; };
request(MTPchannels_TogglePreHistoryHidden( _api.request(MTPchannels_TogglePreHistoryHidden(
channel->inputChannel, channel->inputChannel,
MTP_bool(hidden) MTP_bool(hidden)
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
@ -1390,7 +1389,7 @@ void Controller::saveSignatures() {
|| *_savingData.signatures == channel->addsSignature()) { || *_savingData.signatures == channel->addsSignature()) {
return continueSave(); return continueSave();
} }
request(MTPchannels_ToggleSignatures( _api.request(MTPchannels_ToggleSignatures(
channel->inputChannel, channel->inputChannel,
MTP_bool(*_savingData.signatures) MTP_bool(*_savingData.signatures)
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {

View file

@ -51,9 +51,7 @@ namespace {
constexpr auto kUsernameCheckTimeout = crl::time(200); constexpr auto kUsernameCheckTimeout = crl::time(200);
constexpr auto kMinUsernameLength = 5; constexpr auto kMinUsernameLength = 5;
class Controller class Controller : public base::has_weak_ptr {
: public base::has_weak_ptr
, private MTP::Sender {
public: public:
Controller( Controller(
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
@ -144,6 +142,7 @@ private:
QString inviteLinkText(); QString inviteLinkText();
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
MTP::Sender _api;
std::optional<Privacy> _privacySavedValue; std::optional<Privacy> _privacySavedValue;
std::optional<QString> _usernameSavedValue; std::optional<QString> _usernameSavedValue;
@ -169,6 +168,7 @@ Controller::Controller(
std::optional<Privacy> privacySavedValue, std::optional<Privacy> privacySavedValue,
std::optional<QString> usernameSavedValue) std::optional<QString> usernameSavedValue)
: _peer(peer) : _peer(peer)
, _api(_peer->session().api().instance())
, _privacySavedValue(privacySavedValue) , _privacySavedValue(privacySavedValue)
, _usernameSavedValue(usernameSavedValue) , _usernameSavedValue(usernameSavedValue)
, _useLocationPhrases(useLocationPhrases) , _useLocationPhrases(useLocationPhrases)
@ -364,7 +364,7 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
const auto shown = (_controls.privacy->value() == Privacy::HasUsername); const auto shown = (_controls.privacy->value() == Privacy::HasUsername);
result->toggle(shown, anim::type::instant); result->toggle(shown, anim::type::instant);
return std::move(result); return result;
} }
void Controller::privacyChanged(Privacy value) { void Controller::privacyChanged(Privacy value) {
@ -401,7 +401,7 @@ void Controller::privacyChanged(Privacy value) {
refreshVisibilities(); refreshVisibilities();
_controls.usernameInput->setDisplayFocused(true); _controls.usernameInput->setDisplayFocused(true);
} else { } else {
request(base::take(_checkUsernameRequestId)).cancel(); _api.request(base::take(_checkUsernameRequestId)).cancel();
_checkUsernameTimer.cancel(); _checkUsernameTimer.cancel();
refreshVisibilities(); refreshVisibilities();
} }
@ -420,11 +420,11 @@ void Controller::checkUsernameAvailability() {
return; return;
} }
if (_checkUsernameRequestId) { if (_checkUsernameRequestId) {
request(_checkUsernameRequestId).cancel(); _api.request(_checkUsernameRequestId).cancel();
} }
const auto channel = _peer->migrateToOrMe()->asChannel(); const auto channel = _peer->migrateToOrMe()->asChannel();
const auto username = channel ? channel->username : QString(); const auto username = channel ? channel->username : QString();
_checkUsernameRequestId = request(MTPchannels_CheckUsername( _checkUsernameRequestId = _api.request(MTPchannels_CheckUsername(
channel ? channel->inputChannel : MTP_inputChannelEmpty(), channel ? channel->inputChannel : MTP_inputChannelEmpty(),
MTP_string(checking) MTP_string(checking)
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
@ -630,7 +630,7 @@ object_ptr<Ui::RpWidget> Controller::createInviteLinkEdit() {
observeInviteLink(); observeInviteLink();
return std::move(result); return result;
} }
void Controller::refreshEditInviteLink() { void Controller::refreshEditInviteLink() {
@ -692,7 +692,7 @@ object_ptr<Ui::RpWidget> Controller::createInviteLinkCreate() {
observeInviteLink(); observeInviteLink();
return std::move(result); return result;
} }
void Controller::refreshCreateInviteLink() { void Controller::refreshCreateInviteLink() {

View file

@ -31,6 +31,7 @@ RateCallBox::RateCallBox(
uint64 callId, uint64 callId,
uint64 callAccessHash) uint64 callAccessHash)
: _session(session) : _session(session)
, _api(_session->api().instance())
, _callId(callId) , _callId(callId)
, _callAccessHash(callAccessHash) { , _callAccessHash(callAccessHash) {
} }
@ -120,7 +121,7 @@ void RateCallBox::send() {
return; return;
} }
auto comment = _comment ? _comment->getLastText().trimmed() : QString(); auto comment = _comment ? _comment->getLastText().trimmed() : QString();
_requestId = request(MTPphone_SetCallRating( _requestId = _api.request(MTPphone_SetCallRating(
MTP_flags(0), MTP_flags(0),
MTP_inputPhoneCall(MTP_long(_callId), MTP_long(_callAccessHash)), MTP_inputPhoneCall(MTP_long(_callId), MTP_long(_callAccessHash)),
MTP_int(_rating), MTP_int(_rating),

View file

@ -20,7 +20,7 @@ namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
class RateCallBox : public Ui::BoxContent, private MTP::Sender { class RateCallBox : public Ui::BoxContent {
public: public:
RateCallBox( RateCallBox(
QWidget*, QWidget*,
@ -41,6 +41,7 @@ private:
void commentResized(); void commentResized();
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api;
uint64 _callId = 0; uint64 _callId = 0;
uint64 _callAccessHash = 0; uint64 _callAccessHash = 0;

View file

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
#include "ui/toast/toast.h" #include "ui/toast/toast.h"
#include "mtproto/facade.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "styles/style_layers.h" #include "styles/style_layers.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "boxes/abstract_box.h" #include "boxes/abstract_box.h"
#include "mtproto/mtproto_rpc_sender.h"
namespace Ui { namespace Ui {
template <typename Enum> template <typename Enum>

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/checkbox.h" #include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "api/api_self_destruct.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "styles/style_layers.h" #include "styles/style_layers.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
@ -76,7 +77,7 @@ void SelfDestructionBox::showContent() {
clearButtons(); clearButtons();
addButton(tr::lng_settings_save(), [=] { addButton(tr::lng_settings_save(), [=] {
_session->api().saveSelfDestruct(_ttlGroup->value()); _session->api().selfDestruct().update(_ttlGroup->value());
closeBox(); closeBox();
}); });
addButton(tr::lng_cancel(), [=] { closeBox(); }); addButton(tr::lng_cancel(), [=] { closeBox(); });

View file

@ -20,7 +20,7 @@ namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
class SelfDestructionBox : public Ui::BoxContent, private MTP::Sender { class SelfDestructionBox : public Ui::BoxContent {
public: public:
SelfDestructionBox( SelfDestructionBox(
QWidget*, QWidget*,

View file

@ -365,6 +365,7 @@ void AlbumThumb::prepareCache(QSize size, int shrink) {
ImageRoundRadius::Large, ImageRoundRadius::Large,
_albumCorners, _albumCorners,
QRect(QPoint(), size * cIntRetinaFactor())); QRect(QPoint(), size * cIntRetinaFactor()));
_albumCache.setDevicePixelRatio(cRetinaFactor());
} }
void AlbumThumb::drawSimpleFrame(Painter &p, QRect to, QSize size) const { void AlbumThumb::drawSimpleFrame(Painter &p, QRect to, QSize size) const {

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "apiwrap.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "base/unixtime.h" #include "base/unixtime.h"
@ -77,6 +78,7 @@ private:
SessionsBox::SessionsBox(QWidget*, not_null<Main::Session*> session) SessionsBox::SessionsBox(QWidget*, not_null<Main::Session*> session)
: _session(session) : _session(session)
, _api(_session->api().instance())
, _shortPollTimer([=] { shortPollSessions(); }) { , _shortPollTimer([=] { shortPollSessions(); }) {
} }
@ -280,7 +282,7 @@ void SessionsBox::shortPollSessions() {
if (_shortPollRequest) { if (_shortPollRequest) {
return; return;
} }
_shortPollRequest = request(MTPaccount_GetAuthorizations( _shortPollRequest = _api.request(MTPaccount_GetAuthorizations(
)).done([=](const MTPaccount_Authorizations &result) { )).done([=](const MTPaccount_Authorizations &result) {
got(result); got(result);
}).send(); }).send();
@ -294,7 +296,7 @@ void SessionsBox::terminateOne(uint64 hash) {
_terminateBox->closeBox(); _terminateBox->closeBox();
_terminateBox = nullptr; _terminateBox = nullptr;
} }
request(MTPaccount_ResetAuthorization( _api.request(MTPaccount_ResetAuthorization(
MTP_long(hash) MTP_long(hash)
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
_inner->terminatingOne(hash, false); _inner->terminatingOne(hash, false);
@ -330,12 +332,12 @@ void SessionsBox::terminateAll() {
_terminateBox->closeBox(); _terminateBox->closeBox();
_terminateBox = nullptr; _terminateBox = nullptr;
} }
request(MTPauth_ResetAuthorizations( _api.request(MTPauth_ResetAuthorizations(
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
request(base::take(_shortPollRequest)).cancel(); _api.request(base::take(_shortPollRequest)).cancel();
shortPollSessions(); shortPollSessions();
}).fail([=](const RPCError &result) { }).fail([=](const RPCError &result) {
request(base::take(_shortPollRequest)).cancel(); _api.request(base::take(_shortPollRequest)).cancel();
shortPollSessions(); shortPollSessions();
}).send(); }).send();
setLoading(true); setLoading(true);

View file

@ -22,7 +22,7 @@ namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
class SessionsBox : public Ui::BoxContent, private MTP::Sender { class SessionsBox : public Ui::BoxContent {
public: public:
SessionsBox(QWidget*, not_null<Main::Session*> session); SessionsBox(QWidget*, not_null<Main::Session*> session);
@ -60,6 +60,7 @@ private:
void terminateAll(); void terminateAll();
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api;
bool _loading = false; bool _loading = false;
Full _data; Full _data;

View file

@ -722,7 +722,6 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
yFrom *= _columnCount; yFrom *= _columnCount;
yTo *= _columnCount; yTo *= _columnCount;
_navigation->session().downloader().clearPriorities();
if (_filter.isEmpty()) { if (_filter.isEmpty()) {
if (!_chatsIndexed->empty()) { if (!_chatsIndexed->empty()) {
auto i = _chatsIndexed->cfind(yFrom, _rowHeight); auto i = _chatsIndexed->cfind(yFrom, _rowHeight);

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h" #include "base/timer.h"
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#include "ui/effects/round_checkbox.h" #include "ui/effects/round_checkbox.h"
#include "mtproto/mtproto_rpc_sender.h"
enum class SendMenuType; enum class SendMenuType;

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_file_origin.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "chat_helpers/stickers.h" #include "chat_helpers/stickers.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
@ -99,7 +100,7 @@ private:
void showPreview(); void showPreview();
not_null<Window::SessionController*> _controller; not_null<Window::SessionController*> _controller;
MTP::Sender _mtp; MTP::Sender _api;
std::vector<Element> _elements; std::vector<Element> _elements;
std::unique_ptr<Lottie::MultiPlayer> _lottiePlayer; std::unique_ptr<Lottie::MultiPlayer> _lottiePlayer;
Stickers::Pack _pack; Stickers::Pack _pack;
@ -220,6 +221,7 @@ StickerSetBox::Inner::Inner(
const MTPInputStickerSet &set) const MTPInputStickerSet &set)
: RpWidget(parent) : RpWidget(parent)
, _controller(controller) , _controller(controller)
, _api(_controller->session().api().instance())
, _input(set) , _input(set)
, _previewTimer([=] { showPreview(); }) { , _previewTimer([=] { showPreview(); }) {
set.match([&](const MTPDinputStickerSetID &data) { set.match([&](const MTPDinputStickerSetID &data) {
@ -231,7 +233,7 @@ StickerSetBox::Inner::Inner(
}, [&](const MTPDinputStickerSetAnimatedEmoji &) { }, [&](const MTPDinputStickerSetAnimatedEmoji &) {
}); });
_mtp.request(MTPmessages_GetStickerSet( _api.request(MTPmessages_GetStickerSet(
_input _input
)).done([=](const MTPmessages_StickerSet &result) { )).done([=](const MTPmessages_StickerSet &result) {
gotSet(result); gotSet(result);
@ -700,7 +702,7 @@ void StickerSetBox::Inner::install() {
} else if (_installRequest) { } else if (_installRequest) {
return; return;
} }
_installRequest = _mtp.request(MTPmessages_InstallStickerSet( _installRequest = _api.request(MTPmessages_InstallStickerSet(
_input, _input,
MTP_bool(false) MTP_bool(false)
)).done([=](const MTPmessages_StickerSetInstallResult &result) { )).done([=](const MTPmessages_StickerSetInstallResult &result) {

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_file_origin.h"
#include "core/application.h" #include "core/application.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "mainwidget.h" #include "mainwidget.h"
@ -410,7 +411,7 @@ void StickersBox::updateTabsGeometry() {
auto featuredLeft = width() / 3; auto featuredLeft = width() / 3;
auto featuredRight = 2 * width() / 3; auto featuredRight = 2 * width() / 3;
auto featuredTextWidth = st::stickersTabs.labelFont->width(tr::lng_stickers_featured_tab(tr::now).toUpper()); auto featuredTextWidth = st::stickersTabs.labelStyle.font->width(tr::lng_stickers_featured_tab(tr::now).toUpper());
auto featuredTextRight = featuredLeft + (featuredRight - featuredLeft - featuredTextWidth) / 2 + featuredTextWidth; auto featuredTextRight = featuredLeft + (featuredRight - featuredLeft - featuredTextWidth) / 2 + featuredTextWidth;
auto unreadBadgeLeft = featuredTextRight - st::stickersFeaturedBadgeSkip; auto unreadBadgeLeft = featuredTextRight - st::stickersFeaturedBadgeSkip;
auto unreadBadgeTop = st::stickersFeaturedBadgeTop; auto unreadBadgeTop = st::stickersFeaturedBadgeTop;
@ -661,6 +662,7 @@ StickersBox::Inner::Inner(
StickersBox::Section section) StickersBox::Section section)
: RpWidget(parent) : RpWidget(parent)
, _session(session) , _session(session)
, _api(_session->api().instance())
, _section(section) , _section(section)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) { , _shiftingAnimation([=](crl::time now) {
@ -677,6 +679,7 @@ StickersBox::Inner::Inner(
StickersBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> megagroup) StickersBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> megagroup)
: RpWidget(parent) : RpWidget(parent)
, _session(&megagroup->session()) , _session(&megagroup->session())
, _api(_session->api().instance())
, _section(StickersBox::Section::Installed) , _section(StickersBox::Section::Installed)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) { , _shiftingAnimation([=](crl::time now) {
@ -1469,11 +1472,13 @@ void StickersBox::Inner::handleMegagroupSetAddressChange() {
} }
} }
} else if (!_megagroupSetRequestId) { } else if (!_megagroupSetRequestId) {
_megagroupSetRequestId = request(MTPmessages_GetStickerSet(MTP_inputStickerSetShortName(MTP_string(text)))).done([this](const MTPmessages_StickerSet &result) { _megagroupSetRequestId = _api.request(MTPmessages_GetStickerSet(
MTP_inputStickerSetShortName(MTP_string(text))
)).done([=](const MTPmessages_StickerSet &result) {
_megagroupSetRequestId = 0; _megagroupSetRequestId = 0;
auto set = Stickers::FeedSetFull(result); auto set = Stickers::FeedSetFull(result);
setMegagroupSelectedSet(MTP_inputStickerSetID(MTP_long(set->id), MTP_long(set->access))); setMegagroupSelectedSet(MTP_inputStickerSetID(MTP_long(set->id), MTP_long(set->access)));
}).fail([this](const RPCError &error) { }).fail([=](const RPCError &error) {
_megagroupSetRequestId = 0; _megagroupSetRequestId = 0;
setMegagroupSelectedSet(MTP_inputStickerSetEmpty()); setMegagroupSelectedSet(MTP_inputStickerSetEmpty());
}).send(); }).send();

View file

@ -153,8 +153,7 @@ private:
// This class is hold in header because it requires Qt preprocessing. // This class is hold in header because it requires Qt preprocessing.
class StickersBox::Inner class StickersBox::Inner
: public Ui::RpWidget : public Ui::RpWidget
, private base::Subscriber , private base::Subscriber {
, private MTP::Sender {
Q_OBJECT Q_OBJECT
public: public:
@ -320,6 +319,7 @@ private:
int countMaxNameWidth() const; int countMaxNameWidth() const;
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api;
Section _section; Section _section;

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "boxes/abstract_box.h" #include "boxes/abstract_box.h"
#include "mtproto/mtproto_rpc_sender.h"
namespace Ui { namespace Ui {
class UsernameInput; class UsernameInput;

View file

@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_media_types.h" #include "data/data_media_types.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "apiwrap.h"
#include "facades.h" #include "facades.h"
#include "app.h" #include "app.h"
@ -216,7 +217,8 @@ void BoxController::Row::stopLastActionRipple() {
} }
BoxController::BoxController(not_null<Window::SessionController*> window) BoxController::BoxController(not_null<Window::SessionController*> window)
: _window(window) { : _window(window)
, _api(_window->session().api().instance()) {
} }
Main::Session &BoxController::session() const { Main::Session &BoxController::session() const {
@ -256,7 +258,7 @@ void BoxController::loadMoreRows() {
return; return;
} }
_loadRequestId = request(MTPmessages_Search( _loadRequestId = _api.request(MTPmessages_Search(
MTP_flags(0), MTP_flags(0),
MTP_inputPeerEmpty(), MTP_inputPeerEmpty(),
MTP_string(), MTP_string(),
@ -404,8 +406,7 @@ BoxController::Row *BoxController::rowForItem(not_null<const HistoryItem*> item)
std::unique_ptr<PeerListRow> BoxController::createRow( std::unique_ptr<PeerListRow> BoxController::createRow(
not_null<HistoryItem*> item) const { not_null<HistoryItem*> item) const {
auto row = std::make_unique<Row>(item); return std::make_unique<Row>(item);
return std::move(row);
} }
} // namespace Calls } // namespace Calls

View file

@ -15,10 +15,7 @@ class SessionController;
namespace Calls { namespace Calls {
class BoxController class BoxController : public PeerListController, private base::Subscriber {
: public PeerListController
, private base::Subscriber
, private MTP::Sender {
public: public:
explicit BoxController(not_null<Window::SessionController*> window); explicit BoxController(not_null<Window::SessionController*> window);
@ -44,6 +41,7 @@ private:
not_null<HistoryItem*> item) const; not_null<HistoryItem*> item) const;
const not_null<Window::SessionController*> _window; const not_null<Window::SessionController*> _window;
MTP::Sender _api;
MsgId _offsetId = 0; MsgId _offsetId = 0;
mtpRequestId _loadRequestId = 0; mtpRequestId _loadRequestId = 0;

View file

@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/rate_call_box.h" #include "boxes/rate_call_box.h"
#include "calls/calls_instance.h" #include "calls/calls_instance.h"
#include "base/openssl_help.h" #include "base/openssl_help.h"
#include "mtproto/connection.h" #include "mtproto/mtproto_dh_utils.h"
#include "media/audio/media_audio_track.h" #include "media/audio/media_audio_track.h"
#include "base/platform/base_platform_info.h" #include "base/platform/base_platform_info.h"
#include "calls/calls_panel.h" #include "calls/calls_panel.h"
@ -130,6 +130,7 @@ Call::Call(
Type type) Type type)
: _delegate(delegate) : _delegate(delegate)
, _user(user) , _user(user)
, _api(_user->session().api().instance())
, _type(type) { , _type(type) {
_discardByTimeoutTimer.setCallback([this] { hangup(); }); _discardByTimeoutTimer.setCallback([this] { hangup(); });
@ -189,7 +190,7 @@ void Call::startOutgoing() {
Expects(_state == State::Requesting); Expects(_state == State::Requesting);
Expects(_gaHash.size() == kSha256Size); Expects(_gaHash.size() == kSha256Size);
request(MTPphone_RequestCall( _api.request(MTPphone_RequestCall(
MTP_flags(0), MTP_flags(0),
_user->inputUser, _user->inputUser,
MTP_int(rand_value<int32>()), MTP_int(rand_value<int32>()),
@ -236,11 +237,13 @@ void Call::startIncoming() {
Expects(_type == Type::Incoming); Expects(_type == Type::Incoming);
Expects(_state == State::Starting); Expects(_state == State::Starting);
request(MTPphone_ReceivedCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)))).done([this](const MTPBool &result) { _api.request(MTPphone_ReceivedCall(
MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash))
)).done([=](const MTPBool &result) {
if (_state == State::Starting) { if (_state == State::Starting) {
setState(State::WaitingIncoming); setState(State::WaitingIncoming);
} }
}).fail([this](const RPCError &error) { }).fail([=](const RPCError &error) {
handleRequestError(error); handleRequestError(error);
}).send(); }).send();
} }
@ -267,7 +270,7 @@ void Call::actuallyAnswer() {
} else { } else {
_answerAfterDhConfigReceived = false; _answerAfterDhConfigReceived = false;
} }
request(MTPphone_AcceptCall( _api.request(MTPphone_AcceptCall(
MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)),
MTP_bytes(_gb), MTP_bytes(_gb),
MTP_phoneCallProtocol( MTP_phoneCallProtocol(
@ -504,7 +507,7 @@ void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) {
_keyFingerprint = ComputeFingerprint(_authKey); _keyFingerprint = ComputeFingerprint(_authKey);
setState(State::ExchangingKeys); setState(State::ExchangingKeys);
request(MTPphone_ConfirmCall( _api.request(MTPphone_ConfirmCall(
MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)),
MTP_bytes(_ga), MTP_bytes(_ga),
MTP_long(_keyFingerprint), MTP_long(_keyFingerprint),
@ -623,10 +626,10 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
_controller->SetEncryptionKey(reinterpret_cast<char*>(_authKey.data()), (_type == Type::Outgoing)); _controller->SetEncryptionKey(reinterpret_cast<char*>(_authKey.data()), (_type == Type::Outgoing));
_controller->SetCallbacks(callbacks); _controller->SetCallbacks(callbacks);
if (Global::UseProxyForCalls() if (Global::UseProxyForCalls()
&& (Global::ProxySettings() == ProxyData::Settings::Enabled)) { && (Global::ProxySettings() == MTP::ProxyData::Settings::Enabled)) {
const auto &proxy = Global::SelectedProxy(); const auto &proxy = Global::SelectedProxy();
if (proxy.supportsCalls()) { if (proxy.supportsCalls()) {
Assert(proxy.type == ProxyData::Type::Socks5); Assert(proxy.type == MTP::ProxyData::Type::Socks5);
_controller->SetProxy( _controller->SetProxy(
tgvoip::PROXY_SOCKS5, tgvoip::PROXY_SOCKS5,
proxy.host.toStdString(), proxy.host.toStdString(),
@ -840,7 +843,7 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) {
auto duration = getDurationMs() / 1000; auto duration = getDurationMs() / 1000;
auto connectionId = _controller ? _controller->GetPreferredRelayID() : 0; auto connectionId = _controller ? _controller->GetPreferredRelayID() : 0;
_finishByTimeoutTimer.call(kHangupTimeoutMs, [this, finalState] { setState(finalState); }); _finishByTimeoutTimer.call(kHangupTimeoutMs, [this, finalState] { setState(finalState); });
request(MTPphone_DiscardCall( _api.request(MTPphone_DiscardCall(
MTP_flags(0), MTP_flags(0),
MTP_inputPhoneCall( MTP_inputPhoneCall(
MTP_long(_id), MTP_long(_id),

View file

@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h" #include "base/timer.h"
#include "base/bytes.h" #include "base/bytes.h"
#include "mtproto/sender.h" #include "mtproto/sender.h"
#include "mtproto/auth_key.h" #include "mtproto/mtproto_auth_key.h"
namespace Media { namespace Media {
namespace Audio { namespace Audio {
@ -31,7 +31,7 @@ struct DhConfig {
bytes::vector p; bytes::vector p;
}; };
class Call : public base::has_weak_ptr, private MTP::Sender { class Call : public base::has_weak_ptr {
public: public:
class Delegate { class Delegate {
public: public:
@ -183,6 +183,7 @@ private:
not_null<Delegate*> _delegate; not_null<Delegate*> _delegate;
not_null<UserData*> _user; not_null<UserData*> _user;
MTP::Sender _api;
Type _type = Type::Outgoing; Type _type = Type::Outgoing;
State _state = State::Starting; State _state = State::Starting;
FinishType _finishAfterRequestingCall = FinishType::None; FinishType _finishAfterRequestingCall = FinishType::None;

View file

@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "calls/calls_instance.h" #include "calls/calls_instance.h"
#include "mtproto/connection.h" #include "mtproto/mtproto_dh_utils.h"
#include "core/application.h" #include "core/application.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "apiwrap.h" #include "apiwrap.h"
@ -32,7 +32,9 @@ constexpr auto kServerConfigUpdateTimeoutMs = 24 * 3600 * crl::time(1000);
} // namespace } // namespace
Instance::Instance(not_null<Main::Session*> session) : _session(session) { Instance::Instance(not_null<Main::Session*> session)
: _session(session)
, _api(_session->api().instance()) {
} }
void Instance::startOutgoingCall(not_null<UserData*> user) { void Instance::startOutgoingCall(not_null<UserData*> user) {
@ -139,7 +141,7 @@ void Instance::refreshDhConfig() {
Expects(_currentCall != nullptr); Expects(_currentCall != nullptr);
const auto weak = base::make_weak(_currentCall); const auto weak = base::make_weak(_currentCall);
request(MTPmessages_GetDhConfig( _api.request(MTPmessages_GetDhConfig(
MTP_int(_dhConfig.version), MTP_int(_dhConfig.version),
MTP_int(MTP::ModExpFirst::kRandomPowerSize) MTP_int(MTP::ModExpFirst::kRandomPowerSize)
)).done([=](const MTPmessages_DhConfig &result) { )).done([=](const MTPmessages_DhConfig &result) {
@ -203,13 +205,14 @@ void Instance::refreshServerConfig() {
if (_lastServerConfigUpdateTime && (crl::now() - _lastServerConfigUpdateTime) < kServerConfigUpdateTimeoutMs) { if (_lastServerConfigUpdateTime && (crl::now() - _lastServerConfigUpdateTime) < kServerConfigUpdateTimeoutMs) {
return; return;
} }
_serverConfigRequestId = request(MTPphone_GetCallConfig()).done([this](const MTPDataJSON &result) { _serverConfigRequestId = _api.request(MTPphone_GetCallConfig(
)).done([=](const MTPDataJSON &result) {
_serverConfigRequestId = 0; _serverConfigRequestId = 0;
_lastServerConfigUpdateTime = crl::now(); _lastServerConfigUpdateTime = crl::now();
const auto &json = result.c_dataJSON().vdata().v; const auto &json = result.c_dataJSON().vdata().v;
UpdateConfig(std::string(json.data(), json.size())); UpdateConfig(std::string(json.data(), json.size()));
}).fail([this](const RPCError &error) { }).fail([=](const RPCError &error) {
_serverConfigRequestId = 0; _serverConfigRequestId = 0;
}).send(); }).send();
} }
@ -246,7 +249,7 @@ void Instance::handleCallUpdate(const MTPPhoneCall &call) {
LOG(("API Error: Self found in phoneCallRequested.")); LOG(("API Error: Self found in phoneCallRequested."));
} }
if (alreadyInCall() || !user || user->isSelf()) { if (alreadyInCall() || !user || user->isSelf()) {
request(MTPphone_DiscardCall( _api.request(MTPphone_DiscardCall(
MTP_flags(0), MTP_flags(0),
MTP_inputPhoneCall(phoneCall.vid(), phoneCall.vaccess_hash()), MTP_inputPhoneCall(phoneCall.vid(), phoneCall.vaccess_hash()),
MTP_int(0), MTP_int(0),

View file

@ -25,8 +25,7 @@ namespace Calls {
class Panel; class Panel;
class Instance class Instance
: private MTP::Sender : private Call::Delegate
, private Call::Delegate
, private base::Subscriber , private base::Subscriber
, public base::has_weak_ptr { , public base::has_weak_ptr {
public: public:
@ -74,6 +73,7 @@ private:
void handleCallUpdate(const MTPPhoneCall &call); void handleCallUpdate(const MTPPhoneCall &call);
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api;
DhConfig _dhConfig; DhConfig _dhConfig;

View file

@ -271,7 +271,7 @@ QPoint BotKeyboard::tooltipPos() const {
} }
bool BotKeyboard::tooltipWindowActive() const { bool BotKeyboard::tooltipWindowActive() const {
return Ui::InFocusChain(window()); return Ui::AppInFocus() && Ui::InFocusChain(window());
} }
QString BotKeyboard::tooltipText() const { QString BotKeyboard::tooltipText() const {

View file

@ -72,6 +72,12 @@ struct LangPackData {
return false; return false;
} }
[[nodiscard]] EmojiPtr FindExact(const QString &text) {
auto length = 0;
const auto result = Find(text, &length);
return (length < text.size()) ? nullptr : result;
}
void CreateCacheFilePath() { void CreateCacheFilePath() {
QDir().mkpath(internal::CacheFileFolder() + qstr("/keywords")); QDir().mkpath(internal::CacheFileFolder() + qstr("/keywords"));
} }
@ -120,7 +126,7 @@ void CreateCacheFilePath() {
const auto emoji = MustAddPostfix(text) const auto emoji = MustAddPostfix(text)
? (text + QChar(Ui::Emoji::kPostfix)) ? (text + QChar(Ui::Emoji::kPostfix))
: text; : text;
const auto entry = LangPackEmoji{ Find(emoji), text }; const auto entry = LangPackEmoji{ FindExact(emoji), text };
if (!entry.emoji) { if (!entry.emoji) {
return {}; return {};
} }
@ -251,7 +257,7 @@ void ApplyDifference(
const auto emoji = MustAddPostfix(text) const auto emoji = MustAddPostfix(text)
? (text + QChar(Ui::Emoji::kPostfix)) ? (text + QChar(Ui::Emoji::kPostfix))
: text; : text;
return LangPackEmoji{ Find(emoji), text }; return LangPackEmoji{ FindExact(emoji), text };
}) | ranges::view::filter([&](const LangPackEmoji &entry) { }) | ranges::view::filter([&](const LangPackEmoji &entry) {
if (!entry.emoji) { if (!entry.emoji) {
LOG(("API Warning: emoji %1 is not supported, word: %2." LOG(("API Warning: emoji %1 is not supported, word: %2."

View file

@ -427,7 +427,7 @@ object_ptr<TabbedSelector::InnerFooter> EmojiListWidget::createFooter() {
Expects(_footer == nullptr); Expects(_footer == nullptr);
auto result = object_ptr<Footer>(this); auto result = object_ptr<Footer>(this);
_footer = result; _footer = result;
return std::move(result); return result;
} }
template <typename Callback> template <typename Callback>
@ -770,7 +770,7 @@ QPoint EmojiListWidget::tooltipPos() const {
} }
bool EmojiListWidget::tooltipWindowActive() const { bool EmojiListWidget::tooltipWindowActive() const {
return Ui::InFocusChain(window()); return Ui::AppInFocus() && Ui::InFocusChain(window());
} }
TabbedSelector::InnerFooter *EmojiListWidget::getFooter() const { TabbedSelector::InnerFooter *EmojiListWidget::getFooter() const {

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_peer_values.h" #include "data/data_peer_values.h"
#include "data/data_file_origin.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"

View file

@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "styles/style_chat_helpers.h" #include "data/data_file_origin.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
#include "ui/effects/ripple_animation.h" #include "ui/effects/ripple_animation.h"
@ -22,10 +22,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "apiwrap.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "history/view/history_view_cursor_state.h" #include "history/view/history_view_cursor_state.h"
#include "facades.h" #include "facades.h"
#include "app.h" #include "app.h"
#include "styles/style_chat_helpers.h"
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
@ -130,6 +132,7 @@ GifsListWidget::GifsListWidget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller)
: Inner(parent, controller) : Inner(parent, controller)
, _api(controller->session().api().instance())
, _section(Section::Gifs) , _section(Section::Gifs)
, _updateInlineItems([=] { updateInlineItems(); }) , _updateInlineItems([=] { updateInlineItems(); })
, _previewTimer([=] { showPreview(); }) { , _previewTimer([=] { showPreview(); }) {
@ -178,7 +181,7 @@ object_ptr<TabbedSelector::InnerFooter> GifsListWidget::createFooter() {
auto result = object_ptr<Footer>(this); auto result = object_ptr<Footer>(this);
_footer = result; _footer = result;
return std::move(result); return result;
} }
void GifsListWidget::visibleTopBottomUpdated( void GifsListWidget::visibleTopBottomUpdated(
@ -217,7 +220,7 @@ GifsListWidget::~GifsListWidget() {
void GifsListWidget::cancelGifsSearch() { void GifsListWidget::cancelGifsSearch() {
_footer->setLoading(false); _footer->setLoading(false);
if (_inlineRequestId) { if (_inlineRequestId) {
request(_inlineRequestId).cancel(); _api.request(_inlineRequestId).cancel();
_inlineRequestId = 0; _inlineRequestId = 0;
} }
_inlineRequestTimer.stop(); _inlineRequestTimer.stop();
@ -840,7 +843,7 @@ void GifsListWidget::searchForGifs(const QString &query) {
if (_inlineQuery != query) { if (_inlineQuery != query) {
_footer->setLoading(false); _footer->setLoading(false);
if (_inlineRequestId) { if (_inlineRequestId) {
request(_inlineRequestId).cancel(); _api.request(_inlineRequestId).cancel();
_inlineRequestId = 0; _inlineRequestId = 0;
} }
if (_inlineCache.find(query) != _inlineCache.cend()) { if (_inlineCache.find(query) != _inlineCache.cend()) {
@ -855,7 +858,7 @@ void GifsListWidget::searchForGifs(const QString &query) {
if (!_searchBot && !_searchBotRequestId) { if (!_searchBot && !_searchBotRequestId) {
auto username = str_const_toString(kSearchBotUsername); auto username = str_const_toString(kSearchBotUsername);
_searchBotRequestId = request(MTPcontacts_ResolveUsername( _searchBotRequestId = _api.request(MTPcontacts_ResolveUsername(
MTP_string(username) MTP_string(username)
)).done([=](const MTPcontacts_ResolvedPeer &result) { )).done([=](const MTPcontacts_ResolvedPeer &result) {
Expects(result.type() == mtpc_contacts_resolvedPeer); Expects(result.type() == mtpc_contacts_resolvedPeer);
@ -905,7 +908,7 @@ void GifsListWidget::sendInlineRequest() {
} }
_footer->setLoading(true); _footer->setLoading(true);
_inlineRequestId = request(MTPmessages_GetInlineBotResults( _inlineRequestId = _api.request(MTPmessages_GetInlineBotResults(
MTP_flags(0), MTP_flags(0),
_searchBot->inputUser, _searchBot->inputUser,
_inlineQueryPeer->input, _inlineQueryPeer->input,

View file

@ -34,8 +34,7 @@ namespace ChatHelpers {
class GifsListWidget class GifsListWidget
: public TabbedSelector::Inner : public TabbedSelector::Inner
, public InlineBots::Layout::Context , public InlineBots::Layout::Context
, private base::Subscriber , private base::Subscriber {
, private MTP::Sender {
public: public:
using InlineChosen = TabbedSelector::InlineChosen; using InlineChosen = TabbedSelector::InlineChosen;
@ -119,6 +118,8 @@ private:
void updateInlineItems(); void updateInlineItems();
void showPreview(); void showPreview();
MTP::Sender _api;
Section _section = Section::Gifs; Section _section = Section::Gifs;
crl::time _lastScrolled = 0; crl::time _lastScrolled = 0;
base::Timer _updateInlineItems; base::Timer _updateInlineItems;

View file

@ -278,6 +278,9 @@ void InitSpellchecker(
not_null<Main::Session*> session, not_null<Main::Session*> session,
not_null<Ui::InputField*> field) { not_null<Ui::InputField*> field) {
#ifndef TDESKTOP_DISABLE_SPELLCHECK #ifndef TDESKTOP_DISABLE_SPELLCHECK
if (!Platform::Spellchecker::IsAvailable()) {
return;
}
const auto s = Ui::CreateChild<Spellchecker::SpellingHighlighter>( const auto s = Ui::CreateChild<Spellchecker::SpellingHighlighter>(
field.get(), field.get(),
session->settings().spellcheckerEnabledValue()); session->settings().spellcheckerEnabledValue());

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_file_origin.h"
#include "boxes/stickers_box.h" #include "boxes/stickers_box.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
@ -891,7 +892,7 @@ std::optional<std::vector<not_null<EmojiPtr>>> GetEmojiListFromSet(
if (result.empty()) { if (result.empty()) {
return std::nullopt; return std::nullopt;
} }
return std::move(result); return result;
} }
return std::nullopt; return std::nullopt;
} }

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_file_origin.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#include "ui/effects/ripple_animation.h" #include "ui/effects/ripple_animation.h"
@ -828,6 +829,7 @@ StickersListWidget::StickersListWidget(
QWidget *parent, QWidget *parent,
not_null<Window::SessionController*> controller) not_null<Window::SessionController*> controller)
: Inner(parent, controller) : Inner(parent, controller)
, _api(controller->session().api().instance())
, _section(Section::Stickers) , _section(Section::Stickers)
, _megagroupSetAbout(st::columnMinimalWidthThird - st::emojiScroll.width - st::emojiPanHeaderLeft) , _megagroupSetAbout(st::columnMinimalWidthThird - st::emojiScroll.width - st::emojiPanHeaderLeft)
, _addText(tr::lng_stickers_featured_add(tr::now).toUpper()) , _addText(tr::lng_stickers_featured_add(tr::now).toUpper())
@ -878,7 +880,7 @@ object_ptr<TabbedSelector::InnerFooter> StickersListWidget::createFooter() {
auto result = object_ptr<Footer>(this); auto result = object_ptr<Footer>(this);
_footer = result; _footer = result;
return std::move(result); return result;
} }
void StickersListWidget::visibleTopBottomUpdated( void StickersListWidget::visibleTopBottomUpdated(
@ -1069,7 +1071,7 @@ void StickersListWidget::sendSearchRequest() {
_footer->setLoading(true); _footer->setLoading(true);
const auto hash = int32(0); const auto hash = int32(0);
_searchRequestId = request(MTPmessages_SearchStickerSets( _searchRequestId = _api.request(MTPmessages_SearchStickerSets(
MTP_flags(0), MTP_flags(0),
MTP_string(_searchQuery), MTP_string(_searchQuery),
MTP_int(hash) MTP_int(hash)
@ -1092,7 +1094,7 @@ void StickersListWidget::searchForSets(const QString &query) {
if (_searchQuery != cleaned) { if (_searchQuery != cleaned) {
_footer->setLoading(false); _footer->setLoading(false);
if (const auto requestId = base::take(_searchRequestId)) { if (const auto requestId = base::take(_searchRequestId)) {
request(requestId).cancel(); _api.request(requestId).cancel();
} }
if (_searchCache.find(cleaned) != _searchCache.cend()) { if (_searchCache.find(cleaned) != _searchCache.cend()) {
_searchRequestTimer.cancel(); _searchRequestTimer.cancel();
@ -1108,7 +1110,7 @@ void StickersListWidget::searchForSets(const QString &query) {
void StickersListWidget::cancelSetsSearch() { void StickersListWidget::cancelSetsSearch() {
_footer->setLoading(false); _footer->setLoading(false);
if (const auto requestId = base::take(_searchRequestId)) { if (const auto requestId = base::take(_searchRequestId)) {
request(requestId).cancel(); _api.request(requestId).cancel();
} }
_searchRequestTimer.cancel(); _searchRequestTimer.cancel();
_searchQuery = _searchNextQuery = QString(); _searchQuery = _searchNextQuery = QString();
@ -2468,7 +2470,7 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) {
return; return;
} }
_megagroupSetIdRequested = set.vid().v; _megagroupSetIdRequested = set.vid().v;
request(MTPmessages_GetStickerSet( _api.request(MTPmessages_GetStickerSet(
_megagroupSet->mgInfo->stickerSet _megagroupSet->mgInfo->stickerSet
)).done([=](const MTPmessages_StickerSet &result) { )).done([=](const MTPmessages_StickerSet &result) {
if (const auto set = Stickers::FeedSetFull(result)) { if (const auto set = Stickers::FeedSetFull(result)) {
@ -2810,7 +2812,7 @@ void StickersListWidget::installSet(uint64 setId) {
const auto input = Stickers::inputSetId(*it); const auto input = Stickers::inputSetId(*it);
if ((it->flags & MTPDstickerSet_ClientFlag::f_not_loaded) if ((it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)
|| it->stickers.empty()) { || it->stickers.empty()) {
request(MTPmessages_GetStickerSet( _api.request(MTPmessages_GetStickerSet(
input input
)).done([=](const MTPmessages_StickerSet &result) { )).done([=](const MTPmessages_StickerSet &result) {
Stickers::FeedSetFull(result); Stickers::FeedSetFull(result);
@ -2825,7 +2827,7 @@ void StickersListWidget::installSet(uint64 setId) {
void StickersListWidget::sendInstallRequest( void StickersListWidget::sendInstallRequest(
uint64 setId, uint64 setId,
const MTPInputStickerSet &input) { const MTPInputStickerSet &input) {
request(MTPmessages_InstallStickerSet( _api.request(MTPmessages_InstallStickerSet(
input, input,
MTP_bool(false) MTP_bool(false)
)).done([=](const MTPmessages_StickerSetInstallResult &result) { )).done([=](const MTPmessages_StickerSetInstallResult &result) {
@ -2876,9 +2878,9 @@ void StickersListWidget::removeSet(uint64 setId) {
auto it = sets.find(_removingSetId); auto it = sets.find(_removingSetId);
if (it != sets.cend()) { if (it != sets.cend()) {
if (it->id && it->access) { if (it->id && it->access) {
request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)))).send(); _api.request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)))).send();
} else if (!it->shortName.isEmpty()) { } else if (!it->shortName.isEmpty()) {
request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetShortName(MTP_string(it->shortName)))).send(); _api.request(MTPmessages_UninstallStickerSet(MTP_inputStickerSetShortName(MTP_string(it->shortName)))).send();
} }
auto writeRecent = false; auto writeRecent = false;
auto &recent = Stickers::GetRecentPack(); auto &recent = Stickers::GetRecentPack();

View file

@ -38,8 +38,7 @@ struct StickerIcon;
class StickersListWidget class StickersListWidget
: public TabbedSelector::Inner : public TabbedSelector::Inner
, private base::Subscriber , private base::Subscriber {
, private MTP::Sender {
public: public:
StickersListWidget( StickersListWidget(
QWidget *parent, QWidget *parent,
@ -300,6 +299,7 @@ private:
void showPreview(); void showPreview();
MTP::Sender _api;
ChannelData *_megagroupSet = nullptr; ChannelData *_megagroupSet = nullptr;
uint64 _megagroupSetIdRequested = 0; uint64 _megagroupSetIdRequested = 0;
std::vector<Set> _mySets; std::vector<Set> _mySets;

View file

@ -51,6 +51,8 @@ TabbedPanel::TabbedPanel(
, _heightRatio(st::emojiPanHeightRatio) , _heightRatio(st::emojiPanHeightRatio)
, _minContentHeight(st::emojiPanMinHeight) , _minContentHeight(st::emojiPanMinHeight)
, _maxContentHeight(st::emojiPanMaxHeight) { , _maxContentHeight(st::emojiPanMaxHeight) {
Expects(_selector != nullptr);
_selector->setParent(this); _selector->setParent(this);
_selector->setRoundRadius(st::buttonRadius); _selector->setRoundRadius(st::buttonRadius);
_selector->setAfterShownCallback([=](SelectorTab tab) { _selector->setAfterShownCallback([=](SelectorTab tab) {
@ -145,10 +147,6 @@ void TabbedPanel::setDesiredHeightValues(
} }
void TabbedPanel::updateContentHeight() { void TabbedPanel::updateContentHeight() {
if (isDestroying()) {
return;
}
auto addedHeight = innerPadding().top() + innerPadding().bottom(); auto addedHeight = innerPadding().top() + innerPadding().bottom();
auto marginsHeight = _selector->marginTop() + _selector->marginBottom(); auto marginsHeight = _selector->marginTop() + _selector->marginBottom();
auto availableHeight = _bottom - marginsHeight; auto availableHeight = _bottom - marginsHeight;
@ -183,7 +181,7 @@ void TabbedPanel::paintEvent(QPaintEvent *e) {
auto showAnimating = _a_show.animating(); auto showAnimating = _a_show.animating();
if (_showAnimation && !showAnimating) { if (_showAnimation && !showAnimating) {
_showAnimation.reset(); _showAnimation.reset();
if (!opacityAnimating && !isDestroying()) { if (!opacityAnimating) {
showChildren(); showChildren();
_selector->afterShown(); _selector->afterShown();
} }
@ -217,9 +215,6 @@ void TabbedPanel::enterEventHook(QEvent *e) {
} }
bool TabbedPanel::preventAutoHide() const { bool TabbedPanel::preventAutoHide() const {
if (isDestroying()) {
return false;
}
return _selector->preventAutoHide(); return _selector->preventAutoHide();
} }
@ -267,7 +262,7 @@ void TabbedPanel::hideFast() {
void TabbedPanel::opacityAnimationCallback() { void TabbedPanel::opacityAnimationCallback() {
update(); update();
if (!_a_opacity.animating()) { if (!_a_opacity.animating()) {
if (_hiding || isDestroying()) { if (_hiding) {
_hiding = false; _hiding = false;
hideFinished(); hideFinished();
} else if (!_a_show.animating()) { } else if (!_a_show.animating()) {
@ -363,7 +358,7 @@ void TabbedPanel::hideAnimated() {
} }
_hideTimer.cancel(); _hideTimer.cancel();
if (!isDestroying() && _selector->isSliding()) { if (_selector->isSliding()) {
_hideAfterSlide = true; _hideAfterSlide = true;
} else { } else {
startOpacityAnimation(true); startOpacityAnimation(true);
@ -371,9 +366,6 @@ void TabbedPanel::hideAnimated() {
} }
void TabbedPanel::toggleAnimated() { void TabbedPanel::toggleAnimated() {
if (isDestroying()) {
return;
}
if (isHidden() || _hiding || _hideAfterSlide) { if (isHidden() || _hiding || _hideAfterSlide) {
showAnimated(); showAnimated();
} else { } else {
@ -387,11 +379,7 @@ void TabbedPanel::hideFinished() {
_showAnimation.reset(); _showAnimation.reset();
_cache = QPixmap(); _cache = QPixmap();
_hiding = false; _hiding = false;
if (isDestroying()) { _selector->hideFinished();
deleteLater();
} else {
_selector->hideFinished();
}
} }
void TabbedPanel::showAnimated() { void TabbedPanel::showAnimated() {
@ -401,9 +389,6 @@ void TabbedPanel::showAnimated() {
} }
void TabbedPanel::showStarted() { void TabbedPanel::showStarted() {
if (isDestroying()) {
return;
}
if (isHidden()) { if (isHidden()) {
_selector->showStarted(); _selector->showStarted();
moveByBottom(); moveByBottom();
@ -416,9 +401,6 @@ void TabbedPanel::showStarted() {
} }
bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) { bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) {
if (isDestroying()) {
return false;
}
if (e->type() == QEvent::Enter) { if (e->type() == QEvent::Enter) {
otherEnter(); otherEnter();
} else if (e->type() == QEvent::Leave) { } else if (e->type() == QEvent::Leave) {
@ -455,6 +437,7 @@ bool TabbedPanel::overlaps(const QRect &globalRect) const {
} }
TabbedPanel::~TabbedPanel() { TabbedPanel::~TabbedPanel() {
hideFast();
if (!_ownedSelector) { if (!_ownedSelector) {
_controller->takeTabbedSelectorOwnershipFrom(this); _controller->takeTabbedSelectorOwnershipFrom(this);
} }

View file

@ -75,9 +75,6 @@ private:
void hideByTimerOrLeave(); void hideByTimerOrLeave();
void moveByBottom(); void moveByBottom();
bool isDestroying() const {
return !_selector;
}
void showFromSelector(); void showFromSelector();
style::margins innerPadding() const; style::margins innerPadding() const;

View file

@ -20,7 +20,7 @@ object_ptr<Window::SectionWidget> TabbedMemento::createWidget(
const QRect &geometry) { const QRect &geometry) {
auto result = object_ptr<TabbedSection>(parent, controller); auto result = object_ptr<TabbedSection>(parent, controller);
result->setGeometry(geometry); result->setGeometry(geometry);
return std::move(result); return result;
} }
TabbedSection::TabbedSection( TabbedSection::TabbedSection(
@ -51,6 +51,10 @@ void TabbedSection::resizeEvent(QResizeEvent *e) {
_selector->setGeometry(rect()); _selector->setGeometry(rect());
} }
void TabbedSection::showFinishedHook() {
afterShown();
}
bool TabbedSection::showInternal( bool TabbedSection::showInternal(
not_null<Window::SectionMemento*> memento, not_null<Window::SectionMemento*> memento,
const Window::SectionShow &params) { const Window::SectionShow &params) {

View file

@ -52,9 +52,7 @@ public:
protected: protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
void showFinishedHook() override { void showFinishedHook() override;
afterShown();
}
private: private:
const not_null<TabbedSelector*> _selector; const not_null<TabbedSelector*> _selector;

View file

@ -14,7 +14,7 @@ from generate_tl import generate
generate({ generate({
'namespaces': { 'namespaces': {
'creator': 'MTP::internal', 'creator': 'MTP::details',
}, },
'prefixes': { 'prefixes': {
'type': 'MTP', 'type': 'MTP',
@ -28,7 +28,6 @@ generate({
'buffer': 'mtpBuffer', 'buffer': 'mtpBuffer',
}, },
'sections': [ 'sections': [
'serialization',
'read-write', 'read-write',
], ],
@ -91,4 +90,8 @@ generate({
}, },
'builtinInclude': 'mtproto/core_types.h', 'builtinInclude': 'mtproto/core_types.h',
'dumpToText': {
'include': 'mtproto/details/mtproto_dump_to_text.h',
},
}) })

View file

@ -143,14 +143,8 @@ v1/0UnkegO4jNkSY3ycDqn+T3NjxNxnL0EsKh7MjinyMUe3ZISzaIyrdq/8v4bvB\n\
#if defined TDESKTOP_API_ID && defined TDESKTOP_API_HASH #if defined TDESKTOP_API_ID && defined TDESKTOP_API_HASH
#define TDESKTOP_API_HASH_TO_STRING_HELPER(V) #V
#define TDESKTOP_API_HASH_TO_STRING(V) TDESKTOP_API_HASH_TO_STRING_HELPER(V)
constexpr auto ApiId = TDESKTOP_API_ID; constexpr auto ApiId = TDESKTOP_API_ID;
constexpr auto ApiHash = TDESKTOP_API_HASH_TO_STRING(TDESKTOP_API_HASH); constexpr auto ApiHash = MACRO_TO_STRING(TDESKTOP_API_HASH);
#undef TDESKTOP_API_HASH_TO_STRING
#undef TDESKTOP_API_HASH_TO_STRING_HELPER
#else // TDESKTOP_API_ID && TDESKTOP_API_HASH #else // TDESKTOP_API_ID && TDESKTOP_API_HASH

View file

@ -94,6 +94,7 @@ Application::Application(not_null<Launcher*> launcher)
, _dcOptions(std::make_unique<MTP::DcOptions>()) , _dcOptions(std::make_unique<MTP::DcOptions>())
, _account(std::make_unique<Main::Account>(cDataFile())) , _account(std::make_unique<Main::Account>(cDataFile()))
, _langpack(std::make_unique<Lang::Instance>()) , _langpack(std::make_unique<Lang::Instance>())
, _langCloudManager(std::make_unique<Lang::CloudManager>(langpack()))
, _emojiKeywords(std::make_unique<ChatHelpers::EmojiKeywords>()) , _emojiKeywords(std::make_unique<ChatHelpers::EmojiKeywords>())
, _audio(std::make_unique<Media::Audio::Instance>()) , _audio(std::make_unique<Media::Audio::Instance>())
, _logo(Window::LoadLogo()) , _logo(Window::LoadLogo())
@ -115,9 +116,6 @@ Application::Application(not_null<Launcher*> launcher)
) | rpl::filter([=](MTP::Instance *instance) { ) | rpl::filter([=](MTP::Instance *instance) {
return instance != nullptr; return instance != nullptr;
}) | rpl::start_with_next([=](not_null<MTP::Instance*> mtp) { }) | rpl::start_with_next([=](not_null<MTP::Instance*> mtp) {
_langCloudManager = std::make_unique<Lang::CloudManager>(
langpack(),
mtp);
if (!UpdaterDisabled()) { if (!UpdaterDisabled()) {
UpdateChecker().setMtproto(mtp.get()); UpdateChecker().setMtproto(mtp.get());
} }
@ -126,7 +124,14 @@ Application::Application(not_null<Launcher*> launcher)
Application::~Application() { Application::~Application() {
_window.reset(); _window.reset();
_mediaView.reset(); if (_mediaView) {
_mediaView->clearData();
_mediaView = nullptr;
}
if (activeAccount().sessionExists()) {
activeAccount().session().saveSettingsNowIfNeeded();
}
// This can call writeMap() that serializes Main::Session. // This can call writeMap() that serializes Main::Session.
// In case it gets called after destroySession() we get missing data. // In case it gets called after destroySession() we get missing data.
@ -135,11 +140,6 @@ Application::~Application() {
// Some MTP requests can be cancelled from data clearing. // Some MTP requests can be cancelled from data clearing.
unlockTerms(); unlockTerms();
activeAccount().destroySession(); activeAccount().destroySession();
// The langpack manager should be destroyed before MTProto instance,
// because it is MTP::Sender and it may have pending requests.
_langCloudManager.reset();
activeAccount().clearMtp(); activeAccount().clearMtp();
Shortcuts::Finish(); Shortcuts::Finish();
@ -147,7 +147,6 @@ Application::~Application() {
Ui::Emoji::Clear(); Ui::Emoji::Clear();
Media::Clip::Finish(); Media::Clip::Finish();
stopWebLoadManager();
App::deinitMedia(); App::deinitMedia();
Window::Theme::Uninitialize(); Window::Theme::Uninitialize();
@ -208,9 +207,9 @@ void Application::run() {
style::ShortAnimationPlaying( style::ShortAnimationPlaying(
) | rpl::start_with_next([=](bool playing) { ) | rpl::start_with_next([=](bool playing) {
if (playing) { if (playing) {
MTP::internal::pause(); MTP::details::pause();
} else { } else {
MTP::internal::unpause(); MTP::details::unpause();
} }
}, _lifetime); }, _lifetime);
@ -387,12 +386,12 @@ void Application::saveSettingsDelayed(crl::time delay) {
} }
void Application::setCurrentProxy( void Application::setCurrentProxy(
const ProxyData &proxy, const MTP::ProxyData &proxy,
ProxyData::Settings settings) { MTP::ProxyData::Settings settings) {
const auto current = [&] { const auto current = [&] {
return (Global::ProxySettings() == ProxyData::Settings::Enabled) return (Global::ProxySettings() == MTP::ProxyData::Settings::Enabled)
? Global::SelectedProxy() ? Global::SelectedProxy()
: ProxyData(); : MTP::ProxyData();
}; };
const auto was = current(); const auto was = current();
Global::SetSelectedProxy(proxy); Global::SetSelectedProxy(proxy);
@ -408,12 +407,12 @@ auto Application::proxyChanges() const -> rpl::producer<ProxyChange> {
} }
void Application::badMtprotoConfigurationError() { void Application::badMtprotoConfigurationError() {
if (Global::ProxySettings() == ProxyData::Settings::Enabled if (Global::ProxySettings() == MTP::ProxyData::Settings::Enabled
&& !_badProxyDisableBox) { && !_badProxyDisableBox) {
const auto disableCallback = [=] { const auto disableCallback = [=] {
setCurrentProxy( setCurrentProxy(
Global::SelectedProxy(), Global::SelectedProxy(),
ProxyData::Settings::System); MTP::ProxyData::Settings::System);
}; };
_badProxyDisableBox = Ui::show(Box<InformBox>( _badProxyDisableBox = Ui::show(Box<InformBox>(
Lang::Hard::ProxyConfigError(), Lang::Hard::ProxyConfigError(),
@ -423,14 +422,18 @@ void Application::badMtprotoConfigurationError() {
void Application::startLocalStorage() { void Application::startLocalStorage() {
Local::start(); Local::start();
subscribe(_dcOptions->changed(), [this](const MTP::DcOptions::Ids &ids) {
Local::writeSettings(); const auto writing = _lifetime.make_state<bool>(false);
if (const auto instance = activeAccount().mtp()) { _dcOptions->changed(
for (const auto id : ids) { ) | rpl::filter([=] {
instance->restart(id); return !*writing;
} }) | rpl::start_with_next([=] {
} *writing = true;
}); Ui::PostponeCall(this, [=] {
Local::writeSettings();
});
}, _lifetime);
_saveSettingsTimer.setCallback([=] { Local::writeSettings(); }); _saveSettingsTimer.setCallback([=] { Local::writeSettings(); });
} }
@ -604,27 +607,36 @@ void Application::checkStartUrl() {
} }
bool Application::openLocalUrl(const QString &url, QVariant context) { bool Application::openLocalUrl(const QString &url, QVariant context) {
auto urlTrimmed = url.trimmed(); return openCustomUrl("tg://", LocalUrlHandlers(), url, context);
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192); }
const auto protocol = qstr("tg://"); bool Application::openInternalUrl(const QString &url, QVariant context) {
return openCustomUrl("internal:", InternalUrlHandlers(), url, context);
}
bool Application::openCustomUrl(
const QString &protocol,
const std::vector<LocalUrlHandler> &handlers,
const QString &url,
const QVariant &context) {
const auto urlTrimmed = url.trimmed();
if (!urlTrimmed.startsWith(protocol, Qt::CaseInsensitive) || locked()) { if (!urlTrimmed.startsWith(protocol, Qt::CaseInsensitive) || locked()) {
return false; return false;
} }
auto command = urlTrimmed.midRef(protocol.size()); const auto command = urlTrimmed.midRef(protocol.size(), 8192);
const auto session = activeAccount().sessionExists() const auto session = activeAccount().sessionExists()
? &activeAccount().session() ? &activeAccount().session()
: nullptr; : nullptr;
using namespace qthelp; using namespace qthelp;
const auto options = RegExOption::CaseInsensitive; const auto options = RegExOption::CaseInsensitive;
for (const auto &[expression, handler] : LocalUrlHandlers()) { for (const auto &[expression, handler] : handlers) {
const auto match = regex_match(expression, command, options); const auto match = regex_match(expression, command, options);
if (match) { if (match) {
return handler(session, match, context); return handler(session, match, context);
} }
} }
return false; return false;
} }
void Application::lockByPasscode() { void Application::lockByPasscode() {

View file

@ -8,7 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "core/core_settings.h" #include "core/core_settings.h"
#include "mtproto/auth_key.h" #include "mtproto/mtproto_auth_key.h"
#include "mtproto/mtproto_proxy_data.h"
#include "base/observer.h" #include "base/observer.h"
#include "base/timer.h" #include "base/timer.h"
@ -131,12 +132,12 @@ public:
return _dcOptions.get(); return _dcOptions.get();
} }
struct ProxyChange { struct ProxyChange {
ProxyData was; MTP::ProxyData was;
ProxyData now; MTP::ProxyData now;
}; };
void setCurrentProxy( void setCurrentProxy(
const ProxyData &proxy, const MTP::ProxyData &proxy,
ProxyData::Settings settings); MTP::ProxyData::Settings settings);
[[nodiscard]] rpl::producer<ProxyChange> proxyChanges() const; [[nodiscard]] rpl::producer<ProxyChange> proxyChanges() const;
void badMtprotoConfigurationError(); void badMtprotoConfigurationError();
@ -177,6 +178,7 @@ public:
QString createInternalLinkFull(const QString &query) const; QString createInternalLinkFull(const QString &query) const;
void checkStartUrl(); void checkStartUrl();
bool openLocalUrl(const QString &url, QVariant context); bool openLocalUrl(const QString &url, QVariant context);
bool openInternalUrl(const QString &url, QVariant context);
void forceLogOut(const TextWithEntities &explanation); void forceLogOut(const TextWithEntities &explanation);
void checkLocalTime(); void checkLocalTime();
@ -240,6 +242,12 @@ private:
void clearPasscodeLock(); void clearPasscodeLock();
bool openCustomUrl(
const QString &protocol,
const std::vector<LocalUrlHandler> &handlers,
const QString &url,
const QVariant &context);
static Application *Instance; static Application *Instance;
struct InstanceSetter { struct InstanceSetter {
InstanceSetter(not_null<Application*> instance) { InstanceSetter(not_null<Application*> instance) {
@ -265,7 +273,7 @@ private:
std::unique_ptr<Window::Controller> _window; std::unique_ptr<Window::Controller> _window;
std::unique_ptr<Media::View::OverlayWidget> _mediaView; std::unique_ptr<Media::View::OverlayWidget> _mediaView;
const std::unique_ptr<Lang::Instance> _langpack; const std::unique_ptr<Lang::Instance> _langpack;
std::unique_ptr<Lang::CloudManager> _langCloudManager; const std::unique_ptr<Lang::CloudManager> _langCloudManager;
const std::unique_ptr<ChatHelpers::EmojiKeywords> _emojiKeywords; const std::unique_ptr<ChatHelpers::EmojiKeywords> _emojiKeywords;
std::unique_ptr<Lang::Translator> _translator; std::unique_ptr<Lang::Translator> _translator;
base::Observable<void> _passcodedChanged; base::Observable<void> _passcodedChanged;

View file

@ -18,51 +18,32 @@ namespace {
std::map<int, const char*> BetaLogs() { std::map<int, const char*> BetaLogs() {
return { return {
{
1006004,
"- Replace media when editing messages with media content.\n"
"- Jump quickly to the top of your chats list.\n"
"- Get emoji suggestions for the first word you type in a message.\n"
"- Help Telegram improve emoji suggestions in your language "
"using this interface https://translations.telegram.org/en/emoji"
},
{
1007001,
"- Disable pinned messages notifications in Settings."
},
{
1007004,
"- Download video files while watching them using streaming."
},
{
1007008,
"\xE2\x80\xA2 Hide archived chats in the main menu.\n"
"\xE2\x80\xA2 See who is online straight from the chat list.\n"
"\xE2\x80\xA2 Apply formatting to selected text parts "
"from the MacBook Pro TouchBar."
},
{
1007011,
"\xE2\x80\xA2 Use strikethrough and underline formatting.\n"
"\xE2\x80\xA2 Bug fixes and other minor improvements."
},
{ {
1008005, 1008005,
"\xE2\x80\xA2 Create new themes based on your color and wallpaper choices.\n" "\xE2\x80\xA2 Create new themes based on your color "
"and wallpaper choices.\n"
"\xE2\x80\xA2 Share your themes with other users via links.\n" "\xE2\x80\xA2 Share your themes with other users via links.\n"
"\xE2\x80\xA2 Update your theme for all its users when you change something.\n" "\xE2\x80\xA2 Update your theme for all its users "
"when you change something.\n"
}, },
{ {
1009000, 1009000,
"\xE2\x80\xA2 System spellchecker on Windows 8+ and macOS 10.12+.\n" "\xE2\x80\xA2 System spell checker on Windows 8+ and macOS 10.12+.\n"
},
{
1009002,
"\xE2\x80\xA2 Videos in chats start playing automatically.\n"
"\xE2\x80\xA2 Resume playback from where you left off "
"when watching long videos.\n"
"\xE2\x80\xA2 Control videos, GIFs and round video messages "
"automatic playback in "
"Settings > Advanced > Automatic media download.\n"
"\xE2\x80\xA2 Spell checker on Linux using Enchant.\n"
}, },
}; };
}; };

View file

@ -43,7 +43,8 @@ void HiddenUrlClickHandler::Open(QString url, QVariant context) {
const auto open = [=] { const auto open = [=] {
UrlClickHandler::Open(url, context); UrlClickHandler::Open(url, context);
}; };
if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) { if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)
|| url.startsWith(qstr("internal:"), Qt::CaseInsensitive)) {
open(); open();
} else { } else {
const auto parsedUrl = QUrl::fromUserInput(url); const auto parsedUrl = QUrl::fromUserInput(url);
@ -55,7 +56,9 @@ void HiddenUrlClickHandler::Open(QString url, QVariant context) {
: url; : url;
Ui::show( Ui::show(
Box<ConfirmBox>( Box<ConfirmBox>(
tr::lng_open_this_link(tr::now) + qsl("\n\n") + displayUrl, (tr::lng_open_this_link(tr::now)
+ qsl("\n\n")
+ displayUrl),
tr::lng_open_link(tr::now), tr::lng_open_link(tr::now),
[=] { Ui::hideLayer(); open(); }), [=] { Ui::hideLayer(); open(); }),
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);

View file

@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/core_cloud_password.h" #include "core/core_cloud_password.h"
#include "base/openssl_help.h" #include "base/openssl_help.h"
#include "mtproto/connection.h" #include "mtproto/mtproto_dh_utils.h"
namespace Core { namespace Core {
namespace { namespace {

View file

@ -268,25 +268,25 @@ LastCrashedWindow::LastCrashedWindow(
} }
if (_minidumpFull.isEmpty()) { if (_minidumpFull.isEmpty()) {
QString maxDump, maxDumpFull; QString maxDump, maxDumpFull;
QDateTime maxDumpModified, workingModified = QFileInfo(cWorkingDir() + qsl("tdata/working")).lastModified(); QDateTime maxDumpModified, workingModified = QFileInfo(cWorkingDir() + qsl("tdata/working")).lastModified();
QFileInfoList list = QDir(dumpspath).entryInfoList(); QFileInfoList list = QDir(dumpspath).entryInfoList();
for (int32 i = 0, l = list.size(); i < l; ++i) { for (int32 i = 0, l = list.size(); i < l; ++i) {
QString name = list.at(i).fileName(); QString name = list.at(i).fileName();
if (name.endsWith(qstr(".dmp"))) { if (name.endsWith(qstr(".dmp"))) {
QDateTime modified = list.at(i).lastModified(); QDateTime modified = list.at(i).lastModified();
if (maxDump.isEmpty() || qAbs(workingModified.secsTo(modified)) < qAbs(workingModified.secsTo(maxDumpModified))) { if (maxDump.isEmpty() || qAbs(workingModified.secsTo(modified)) < qAbs(workingModified.secsTo(maxDumpModified))) {
maxDump = name; maxDump = name;
maxDumpModified = modified; maxDumpModified = modified;
maxDumpFull = list.at(i).absoluteFilePath(); maxDumpFull = list.at(i).absoluteFilePath();
dumpsize = list.at(i).size(); dumpsize = list.at(i).size();
} }
} }
} }
if (!maxDump.isEmpty() && qAbs(workingModified.secsTo(maxDumpModified)) < 10) { if (!maxDump.isEmpty() && qAbs(workingModified.secsTo(maxDumpModified)) < 10) {
_minidumpName = maxDump; _minidumpName = maxDump;
_minidumpFull = maxDumpFull; _minidumpFull = maxDumpFull;
} }
} }
if (_minidumpName.isEmpty()) { // currently don't accept crash reports without dumps from google libraries if (_minidumpName.isEmpty()) { // currently don't accept crash reports without dumps from google libraries
_sendingState = SendingNoReport; _sendingState = SendingNoReport;
} else { } else {
@ -814,10 +814,10 @@ void LastCrashedWindow::onNetworkSettingsSaved(
QString password) { QString password) {
Expects(host.isEmpty() || port != 0); Expects(host.isEmpty() || port != 0);
auto proxy = ProxyData(); auto proxy = MTP::ProxyData();
proxy.type = host.isEmpty() proxy.type = host.isEmpty()
? ProxyData::Type::None ? MTP::ProxyData::Type::None
: ProxyData::Type::Http; : MTP::ProxyData::Type::Http;
proxy.host = host; proxy.host = host;
proxy.port = port; proxy.port = port;
proxy.user = username; proxy.user = username;
@ -843,7 +843,7 @@ void LastCrashedWindow::proxyUpdated() {
activate(); activate();
} }
rpl::producer<ProxyData> LastCrashedWindow::proxyChanges() const { rpl::producer<MTP::ProxyData> LastCrashedWindow::proxyChanges() const {
return _proxyChanges.events(); return _proxyChanges.events();
} }

View file

@ -16,6 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtNetwork/QHttpMultiPart> #include <QtNetwork/QHttpMultiPart>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
namespace MTP {
struct ProxyData;
} // namespace MTP
namespace Core { namespace Core {
class Launcher; class Launcher;
} // namespace Core } // namespace Core
@ -96,7 +100,7 @@ public:
const QByteArray &crashdump, const QByteArray &crashdump,
Fn<void()> launch); Fn<void()> launch);
rpl::producer<ProxyData> proxyChanges() const; rpl::producer<MTP::ProxyData> proxyChanges() const;
rpl::lifetime &lifetime() { rpl::lifetime &lifetime() {
return _lifetime; return _lifetime;
@ -199,7 +203,7 @@ private:
void setDownloadProgress(qint64 ready, qint64 total); void setDownloadProgress(qint64 ready, qint64 total);
Fn<void()> _launch; Fn<void()> _launch;
rpl::event_stream<ProxyData> _proxyChanges; rpl::event_stream<MTP::ProxyData> _proxyChanges;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
}; };
@ -237,7 +241,7 @@ public:
protected: protected:
void resizeEvent(QResizeEvent *e); void resizeEvent(QResizeEvent *e);
void closeEvent(QCloseEvent *e); void closeEvent(QCloseEvent *e);
private: private:
PreLaunchLog _log; PreLaunchLog _log;

View file

@ -201,13 +201,13 @@ void SignalHandler(int signum) {
if (name) { if (name) {
dump() << "Caught signal " << signum << " (" << name << ") in thread " << uint64(thread) << "\n"; dump() << "Caught signal " << signum << " (" << name << ") in thread " << uint64(thread) << "\n";
} else if (signum == -1) { } else if (signum == -1) {
dump() << "Google Breakpad caught a crash, minidump written in thread " << uint64(thread) << "\n"; dump() << "Google Breakpad caught a crash, minidump written in thread " << uint64(thread) << "\n";
if (BreakpadDumpPath) { if (BreakpadDumpPath) {
dump() << "Minidump: " << BreakpadDumpPath << "\n"; dump() << "Minidump: " << BreakpadDumpPath << "\n";
} else if (BreakpadDumpPathW) { } else if (BreakpadDumpPathW) {
dump() << "Minidump: " << BreakpadDumpPathW << "\n"; dump() << "Minidump: " << BreakpadDumpPathW << "\n";
} }
} else { } else {
dump() << "Caught signal " << signum << " in thread " << uint64(thread) << "\n"; dump() << "Caught signal " << signum << " in thread " << uint64(thread) << "\n";
} }
@ -246,18 +246,18 @@ void SignalHandler(int signum) {
#endif #endif
} }
void *addresses[132] = { 0 }; void *addresses[132] = { 0 };
size_t size = backtrace(addresses, 128); size_t size = backtrace(addresses, 128);
/* overwrite sigaction with caller's address */ /* overwrite sigaction with caller's address */
if (caller) { if (caller) {
for (int i = size; i > 1; --i) { for (int i = size; i > 1; --i) {
addresses[i + 3] = addresses[i]; addresses[i + 3] = addresses[i];
} }
addresses[2] = (void*)0x1; addresses[2] = (void*)0x1;
addresses[3] = caller; addresses[3] = caller;
addresses[4] = (void*)0x1; addresses[4] = (void*)0x1;
} }
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
dump() << "\nBase image addresses:\n"; dump() << "\nBase image addresses:\n";
@ -302,14 +302,14 @@ bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context,
CrashLogged = true; CrashLogged = true;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
BreakpadDumpPathW = _minidump_id; BreakpadDumpPathW = _minidump_id;
SignalHandler(-1); SignalHandler(-1);
#else // Q_OS_WIN #else // Q_OS_WIN
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
BreakpadDumpPath = _minidump_id; BreakpadDumpPath = _minidump_id;
#else // Q_OS_MAC #else // Q_OS_MAC
BreakpadDumpPath = md.path(); BreakpadDumpPath = md.path();
#endif // else for Q_OS_MAC #endif // else for Q_OS_MAC
SignalHandler(-1, 0, 0); SignalHandler(-1, 0, 0);
#endif // else for Q_OS_WIN #endif // else for Q_OS_WIN
@ -382,12 +382,13 @@ void StartCatching(not_null<Core::Launcher*> launcher) {
crashpad::CrashpadClient crashpad_client; crashpad::CrashpadClient crashpad_client;
std::string handler = (cExeDir() + cExeName() + qsl("/Contents/Helpers/crashpad_handler")).toUtf8().constData(); std::string handler = (cExeDir() + cExeName() + qsl("/Contents/Helpers/crashpad_handler")).toUtf8().constData();
std::string database = QFile::encodeName(dumpspath).constData(); std::string database = QFile::encodeName(dumpspath).constData();
if (crashpad_client.StartHandler(base::FilePath(handler), if (crashpad_client.StartHandler(
base::FilePath(database), base::FilePath(handler),
std::string(), base::FilePath(database),
ProcessAnnotations, std::string(),
std::vector<std::string>(), ProcessAnnotations,
false)) { std::vector<std::string>(),
false)) {
crashpad_client.UseHandler(); crashpad_client.UseHandler();
} }
#endif // else for MAC_USE_BREAKPAD #endif // else for MAC_USE_BREAKPAD
@ -580,20 +581,20 @@ const dump &operator<<(const dump &stream, const char *str) {
} }
const dump &operator<<(const dump &stream, const wchar_t *str) { const dump &operator<<(const dump &stream, const wchar_t *str) {
if (!ReportFile) return stream; if (!ReportFile) return stream;
for (int i = 0, l = wcslen(str); i < l; ++i) { for (int i = 0, l = wcslen(str); i < l; ++i) {
if ( if (
#if !defined(__WCHAR_UNSIGNED__) #if !defined(__WCHAR_UNSIGNED__)
str[i] >= 0 && str[i] >= 0 &&
#endif #endif
str[i] < 128) { str[i] < 128) {
SafeWriteChar(char(str[i])); SafeWriteChar(char(str[i]));
} else { } else {
SafeWriteChar('?'); SafeWriteChar('?');
} }
} }
return stream; return stream;
} }
const dump &operator<<(const dump &stream, int num) { const dump &operator<<(const dump &stream, int num) {

View file

@ -249,12 +249,11 @@ void Launcher::init() {
QApplication::setApplicationName(qsl("KotatogramDesktop")); QApplication::setApplicationName(qsl("KotatogramDesktop"));
#ifdef TDESKTOP_LAUNCHER_FILENAME #ifdef TDESKTOP_LAUNCHER_FILENAME
#define TDESKTOP_LAUNCHER_FILENAME_TO_STRING_HELPER(V) #V QApplication::setDesktopFileName(qsl(MACRO_TO_STRING(TDESKTOP_LAUNCHER_FILENAME)));
#define TDESKTOP_LAUNCHER_FILENAME_TO_STRING(V) TDESKTOP_LAUNCHER_FILENAME_TO_STRING_HELPER(V)
QApplication::setDesktopFileName(qsl(TDESKTOP_LAUNCHER_FILENAME_TO_STRING(TDESKTOP_LAUNCHER_FILENAME)));
#elif defined(Q_OS_LINUX) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) #elif defined(Q_OS_LINUX) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
QApplication::setDesktopFileName(qsl("kotatogramdesktop.desktop")); QApplication::setDesktopFileName(qsl("kotatogramdesktop.desktop"));
#endif #endif
#ifndef OS_MAC_OLD #ifndef OS_MAC_OLD
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true); QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true);
#endif // OS_MAC_OLD #endif // OS_MAC_OLD

View file

@ -23,8 +23,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "passport/passport_form_controller.h" #include "passport/passport_form_controller.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_cloud_themes.h" #include "data/data_cloud_themes.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "media/player/media_player_instance.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "main/main_session.h" #include "main/main_session.h"
@ -163,7 +165,9 @@ bool ApplySocksProxy(
auto params = url_parse_params( auto params = url_parse_params(
match->captured(1), match->captured(1),
qthelp::UrlParamNameTransform::ToLower); qthelp::UrlParamNameTransform::ToLower);
ProxiesBoxController::ShowApplyConfirmation(ProxyData::Type::Socks5, params); ProxiesBoxController::ShowApplyConfirmation(
MTP::ProxyData::Type::Socks5,
params);
return true; return true;
} }
@ -174,7 +178,9 @@ bool ApplyMtprotoProxy(
auto params = url_parse_params( auto params = url_parse_params(
match->captured(1), match->captured(1),
qthelp::UrlParamNameTransform::ToLower); qthelp::UrlParamNameTransform::ToLower);
ProxiesBoxController::ShowApplyConfirmation(ProxyData::Type::Mtproto, params); ProxiesBoxController::ShowApplyConfirmation(
MTP::ProxyData::Type::Mtproto,
params);
return true; return true;
} }
@ -358,6 +364,40 @@ bool HandleUnknown(
return true; return true;
} }
bool OpenMediaTimestamp(
Main::Session *session,
const Match &match,
const QVariant &context) {
if (!session) {
return false;
}
const auto time = match->captured(2).toInt();
if (time < 0) {
return false;
}
const auto base = match->captured(1);
if (base.startsWith(qstr("doc"))) {
const auto parts = base.mid(3).split('_');
const auto documentId = parts.value(0).toULongLong();
const auto itemId = FullMsgId(
parts.value(1).toInt(),
parts.value(2).toInt());
const auto document = session->data().document(documentId);
session->settings().setMediaLastPlaybackPosition(
documentId,
time * crl::time(1000));
if (document->isVideoFile()) {
Core::App().showDocument(
document,
session->data().message(itemId));
} else if (document->isSong()) {
Media::Player::instance()->play({ document, itemId });
}
return true;
}
return false;
}
} // namespace } // namespace
const std::vector<LocalUrlHandler> &LocalUrlHandlers() { const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
@ -417,7 +457,17 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
{ {
qsl("^([^\\?]+)(\\?|#|$)"), qsl("^([^\\?]+)(\\?|#|$)"),
HandleUnknown HandleUnknown
} },
};
return Result;
}
const std::vector<LocalUrlHandler> &InternalUrlHandlers() {
static auto Result = std::vector<LocalUrlHandler>{
{
qsl("^media_timestamp/?\\?base=([a-zA-Z0-9\\.\\_\\-]+)&t=(\\d+)(&|$)"),
OpenMediaTimestamp
},
}; };
return Result; return Result;
} }

View file

@ -26,6 +26,7 @@ struct LocalUrlHandler {
}; };
[[nodiscard]] const std::vector<LocalUrlHandler> &LocalUrlHandlers(); [[nodiscard]] const std::vector<LocalUrlHandler> &LocalUrlHandlers();
[[nodiscard]] const std::vector<LocalUrlHandler> &InternalUrlHandlers();
[[nodiscard]] QString TryConvertUrlToLocal(QString url); [[nodiscard]] QString TryConvertUrlToLocal(QString url);

Some files were not shown because too many files have changed in this diff Show more