2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-30 14:17:45 +00:00

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

This commit is contained in:
RadRussianRus 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__
/Telegram/*.user.*
*.txt.user
*.pro.user
/Linux/
/Telegram/Makefile

15
.gitmodules vendored
View File

@ -49,3 +49,18 @@
[submodule "Telegram/lib_spellcheck"]
path = Telegram/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
- libopus-dev
- libpulse-dev
- libenchant-dev
- libssl-dev
- libdee-dev
- libva-dev
- libvdpau-dev
- libxcb-xkb-dev
- libxkbcommon-dev
- libatspi2.0-dev
- lintian
- quilt
- valac

View File

@ -17,7 +17,7 @@ XKB_PATH="$BUILD/libxkbcommon"
XKB_CACHE_VERSION="3"
QT_PATH="$BUILD/qt"
QT_CACHE_VERSION="4"
QT_CACHE_VERSION="5"
QT_PATCH="$EXTERNAL/patches/qtbase_${QT_VERSION//\./_}.diff"
BREAKPAD_PATH="$BUILD/breakpad"
@ -694,7 +694,6 @@ buildTelegram() {
-Dlinux_path_qt=$QT_PATH \
-Dlinux_path_breakpad=$BREAKPAD_PATH \
-Dlinux_path_libexif_lib=/usr/local/lib \
-Dlinux_path_opus_include=/usr/include/opus \
-Dlinux_lib_ssl=-lssl \
-Dlinux_lib_crypto=-lcrypto \
-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,
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
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_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_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_bad_country_code" = "Invalid Country Code";
"lng_country_ph" = "Search";
@ -408,7 +415,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_system_integration" = "System integration";
"lng_settings_performance" = "Performance";
"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_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_channels" = "In channels";
"lng_media_auto_title" = "Automatically download";
"lng_media_auto_play" = "Autoplay";
"lng_media_photo_title" = "Photos";
"lng_media_video_title" = "Video files";
"lng_media_audio_title" = "Voice messages";
"lng_media_video_messages_title" = "Round video messages";
"lng_media_file_title" = "Files";
"lng_media_music_title" = "Music";
"lng_media_animation_title" = "Animated GIFs";
"lng_media_size_limit" = "Limit by 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_channel" = "New Channel";
"lng_mac_menu_show" = "Show Telegram";
"lng_mac_menu_emoji_and_symbols" = "Emoji & Symbols";
"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;
inputTakeoutFileLocation#29be5899 = 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;
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;
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;
inputReportReasonViolence#1e22c78d = ReportReason;
@ -347,6 +349,8 @@ updatePeerLocated#b4afcfb0 peers:Vector<PeerLocated> = Update;
updateNewScheduledMessage#39a51dfb message:Message = Update;
updateDeleteScheduledMessages#90866cee peer:Peer messages:Vector<int> = 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;
@ -496,7 +500,7 @@ messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMess
webPageEmpty#eb1477e8 id:long = 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;
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;
inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
inputWallPaperNoFile#8427bbac = InputWallPaper;
account.wallPapersNotModified#1c199183 = 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;
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;
@ -1073,7 +1078,7 @@ inputTheme#3c5693e9 id:long access_hash:long = InputTheme;
inputThemeSlug#f5890df1 slug:string = InputTheme;
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.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;
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---
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.cancelCode#1f040578 phone_number:string phone_code_hash:string = 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.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.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.createTheme#2b7ffd7f slug:string title:string document:InputDocument = Theme;
account.updateTheme#3b8ea202 flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument = Theme;
account.createTheme#8432c21f flags:# slug:string title:string document:flags.2?InputDocument settings:flags.3?InputThemeSettings = 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.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.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.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.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint address:string = Bool;
channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates;
channels.getInactiveChannels#11e831ee = messages.InactiveChats;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
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.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_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_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;

View File

@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="1.9.1.0" />
Version="1.9.4.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<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 "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_photo.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 "storage/localstorage.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "boxes/confirm_box.h"
#include "boxes/stickers_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 "support/support_helper.h"
#include "storage/localimageloader.h"
#include "storage/file_download.h"
#include "storage/download_manager_mtproto.h"
#include "storage/file_upload.h"
#include "storage/storage_facade.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)
: _session(session)
: MTP::Sender(session->account().mtp())
, _session(session)
, _messageDataResolveDelayed([=] { resolveMessageDatas(); })
, _webPagesTimer([=] { resolveWebPages(); })
, _draftsSaveTimer([=] { saveDraftsToCloud(); })
@ -231,7 +235,9 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
, _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout))
//, _feedReadTimer([=] { readFeeds(); }) // #feed
, _proxyPromotionTimer([=] { refreshProxyPromotion(); })
, _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); }) {
, _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); })
, _selfDestruct(std::make_unique<Api::SelfDestruct>(this))
, _sensitiveContent(std::make_unique<Api::SensitiveContent>(this)) {
crl::on_main([=] {
// You can't use _session->lifetime() in the constructor,
// 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 {
return *_session;
}
@ -280,11 +288,11 @@ void ApiWrap::refreshProxyPromotion() {
return;
}
const auto key = [&]() -> std::pair<QString, uint32> {
if (Global::ProxySettings() != ProxyData::Settings::Enabled) {
if (Global::ProxySettings() != MTP::ProxyData::Settings::Enabled) {
return {};
}
const auto &proxy = Global::SelectedProxy();
if (proxy.type != ProxyData::Type::Mtproto) {
if (proxy.type != MTP::ProxyData::Type::Mtproto) {
return {};
}
return { proxy.host, proxy.port };
@ -2971,12 +2979,12 @@ void ApiWrap::requestFileReference(
void ApiWrap::refreshFileReference(
Data::FileOrigin origin,
not_null<mtpFileLoader*> loader,
not_null<Storage::DownloadMtprotoTask*> task,
int requestId,
const QByteArray &current) {
return refreshFileReference(origin, crl::guard(loader, [=](
return refreshFileReference(origin, crl::guard(task, [=](
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());
}
void ApiWrap::reloadSelfDestruct() {
if (_selfDestructRequestId) {
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();
Api::SelfDestruct &ApiWrap::selfDestruct() {
return *_selfDestruct;
}
rpl::producer<int> ApiWrap::selfDestructValue() const {
return _selfDestructDays
? _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);
Api::SensitiveContent &ApiWrap::sensitiveContent() {
return *_sensitiveContent;
}
void ApiWrap::createPoll(
@ -6105,5 +6083,3 @@ void ApiWrap::sendReadRequest(not_null<PeerData*> peer, MsgId upTo) {
}();
_readRequests.emplace(peer, requestId, upTo);
}
ApiWrap::~ApiWrap() = default;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/calendar_box.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "ui/widgets/buttons.h"
#include "lang/lang_keys.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_chat.h"
#include "data/data_user.h"
#include "data/data_file_origin.h"
#include "base/unixtime.h"
#include "main/main_session.h"
#include "observer_peer.h"

View File

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

View File

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "numbers.h"
#include "app.h"
#include "lang/lang_keys.h"
#include "mtproto/facade.h"
#include "styles/style_layers.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 "base/timer.h"
#include "ui/widgets/input_fields.h"
#include "mtproto/mtproto_rpc_sender.h"
namespace Ui {
class InputField;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -223,7 +223,7 @@ object_ptr<Ui::RpWidget> SetupAbout(
tr::now,
Ui::Text::WithEntities);
}());
return std::move(about);
return about;
}
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 "base/unique_qptr.h"
class RPCError;
namespace Ui {
class FlatLabel;
class LinkButton;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@ namespace Main {
class Session;
} // namespace Main
class RateCallBox : public Ui::BoxContent, private MTP::Sender {
class RateCallBox : public Ui::BoxContent {
public:
RateCallBox(
QWidget*,
@ -41,6 +41,7 @@ private:
void commentResized();
const not_null<Main::Session*> _session;
MTP::Sender _api;
uint64 _callId = 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/input_fields.h"
#include "ui/toast/toast.h"
#include "mtproto/facade.h"
#include "mainwindow.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "boxes/abstract_box.h"
#include "mtproto/mtproto_rpc_sender.h"
namespace Ui {
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/labels.h"
#include "apiwrap.h"
#include "api/api_self_destruct.h"
#include "main/main_session.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@ -76,7 +77,7 @@ void SelfDestructionBox::showContent() {
clearButtons();
addButton(tr::lng_settings_save(), [=] {
_session->api().saveSelfDestruct(_ttlGroup->value());
_session->api().selfDestruct().update(_ttlGroup->value());
closeBox();
});
addButton(tr::lng_cancel(), [=] { closeBox(); });

View File

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

View File

@ -365,6 +365,7 @@ void AlbumThumb::prepareCache(QSize size, int shrink) {
ImageRoundRadius::Large,
_albumCorners,
QRect(QPoint(), size * cIntRetinaFactor()));
_albumCache.setDevicePixelRatio(cRetinaFactor());
}
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 "mainwidget.h"
#include "mainwindow.h"
#include "apiwrap.h"
#include "main/main_session.h"
#include "data/data_session.h"
#include "base/unixtime.h"
@ -77,6 +78,7 @@ private:
SessionsBox::SessionsBox(QWidget*, not_null<Main::Session*> session)
: _session(session)
, _api(_session->api().instance())
, _shortPollTimer([=] { shortPollSessions(); }) {
}
@ -280,7 +282,7 @@ void SessionsBox::shortPollSessions() {
if (_shortPollRequest) {
return;
}
_shortPollRequest = request(MTPaccount_GetAuthorizations(
_shortPollRequest = _api.request(MTPaccount_GetAuthorizations(
)).done([=](const MTPaccount_Authorizations &result) {
got(result);
}).send();
@ -294,7 +296,7 @@ void SessionsBox::terminateOne(uint64 hash) {
_terminateBox->closeBox();
_terminateBox = nullptr;
}
request(MTPaccount_ResetAuthorization(
_api.request(MTPaccount_ResetAuthorization(
MTP_long(hash)
)).done([=](const MTPBool &result) {
_inner->terminatingOne(hash, false);
@ -330,12 +332,12 @@ void SessionsBox::terminateAll() {
_terminateBox->closeBox();
_terminateBox = nullptr;
}
request(MTPauth_ResetAuthorizations(
_api.request(MTPauth_ResetAuthorizations(
)).done([=](const MTPBool &result) {
request(base::take(_shortPollRequest)).cancel();
_api.request(base::take(_shortPollRequest)).cancel();
shortPollSessions();
}).fail([=](const RPCError &result) {
request(base::take(_shortPollRequest)).cancel();
_api.request(base::take(_shortPollRequest)).cancel();
shortPollSessions();
}).send();
setLoading(true);

View File

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

View File

@ -722,7 +722,6 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
yFrom *= _columnCount;
yTo *= _columnCount;
_navigation->session().downloader().clearPriorities();
if (_filter.isEmpty()) {
if (!_chatsIndexed->empty()) {
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 "ui/effects/animations.h"
#include "ui/effects/round_checkbox.h"
#include "mtproto/mtproto_rpc_sender.h"
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_session.h"
#include "data/data_file_origin.h"
#include "lang/lang_keys.h"
#include "chat_helpers/stickers.h"
#include "boxes/confirm_box.h"
@ -99,7 +100,7 @@ private:
void showPreview();
not_null<Window::SessionController*> _controller;
MTP::Sender _mtp;
MTP::Sender _api;
std::vector<Element> _elements;
std::unique_ptr<Lottie::MultiPlayer> _lottiePlayer;
Stickers::Pack _pack;
@ -220,6 +221,7 @@ StickerSetBox::Inner::Inner(
const MTPInputStickerSet &set)
: RpWidget(parent)
, _controller(controller)
, _api(_controller->session().api().instance())
, _input(set)
, _previewTimer([=] { showPreview(); }) {
set.match([&](const MTPDinputStickerSetID &data) {
@ -231,7 +233,7 @@ StickerSetBox::Inner::Inner(
}, [&](const MTPDinputStickerSetAnimatedEmoji &) {
});
_mtp.request(MTPmessages_GetStickerSet(
_api.request(MTPmessages_GetStickerSet(
_input
)).done([=](const MTPmessages_StickerSet &result) {
gotSet(result);
@ -700,7 +702,7 @@ void StickerSetBox::Inner::install() {
} else if (_installRequest) {
return;
}
_installRequest = _mtp.request(MTPmessages_InstallStickerSet(
_installRequest = _api.request(MTPmessages_InstallStickerSet(
_input,
MTP_bool(false)
)).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_session.h"
#include "data/data_channel.h"
#include "data/data_file_origin.h"
#include "core/application.h"
#include "lang/lang_keys.h"
#include "mainwidget.h"
@ -410,7 +411,7 @@ void StickersBox::updateTabsGeometry() {
auto featuredLeft = 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 unreadBadgeLeft = featuredTextRight - st::stickersFeaturedBadgeSkip;
auto unreadBadgeTop = st::stickersFeaturedBadgeTop;
@ -661,6 +662,7 @@ StickersBox::Inner::Inner(
StickersBox::Section section)
: RpWidget(parent)
, _session(session)
, _api(_session->api().instance())
, _section(section)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) {
@ -677,6 +679,7 @@ StickersBox::Inner::Inner(
StickersBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> megagroup)
: RpWidget(parent)
, _session(&megagroup->session())
, _api(_session->api().instance())
, _section(StickersBox::Section::Installed)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) {
@ -1469,11 +1472,13 @@ void StickersBox::Inner::handleMegagroupSetAddressChange() {
}
}
} 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;
auto set = Stickers::FeedSetFull(result);
setMegagroupSelectedSet(MTP_inputStickerSetID(MTP_long(set->id), MTP_long(set->access)));
}).fail([this](const RPCError &error) {
}).fail([=](const RPCError &error) {
_megagroupSetRequestId = 0;
setMegagroupSelectedSet(MTP_inputStickerSetEmpty());
}).send();

View File

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

View File

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

View File

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

View File

@ -15,10 +15,7 @@ class SessionController;
namespace Calls {
class BoxController
: public PeerListController
, private base::Subscriber
, private MTP::Sender {
class BoxController : public PeerListController, private base::Subscriber {
public:
explicit BoxController(not_null<Window::SessionController*> window);
@ -44,6 +41,7 @@ private:
not_null<HistoryItem*> item) const;
const not_null<Window::SessionController*> _window;
MTP::Sender _api;
MsgId _offsetId = 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 "calls/calls_instance.h"
#include "base/openssl_help.h"
#include "mtproto/connection.h"
#include "mtproto/mtproto_dh_utils.h"
#include "media/audio/media_audio_track.h"
#include "base/platform/base_platform_info.h"
#include "calls/calls_panel.h"
@ -130,6 +130,7 @@ Call::Call(
Type type)
: _delegate(delegate)
, _user(user)
, _api(_user->session().api().instance())
, _type(type) {
_discardByTimeoutTimer.setCallback([this] { hangup(); });
@ -189,7 +190,7 @@ void Call::startOutgoing() {
Expects(_state == State::Requesting);
Expects(_gaHash.size() == kSha256Size);
request(MTPphone_RequestCall(
_api.request(MTPphone_RequestCall(
MTP_flags(0),
_user->inputUser,
MTP_int(rand_value<int32>()),
@ -236,11 +237,13 @@ void Call::startIncoming() {
Expects(_type == Type::Incoming);
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) {
setState(State::WaitingIncoming);
}
}).fail([this](const RPCError &error) {
}).fail([=](const RPCError &error) {
handleRequestError(error);
}).send();
}
@ -267,7 +270,7 @@ void Call::actuallyAnswer() {
} else {
_answerAfterDhConfigReceived = false;
}
request(MTPphone_AcceptCall(
_api.request(MTPphone_AcceptCall(
MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)),
MTP_bytes(_gb),
MTP_phoneCallProtocol(
@ -504,7 +507,7 @@ void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) {
_keyFingerprint = ComputeFingerprint(_authKey);
setState(State::ExchangingKeys);
request(MTPphone_ConfirmCall(
_api.request(MTPphone_ConfirmCall(
MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)),
MTP_bytes(_ga),
MTP_long(_keyFingerprint),
@ -623,10 +626,10 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
_controller->SetEncryptionKey(reinterpret_cast<char*>(_authKey.data()), (_type == Type::Outgoing));
_controller->SetCallbacks(callbacks);
if (Global::UseProxyForCalls()
&& (Global::ProxySettings() == ProxyData::Settings::Enabled)) {
&& (Global::ProxySettings() == MTP::ProxyData::Settings::Enabled)) {
const auto &proxy = Global::SelectedProxy();
if (proxy.supportsCalls()) {
Assert(proxy.type == ProxyData::Type::Socks5);
Assert(proxy.type == MTP::ProxyData::Type::Socks5);
_controller->SetProxy(
tgvoip::PROXY_SOCKS5,
proxy.host.toStdString(),
@ -840,7 +843,7 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) {
auto duration = getDurationMs() / 1000;
auto connectionId = _controller ? _controller->GetPreferredRelayID() : 0;
_finishByTimeoutTimer.call(kHangupTimeoutMs, [this, finalState] { setState(finalState); });
request(MTPphone_DiscardCall(
_api.request(MTPphone_DiscardCall(
MTP_flags(0),
MTP_inputPhoneCall(
MTP_long(_id),

View File

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

View File

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

View File

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

View File

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

View File

@ -72,6 +72,12 @@ struct LangPackData {
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() {
QDir().mkpath(internal::CacheFileFolder() + qstr("/keywords"));
}
@ -120,7 +126,7 @@ void CreateCacheFilePath() {
const auto emoji = MustAddPostfix(text)
? (text + QChar(Ui::Emoji::kPostfix))
: text;
const auto entry = LangPackEmoji{ Find(emoji), text };
const auto entry = LangPackEmoji{ FindExact(emoji), text };
if (!entry.emoji) {
return {};
}
@ -251,7 +257,7 @@ void ApplyDifference(
const auto emoji = MustAddPostfix(text)
? (text + QChar(Ui::Emoji::kPostfix))
: text;
return LangPackEmoji{ Find(emoji), text };
return LangPackEmoji{ FindExact(emoji), text };
}) | ranges::view::filter([&](const LangPackEmoji &entry) {
if (!entry.emoji) {
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);
auto result = object_ptr<Footer>(this);
_footer = result;
return std::move(result);
return result;
}
template <typename Callback>
@ -770,7 +770,7 @@ QPoint EmojiListWidget::tooltipPos() const {
}
bool EmojiListWidget::tooltipWindowActive() const {
return Ui::InFocusChain(window());
return Ui::AppInFocus() && Ui::InFocusChain(window());
}
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_user.h"
#include "data/data_peer_values.h"
#include "data/data_file_origin.h"
#include "mainwindow.h"
#include "apiwrap.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_session.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/input_fields.h"
#include "ui/effects/ripple_animation.h"
@ -22,10 +22,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "apiwrap.h"
#include "window/window_session_controller.h"
#include "history/view/history_view_cursor_state.h"
#include "facades.h"
#include "app.h"
#include "styles/style_chat_helpers.h"
#include <QtWidgets/QApplication>
@ -130,6 +132,7 @@ GifsListWidget::GifsListWidget(
QWidget *parent,
not_null<Window::SessionController*> controller)
: Inner(parent, controller)
, _api(controller->session().api().instance())
, _section(Section::Gifs)
, _updateInlineItems([=] { updateInlineItems(); })
, _previewTimer([=] { showPreview(); }) {
@ -178,7 +181,7 @@ object_ptr<TabbedSelector::InnerFooter> GifsListWidget::createFooter() {
auto result = object_ptr<Footer>(this);
_footer = result;
return std::move(result);
return result;
}
void GifsListWidget::visibleTopBottomUpdated(
@ -217,7 +220,7 @@ GifsListWidget::~GifsListWidget() {
void GifsListWidget::cancelGifsSearch() {
_footer->setLoading(false);
if (_inlineRequestId) {
request(_inlineRequestId).cancel();
_api.request(_inlineRequestId).cancel();
_inlineRequestId = 0;
}
_inlineRequestTimer.stop();
@ -840,7 +843,7 @@ void GifsListWidget::searchForGifs(const QString &query) {
if (_inlineQuery != query) {
_footer->setLoading(false);
if (_inlineRequestId) {
request(_inlineRequestId).cancel();
_api.request(_inlineRequestId).cancel();
_inlineRequestId = 0;
}
if (_inlineCache.find(query) != _inlineCache.cend()) {
@ -855,7 +858,7 @@ void GifsListWidget::searchForGifs(const QString &query) {
if (!_searchBot && !_searchBotRequestId) {
auto username = str_const_toString(kSearchBotUsername);
_searchBotRequestId = request(MTPcontacts_ResolveUsername(
_searchBotRequestId = _api.request(MTPcontacts_ResolveUsername(
MTP_string(username)
)).done([=](const MTPcontacts_ResolvedPeer &result) {
Expects(result.type() == mtpc_contacts_resolvedPeer);
@ -905,7 +908,7 @@ void GifsListWidget::sendInlineRequest() {
}
_footer->setLoading(true);
_inlineRequestId = request(MTPmessages_GetInlineBotResults(
_inlineRequestId = _api.request(MTPmessages_GetInlineBotResults(
MTP_flags(0),
_searchBot->inputUser,
_inlineQueryPeer->input,

View File

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

View File

@ -278,6 +278,9 @@ void InitSpellchecker(
not_null<Main::Session*> session,
not_null<Ui::InputField*> field) {
#ifndef TDESKTOP_DISABLE_SPELLCHECK
if (!Platform::Spellchecker::IsAvailable()) {
return;
}
const auto s = Ui::CreateChild<Spellchecker::SpellingHighlighter>(
field.get(),
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_session.h"
#include "data/data_file_origin.h"
#include "boxes/stickers_box.h"
#include "boxes/confirm_box.h"
#include "lang/lang_keys.h"
@ -891,7 +892,7 @@ std::optional<std::vector<not_null<EmojiPtr>>> GetEmojiListFromSet(
if (result.empty()) {
return std::nullopt;
}
return std::move(result);
return result;
}
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_session.h"
#include "data/data_channel.h"
#include "data/data_file_origin.h"
#include "ui/widgets/buttons.h"
#include "ui/effects/animations.h"
#include "ui/effects/ripple_animation.h"
@ -828,6 +829,7 @@ StickersListWidget::StickersListWidget(
QWidget *parent,
not_null<Window::SessionController*> controller)
: Inner(parent, controller)
, _api(controller->session().api().instance())
, _section(Section::Stickers)
, _megagroupSetAbout(st::columnMinimalWidthThird - st::emojiScroll.width - st::emojiPanHeaderLeft)
, _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);
_footer = result;
return std::move(result);
return result;
}
void StickersListWidget::visibleTopBottomUpdated(
@ -1069,7 +1071,7 @@ void StickersListWidget::sendSearchRequest() {
_footer->setLoading(true);
const auto hash = int32(0);
_searchRequestId = request(MTPmessages_SearchStickerSets(
_searchRequestId = _api.request(MTPmessages_SearchStickerSets(
MTP_flags(0),
MTP_string(_searchQuery),
MTP_int(hash)
@ -1092,7 +1094,7 @@ void StickersListWidget::searchForSets(const QString &query) {
if (_searchQuery != cleaned) {
_footer->setLoading(false);
if (const auto requestId = base::take(_searchRequestId)) {
request(requestId).cancel();
_api.request(requestId).cancel();
}
if (_searchCache.find(cleaned) != _searchCache.cend()) {
_searchRequestTimer.cancel();
@ -1108,7 +1110,7 @@ void StickersListWidget::searchForSets(const QString &query) {
void StickersListWidget::cancelSetsSearch() {
_footer->setLoading(false);
if (const auto requestId = base::take(_searchRequestId)) {
request(requestId).cancel();
_api.request(requestId).cancel();
}
_searchRequestTimer.cancel();
_searchQuery = _searchNextQuery = QString();
@ -2468,7 +2470,7 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) {
return;
}
_megagroupSetIdRequested = set.vid().v;
request(MTPmessages_GetStickerSet(
_api.request(MTPmessages_GetStickerSet(
_megagroupSet->mgInfo->stickerSet
)).done([=](const MTPmessages_StickerSet &result) {
if (const auto set = Stickers::FeedSetFull(result)) {
@ -2810,7 +2812,7 @@ void StickersListWidget::installSet(uint64 setId) {
const auto input = Stickers::inputSetId(*it);
if ((it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)
|| it->stickers.empty()) {
request(MTPmessages_GetStickerSet(
_api.request(MTPmessages_GetStickerSet(
input
)).done([=](const MTPmessages_StickerSet &result) {
Stickers::FeedSetFull(result);
@ -2825,7 +2827,7 @@ void StickersListWidget::installSet(uint64 setId) {
void StickersListWidget::sendInstallRequest(
uint64 setId,
const MTPInputStickerSet &input) {
request(MTPmessages_InstallStickerSet(
_api.request(MTPmessages_InstallStickerSet(
input,
MTP_bool(false)
)).done([=](const MTPmessages_StickerSetInstallResult &result) {
@ -2876,9 +2878,9 @@ void StickersListWidget::removeSet(uint64 setId) {
auto it = sets.find(_removingSetId);
if (it != sets.cend()) {
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()) {
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 &recent = Stickers::GetRecentPack();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@ from generate_tl import generate
generate({
'namespaces': {
'creator': 'MTP::internal',
'creator': 'MTP::details',
},
'prefixes': {
'type': 'MTP',
@ -28,7 +28,6 @@ generate({
'buffer': 'mtpBuffer',
},
'sections': [
'serialization',
'read-write',
],
@ -91,4 +90,8 @@ generate({
},
'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
#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 ApiHash = TDESKTOP_API_HASH_TO_STRING(TDESKTOP_API_HASH);
#undef TDESKTOP_API_HASH_TO_STRING
#undef TDESKTOP_API_HASH_TO_STRING_HELPER
constexpr auto ApiHash = MACRO_TO_STRING(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>())
, _account(std::make_unique<Main::Account>(cDataFile()))
, _langpack(std::make_unique<Lang::Instance>())
, _langCloudManager(std::make_unique<Lang::CloudManager>(langpack()))
, _emojiKeywords(std::make_unique<ChatHelpers::EmojiKeywords>())
, _audio(std::make_unique<Media::Audio::Instance>())
, _logo(Window::LoadLogo())
@ -115,9 +116,6 @@ Application::Application(not_null<Launcher*> launcher)
) | rpl::filter([=](MTP::Instance *instance) {
return instance != nullptr;
}) | rpl::start_with_next([=](not_null<MTP::Instance*> mtp) {
_langCloudManager = std::make_unique<Lang::CloudManager>(
langpack(),
mtp);
if (!UpdaterDisabled()) {
UpdateChecker().setMtproto(mtp.get());
}
@ -126,7 +124,14 @@ Application::Application(not_null<Launcher*> launcher)
Application::~Application() {
_window.reset();
_mediaView.reset();
if (_mediaView) {
_mediaView->clearData();
_mediaView = nullptr;
}
if (activeAccount().sessionExists()) {
activeAccount().session().saveSettingsNowIfNeeded();
}
// This can call writeMap() that serializes Main::Session.
// 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.
unlockTerms();
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();
Shortcuts::Finish();
@ -147,7 +147,6 @@ Application::~Application() {
Ui::Emoji::Clear();
Media::Clip::Finish();
stopWebLoadManager();
App::deinitMedia();
Window::Theme::Uninitialize();
@ -208,9 +207,9 @@ void Application::run() {
style::ShortAnimationPlaying(
) | rpl::start_with_next([=](bool playing) {
if (playing) {
MTP::internal::pause();
MTP::details::pause();
} else {
MTP::internal::unpause();
MTP::details::unpause();
}
}, _lifetime);
@ -387,12 +386,12 @@ void Application::saveSettingsDelayed(crl::time delay) {
}
void Application::setCurrentProxy(
const ProxyData &proxy,
ProxyData::Settings settings) {
const MTP::ProxyData &proxy,
MTP::ProxyData::Settings settings) {
const auto current = [&] {
return (Global::ProxySettings() == ProxyData::Settings::Enabled)
return (Global::ProxySettings() == MTP::ProxyData::Settings::Enabled)
? Global::SelectedProxy()
: ProxyData();
: MTP::ProxyData();
};
const auto was = current();
Global::SetSelectedProxy(proxy);
@ -408,12 +407,12 @@ auto Application::proxyChanges() const -> rpl::producer<ProxyChange> {
}
void Application::badMtprotoConfigurationError() {
if (Global::ProxySettings() == ProxyData::Settings::Enabled
if (Global::ProxySettings() == MTP::ProxyData::Settings::Enabled
&& !_badProxyDisableBox) {
const auto disableCallback = [=] {
setCurrentProxy(
Global::SelectedProxy(),
ProxyData::Settings::System);
MTP::ProxyData::Settings::System);
};
_badProxyDisableBox = Ui::show(Box<InformBox>(
Lang::Hard::ProxyConfigError(),
@ -423,14 +422,18 @@ void Application::badMtprotoConfigurationError() {
void Application::startLocalStorage() {
Local::start();
subscribe(_dcOptions->changed(), [this](const MTP::DcOptions::Ids &ids) {
Local::writeSettings();
if (const auto instance = activeAccount().mtp()) {
for (const auto id : ids) {
instance->restart(id);
}
}
});
const auto writing = _lifetime.make_state<bool>(false);
_dcOptions->changed(
) | rpl::filter([=] {
return !*writing;
}) | rpl::start_with_next([=] {
*writing = true;
Ui::PostponeCall(this, [=] {
Local::writeSettings();
});
}, _lifetime);
_saveSettingsTimer.setCallback([=] { Local::writeSettings(); });
}
@ -604,27 +607,36 @@ void Application::checkStartUrl() {
}
bool Application::openLocalUrl(const QString &url, QVariant context) {
auto urlTrimmed = url.trimmed();
if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192);
return openCustomUrl("tg://", LocalUrlHandlers(), url, context);
}
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()) {
return false;
}
auto command = urlTrimmed.midRef(protocol.size());
const auto command = urlTrimmed.midRef(protocol.size(), 8192);
const auto session = activeAccount().sessionExists()
? &activeAccount().session()
: nullptr;
using namespace qthelp;
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);
if (match) {
return handler(session, match, context);
}
}
return false;
}
void Application::lockByPasscode() {

View File

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

View File

@ -18,51 +18,32 @@ namespace {
std::map<int, const char*> BetaLogs() {
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,
"\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 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,
"\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 = [=] {
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();
} else {
const auto parsedUrl = QUrl::fromUserInput(url);
@ -55,7 +56,9 @@ void HiddenUrlClickHandler::Open(QString url, QVariant context) {
: url;
Ui::show(
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),
[=] { Ui::hideLayer(); open(); }),
Ui::LayerOption::KeepOther);

View File

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

View File

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

View File

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

View File

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

View File

@ -249,12 +249,11 @@ void Launcher::init() {
QApplication::setApplicationName(qsl("KotatogramDesktop"));
#ifdef TDESKTOP_LAUNCHER_FILENAME
#define TDESKTOP_LAUNCHER_FILENAME_TO_STRING_HELPER(V) #V
#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)));
QApplication::setDesktopFileName(qsl(MACRO_TO_STRING(TDESKTOP_LAUNCHER_FILENAME)));
#elif defined(Q_OS_LINUX) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
QApplication::setDesktopFileName(qsl("kotatogramdesktop.desktop"));
#endif
#ifndef OS_MAC_OLD
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, true);
#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 "window/window_session_controller.h"
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_cloud_themes.h"
#include "data/data_channel.h"
#include "media/player/media_player_instance.h"
#include "mainwindow.h"
#include "mainwidget.h"
#include "main/main_session.h"
@ -163,7 +165,9 @@ bool ApplySocksProxy(
auto params = url_parse_params(
match->captured(1),
qthelp::UrlParamNameTransform::ToLower);
ProxiesBoxController::ShowApplyConfirmation(ProxyData::Type::Socks5, params);
ProxiesBoxController::ShowApplyConfirmation(
MTP::ProxyData::Type::Socks5,
params);
return true;
}
@ -174,7 +178,9 @@ bool ApplyMtprotoProxy(
auto params = url_parse_params(
match->captured(1),
qthelp::UrlParamNameTransform::ToLower);
ProxiesBoxController::ShowApplyConfirmation(ProxyData::Type::Mtproto, params);
ProxiesBoxController::ShowApplyConfirmation(
MTP::ProxyData::Type::Mtproto,
params);
return true;
}
@ -358,6 +364,40 @@ bool HandleUnknown(
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
const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
@ -417,7 +457,17 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
{
qsl("^([^\\?]+)(\\?|#|$)"),
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;
}

View File

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

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