Compare commits

...

102 Commits

Author SHA1 Message Date
John Preston
075ab20e5b Version 3.7.3: Don't copy text from a restricted post. 2022-04-26 14:13:16 +04:00
John Preston
deeea0aaed Version 3.7.3: Update lib_webview. 2022-04-26 13:06:42 +04:00
John Preston
8113117cc4 Version 3.7.3.
- Fix a crash in the pinned bar bot button refresh.
2022-04-26 10:38:58 +04:00
John Preston
7bfe096f3b Fix possible crashes in pinned bar button. 2022-04-26 10:24:36 +04:00
John Preston
c37b08ac8b Version 3.7.2.
- Fix mute period selector values.
- Fix a crash in repeated context menu item selection.
- Fix context menu item selection of systems without a compositor.
2022-04-25 22:38:29 +04:00
Hugo Osvaldo Barrera
c52a5927e5 Avoid a second query for the current color-scheme
Telegram listens for a signal that indicates when the color-scheme
changes. The signal itself includes the new value, but Telegram
currently queries for the value immediately after getting the signal.
This second round-trip is unnecessary, since the signal itself contains
the same information.

This changeset avoids this follow-up query, and drops the now-unused
`Setter`.
2022-04-25 22:38:08 +04:00
23rd
edcfac8da3 Slightly improved display of media replacement in admin log. 2022-04-25 22:35:02 +04:00
23rd
a994c9f017 Moved EditPeerHistoryVisibilityBox to td_ui. 2022-04-25 22:35:02 +04:00
23rd
66e6bf8217 Replaced EditPeerHistoryVisibilityBox with generic box. 2022-04-25 22:35:02 +04:00
23rd
4a4cc766c2 Replaced icons in manage group / channel. 2022-04-25 22:35:02 +04:00
23rd
31cd841b75 Added bot button to bar of pinned messages. 2022-04-25 22:35:02 +04:00
23rd
1710890886 Added ability to change width between pinned bar animation entries. 2022-04-25 22:35:02 +04:00
23rd
16f616c5e0 Added ability to set content to bar of pinned messages later. 2022-04-25 22:35:02 +04:00
23rd
7600c9bb2f Added fade animation to right button in bar of pinned messages. 2022-04-25 22:35:02 +04:00
23rd
100a44daef Removed unused includes from MultiSelect. 2022-04-25 22:35:02 +04:00
23rd
54305fafde Removed forced context menu in profiles for muted peers. 2022-04-25 22:35:02 +04:00
23rd
d172d3d7db Fixed intervals of seconds in PickMuteBox. 2022-04-25 22:35:02 +04:00
Ilya Fedin
cee593c423 Check whether notification image has alpha channel 2022-04-25 22:33:22 +04:00
John Preston
43adbb1cb1 Revert some changes in Menu actions triggering. 2022-04-25 15:54:32 +04:00
John Preston
e96731be11 Fix popup menu callbacks on systems without compositing. 2022-04-25 15:42:42 +04:00
John Preston
6ea062462f Fix crash in Ui::Menu second action trigger event. 2022-04-25 14:03:57 +04:00
John Preston
1bc8d6fb18 Fix non-working Qt-on-Windows bug workaround. 2022-04-25 14:03:43 +04:00
John Preston
73d00a4caf Reload stale video chat on join. 2022-04-25 13:41:24 +04:00
John Preston
a23561c380 Reload stale video chats on group / channel open. 2022-04-25 12:50:58 +04:00
Ilya Fedin
bb75a6a31b Speed up submodule checkout in Dockerfile
Use --depth=1 for submodules, too.
This also replaces perl init-repository for Qt as the only thing it does is fetches submodules, but there's no way to specify --depth=1 with it.
2022-04-24 07:26:20 +04:00
John Preston
ce79c1f0c4 Handle "web_app_request_theme" event in WebView. 2022-04-21 10:47:21 +04:00
John Preston
3cdb82a0bf Version 3.7.1.
- Hardware accelerated video decoding off by default.
- Fix several crashes.
2022-04-20 13:56:09 +04:00
John Preston
d2f928f0c3 Fix info layer animations. 2022-04-20 13:53:07 +04:00
John Preston
3cc0110464 Fix menu callbacks triggering in some cases. 2022-04-20 11:43:53 +04:00
John Preston
df533f2efe Don't use WebView embed in Windows before 8.1. 2022-04-20 11:43:53 +04:00
John Preston
2529bd3f44 Add logging of PickMuteBox invocation. 2022-04-20 11:43:53 +04:00
23rd
a5c12065af Slightly improved style of ttl button. 2022-04-19 17:48:48 +03:00
23rd
101e795af8 Changed time picker box to highlight closest value. 2022-04-19 17:48:48 +03:00
23rd
8faa65fdf3 Improved format of ttl and mute phrases. 2022-04-19 17:48:48 +03:00
John Preston
644881bd3e Fix build on Windows. 2022-04-19 18:13:27 +04:00
John Preston
efa1b2dcbc Update WebView2 package version. 2022-04-19 16:59:23 +04:00
John Preston
92a9832337 Update patches revision in CentOS docker. 2022-04-19 16:21:18 +04:00
John Preston
8f3456cd6c Attempt to fix the build on GCC. 2022-04-19 16:10:45 +04:00
John Preston
e67192cdf0 Fix export window size.
Fixes #24373.

SeparatePanel::show calls activePopupWidget::close,
activePopupWidget::close calls SeparatePanel::resizeEvents with strange values.
2022-04-19 12:02:54 +04:00
John Preston
9f2683a35b Fix crash in MessagesSearch requests. 2022-04-19 12:02:11 +04:00
Ilya Fedin
0a7e25e45a Update cmake_helpers 2022-04-19 10:23:24 +04:00
Ilya Fedin
643a034aae Fix default branch check in the Dokcer action 2022-04-19 10:23:24 +04:00
John Preston
1c5a3aef54 Hardware accelerated video decoding off by default. 2022-04-19 09:51:29 +04:00
John Preston
bfe47a1ba2 Clear hw_device_ctx in AVCodecContext. 2022-04-19 09:39:01 +04:00
John Preston
acd76fc97b Clear possible crash in media viewer. 2022-04-19 09:39:01 +04:00
John Preston
78fedce2d5 Fix icon positions in manage group / channel. 2022-04-19 09:39:01 +04:00
23rd
5261e962e2 Removed Ui::show from menu item for poll stopping. 2022-04-19 09:39:01 +04:00
23rd
e4bfd562b5 Fixed phone formatting when app is started from settings. 2022-04-19 09:39:01 +04:00
23rd
d289bbdc5e Added ability to report profile photos.
Fixed #24325.
2022-04-19 09:39:01 +04:00
23rd
2e9e3b3751 Provided parent to report toasts. 2022-04-19 09:39:01 +04:00
23rd
af0a2f182c Removed Ui::show from ShowReportItemsBox. 2022-04-19 09:39:01 +04:00
23rd
e3ac84a849 Moved boxes for reporting messages or peers to separated file. 2022-04-19 09:39:01 +04:00
23rd
6dce8dfa20 Moved api for report messages to separated file. 2022-04-19 09:39:01 +04:00
23rd
eef1da56c8 Slightly optimized box of messages reporting in HistoryWidget. 2022-04-19 09:39:01 +04:00
23rd
e37866d0b9 Added animated reactions in manage of groups / channels. 2022-04-19 09:39:00 +04:00
23rd
1ed7d482ab Added ability to choose precise time for user restriction.
Fixed #3599.
Fixed #6923.
2022-04-19 09:39:00 +04:00
23rd
f1a7db780e Fixed text color of menu item for disabling notifications. 2022-04-19 09:39:00 +04:00
23rd
8591fae031 Added slight nice effect to time picker. 2022-04-19 09:39:00 +04:00
23rd
18b9bba21c Fixed width of time picker for different scales. 2022-04-19 09:39:00 +04:00
Ilya Fedin
580e15dc21 Update cmake_helpers 2022-04-19 09:33:23 +04:00
Ilya Fedin
bf4fc2596a Remove unneeded primary screen fallbacks
QWidget::screen automatically fallbacks to primary screen as the last effort, so this is not needed
2022-04-19 09:33:23 +04:00
Ilya Fedin
9a4d2bc8f9 Make processDpi a constexpr and remove unneeded qreal 2022-04-19 08:40:07 +04:00
Ilya Fedin
62a2277f43 Passthrough QT_FONT_DPI in crash report window just like in the main scaling engine 2022-04-19 08:40:07 +04:00
Ilya Fedin
d11885d48c Update URL to the Docker image in Linux action 2022-04-18 21:21:57 +04:00
Ilya Fedin
c8cec18ad3 Update patches in Dockerfile 2022-04-18 20:17:08 +04:00
Ilya Fedin
86105403bf Automatically update Docker image on GHCR 2022-04-18 20:17:08 +04:00
Ilya Fedin
41288f5ddb Update patches in Dockerfile 2022-04-18 10:06:16 +04:00
Ilya Fedin
9cc1a020f3 Have a variable to control debug info in docker image 2022-04-18 10:06:16 +04:00
Ilya Fedin
68f35e98e0 Have less Docker steps to avoid saving superfluous data 2022-04-18 10:06:16 +04:00
Ilya Fedin
b6c9a1d655 Add glib-networking to snap
It's required by webkit2gtk for correct operation
2022-04-17 13:50:25 +04:00
Ilya Fedin
9b35fa29b8 Remove object files from the resulting Docker image 2022-04-17 09:10:44 +04:00
Ilya Fedin
53272d951b Adjust path variables in Dockerfile 2022-04-17 09:10:44 +04:00
John Preston
e3dc4ae088 Version 3.7: Fix a crash in some langpacks. 2022-04-16 20:58:17 +04:00
John Preston
000d9d8b52 Version 3.7.
- Use any short music file or voice message as a notification sound.
- Right click audio files in chats to add them to your list
of sounds - or use 'Upload Sound' in the Notifications menu.
- Click on Mute notifications > Select sound in a chat's (...) menu
to change its notification sound.
- Set custom tones for notifications
in Settings > Notifications > Play sound.
- Click on Mute notifications in a chat's (...) menu
to manage its notifications.
- Choose 'Mute for...' to turn off notifications for a preset period,
like 1 hour or 1 day.
- Quickly configure Auto-Delete settings from any chat info page.
- Click (...) to turn on Auto-Delete,
then select a specific duration.
- Replies are now preserved when forwarding messages,
making forwarded conversations easier to read.
- Bots can now open detailed pages directly in the chat.
- Use these streamlined interfaces to buy real-world goods
and services without leaving the app.
- Open a bot's profile to add it to your group or channel.
- Instantly configure a bot's rights and permissions when adding it.
- Bots can send a new type of button
that lets you add them to your group or channel.
2022-04-16 20:37:17 +04:00
Ilya Fedin
3d8742fa7c Fix some working with paths in prepare.py
Use os.path.join for separator
Get real path of Libraries/ThirdParty directories to workaround gyp's problems with drive letters
2022-04-16 20:27:19 +04:00
Ilya Fedin
ae43e78a86 Have libraries in GITHUB_WORKSPACE for caching in Windows action 2022-04-16 20:27:19 +04:00
Ilya Fedin
7c72393361 Add architecture to Windows action cache key 2022-04-16 20:27:19 +04:00
Ilya Fedin
fa95ca4289 Don't install unused brew packages 2022-04-16 20:27:19 +04:00
Ilya Fedin
e6e90e99da Run Windows action on changes in prepare.py 2022-04-16 20:27:19 +04:00
Ilya Fedin
6a3c1f2fd9 Fix macOS action 2022-04-16 20:27:19 +04:00
John Preston
90f99ebfbe Add some additional space for TimePickerBox. 2022-04-16 20:26:49 +04:00
John Preston
59fb61e3e6 Don't re-request ringtones on empty list. 2022-04-16 20:13:21 +04:00
John Preston
261740967d Fix media viewer crop on multi-monitor setup. 2022-04-16 19:56:28 +04:00
Nicholas Guriev
e99e35a12a Close restarting confirm box when cancelled
The regression seems introduced in commit 5718789d53.
2022-04-16 18:14:33 +04:00
Ilya Fedin
fd6d09caaa Fix cache update for the actions
The caching action doesn't update the cache when cache hit is happenned.
This could be fixed by having unique keys for every cache change and using restore-keys to find these caches.
2022-04-16 07:28:06 +04:00
23rd
47ec5b18b8 Removed info button from top bar in profile when menu is empty. 2022-04-15 14:19:29 +03:00
23rd
aac21e1f71 Removed ttl menu for deleted accounts. 2022-04-15 13:59:44 +03:00
23rd
21c647147a Fixed total count of found messages in channels via api search. 2022-04-15 13:13:44 +03:00
23rd
07a022bfb6 Converted ttl and mute boxes to confirm boxes. 2022-04-15 13:13:44 +03:00
23rd
0427f90649 Removed label from confirm box when text is not provided. 2022-04-15 13:13:44 +03:00
23rd
64627c9093 Fixed theme of sample bubble message in reactions settings. 2022-04-15 13:11:32 +03:00
23rd
148a173474 Removed animation when removing reaction with double click. 2022-04-15 13:11:32 +03:00
John Preston
acb6e5dbc3 Fix date layout for webpage preview without description. 2022-04-15 09:30:34 +04:00
John Preston
9bd9f17a6c Show only active reactions in quick reaction box. 2022-04-15 09:26:58 +04:00
John Preston
d59ed7b14c Fix glitch on layer open. 2022-04-14 17:29:58 +04:00
John Preston
3600055424 Fix possible use-after-free in VerticalLayout. 2022-04-14 17:29:56 +04:00
John Preston
949caecb75 Fix bot start token sending. 2022-04-14 16:13:12 +04:00
John Preston
87df42f8c1 Improve icon padding in bot inline buttons. 2022-04-14 15:24:12 +04:00
John Preston
2996cbc518 Fix bot menu button on voice recording. 2022-04-14 15:22:19 +04:00
John Preston
205cd3b751 Fix mention links to groups and channels. 2022-04-14 14:15:29 +04:00
Ilya Fedin
d25bd2f481 Update tg_owt in Dockerfile & snapcraft.yaml 2022-04-14 14:14:15 +04:00
Ilya Fedin
072974216b Disable egl-extension-platform-wayland again
Looks like it causes problems along with -Wl,-z,now
2022-04-14 13:54:51 +04:00
131 changed files with 1723 additions and 1383 deletions

View File

@@ -15,6 +15,9 @@ jobs:
name: Ubuntu
runs-on: ubuntu-latest
env:
IMAGE_TAG: ghcr.io/${{ github.repository }}/centos_env:latest
steps:
- name: Clone.
uses: actions/checkout@v2
@@ -22,4 +25,10 @@ jobs:
submodules: recursive
- name: Docker image build.
run: docker build -t telegram_desktop Telegram/build/docker/centos_env
run: docker build -t $IMAGE_TAG --build-arg DEBUG= Telegram/build/docker/centos_env
- name: Push the Docker image.
if: ${{ github.ref_name == github.event.repository.default_branch }}
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
docker push $IMAGE_TAG

View File

@@ -46,7 +46,7 @@ jobs:
name: CentOS 7
runs-on: ubuntu-latest
container:
image: docker.pkg.github.com/telegramdesktop/tdesktop/centos_env
image: ghcr.io/${{ github.repository }}/centos_env
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -51,6 +51,7 @@ jobs:
env:
UPLOAD_ARTIFACT: "false"
ONLY_CACHE: "false"
PREPARE_PATH: "Telegram/build/prepare/prepare.py"
steps:
- name: Get repository name.
@@ -65,8 +66,7 @@ jobs:
- name: First set up.
run: |
sudo chown -R `whoami`:admin /usr/local/share
brew install automake fdk-aac lame libass libtool libvorbis libvpx \
ninja opus sdl shtool texi2html theora x264 xvid yasm pkg-config
brew install automake
# Disable spotlight.
sudo mdutil -a -i off
@@ -78,14 +78,16 @@ jobs:
uses: actions/cache@v2
with:
path: ThirdParty
key: ${{ runner.OS }}-third-party
key: ${{ runner.OS }}-third-party-${{ hashFiles(format('{0}/{1}', env.REPO_NAME, env.PREPARE_PATH)) }}
restore-keys: ${{ runner.OS }}-third-party-
- name: Libraries cache.
id: cache-libs
uses: actions/cache@v2
with:
path: Libraries
key: ${{ runner.OS }}-libs
key: ${{ runner.OS }}-libs-${{ hashFiles(format('{0}/{1}', env.REPO_NAME, env.PREPARE_PATH)) }}
restore-keys: ${{ runner.OS }}-libs-
- name: Libraries.
run: |

View File

@@ -13,7 +13,7 @@ on:
- '!.github/workflows/win.yml'
- 'lib/xdg/**'
- 'snap/**'
- 'Telegram/build/**'
- 'Telegram/build/docker/**'
- 'Telegram/Resources/uwp/**'
- 'Telegram/SourceFiles/platform/linux/**'
- 'Telegram/SourceFiles/platform/mac/**'
@@ -32,7 +32,7 @@ on:
- '!.github/workflows/win.yml'
- 'lib/xdg/**'
- 'snap/**'
- 'Telegram/build/**'
- 'Telegram/build/docker/**'
- 'Telegram/Resources/uwp/**'
- 'Telegram/SourceFiles/platform/linux/**'
- 'Telegram/SourceFiles/platform/mac/**'
@@ -58,12 +58,12 @@ jobs:
defaults:
run:
shell: cmd
working-directory: ${{ github.workspace }}
steps:
- name: Prepare directories.
run: |
mkdir %userprofile%\TBuild\Libraries
mkdir %userprofile%\TBuild Libraries
mklink /d %userprofile%\TBuild\Libraries %GITHUB_WORKSPACE%\Libraries
echo TBUILD=%userprofile%\TBuild>>%GITHUB_ENV%
- name: Get repository name.
@@ -98,6 +98,8 @@ jobs:
echo "C:\\Program Files\\NASM\\" >> $GITHUB_PATH
echo "C:\\ProgramData\\chocolatey\\lib\\ninja\\tools\\" >> $GITHUB_PATH
echo "CACHE_KEY=$(sha256sum $TBUILD/$REPO_NAME/$PREPARE_PATH | awk '{ print $1 }')" >> $GITHUB_ENV
echo "Configurate git for cherry-picks."
git config --global user.email "you@example.com"
git config --global user.name "Sample"
@@ -111,17 +113,15 @@ jobs:
id: cache-libs
uses: actions/cache@v2
with:
path: ${{ env.TBUILD }}/Libraries
key: ${{ runner.OS }}-libs
path: Libraries
key: ${{ runner.OS }}-${{ matrix.arch }}-libs-${{ env.CACHE_KEY }}
restore-keys: ${{ runner.OS }}-${{ matrix.arch }}-libs-
- name: Libraries.
env:
GYP_MSVS_OVERRIDE_PATH: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\'
GYP_MSVS_VERSION: 2022
run: |
C:
cd %TBUILD%
%REPO_NAME%/Telegram/build/prepare/win.bat skip-release silent
run: '%TBUILD%\%REPO_NAME%\Telegram\build\prepare\win.bat skip-release silent'
- name: Read defines.
shell: bash
@@ -138,8 +138,6 @@ jobs:
- name: Free up some disk space.
run: |
C:
cd %TBUILD%
del /S Libraries\*.pdb
del /S Libraries\*.pch
del /S Libraries\*.obj

View File

@@ -137,6 +137,8 @@ PRIVATE
api/api_peer_photo.h
api/api_polls.cpp
api/api_polls.h
api/api_report.cpp
api/api_report.h
api/api_ringtones.cpp
api/api_ringtones.h
api/api_self_destruct.cpp
@@ -186,8 +188,6 @@ PRIVATE
boxes/peers/edit_peer_invite_link.h
boxes/peers/edit_peer_invite_links.cpp
boxes/peers/edit_peer_invite_links.h
boxes/peers/edit_peer_history_visibility_box.cpp
boxes/peers/edit_peer_history_visibility_box.h
boxes/peers/edit_peer_permissions_box.cpp
boxes/peers/edit_peer_permissions_box.h
boxes/peers/edit_peer_reactions.cpp
@@ -258,6 +258,8 @@ PRIVATE
boxes/pin_messages_box.h
boxes/reactions_settings_box.cpp
boxes/reactions_settings_box.h
boxes/report_messages_box.cpp
boxes/report_messages_box.h
boxes/ringtones_box.cpp
boxes/ringtones_box.h
boxes/self_destruction_box.cpp

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 B

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 957 B

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1023 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 989 B

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1141,6 +1141,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_report_group_title" = "Report group";
"lng_report_bot_title" = "Report bot";
"lng_report_message_title" = "Report message";
"lng_report_profile_photo_title" = "Report profile photo";
"lng_report_profile_video_title" = "Report profile video";
"lng_report_please_select_messages" = "Please select messages to report.";
"lng_report_select_messages" = "Select messages";
"lng_report_messages_none" = "Select Messages";
@@ -1974,7 +1976,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_try_other_contact" = "Try someone else";
"lng_create_group_link" = "Link";
"lng_create_group_invite_link" = "Invite link";
"lng_create_group_description" = "Description (optional)";
"lng_create_group_description" = "Add description...";
"lng_drag_images_here" = "Drop images here";
"lng_drag_photos_here" = "Drop photos here";
@@ -2053,6 +2055,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_mediaview_yesterday" = "yesterday at {time}";
"lng_mediaview_date_time" = "{date} at {time}";
"lng_mediaview_set_userpic" = "Set as Main";
"lng_mediaview_report_profile_photo" = "Report";
"lng_mediaview_saved_to" = "Image was saved to your {downloads} folder";
"lng_mediaview_downloads" = "Downloads";
@@ -2145,6 +2148,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_payments_webview_install_webkit" = "Please install WebKitGTK (webkit2gtk-5.0/webkit2gtk-4.1/webkit2gtk-4.0) using your package manager.";
"lng_payments_webview_switch_mutter" = "Qt's window embedding doesn't work well with Mutter window manager. Please switch to another window manager or desktop environment.";
"lng_payments_webview_switch_wayland" = "There is no way to embed WebView window on Wayland. Please switch to X11.";
"lng_payments_webview_update_windows" = "Please update your system to Windows 8.1 or later.";
"lng_payments_sure_close" = "Are you sure you want to close this payment form? The changes you made will be lost.";
"lng_payments_receipt_label" = "Receipt";
"lng_payments_receipt_label_test" = "Test receipt";
@@ -2657,7 +2661,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_pinned_message" = "{from} pinned this message:";
"lng_admin_log_unpinned_message" = "{from} unpinned this message";
"lng_admin_log_edited_caption" = "{from} edited caption:";
"lng_admin_log_removed_caption" = "{from} removed caption";
"lng_admin_log_edited_media" = "{from} edited media:";
"lng_admin_log_edited_media_and_caption" = "{from} edited media and caption:";
"lng_admin_log_edited_media_and_removed_caption" = "{from} edited media and removed caption:";
"lng_admin_log_removed_caption" = "{from} removed caption:";
"lng_admin_log_previous_caption" = "Original caption";
"lng_admin_log_edited_message" = "{from} edited this message:";
"lng_admin_log_previous_message" = "Original message";

View File

@@ -10,7 +10,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="3.6.3.0" />
Version="3.7.3.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>

View File

@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,6,3,0
PRODUCTVERSION 3,6,3,0
FILEVERSION 3,7,3,0
PRODUCTVERSION 3,7,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "3.6.3.0"
VALUE "FileVersion", "3.7.3.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2022"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "3.6.3.0"
VALUE "ProductVersion", "3.7.3.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,6,3,0
PRODUCTVERSION 3,6,3,0
FILEVERSION 3,7,3,0
PRODUCTVERSION 3,7,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater"
VALUE "FileVersion", "3.6.3.0"
VALUE "FileVersion", "3.7.3.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2022"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "3.6.3.0"
VALUE "ProductVersion", "3.7.3.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -17,10 +17,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
namespace Api {
namespace {
MessageIdsList HistoryItemsFromTL(
[[nodiscard]] MessageIdsList HistoryItemsFromTL(
not_null<Data::Session*> data,
const QVector<MTPMessage> &messages) {
auto result = MessageIdsList();
@@ -45,8 +44,12 @@ MessageIdsList HistoryItemsFromTL(
} // namespace
MessagesSearch::MessagesSearch(not_null<History*> history)
: _history(history)
, _api(&history->session().mtp()) {
: _history(history) {
}
MessagesSearch::~MessagesSearch() {
_history->owner().histories().cancelRequest(
base::take(_searchInHistoryRequest));
}
void MessagesSearch::searchMessages(const QString &query, PeerData *from) {
@@ -78,7 +81,7 @@ void MessagesSearch::searchRequest() {
const auto flags = _from
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
: MTP_flags(0);
_requestId = _api.request(MTPmessages_Search(
_requestId = _history->session().api().request(MTPmessages_Search(
flags,
_history->peer->input,
MTP_string(_query),
@@ -102,10 +105,11 @@ void MessagesSearch::searchRequest() {
}).fail([=](const MTP::Error &error, mtpRequestId id) {
_searchInHistoryRequest = 0;
if (_requestId == id) {
_requestId = 0;
}
if (error.type() == u"SEARCH_QUERY_EMPTY"_q) {
_messagesFounds.fire({ 0, MessageIdsList(), nextToken });
} else if (_requestId == id) {
_requestId = 0;
}
finish();
@@ -159,7 +163,7 @@ void MessagesSearch::searchReceived(
owner.processChats(data.vchats());
}
auto items = HistoryItemsFromTL(&owner, data.vmessages().v);
const auto total = int(data.vmessages().v.size());
const auto total = int(data.vcount().v);
return FoundMessages{ total, std::move(items), nextToken };
}, [](const MTPDmessages_messagesNotModified &data) {
return FoundMessages{};

View File

@@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/sender.h"
class HistoryItem;
class History;
class PeerData;
@@ -24,6 +22,7 @@ struct FoundMessages {
class MessagesSearch final {
public:
explicit MessagesSearch(not_null<History*> history);
~MessagesSearch();
void searchMessages(const QString &query, PeerData *from);
void searchMore();
@@ -39,7 +38,6 @@ private:
const QString &nextToken);
const not_null<History*> _history;
MTP::Sender _api;
base::flat_map<QString, TLMessages> _cacheOfStartByToken;

View File

@@ -18,11 +18,10 @@ bool MessagesSearchMerged::RequestCompare::operator()(
}
MessagesSearchMerged::MessagesSearchMerged(not_null<History*> history)
: _apiSearch(history)
, _migratedSearch(history->migrateFrom()
? std::make_optional<MessagesSearch>(history->migrateFrom())
: std::nullopt) {
: _apiSearch(history) {
if (const auto migrated = history->migrateFrom()) {
_migratedSearch.emplace(migrated);
}
const auto checkWaitingForTotal = [=] {
if (_waitingForTotal) {
if (_concatedFound.total >= 0 && _migratedFirstFound.total >= 0) {

View File

@@ -0,0 +1,78 @@
/*
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_report.h"
#include "apiwrap.h"
#include "data/data_peer.h"
#include "data/data_photo.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/boxes/report_box.h"
#include "ui/toast/toast.h"
namespace Api {
namespace {
MTPreportReason ReasonToTL(const Ui::ReportReason &reason) {
using Reason = Ui::ReportReason;
switch (reason) {
case Reason::Spam: return MTP_inputReportReasonSpam();
case Reason::Fake: return MTP_inputReportReasonFake();
case Reason::Violence: return MTP_inputReportReasonViolence();
case Reason::ChildAbuse: return MTP_inputReportReasonChildAbuse();
case Reason::Pornography: return MTP_inputReportReasonPornography();
case Reason::Copyright: return MTP_inputReportReasonCopyright();
case Reason::IllegalDrugs: return MTP_inputReportReasonIllegalDrugs();
case Reason::PersonalDetails:
return MTP_inputReportReasonPersonalDetails();
case Reason::Other: return MTP_inputReportReasonOther();
}
Unexpected("Bad reason group value.");
}
} // namespace
void SendReport(
not_null<QWidget*> toastParent,
not_null<PeerData*> peer,
Ui::ReportReason reason,
const QString &comment,
std::variant<v::null_t, MessageIdsList, not_null<PhotoData*>> data) {
auto done = [=] {
Ui::Toast::Show(toastParent, tr::lng_report_thanks(tr::now));
};
v::match(data, [&](v::null_t) {
peer->session().api().request(MTPaccount_ReportPeer(
peer->input,
ReasonToTL(reason),
MTP_string(comment)
)).done(std::move(done)).send();
}, [&](const MessageIdsList &ids) {
auto apiIds = QVector<MTPint>();
apiIds.reserve(ids.size());
for (const auto &fullId : ids) {
apiIds.push_back(MTP_int(fullId.msg));
}
peer->session().api().request(MTPmessages_Report(
peer->input,
MTP_vector<MTPint>(apiIds),
ReasonToTL(reason),
MTP_string(comment)
)).done(std::move(done)).send();
}, [&](not_null<PhotoData*> photo) {
peer->session().api().request(MTPaccount_ReportProfilePhoto(
peer->input,
photo->mtpInput(),
ReasonToTL(reason),
MTP_string(comment)
)).done(std::move(done)).send();
});
}
} // namespace Api

View File

@@ -0,0 +1,26 @@
/*
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
class PeerData;
class PhotoData;
namespace Ui {
enum class ReportReason;
} // namespace Ui
namespace Api {
void SendReport(
not_null<QWidget*> toastParent,
not_null<PeerData*> peer,
Ui::ReportReason reason,
const QString &comment,
std::variant<v::null_t, MessageIdsList, not_null<PhotoData*>> data);
} // namespace Api

View File

@@ -146,7 +146,6 @@ void Ringtones::requestList() {
document->forceToCache(true);
_list.documents.emplace_back(document->id);
}
requestList();
_list.updates.fire({});
}, [&](const MTPDaccount_savedRingtonesNotModified &) {
});

View File

@@ -3570,7 +3570,7 @@ void ApiWrap::sendBotStart(
}
auto &info = bot->botInfo;
auto &token = chat ? startTokenForChat : info->startToken;
const auto token = chat ? startTokenForChat : info->startToken;
if (token.isEmpty()) {
auto message = MessageToSend(
Api::SendAction(_session->data().history(chat

View File

@@ -20,10 +20,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/text/text_utilities.h"
#include "ui/text/text_options.h"
#include "ui/boxes/calendar_box.h"
#include "ui/special_buttons.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "settings/settings_privacy_security.h"
#include "ui/boxes/choose_date_time.h"
#include "ui/boxes/confirm_box.h"
#include "boxes/passcode_box.h"
#include "boxes/peers/add_bot_to_chat_box.h"
@@ -510,7 +510,8 @@ not_null<Ui::SlideWrap<Ui::RpWidget>*> EditAdminBox::setupTransferButton(
: tr::lng_rights_transfer_channel)(),
rpl::single(QString()),
[=] { transferOwnership(); },
st::peerPermissionsButton));
st::peerPermissionsButton,
{}));
return wrap;
}
@@ -783,35 +784,33 @@ ChatRestrictionsInfo EditRestrictedBox::defaultRights() const {
}
void EditRestrictedBox::showRestrictUntil() {
auto tomorrow = QDate::currentDate().addDays(1);
auto highlighted = isUntilForever()
? tomorrow
: base::unixtime::parse(getRealUntilValue()).date();
auto month = highlighted;
auto box = Box<Ui::CalendarBox>(Ui::CalendarBoxArgs{
.month = month,
.highlighted = highlighted,
.callback = [=](const QDate &date) {
setRestrictUntil(
static_cast<int>(date.startOfDay().toSecsSinceEpoch()));
},
.finalize = [=](not_null<Ui::CalendarBox*> box) {
box->addLeftButton(
tr::lng_rights_chat_banned_forever(),
[=] { setRestrictUntil(0); });
},
.minDate = tomorrow,
.maxDate = QDate::currentDate().addDays(kMaxRestrictDelayDays),
});
_restrictUntilBox = Ui::MakeWeak(box.data());
_show.showBox(std::move(box));
_show.showBox(Box([=](not_null<Ui::GenericBox*> box) {
const auto save = [=](TimeId result) {
if (!result) {
return;
}
setRestrictUntil(result);
box->closeBox();
};
const auto now = base::unixtime::now();
const auto time = isUntilForever()
? (now + kSecondsInDay)
: getRealUntilValue();
ChooseDateTimeBox(box, {
.title = tr::lng_rights_chat_banned_until_header(),
.submit = tr::lng_settings_save(),
.done = save,
.min = [=] { return now; },
.time = time,
.max = [=] {
return now + kSecondsInDay * kMaxRestrictDelayDays;
},
});
}));
}
void EditRestrictedBox::setRestrictUntil(TimeId until) {
_until = until;
if (_restrictUntilBox) {
_restrictUntilBox->closeBox();
}
_untilVariants.clear();
createUntilGroup();
createUntilVariants();
@@ -861,8 +860,7 @@ void EditRestrictedBox::createUntilVariants() {
tr::lng_rights_chat_banned_custom_date(
tr::now,
lt_date,
langDayOfMonthFull(
base::unixtime::parse(until).date())));
langDateTime(base::unixtime::parse(until))));
}
};
auto addCurrentVariant = [&](TimeId from, TimeId to) {

View File

@@ -17,7 +17,6 @@ class LinkButton;
class Checkbox;
class Radiobutton;
class RadiobuttonGroup;
class CalendarBox;
class VerticalLayout;
template <typename Widget>
class SlideWrap;
@@ -176,7 +175,6 @@ private:
std::shared_ptr<Ui::RadiobuttonGroup> _untilGroup;
std::vector<base::unique_qptr<Ui::Radiobutton>> _untilVariants;
QPointer<Ui::CalendarBox> _restrictUntilBox;
static constexpr auto kUntilOneDay = -1;
static constexpr auto kUntilOneWeek = -2;

View File

@@ -7,125 +7,56 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peers/edit_peer_history_visibility_box.h"
#include "boxes/peers/edit_peer_permissions_box.h"
#include "boxes/peers/edit_participants_box.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
#include "lang/lang_keys.h"
#include "ui/layers/generic_box.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "styles/style_layers.h"
#include "styles/style_info.h"
namespace {
void EditPeerHistoryVisibilityBox(
not_null<Ui::GenericBox*> box,
bool isLegacy,
Fn<void(HistoryVisibility)> savedCallback,
HistoryVisibility historyVisibilitySavedValue) {
const auto historyVisibility = std::make_shared<
Ui::RadioenumGroup<HistoryVisibility>
>(historyVisibilitySavedValue);
void AddRadioButton(
not_null<Ui::VerticalLayout*> container,
HistoryVisibility value,
const QString &groupText,
rpl::producer<QString> groupAbout,
std::shared_ptr<Ui::RadioenumGroup<HistoryVisibility>> historyVisibility) {
container->add(object_ptr<Ui::FixedHeightWidget>(
container,
st::editPeerHistoryVisibilityTopSkip));
container->add(object_ptr<Ui::Radioenum<HistoryVisibility>>(
container,
box->setTitle(tr::lng_manage_history_visibility_title());
box->addButton(tr::lng_settings_save(), [=] {
savedCallback(historyVisibility->value());
box->closeBox();
});
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
box->addSkip(st::editPeerHistoryVisibilityTopSkip);
box->addRow(object_ptr<Ui::Radioenum<HistoryVisibility>>(
box,
historyVisibility,
value,
groupText,
st::defaultBoxCheckbox));
container->add(object_ptr<Ui::PaddingWrap<Ui::FlatLabel>>(
container,
object_ptr<Ui::FlatLabel>(
container,
std::move(groupAbout),
st::editPeerPrivacyLabel),
st::editPeerPreHistoryLabelMargins));
}
void FillContent(
not_null<Ui::VerticalLayout*> parent,
not_null<PeerData*> peer,
std::shared_ptr<Ui::RadioenumGroup<HistoryVisibility>> historyVisibility,
HistoryVisibility savedValue) {
const auto canEdit = [&] {
if (const auto chat = peer->asChat()) {
return chat->canEditPreHistoryHidden();
} else if (const auto channel = peer->asChannel()) {
return channel->canEditPreHistoryHidden();
}
Unexpected("User in HistoryVisibilityEdit.");
}();
if (!canEdit) {
return;
}
historyVisibility->setValue(savedValue);
const auto result = parent->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
parent,
object_ptr<Ui::VerticalLayout>(parent),
st::editPeerHistoryVisibilityMargins));
const auto container = result->entity();
Assert(historyVisibility != nullptr);
AddRadioButton(
container,
HistoryVisibility::Visible,
tr::lng_manage_history_visibility_shown(tr::now),
tr::lng_manage_history_visibility_shown_about(),
historyVisibility);
AddRadioButton(
container,
st::defaultBoxCheckbox));
box->addRow(
object_ptr<Ui::FlatLabel>(
box,
tr::lng_manage_history_visibility_shown_about(),
st::editPeerPrivacyLabel),
st::editPeerPreHistoryLabelMargins + st::boxRowPadding);
box->addSkip(st::editPeerHistoryVisibilityTopSkip);
box->addRow(object_ptr<Ui::Radioenum<HistoryVisibility>>(
box,
historyVisibility,
HistoryVisibility::Hidden,
tr::lng_manage_history_visibility_hidden(tr::now),
(peer->isChat()
? tr::lng_manage_history_visibility_hidden_legacy
: tr::lng_manage_history_visibility_hidden_about)(),
historyVisibility);
}
} // namespace
EditPeerHistoryVisibilityBox::EditPeerHistoryVisibilityBox(
QWidget*,
not_null<PeerData*> peer,
FnMut<void(HistoryVisibility)> savedCallback,
HistoryVisibility historyVisibilitySavedValue)
: _peer(peer)
, _savedCallback(std::move(savedCallback))
, _historyVisibilitySavedValue(historyVisibilitySavedValue)
, _historyVisibility(
std::make_shared<Ui::RadioenumGroup<HistoryVisibility>>(
_historyVisibilitySavedValue)) {
}
void EditPeerHistoryVisibilityBox::prepare() {
_peer->updateFull();
setTitle(tr::lng_manage_history_visibility_title());
addButton(tr::lng_settings_save(), [=] {
auto local = std::move(_savedCallback);
local(_historyVisibility->value());
closeBox();
});
addButton(tr::lng_cancel(), [=] { closeBox(); });
setupContent();
}
void EditPeerHistoryVisibilityBox::setupContent() {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
FillContent(
content,
_peer,
_historyVisibility,
_historyVisibilitySavedValue);
setDimensionsToContent(st::boxWidth, content);
st::defaultBoxCheckbox));
box->addRow(
object_ptr<Ui::FlatLabel>(
box,
(isLegacy
? tr::lng_manage_history_visibility_hidden_legacy
: tr::lng_manage_history_visibility_hidden_about)(),
st::editPeerPrivacyLabel),
st::editPeerPreHistoryLabelMargins + st::boxRowPadding);
}

View File

@@ -7,32 +7,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "boxes/abstract_box.h"
#include "ui/widgets/checkbox.h"
namespace Ui {
class GenericBox;
} // namespace Ui
enum class HistoryVisibility {
Visible,
Hidden,
};
class EditPeerHistoryVisibilityBox : public Ui::BoxContent {
public:
EditPeerHistoryVisibilityBox(
QWidget*,
not_null<PeerData*> peer,
FnMut<void(HistoryVisibility)> savedCallback,
HistoryVisibility historyVisibilitySavedValue);
protected:
void prepare() override;
private:
void setupContent();
not_null<PeerData*> _peer;
FnMut<void(HistoryVisibility)> _savedCallback;
HistoryVisibility _historyVisibilitySavedValue;
std::shared_ptr<Ui::RadioenumGroup<HistoryVisibility>> _historyVisibility;
};
void EditPeerHistoryVisibilityBox(
not_null<Ui::GenericBox*> box,
bool isLegacy,
Fn<void(HistoryVisibility)> savedCallback,
HistoryVisibility historyVisibilitySavedValue);

View File

@@ -37,9 +37,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/admin_log/history_admin_log_section.h"
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "mtproto/sender.h"
#include "settings/settings_common.h"
#include "ui/rp_widget.h"
#include "ui/special_buttons.h"
#include "ui/toast/toast.h"
@@ -53,22 +52,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/vertical_layout.h"
#include "window/window_session_controller.h"
#include "info/profile/info_profile_icon.h"
#include "apiwrap.h"
#include "api/api_invite_links.h"
#include "facades.h"
#include "facades.h" // Ui::showChatsList
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_info.h"
#include "styles/style_settings.h"
namespace {
auto ToPositiveNumberString() {
[[nodiscard]] auto ToPositiveNumberString() {
return rpl::map([](int count) {
return count ? QString::number(count) : QString();
});
}
auto ToPositiveNumberStringRestrictions() {
[[nodiscard]] auto ToPositiveNumberStringRestrictions() {
return rpl::map([](int count) {
return QString::number(count)
+ QString("/")
@@ -94,40 +93,29 @@ void AddButtonWithCount(
rpl::producer<QString> &&text,
rpl::producer<QString> &&count,
Fn<void()> callback,
const style::icon &icon) {
Settings::IconDescriptor &&descriptor) {
parent->add(EditPeerInfoBox::CreateButton(
parent,
std::move(text),
std::move(count),
std::move(callback),
st::manageGroupButton,
&icon));
std::move(descriptor)));
}
object_ptr<Ui::SettingsButton> CreateButtonWithText(
not_null<QWidget*> parent,
not_null<Ui::SettingsButton*> AddButtonWithText(
not_null<Ui::VerticalLayout*> parent,
rpl::producer<QString> &&text,
rpl::producer<QString> &&label,
Fn<void()> callback) {
return EditPeerInfoBox::CreateButton(
Fn<void()> callback,
Settings::IconDescriptor &&descriptor) {
return parent->add(EditPeerInfoBox::CreateButton(
parent,
std::move(text),
std::move(label),
std::move(callback),
st::manageGroupTopButtonWithText,
nullptr);
}
Ui::SettingsButton *AddButtonWithText(
not_null<Ui::VerticalLayout*> parent,
rpl::producer<QString> &&text,
rpl::producer<QString> &&label,
Fn<void()> callback) {
return parent->add(CreateButtonWithText(
parent,
std::move(text),
std::move(label),
std::move(callback)));
std::move(descriptor)));
}
void AddButtonDelete(
@@ -140,7 +128,7 @@ void AddButtonDelete(
rpl::single(QString()),
std::move(callback),
st::manageDeleteGroupButton,
nullptr));
{}));
}
void SaveDefaultRestrictions(
@@ -262,7 +250,7 @@ public:
not_null<Ui::BoxContent*> box,
not_null<PeerData*> peer);
object_ptr<Ui::VerticalLayout> createContent();
[[nodiscard]] object_ptr<Ui::VerticalLayout> createContent();
void setFocus();
private:
@@ -284,12 +272,12 @@ private:
std::optional<ChannelData*> linkedChat;
};
object_ptr<Ui::RpWidget> createPhotoAndTitleEdit();
object_ptr<Ui::RpWidget> createTitleEdit();
object_ptr<Ui::RpWidget> createPhotoEdit();
object_ptr<Ui::RpWidget> createDescriptionEdit();
object_ptr<Ui::RpWidget> createManageGroupButtons();
object_ptr<Ui::RpWidget> createStickersEdit();
[[nodiscard]] object_ptr<Ui::RpWidget> createPhotoAndTitleEdit();
[[nodiscard]] object_ptr<Ui::RpWidget> createTitleEdit();
[[nodiscard]] object_ptr<Ui::RpWidget> createPhotoEdit();
[[nodiscard]] object_ptr<Ui::RpWidget> createDescriptionEdit();
[[nodiscard]] object_ptr<Ui::RpWidget> createManageGroupButtons();
[[nodiscard]] object_ptr<Ui::RpWidget> createStickersEdit();
[[nodiscard]] bool canEditInformation() const;
[[nodiscard]] bool canEditReactions() const;
@@ -310,14 +298,14 @@ private:
void deleteWithConfirmation();
void deleteChannel();
std::optional<Saving> validate() const;
bool validateUsername(Saving &to) const;
bool validateLinkedChat(Saving &to) const;
bool validateTitle(Saving &to) const;
bool validateDescription(Saving &to) const;
bool validateHistoryVisibility(Saving &to) const;
bool validateSignatures(Saving &to) const;
bool validateForwards(Saving &to) const;
[[nodiscard]] std::optional<Saving> validate() const;
[[nodiscard]] bool validateUsername(Saving &to) const;
[[nodiscard]] bool validateLinkedChat(Saving &to) const;
[[nodiscard]] bool validateTitle(Saving &to) const;
[[nodiscard]] bool validateDescription(Saving &to) const;
[[nodiscard]] bool validateHistoryVisibility(Saving &to) const;
[[nodiscard]] bool validateSignatures(Saving &to) const;
[[nodiscard]] bool validateForwards(Saving &to) const;
void save();
void saveUsername();
@@ -522,7 +510,8 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
result->entity()->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
result->entity()->setSubmitSettings(Core::App().settings().sendSubmitWay());
result->entity()->setSubmitSettings(
Core::App().settings().sendSubmitWay());
Ui::Emoji::SuggestionsController::Init(
_wrap->window(),
result->entity(),
@@ -739,7 +728,8 @@ void Controller::fillPrivacyTypeButton() {
? tr::lng_manage_private_group_title
: tr::lng_manage_private_peer_title)();
}) | rpl::flatten_latest(),
[=] { showEditPeerTypeBox(); });
[=] { showEditPeerTypeBox(); },
{ &st::infoIconGroupType, Settings::kIconLightBlue });
_privacyTypeUpdates.fire_copy(*_privacySavedValue);
}
@@ -781,7 +771,8 @@ void Controller::fillLinkedChatButton() {
_controls.buttonsLayout,
std::move(text),
std::move(label),
[=] { showEditLinkedChatBox(); });
[=] { showEditLinkedChatBox(); },
{ &st::settingsIconChat, Settings::kIconGreen });
_linkedChatUpdates.fire_copy(*_linkedChatSavedValue);
}
//
@@ -803,13 +794,16 @@ void Controller::fillSignaturesButton() {
Expects(_controls.buttonsLayout != nullptr);
const auto channel = _peer->asChannel();
if (!channel) return;
if (!channel) {
return;
}
AddButtonWithText(
_controls.buttonsLayout,
tr::lng_edit_sign_messages(),
rpl::single(QString()),
[=] {}
[] {},
{ &st::infoIconSignature, Settings::kIconLightBlue }
)->toggleOn(rpl::single(channel->addsSignature())
)->toggledValue(
) | rpl::start_with_next([=](bool toggled) {
@@ -843,12 +837,23 @@ void Controller::fillHistoryVisibilityButton() {
_historyVisibilitySavedValue = checked;
});
const auto buttonCallback = [=] {
_navigation->parentController()->show(
Box<EditPeerHistoryVisibilityBox>(
_peer,
boxCallback,
*_historyVisibilitySavedValue),
Ui::LayerOption::KeepOther);
_peer->updateFull();
const auto canEdit = [&] {
if (const auto chat = _peer->asChat()) {
return chat->canEditPreHistoryHidden();
} else if (const auto channel = _peer->asChannel()) {
return channel->canEditPreHistoryHidden();
}
Unexpected("User in HistoryVisibilityEdit.");
}();
if (!canEdit) {
return;
}
_navigation->parentController()->show(Box(
EditPeerHistoryVisibilityBox,
_peer->isChat(),
boxCallback,
*_historyVisibilitySavedValue));
};
AddButtonWithText(
container,
@@ -859,7 +864,8 @@ void Controller::fillHistoryVisibilityButton() {
? tr::lng_manage_history_visibility_shown
: tr::lng_manage_history_visibility_hidden)();
}) | rpl::flatten_latest(),
buttonCallback);
buttonCallback,
{ &st::settingsIconChat, Settings::kIconGreen });
updateHistoryVisibility->fire_copy(*_historyVisibilitySavedValue);
@@ -970,6 +976,40 @@ void Controller::fillManageSection() {
st::editPeerTopButtonsLayoutSkipCustomBottom);
}
if (canEditReactions()) {
const auto session = &_peer->session();
auto reactionsCount = Info::Profile::MigratedOrMeValue(
_peer
) | rpl::map(
Info::Profile::AllowedReactionsCountValue
) | rpl::flatten_latest();
auto fullCount = Info::Profile::FullReactionsCountValue(session);
auto label = rpl::combine(
std::move(reactionsCount),
std::move(fullCount)
) | rpl::map([=](int allowed, int total) {
return allowed
? QString::number(allowed) + " / " + QString::number(total)
: tr::lng_manage_peer_reactions_off(tr::now);
});
const auto done = [=](const std::vector<QString> &chosen) {
SaveAllowedReactions(_peer, chosen);
};
AddButtonWithCount(
_controls.buttonsLayout,
tr::lng_manage_peer_reactions(),
std::move(label),
[=] {
_navigation->parentController()->show(Box(
EditAllowedReactionsBox,
!_peer->isBroadcast(),
session->data().reactions().list(
Data::Reactions::Type::Active),
*Data::PeerAllowedReactions(_peer),
done));
},
{ &st::infoIconReactions, Settings::kIconRed });
}
if (canEditPermissions) {
AddButtonWithCount(
_controls.buttonsLayout,
@@ -981,7 +1021,7 @@ void Controller::fillManageSection() {
) | rpl::flatten_latest(
) | ToPositiveNumberStringRestrictions(),
[=] { ShowEditPermissions(_navigation, _peer); },
st::infoIconPermissions);
{ &st::settingsIconKey, Settings::kIconGreen });
}
if (canEditInviteLinks) {
auto count = Info::Profile::MigratedOrMeValue(
@@ -1017,7 +1057,7 @@ void Controller::fillManageSection() {
0),
Ui::LayerOption::KeepOther);
},
st::infoIconInviteLinks);
{ &st::infoIconInviteLinks, Settings::kIconLightOrange });
if (_privacySavedValue) {
_privacyTypeUpdates.events_starting_with_copy(
@@ -1029,40 +1069,6 @@ void Controller::fillManageSection() {
}, wrap->lifetime());
}
}
if (canEditReactions()) {
const auto session = &_peer->session();
auto reactionsCount = Info::Profile::MigratedOrMeValue(
_peer
) | rpl::map(
Info::Profile::AllowedReactionsCountValue
) | rpl::flatten_latest();
auto fullCount = Info::Profile::FullReactionsCountValue(session);
auto label = rpl::combine(
std::move(reactionsCount),
std::move(fullCount)
) | rpl::map([=](int allowed, int total) {
return allowed
? QString::number(allowed) + " / " + QString::number(total)
: tr::lng_manage_peer_reactions_off(tr::now);
});
const auto done = [=](const std::vector<QString> &chosen) {
SaveAllowedReactions(_peer, chosen);
};
AddButtonWithCount(
_controls.buttonsLayout,
tr::lng_manage_peer_reactions(),
std::move(label),
[=] {
_navigation->parentController()->show(Box(
EditAllowedReactionsBox,
!_peer->isBroadcast(),
session->data().reactions().list(
Data::Reactions::Type::Active),
*Data::PeerAllowedReactions(_peer),
done));
},
st::infoIconReactions);
}
if (canViewAdmins) {
AddButtonWithCount(
_controls.buttonsLayout,
@@ -1079,12 +1085,14 @@ void Controller::fillManageSection() {
_peer,
ParticipantsBoxController::Role::Admins);
},
st::infoIconAdministrators);
{ &st::infoIconAdministrators, Settings::kIconLightBlue });
}
if (canViewMembers) {
AddButtonWithCount(
_controls.buttonsLayout,
(_isGroup ? tr::lng_manage_peer_members() : tr::lng_manage_peer_subscribers()),
(_isGroup
? tr::lng_manage_peer_members()
: tr::lng_manage_peer_subscribers()),
Info::Profile::MigratedOrMeValue(
_peer
) | rpl::map(
@@ -1097,7 +1105,7 @@ void Controller::fillManageSection() {
_peer,
ParticipantsBoxController::Role::Members);
},
st::infoIconMembers);
{ &st::settingsIconGroup, Settings::kIconDarkBlue });
}
fillPendingRequestsButton();
@@ -1114,7 +1122,7 @@ void Controller::fillManageSection() {
_peer,
ParticipantsBoxController::Role::Kicked);
},
st::infoIconBlacklist);
{ &st::settingsIconMinus, Settings::kIconRed });
}
if (hasRecentActions) {
auto callback = [=] {
@@ -1126,7 +1134,7 @@ void Controller::fillManageSection() {
tr::lng_manage_peer_recent_actions(),
rpl::single(QString()), //Empty count.
std::move(callback),
st::infoIconRecentActions);
{ &st::infoIconRecentActions, Settings::kIconPurple });
}
if (canEditStickers || canDeleteChannel) {
@@ -1168,7 +1176,7 @@ void Controller::fillPendingRequestsButton() {
: tr::lng_manage_peer_requests_channel()),
rpl::duplicate(pendingRequestsCount) | ToPositiveNumberString(),
[=] { RequestsBoxController::Start(_navigation, _peer); },
st::infoIconRequests);
{ &st::infoIconRequests, Settings::kIconRed });
std::move(
pendingRequestsCount
) | rpl::start_with_next([=](int count) {
@@ -1670,18 +1678,18 @@ object_ptr<Ui::SettingsButton> EditPeerInfoBox::CreateButton(
rpl::producer<QString> &&count,
Fn<void()> callback,
const style::SettingsCountButton &st,
const style::icon *icon) {
Settings::IconDescriptor &&descriptor) {
auto result = object_ptr<Ui::SettingsButton>(
parent,
rpl::duplicate(text),
st.button);
const auto button = result.data();
button->addClickHandler(callback);
if (icon) {
Ui::CreateChild<Info::Profile::FloatingIcon>(
if (descriptor) {
AddButtonIcon(
button,
*icon,
st.iconPosition);
st.button,
std::move(descriptor));
}
auto labelText = rpl::combine(

View File

@@ -7,8 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <rpl/event_stream.h>
#include "boxes/abstract_box.h"
#include "ui/layers/box_content.h"
namespace Settings {
struct IconDescriptor;
} // namespace Settings
namespace style {
struct SettingsCountButton;
@@ -42,7 +45,7 @@ public:
rpl::producer<QString> &&count,
Fn<void()> callback,
const style::SettingsCountButton &st,
const style::icon *icon = nullptr);
Settings::IconDescriptor &&descriptor);
protected:
void prepare() override;

View File

@@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "mainwindow.h"
#include "apiwrap.h"
#include "settings/settings_common.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_info.h"
@@ -612,7 +613,8 @@ void EditPeerPermissionsBox::addSuggestGigagroup(
AboutGigagroupCallback(
_peer->asChannel(),
_navigation->parentController()),
st::peerPermissionsButton));
st::peerPermissionsButton,
{}));
container->add(
object_ptr<Ui::DividerLabel>(
@@ -645,7 +647,8 @@ void EditPeerPermissionsBox::addBannedButtons(
_peer,
ParticipantsBoxController::Role::Restricted);
},
st::peerPermissionsButton));
st::peerPermissionsButton,
{}));
if (channel) {
container->add(EditPeerInfoBox::CreateButton(
container,
@@ -658,7 +661,8 @@ void EditPeerPermissionsBox::addBannedButtons(
_peer,
ParticipantsBoxController::Role::Kicked);
},
st::peerPermissionsButton));
st::peerPermissionsButton,
{}));
}
}

View File

@@ -7,92 +7,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peers/edit_peer_reactions.h"
#include "boxes/reactions_settings_box.h" // AddReactionLottieIcon
#include "data/data_message_reactions.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_peer.h"
#include "data/data_chat.h"
#include "data/data_channel.h"
#include "data/data_session.h"
#include "main/main_session.h"
#include "apiwrap.h"
#include "lottie/lottie_icon.h"
#include "lang/lang_keys.h"
#include "ui/layers/generic_box.h"
#include "ui/widgets/buttons.h"
#include "info/profile/info_profile_icon.h"
#include "settings/settings_common.h"
#include "styles/style_settings.h"
#include "styles/style_info.h"
namespace {
using Data::Reaction;
void AddReactionIcon(
not_null<Ui::RpWidget*> button,
not_null<DocumentData*> document) {
struct State {
std::shared_ptr<Data::DocumentMedia> media;
std::unique_ptr<Lottie::Icon> icon;
QImage image;
};
const auto size = st::editPeerReactionsPreview;
const auto state = button->lifetime().make_state<State>(State{
.media = document->createMediaView(),
});
const auto icon = Ui::CreateChild<Ui::RpWidget>(button.get());
icon->setAttribute(Qt::WA_TransparentForMouseEvents);
icon->resize(size, size);
button->sizeValue(
) | rpl::start_with_next([=](QSize size) {
icon->moveToLeft(
st::editPeerReactionsIconLeft,
(size.height() - icon->height()) / 2,
size.width());
}, icon->lifetime());
const auto initLottie = [=] {
state->icon = Lottie::MakeIcon({
.path = state->media->owner()->filepath(true),
.json = state->media->bytes(),
.sizeOverride = QSize(size, size),
.frame = -1,
});
state->media = nullptr;
};
state->media->checkStickerLarge();
if (state->media->loaded()) {
initLottie();
} else {
document->session().downloaderTaskFinished(
) | rpl::filter([=] {
return state->media->loaded();
}) | rpl::take(1) | rpl::start_with_next([=] {
initLottie();
icon->update();
}, icon->lifetime());
}
icon->paintRequest(
) | rpl::start_with_next([=] {
QPainter p(icon);
if (state->image.isNull() && state->icon) {
state->image = state->icon->frame();
crl::async([icon = std::move(state->icon)]{});
}
if (!state->image.isNull()) {
p.drawImage(QRect(0, 0, size, size), state->image);
}
}, icon->lifetime());
}
} // namespace
void EditAllowedReactionsBox(
not_null<Ui::GenericBox*> box,
bool isGroup,
const std::vector<Reaction> &list,
const std::vector<Data::Reaction> &list,
const base::flat_set<QString> &selected,
Fn<void(const std::vector<QString> &)> callback) {
box->setTitle(tr::lng_manage_peer_reactions());
@@ -153,9 +87,23 @@ void EditAllowedReactionsBox(
container,
rpl::single(entry.title),
st::manageGroupButton.button);
AddReactionIcon(button, entry.centerIcon
? entry.centerIcon
: entry.appearAnimation.get());
const auto iconHeight = st::editPeerReactionsPreview;
AddReactionLottieIcon(
button,
button->sizeValue(
) | rpl::map([=](const QSize &size) {
return QPoint(
st::editPeerReactionsIconLeft,
(size.height() - iconHeight) / 2);
}),
iconHeight,
entry,
button->events(
) | rpl::filter([=](not_null<QEvent*> event) {
return event->type() == QEvent::Enter;
}) | rpl::to_empty,
rpl::never<>(),
&button->lifetime());
state->toggles.emplace(entry.emoji, button);
button->toggleOn(rpl::single(
active(entry)

View File

@@ -7,14 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/layers/generic_box.h"
class PeerData;
namespace Data {
struct Reaction;
} // namespace Data
namespace Ui {
class GenericBox;
} // namespace Ui
void EditAllowedReactionsBox(
not_null<Ui::GenericBox*> box,
bool isGroup,

View File

@@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peers/edit_peer_type_box.h"
#include "apiwrap.h"
#include "api/api_invite_links.h"
#include "main/main_session.h"
#include "boxes/add_contact_box.h"
#include "ui/boxes/confirm_box.h"
@@ -19,7 +17,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peers/edit_peer_invite_link.h"
#include "boxes/peers/edit_peer_invite_links.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "core/application.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
@@ -27,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "mtproto/sender.h"
#include "ui/rp_widget.h"
#include "ui/special_buttons.h"
@@ -35,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/box_content_divider.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h"
@@ -48,11 +43,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_info.h"
#include "styles/style_settings.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QClipboard>
#include <rpl/flatten_latest.h>
namespace {
class Controller : public base::has_weak_ptr {
@@ -209,21 +199,22 @@ void Controller::createContent() {
Ui::LayerOption::KeepOther);
},
st::manageGroupButton,
&st::infoIconInviteLinks));
{ &st::infoIconInviteLinks, Settings::kIconLightOrange }));
AddSkip(_wrap.get());
AddDividerText(_wrap.get(), tr::lng_group_invite_manage_about());
if (!_linkOnly) {
AddSkip(_wrap.get());
AddSubsectionTitle(_wrap.get(), tr::lng_manage_peer_no_forwards_title());
AddSubsectionTitle(
_wrap.get(),
tr::lng_manage_peer_no_forwards_title());
_controls.noForwards = _wrap->add(EditPeerInfoBox::CreateButton(
_wrap.get(),
tr::lng_manage_peer_no_forwards(),
rpl::single(QString()),
[=] {},
st::manageGroupTopButtonWithText,
nullptr
));
[] {},
st::peerPermissionsButton,
{}));
_controls.noForwards->toggleOn(
rpl::single(_noForwardsSavedValue.value_or(false))
)->toggledValue(

View File

@@ -7,8 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "ui/layers/box_content.h"
namespace style {
struct SettingsCountButton;

View File

@@ -43,6 +43,7 @@ constexpr auto kVisibleButtonsCount = 7;
PeerId GenerateUser(not_null<History*> history, const QString &name) {
Expects(history->peer->isUser());
const auto peerId = Data::FakePeerIdForJustName(name);
history->owner().processUser(MTP_user(
MTP_flags(MTPDuser::Flag::f_first_name | MTPDuser::Flag::f_min),
@@ -125,6 +126,7 @@ void AddMessage(
controller,
crl::guard(widget, [=] { widget->update(); }));
state->style = std::make_unique<Ui::ChatStyle>();
state->style->apply(controller->defaultChatTheme().get());
state->icons.lifetimes = std::vector<rpl::lifetime>(2);
const auto history = controller->session().data().history(
@@ -215,7 +217,7 @@ void AddMessage(
iconSize = st::settingsReactionMessageSize
](const QString &emoji) {
const auto &reactions = controller->session().data().reactions();
for (const auto &r : reactions.list(Data::Reactions::Type::All)) {
for (const auto &r : reactions.list(Data::Reactions::Type::Active)) {
if (emoji != r.emoji) {
continue;
}
@@ -232,7 +234,6 @@ void AddMessage(
(rightSize.height() - iconSize) / 2);
}),
iconSize,
&controller->session(),
r,
rpl::never<>(),
rpl::duplicate(emojiValue) | rpl::skip(1) | rpl::to_empty,
@@ -249,7 +250,6 @@ void AddReactionLottieIcon(
not_null<Ui::RpWidget*> parent,
rpl::producer<QPoint> iconPositionValue,
int iconSize,
not_null<Main::Session*> session,
const Data::Reaction &reaction,
rpl::producer<> &&selects,
rpl::producer<> &&destroys,
@@ -278,7 +278,7 @@ void AddReactionLottieIcon(
state->appear.media->checkStickerLarge();
state->select.media->checkStickerLarge();
rpl::single() | rpl::then(
session->downloaderTaskFinished()
reaction.appearAnimation->session().downloaderTaskFinished()
) | rpl::start_with_next([=] {
const auto check = [&](State::Entry &entry) {
if (!entry.media) {
@@ -430,7 +430,7 @@ void ReactionsSettingsBox(
};
auto firstCheckedButton = (Ui::RpWidget*)(nullptr);
for (const auto &r : reactions.list(Data::Reactions::Type::All)) {
for (const auto &r : reactions.list(Data::Reactions::Type::Active)) {
const auto button = Settings::AddButton(
buttonsContainer,
rpl::single<QString>(base::duplicate(r.title)),
@@ -446,7 +446,6 @@ void ReactionsSettingsBox(
(s.height() - iconSize) / 2);
}),
iconSize,
&controller->session(),
r,
button->events(
) | rpl::filter([=](not_null<QEvent*> event) {

View File

@@ -16,10 +16,6 @@ namespace Window {
class SessionController;
} // namespace Window
namespace Main {
class Session;
} // namespace Main
namespace Data {
struct Reaction;
} // namespace Data
@@ -28,7 +24,6 @@ void AddReactionLottieIcon(
not_null<Ui::RpWidget*> parent,
rpl::producer<QPoint> iconPositionValue,
int iconSize,
not_null<Main::Session*> session,
const Data::Reaction &reaction,
rpl::producer<> &&selects,
rpl::producer<> &&destroys,

View File

@@ -0,0 +1,106 @@
/*
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 "boxes/report_messages_box.h"
#include "api/api_report.h"
#include "data/data_peer.h"
#include "data/data_photo.h"
#include "lang/lang_keys.h"
#include "ui/boxes/report_box.h"
#include "ui/layers/generic_box.h"
#include "window/window_session_controller.h"
namespace {
[[nodiscard]] object_ptr<Ui::BoxContent> Report(
not_null<PeerData*> peer,
std::variant<v::null_t, MessageIdsList, not_null<PhotoData*>> data) {
const auto source = v::match(data, [](const MessageIdsList &ids) {
return Ui::ReportSource::Message;
}, [](not_null<PhotoData*> photo) {
return photo->hasVideo()
? Ui::ReportSource::ProfileVideo
: Ui::ReportSource::ProfilePhoto;
}, [](v::null_t) {
Unexpected("Bad source report.");
return Ui::ReportSource::Bot;
});
return Box([=](not_null<Ui::GenericBox*> box) {
Ui::ReportReasonBox(box, source, [=](Ui::ReportReason reason) {
Ui::BoxShow(box).showBox(Box([=](not_null<Ui::GenericBox*> box) {
const auto show = Ui::BoxShow(box);
Ui::ReportDetailsBox(box, [=](const QString &text) {
const auto toastParent = show.toastParent();
Api::SendReport(toastParent, peer, reason, text, data);
show.hideLayer();
});
}));
});
});
}
} // namespace
object_ptr<Ui::BoxContent> ReportItemsBox(
not_null<PeerData*> peer,
MessageIdsList ids) {
return Report(peer, ids);
}
object_ptr<Ui::BoxContent> ReportProfilePhotoBox(
not_null<PeerData*> peer,
not_null<PhotoData*> photo) {
return Report(peer, photo);
}
void ShowReportPeerBox(
not_null<Window::SessionController*> window,
not_null<PeerData*> peer) {
struct State {
QPointer<Ui::BoxContent> reasonBox;
QPointer<Ui::BoxContent> detailsBox;
MessageIdsList ids;
};
const auto state = std::make_shared<State>();
const auto chosen = [=](Ui::ReportReason reason) {
const auto send = [=](const QString &text) {
window->clearChooseReportMessages();
Api::SendReport(
Window::Show(window).toastParent(),
peer,
reason,
text,
std::move(state->ids));
if (const auto strong = state->reasonBox.data()) {
strong->closeBox();
}
if (const auto strong = state->detailsBox.data()) {
strong->closeBox();
}
};
if (reason == Ui::ReportReason::Fake
|| reason == Ui::ReportReason::Other) {
state->ids = {};
state->detailsBox = window->show(Box(Ui::ReportDetailsBox, send));
return;
}
window->showChooseReportMessages(peer, reason, [=](
MessageIdsList ids) {
state->ids = std::move(ids);
state->detailsBox = window->show(Box(Ui::ReportDetailsBox, send));
});
};
state->reasonBox = window->show(Box(
Ui::ReportReasonBox,
(peer->isBroadcast()
? Ui::ReportSource::Channel
: peer->isUser()
? Ui::ReportSource::Bot
: Ui::ReportSource::Group),
chosen));
}

View File

@@ -0,0 +1,31 @@
/*
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
template <typename Object>
class object_ptr;
namespace Ui {
class BoxContent;
} // namespace Ui
namespace Window {
class SessionController;
} // namespace Main
class PeerData;
[[nodiscard]] object_ptr<Ui::BoxContent> ReportItemsBox(
not_null<PeerData*> peer,
MessageIdsList ids);
[[nodiscard]] object_ptr<Ui::BoxContent> ReportProfilePhotoBox(
not_null<PeerData*> peer,
not_null<PhotoData*> photo);
void ShowReportPeerBox(
not_null<Window::SessionController*> window,
not_null<PeerData*> peer);

View File

@@ -1065,6 +1065,7 @@ void GroupCall::start(TimeId scheduleDate, bool rtmp) {
MTPstring(), // title
MTP_int(scheduleDate)
)).done([=](const MTPUpdates &result) {
_reloadedStaleCall = true;
_acceptFields = true;
_peer->session().api().applyUpdates(result);
_acceptFields = false;
@@ -1393,6 +1394,13 @@ void GroupCall::rejoin(not_null<PeerData*> as) {
sendSelfUpdate(SendUpdateType::CameraPaused);
}
sendPendingSelfUpdates();
if (!_reloadedStaleCall
&& _state.current() != State::Joining) {
if (const auto real = lookupReal()) {
_reloadedStaleCall = true;
real->reloadIfStale();
}
}
}).fail([=](const MTP::Error &error) {
_joinState.finish();

View File

@@ -674,6 +674,7 @@ private:
bool _hadJoinedState = false;
bool _listenersHidden = false;
bool _rtmp = false;
bool _reloadedStaleCall = false;
int _rtmpVolume = 0;
std::unique_ptr<Webrtc::MediaDevices> _mediaDevices;

View File

@@ -176,7 +176,7 @@ void MentionClickHandler::onClick(ClickContext context) const {
using Info = Window::SessionNavigation::PeerByLinkInfo;
m->controller()->showPeerByLink(Info{
.usernameOrId = _tag.mid(1),
.messageId = ShowAtProfileMsgId
.resolveType = Window::ResolveType::Mention,
});
}
}

View File

@@ -239,8 +239,9 @@ QByteArray Settings::serialize() const {
}
stream
<< qint32(_hardwareAcceleratedVideo ? 1 : 0)
<< qint32(_chatQuickAction);
<< qint32(0) // old hardwareAcceleratedVideo
<< qint32(_chatQuickAction)
<< qint32(_hardwareAcceleratedVideo ? 1 : 0);
}
return result;
}
@@ -514,11 +515,15 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
}
}
if (!stream.atEnd()) {
stream >> hardwareAcceleratedVideo;
qint32 legacyHardwareAcceleratedVideo = 0;
stream >> legacyHardwareAcceleratedVideo;
}
if (!stream.atEnd()) {
stream >> chatQuickAction;
}
if (!stream.atEnd()) {
stream >> hardwareAcceleratedVideo;
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for Core::Settings::constructFromSerialized()"));

View File

@@ -792,7 +792,11 @@ private:
rpl::variable<Media::Player::OrderMode> _playerOrderMode;
bool _macWarnBeforeQuit = true;
std::vector<uint64> _accountsOrder;
#ifdef Q_OS_MAC
bool _hardwareAcceleratedVideo = true;
#else // Q_OS_MAC
bool _hardwareAcceleratedVideo = false;
#endif // Q_OS_MAC
HistoryView::DoubleClickQuickAction _chatQuickAction =
HistoryView::DoubleClickQuickAction();

View File

@@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtGui/QDesktopServices>
#include <QtCore/QStandardPaths>
#include <QtCore/QTimer>
#include <qpa/qplatformscreen.h>
namespace {
@@ -43,7 +44,18 @@ PreLaunchWindow::PreLaunchWindow(QString title) {
p.setColor(QPalette::Window, QColor(255, 255, 255));
setPalette(p);
_size = QFontMetrics(QGuiApplication::font()).height();
constexpr auto processDpi = [](const QDpi &dpi) {
return (dpi.first + dpi.second) * 0.5;
};
const auto screen = QGuiApplication::primaryScreen();
const auto scale = processDpi(screen->handle()->logicalDpi())
/ processDpi(screen->handle()->logicalBaseDpi());
auto font = QGuiApplication::font();
font.setPixelSize(base::SafeRound(font.pointSize() * scale));
_size = QFontMetrics(font).height();
int paddingVertical = (_size / 2);
int paddingHorizontal = _size;

View File

@@ -330,22 +330,21 @@ bool ResolveUsernameOrPhone(
} else if (!validDomain(domain) && !validPhone(phone)) {
return false;
}
using BotStartType = Window::BotStartType;
auto startType = BotStartType::None;
using ResolveType = Window::ResolveType;
auto resolveType = ResolveType::Default;
auto startToken = params.value(u"start"_q);
if (!startToken.isEmpty()) {
startType = BotStartType::Personal;
resolveType = ResolveType::BotStart;
} else if (params.contains(u"startgroup"_q)) {
startType = BotStartType::Group;
resolveType = ResolveType::AddToGroup;
startToken = params.value(u"startgroup"_q);
} else if (params.contains(u"startchannel"_q)) {
startType = BotStartType::Channel;
resolveType = ResolveType::AddToChannel;
}
auto post = ShowAtUnreadMsgId;
auto adminRights = ChatAdminRights();
if (startType == BotStartType::Group
|| startType == BotStartType::Channel) {
post = ShowAtProfileMsgId;
if (resolveType == ResolveType::AddToGroup
|| resolveType == ResolveType::AddToChannel) {
adminRights = ParseRequestedAdminRights(params.value(u"admin"_q));
}
const auto postParam = params.value(qsl("post"));
@@ -359,8 +358,7 @@ bool ResolveUsernameOrPhone(
const auto gameParam = params.value(qsl("game"));
if (!gameParam.isEmpty() && validDomain(gameParam)) {
startToken = gameParam;
post = ShowAtProfileMsgId;
startType = BotStartType::ShareGame;
resolveType = ResolveType::ShareGame;
}
const auto fromMessageId = context.value<ClickHandlerContext>().itemId;
using Navigation = Window::SessionNavigation;
@@ -377,7 +375,7 @@ bool ResolveUsernameOrPhone(
Navigation::ThreadId{ threadId }
}
: Navigation::RepliesByLinkInfo{ v::null },
.startType = startType,
.resolveType = resolveType,
.startToken = startToken,
.startAdminRights = adminRights,
.attachBotUsername = params.value(u"attach"_q),

View File

@@ -219,8 +219,8 @@ void Sandbox::launchApplication() {
}
void Sandbox::setupScreenScale() {
const auto processDpi = [](const QDpi &dpi) {
return (dpi.first + dpi.second) * qreal(0.5);
constexpr auto processDpi = [](const QDpi &dpi) {
return (dpi.first + dpi.second) * 0.5;
};
const auto dpi = processDpi(
Sandbox::primaryScreen()->handle()->logicalDpi());

View File

@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Telegram Desktop"_cs;
constexpr auto AppFile = "Telegram"_cs;
constexpr auto AppVersion = 3006003;
constexpr auto AppVersionStr = "3.6.3";
constexpr auto AppBetaVersion = true;
constexpr auto AppVersion = 3007003;
constexpr auto AppVersionStr = "3.7.3";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View File

@@ -208,4 +208,8 @@ UpdatedFileReferences GetFileReferences(
return GetFileReferencesHelper(data);
}
UpdatedFileReferences GetFileReferences(const MTPMessageMedia &data) {
return GetFileReferencesHelper(data);
}
} // namespace Data

View File

@@ -179,4 +179,7 @@ UpdatedFileReferences GetFileReferences(const MTPTheme &data);
UpdatedFileReferences GetFileReferences(
const MTPaccount_SavedRingtones &data);
// Admin Log Event.
UpdatedFileReferences GetFileReferences(const MTPMessageMedia &data);
} // namespace Data

View File

@@ -26,6 +26,7 @@ constexpr auto kRequestPerPage = 50;
constexpr auto kSpeakingAfterActive = crl::time(6000);
constexpr auto kActiveAfterJoined = crl::time(1000);
constexpr auto kWaitForUpdatesTimeout = 3 * crl::time(1000);
constexpr auto kReloadStaleTimeout = 16 * crl::time(1000);
[[nodiscard]] QString ExtractNextOffset(const MTPphone_GroupCall &call) {
return call.match([&](const MTPDphone_groupCall &data) {
@@ -168,6 +169,7 @@ bool GroupCall::processSavedFullCall() {
return false;
}
_reloadRequestId = 0;
_reloadLastFinished = crl::now();
processFullCallFields(*base::take(_savedFull));
return true;
}
@@ -497,6 +499,15 @@ void GroupCall::computeParticipantsCount() {
: std::max(int(_participants.size()), _serverParticipantsCount);
}
void GroupCall::reloadIfStale() {
if (!fullCount() && !participantsLoaded()) {
reload();
} else if (!_reloadLastFinished
|| crl::now() > _reloadLastFinished + kReloadStaleTimeout) {
reload();
}
}
void GroupCall::reload() {
if (_reloadRequestId || _applyingQueuedUpdates) {
return;
@@ -528,9 +539,11 @@ void GroupCall::reload() {
return;
}
_reloadRequestId = 0;
_reloadLastFinished = crl::now();
processFullCall(result);
}).fail([=] {
_reloadRequestId = 0;
_reloadLastFinished = crl::now();
}).send();
}

View File

@@ -156,6 +156,7 @@ public:
void setInCall();
void reload();
void reloadIfStale();
void processFullCall(const MTPphone_GroupCall &call);
void setJoinMutedLocally(bool muted);
@@ -206,6 +207,7 @@ private:
int _version = 0;
mtpRequestId _participantsRequestId = 0;
mtpRequestId _reloadRequestId = 0;
crl::time _reloadLastFinished = 0;
rpl::variable<QString> _title;
base::flat_multi_map<

View File

@@ -82,7 +82,6 @@ constexpr auto ShowAtUnreadMsgId = MsgId(0);
constexpr auto SpecialMsgIdShift = EndClientMsgId.bare;
constexpr auto ShowAtTheEndMsgId = MsgId(SpecialMsgIdShift + 1);
constexpr auto SwitchAtTopMsgId = MsgId(SpecialMsgIdShift + 2);
constexpr auto ShowAtProfileMsgId = MsgId(SpecialMsgIdShift + 3);
constexpr auto ShowAndStartBotMsgId = MsgId(SpecialMsgIdShift + 4);
constexpr auto ShowForChooseMessagesMsgId = MsgId(SpecialMsgIdShift + 6);

View File

@@ -81,9 +81,11 @@ style::color PeerUserpicColor(PeerId peerId) {
}
PeerId FakePeerIdForJustName(const QString &name) {
return peerFromUser(name.isEmpty()
constexpr auto kShift = (0xFEULL << 32);
const auto base = name.isEmpty()
? 777
: base::crc32(name.constData(), name.size() * sizeof(QChar)));
: base::crc32(name.constData(), name.size() * sizeof(QChar));
return peerFromUser(kShift + std::abs(base));
}
bool UpdateBotCommands(

View File

@@ -86,6 +86,8 @@ void PremultiplyLine(uchar *dst, const uchar *src, int intsCount) {
}
[[nodiscard]] bool InitHw(AVCodecContext *context, AVHWDeviceType type) {
AVCodecContext *parent = static_cast<AVCodecContext*>(context->opaque);
auto hwDeviceContext = (AVBufferRef*)nullptr;
AvErrorWrap error = av_hwdevice_ctx_create(
&hwDeviceContext,
@@ -101,11 +103,13 @@ void PremultiplyLine(uchar *dst, const uchar *src, int intsCount) {
"Trying \"%1\" hardware acceleration for \"%2\" decoder."
).arg(av_hwdevice_get_type_name(type)
).arg(context->codec->name));
if (context->hw_device_ctx) {
av_buffer_unref(&context->hw_device_ctx);
if (parent->hw_device_ctx) {
av_buffer_unref(&parent->hw_device_ctx);
}
context->hw_device_ctx = av_buffer_ref(hwDeviceContext);
parent->hw_device_ctx = av_buffer_ref(hwDeviceContext);
av_buffer_unref(&hwDeviceContext);
context->hw_device_ctx = parent->hw_device_ctx;
return true;
}
@@ -294,6 +298,7 @@ CodecPointer MakeCodecPointer(CodecDescriptor descriptor) {
if (descriptor.hwAllowed) {
context->get_format = GetHwFormat;
context->opaque = context;
} else {
DEBUG_LOG(("Video Info: Using software \"%2\" decoder."
).arg(codec->name));

View File

@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_chat_participants.h"
#include "api/api_text_entities.h"
#include "data/data_channel.h"
#include "data/data_file_origin.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "lang/lang_keys.h"
@@ -136,6 +137,18 @@ bool MediaCanHaveCaption(const MTPMessage &message) {
|| (mediaType == mtpc_messageMediaPhoto);
}
uint64 MediaId(const MTPMessage &message) {
if (!MediaCanHaveCaption(message)) {
return 0;
}
const auto &media = message.c_message().vmedia();
return media
? v::match(
Data::GetFileReferences(*media).data.begin()->first,
[](const auto &d) { return d.id; })
: 0;
}
TextWithEntities ExtractEditedText(
not_null<Main::Session*> session,
const MTPMessage &message) {
@@ -868,22 +881,36 @@ void GenerateItems(
const auto newValue = ExtractEditedText(
session,
action.vnew_message());
auto oldValue = ExtractEditedText(
session,
action.vprev_message());
const auto canHaveCaption = MediaCanHaveCaption(
action.vnew_message());
const auto changedCaption = (newValue != oldValue);
const auto changedMedia = MediaId(action.vnew_message())
!= MediaId(action.vprev_message());
const auto removedCaption = !oldValue.text.isEmpty()
&& newValue.text.isEmpty();
const auto text = (!canHaveCaption
? tr::lng_admin_log_edited_message
: newValue.text.isEmpty()
: (changedMedia && removedCaption)
? tr::lng_admin_log_edited_media_and_removed_caption
: (changedMedia && changedCaption)
? tr::lng_admin_log_edited_media_and_caption
: changedMedia
? tr::lng_admin_log_edited_media
: removedCaption
? tr::lng_admin_log_removed_caption
: tr::lng_admin_log_edited_caption)(
: changedCaption
? tr::lng_admin_log_edited_caption
: tr::lng_admin_log_edited_message)(
tr::now,
lt_from,
fromLinkText,
Ui::Text::WithEntities);
addSimpleServiceMessage(text);
auto oldValue = ExtractEditedText(
session,
action.vprev_message());
const auto detachExistingItem = false;
const auto body = history->createItem(
history->nextNonHistoryEntryId(),

View File

@@ -47,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/notifications_manager.h"
#include "boxes/about_sponsored_box.h"
#include "boxes/delete_messages_box.h"
#include "boxes/report_messages_box.h"
#include "boxes/sticker_set_box.h"
#include "chat_helpers/message_field.h"
#include "chat_helpers/emoji_interactions.h"
@@ -1874,10 +1875,13 @@ void HistoryInner::toggleFavoriteReaction(not_null<Element*> view) const {
if (allowed && !allowed->contains(favorite)) {
return;
}
view->data()->toggleReaction(favorite);
if (const auto top = itemTop(view); top >= 0) {
view->animateReaction({ .emoji = favorite });
const auto item = view->data();
if (item->chosenReaction() != favorite) {
if (const auto top = itemTop(view); top >= 0) {
view->animateReaction({ .emoji = favorite });
}
}
item->toggleReaction(favorite);
}
void HistoryInner::contextMenuEvent(QContextMenuEvent *e) {
@@ -2244,7 +2248,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu,
poll,
item,
HistoryView::Context::History);
HistoryView::Context::History,
_controller);
} else if (const auto contact = media->sharedContact()) {
const auto phone = contact->phoneNumber;
_menu->addAction(tr::lng_profile_copy_phone(tr::now), [=] {
@@ -3861,17 +3866,17 @@ void HistoryInner::deleteAsGroup(FullMsgId itemId) {
}
void HistoryInner::reportItem(FullMsgId itemId) {
HistoryView::ShowReportItemsBox(_peer, { 1, itemId });
_controller->show(ReportItemsBox(_peer, { 1, itemId }));
}
void HistoryInner::reportAsGroup(FullMsgId itemId) {
if (const auto item = session().data().message(itemId)) {
const auto group = session().data().groups().find(item);
HistoryView::ShowReportItemsBox(
_controller->show(ReportItemsBox(
_peer,
(group
? session().data().itemsToIds(group->items)
: MessageIdsList{ 1, itemId }));
: MessageIdsList{ 1, itemId })));
}
}

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_editing.h"
#include "api/api_bot.h"
#include "api/api_chat_participants.h"
#include "api/api_report.h"
#include "api/api_sending.h"
#include "api/api_text_entities.h"
#include "api/api_send_progress.h"
@@ -3877,19 +3878,18 @@ void HistoryWidget::reportSelectedMessages() {
const auto ids = _list->getSelectedItems();
const auto peer = _peer;
const auto reason = _chooseForReport->reason;
const auto box = std::make_shared<QPointer<Ui::GenericBox>>();
const auto weak = Ui::MakeWeak(_list.data());
const auto send = [=](const QString &text) {
if (weak) {
clearSelected();
controller()->clearChooseReportMessages();
}
HistoryView::SendReport(peer, reason, text, ids);
if (*box) {
(*box)->closeBox();
}
};
*box = controller()->window().show(Box(Ui::ReportDetailsBox, send));
controller()->window().show(Box([=](not_null<Ui::GenericBox*> box) {
Ui::ReportDetailsBox(box, [=](const QString &text) {
if (weak) {
clearSelected();
controller()->clearChooseReportMessages();
}
const auto toastParent = Window::Show(controller()).toastParent();
Api::SendReport(toastParent, peer, reason, text, ids);
box->closeBox();
});
}));
}
History *HistoryWidget::history() const {
@@ -4464,6 +4464,8 @@ bool HistoryWidget::updateCmdStartShown() {
? tr::lng_bot_menu_button()
: rpl::single(_botMenuButtonText)),
st::historyBotMenuButton);
orderWidgets();
_botMenuButton->setTextTransform(
Ui::RoundButton::TextTransform::NoTransform);
_botMenuButton->setFullRadius(true);
@@ -6386,25 +6388,28 @@ void HistoryWidget::checkPinnedBarState() {
auto barContent = HistoryView::PinnedBarContent(
&session(),
_pinnedTracker->shownMessageId());
_pinnedBar = std::make_unique<Ui::PinnedBar>(
this,
std::move(barContent));
Info::Profile::SharedMediaCountValue(
_peer,
nullptr,
Storage::SharedMediaType::Pinned
) | rpl::distinct_until_changed(
) | rpl::map([=](int count) {
if (_pinnedClickedId) {
_pinnedClickedId = FullMsgId();
_minPinnedId = std::nullopt;
updatePinnedViewer();
}
return (count > 1);
}) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](bool many) {
refreshPinnedBarButton(many);
_pinnedBar = std::make_unique<Ui::PinnedBar>(this);
rpl::combine(
Info::Profile::SharedMediaCountValue(
_peer,
nullptr,
Storage::SharedMediaType::Pinned
) | rpl::distinct_until_changed(
) | rpl::map([=](int count) {
if (_pinnedClickedId) {
_pinnedClickedId = FullMsgId();
_minPinnedId = std::nullopt;
updatePinnedViewer();
}
return (count > 1);
}) | rpl::distinct_until_changed(),
HistoryView::PinnedBarItemWithReplyMarkup(
&session(),
_pinnedTracker->shownMessageId())
) | rpl::start_with_next([=](bool many, HistoryItem *item) {
refreshPinnedBarButton(many, item);
}, _pinnedBar->lifetime());
_pinnedBar->setContent(std::move(barContent));
controller()->adaptive().oneColumnValue(
) | rpl::start_with_next([=](bool one) {
@@ -6491,7 +6496,30 @@ void HistoryWidget::setChooseReportMessagesDetails(
}
}
void HistoryWidget::refreshPinnedBarButton(bool many) {
void HistoryWidget::refreshPinnedBarButton(bool many, HistoryItem *item) {
if (const auto replyMarkup = item ? item->inlineReplyMarkup() : nullptr) {
const auto &rows = replyMarkup->data.rows;
if ((rows.size() == 1) && (rows.front().size() == 1)) {
const auto text = rows.front().front().text;
if (!text.isEmpty()) {
auto button = object_ptr<Ui::RoundButton>(
this,
rpl::single(text),
st::historyPinnedBotButton);
button->setTextTransform(
Ui::RoundButton::TextTransform::NoTransform);
button->setFullRadius(true);
button->setClickedCallback([=] {
App::activateBotCommand(controller(), item, 0, 0);
});
if (button->width() > st::historyPinnedBotButtonMaxWidth) {
button->setFullWidth(st::historyPinnedBotButtonMaxWidth);
}
_pinnedBar->setRightButton(std::move(button));
return;
}
}
}
const auto close = !many;
auto button = object_ptr<Ui::IconButton>(
this,

View File

@@ -512,7 +512,7 @@ private:
void updatePinnedViewer();
void setupPinnedTracker();
void checkPinnedBarState();
void refreshPinnedBarButton(bool many);
void refreshPinnedBarButton(bool many, HistoryItem *item);
void checkLastPinnedClickedIdReset(
int wasScrollTop,
int nowScrollTop);

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_attached_stickers.h"
#include "api/api_editing.h"
#include "api/api_polls.h"
#include "api/api_report.h"
#include "api/api_ringtones.h"
#include "api/api_who_reacted.h"
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
@@ -34,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "menu/menu_send.h"
#include "ui/boxes/confirm_box.h"
#include "boxes/delete_messages_box.h"
#include "boxes/report_messages_box.h"
#include "boxes/sticker_set_box.h"
#include "data/data_photo.h"
#include "data/data_photo_media.h"
@@ -54,11 +56,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_session_controller.h"
#include "lang/lang_keys.h"
#include "core/application.h"
#include "mainwidget.h"
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "apiwrap.h"
#include "facades.h"
#include "facades.h" // LambdaDelayed
#include "styles/style_chat.h"
#include "styles/style_menu_icons.h"
@@ -806,11 +807,11 @@ void AddReportAction(
const auto callback = crl::guard(controller, [=] {
if (const auto item = owner->message(itemId)) {
const auto group = owner->groups().find(item);
ShowReportItemsBox(
controller->show(ReportItemsBox(
item->history()->peer,
(group
? owner->itemsToIds(group->items)
: MessageIdsList{ 1, itemId }));
: MessageIdsList{ 1, itemId })));
}
});
menu->addAction(
@@ -960,7 +961,8 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
} else if (lnkDocument) {
AddDocumentActions(result, lnkDocument, item, list);
} else if (poll) {
AddPollActions(result, poll, item, list->elementContext());
const auto context = list->elementContext();
AddPollActions(result, poll, item, context, list->controller());
} else if (!request.overSelection && view && !hasSelection) {
const auto owner = &view->data()->history()->owner();
const auto media = view->media();
@@ -1034,26 +1036,12 @@ void CopyPostLink(
: tr::lng_context_about_private_link(tr::now));
}
void StopPoll(not_null<Main::Session*> session, FullMsgId itemId) {
const auto stop = [=] {
Ui::hideLayer();
if (const auto item = session->data().message(itemId)) {
session->api().polls().close(item);
}
};
Ui::show(Ui::MakeConfirmBox({
.text = tr::lng_polls_stop_warning(),
.confirmed = stop,
.confirmText = tr::lng_polls_stop_sure(),
.cancelText = tr::lng_cancel(),
}));
}
void AddPollActions(
not_null<Ui::PopupMenu*> menu,
not_null<PollData*> poll,
not_null<HistoryItem*> item,
Context context) {
Context context,
not_null<Window::SessionController*> controller) {
if ((context != Context::History)
&& (context != Context::Replies)
&& (context != Context::Pinned)) {
@@ -1070,7 +1058,17 @@ void AddPollActions(
}
if (item->canStopPoll()) {
menu->addAction(tr::lng_polls_stop(tr::now), [=] {
StopPoll(&poll->session(), itemId);
controller->show(Ui::MakeConfirmBox({
.text = tr::lng_polls_stop_warning(),
.confirmed = [=](Fn<void()> &&close) {
close();
if (const auto item = poll->owner().message(itemId)) {
controller->session().api().polls().close(item);
}
},
.confirmText = tr::lng_polls_stop_sure(),
.cancelText = tr::lng_cancel(),
}));
}, &st::menuIconStopPoll);
}
}
@@ -1204,108 +1202,4 @@ void ShowWhoReactedMenu(
}, lifetime);
}
void ShowReportItemsBox(not_null<PeerData*> peer, MessageIdsList ids) {
const auto chosen = [=](Ui::ReportReason reason) {
Ui::show(Box(Ui::ReportDetailsBox, [=](const QString &text) {
SendReport(peer, reason, text, ids);
Ui::hideLayer();
}));
};
Ui::show(Box(
Ui::ReportReasonBox,
Ui::ReportSource::Message,
chosen));
}
void ShowReportPeerBox(
not_null<Window::SessionController*> window,
not_null<PeerData*> peer) {
struct State {
QPointer<Ui::GenericBox> reasonBox;
QPointer<Ui::GenericBox> detailsBox;
MessageIdsList ids;
};
const auto state = std::make_shared<State>();
const auto chosen = [=](Ui::ReportReason reason) {
const auto send = [=](const QString &text) {
window->clearChooseReportMessages();
SendReport(peer, reason, text, std::move(state->ids));
if (const auto strong = state->reasonBox.data()) {
strong->closeBox();
}
if (const auto strong = state->detailsBox.data()) {
strong->closeBox();
}
};
if (reason == Ui::ReportReason::Fake
|| reason == Ui::ReportReason::Other) {
state->ids = {};
state->detailsBox = window->window().show(
Box(Ui::ReportDetailsBox, send));
return;
}
window->showChooseReportMessages(peer, reason, [=](
MessageIdsList ids) {
state->ids = std::move(ids);
state->detailsBox = window->window().show(
Box(Ui::ReportDetailsBox, send));
});
};
state->reasonBox = window->window().show(Box(
Ui::ReportReasonBox,
(peer->isBroadcast()
? Ui::ReportSource::Channel
: peer->isUser()
? Ui::ReportSource::Bot
: Ui::ReportSource::Group),
chosen));
}
void SendReport(
not_null<PeerData*> peer,
Ui::ReportReason reason,
const QString &comment,
MessageIdsList ids) {
const auto apiReason = [&] {
using Reason = Ui::ReportReason;
switch (reason) {
case Reason::Spam: return MTP_inputReportReasonSpam();
case Reason::Fake: return MTP_inputReportReasonFake();
case Reason::Violence: return MTP_inputReportReasonViolence();
case Reason::ChildAbuse: return MTP_inputReportReasonChildAbuse();
case Reason::Pornography: return MTP_inputReportReasonPornography();
case Reason::Copyright: return MTP_inputReportReasonCopyright();
case Reason::IllegalDrugs:
return MTP_inputReportReasonIllegalDrugs();
case Reason::PersonalDetails:
return MTP_inputReportReasonPersonalDetails();
case Reason::Other: return MTP_inputReportReasonOther();
}
Unexpected("Bad reason group value.");
}();
if (ids.empty()) {
peer->session().api().request(MTPaccount_ReportPeer(
peer->input,
apiReason,
MTP_string(comment)
)).done([=] {
Ui::Toast::Show(tr::lng_report_thanks(tr::now));
}).send();
} else {
auto apiIds = QVector<MTPint>();
apiIds.reserve(ids.size());
for (const auto &fullId : ids) {
apiIds.push_back(MTP_int(fullId.msg));
}
peer->session().api().request(MTPmessages_Report(
peer->input,
MTP_vector<MTPint>(apiIds),
apiReason,
MTP_string(comment)
)).done([=] {
Ui::Toast::Show(tr::lng_report_thanks(tr::now));
}).send();
}
}
} // namespace HistoryView

View File

@@ -54,12 +54,12 @@ void CopyPostLink(
not_null<Main::Session*> session,
FullMsgId itemId,
Context context);
void StopPoll(not_null<Main::Session*> session, FullMsgId itemId);
void AddPollActions(
not_null<Ui::PopupMenu*> menu,
not_null<PollData*> poll,
not_null<HistoryItem*> item,
Context context);
Context context,
not_null<Window::SessionController*> controller);
void AddSaveSoundForNotifications(
not_null<Ui::PopupMenu*> menu,
not_null<HistoryItem*> item,
@@ -79,14 +79,4 @@ void ShowWhoReactedMenu(
not_null<Window::SessionController*> controller,
rpl::lifetime &lifetime);
void ShowReportItemsBox(not_null<PeerData*> peer, MessageIdsList ids);
void ShowReportPeerBox(
not_null<Window::SessionController*> window,
not_null<PeerData*> peer);
void SendReport(
not_null<PeerData*> peer,
Ui::ReportReason reason,
const QString &comment,
MessageIdsList ids = {});
} // namespace HistoryView

View File

@@ -364,9 +364,8 @@ rpl::producer<Ui::GroupCallBarContent> GroupCallBarContentByPeer(
-> rpl::producer<Ui::GroupCallBarContent> {
if (!call) {
return rpl::single(Ui::GroupCallBarContent{ .shown = false });
} else if (!call->fullCount() && !call->participantsLoaded()) {
call->reload();
}
call->reloadIfStale();
return GroupCallBarContentByCall(call, userpicSize);
}) | rpl::flatten_latest();
}

View File

@@ -1243,6 +1243,11 @@ bool ListWidget::hasCopyRestrictionForSelected() const {
if (hasCopyRestriction()) {
return true;
}
if (_selected.empty()) {
if (_selectedTextItem && _selectedTextItem->forbidsForward()) {
return true;
}
}
for (const auto &[itemId, selection] : _selected) {
if (const auto item = session().data().message(itemId)) {
if (item->forbidsForward()) {
@@ -1254,6 +1259,11 @@ bool ListWidget::hasCopyRestrictionForSelected() const {
}
bool ListWidget::showCopyRestrictionForSelected() {
if (_selected.empty()) {
if (_selectedTextItem && showCopyRestriction(_selectedTextItem)) {
return true;
}
}
for (const auto &[itemId, selection] : _selected) {
if (showCopyRestriction(session().data().message(itemId))) {
return true;
@@ -2108,10 +2118,13 @@ void ListWidget::toggleFavoriteReaction(not_null<Element*> view) const {
if (allowed && !allowed->contains(favorite)) {
return;
}
view->data()->toggleReaction(favorite);
if (const auto top = itemTop(view); top >= 0) {
view->animateReaction({ .emoji = favorite });
const auto item = view->data();
if (item->chosenReaction() != favorite) {
if (const auto top = itemTop(view); top >= 0) {
view->animateReaction({ .emoji = favorite });
}
}
item->toggleReaction(favorite);
}
void ListWidget::trySwitchToWordSelection() {

View File

@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_pinned_tracker.h"
#include "history/history_item.h"
#include "history/history.h"
#include "base/weak_ptr.h"
#include "apiwrap.h"
#include "styles/style_chat.h"
@@ -154,4 +155,66 @@ rpl::producer<Ui::MessageBarContent> PinnedBarContent(
}) | rpl::flatten_latest();
}
rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
not_null<Main::Session*> session,
rpl::producer<PinnedId> id) {
return rpl::make_producer<HistoryItem*>([=,
id = std::move(id)](auto consumer) {
auto lifetime = rpl::lifetime();
consumer.put_next(nullptr);
struct State {
bool hasReplyMarkup = false;
base::has_weak_ptr guard;
rpl::lifetime lifetime;
FullMsgId resolvedId;
};
const auto state = lifetime.make_state<State>();
const auto pushUnique = [=](not_null<HistoryItem*> item) {
const auto replyMarkup = item->inlineReplyMarkup();
if (!state->hasReplyMarkup && !replyMarkup) {
return;
}
state->hasReplyMarkup = (replyMarkup != nullptr);
consumer.put_next(item.get());
};
rpl::duplicate(
id
) | rpl::filter([=](PinnedId current) {
return current.message && (current.message != state->resolvedId);
}) | rpl::start_with_next([=](PinnedId current) {
const auto fullId = current.message;
state->lifetime.destroy();
state->resolvedId = fullId;
invalidate_weak_ptrs(&state->guard);
const auto messageFlag = [=](not_null<HistoryItem*> item) {
using Update = Data::MessageUpdate;
session->changes().messageFlagsValue(
item,
Update::Flag::ReplyMarkup
) | rpl::start_with_next([=](const Update &update) {
pushUnique(update.item);
}, state->lifetime);
};
if (const auto item = session->data().message(fullId)) {
messageFlag(item);
return;
}
const auto resolved = crl::guard(&state->guard, [=] {
if (const auto item = session->data().message(fullId)) {
messageFlag(item);
}
});
session->api().requestMessageData(
session->data().peer(fullId.peer),
fullId.msg,
resolved);
}, lifetime);
return lifetime;
});
}
} // namespace HistoryView

View File

@@ -49,4 +49,8 @@ struct PinnedId {
not_null<Main::Session*> session,
rpl::producer<PinnedId> id);
[[nodiscard]] rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
not_null<Main::Session*> session,
rpl::producer<PinnedId> id);
} // namespace HistoryView

View File

@@ -388,7 +388,8 @@ void RepliesWidget::setupRootView() {
) | rpl::map([=](Ui::MessageBarContent &&content, bool shown) {
return shown ? std::move(content) : Ui::MessageBarContent();
});
_rootView = std::make_unique<Ui::PinnedBar>(this, std::move(content));
_rootView = std::make_unique<Ui::PinnedBar>(this);
_rootView->setContent(std::move(content));
controller()->adaptive().oneColumnValue(
) | rpl::start_with_next([=](bool one) {

View File

@@ -235,11 +235,6 @@ QSize WebPage::countOptimalSize() {
}
if (_title.isEmpty() && !title.isEmpty()) {
auto titleWithEntities = Ui::Text::Link(title, _data->url);
if (textFloatsAroundInfo && _description.isEmpty()) {
_title.updateSkipBlock(
_parent->skipBlockWidth(),
_parent->skipBlockHeight());
}
if (!_siteNameLines && !_data->url.isEmpty()) {
_title.setMarkedText(
st::webPageTitleStyle,
@@ -252,6 +247,11 @@ QSize WebPage::countOptimalSize() {
title,
Ui::WebpageTextTitleOptions());
}
if (textFloatsAroundInfo && _description.isEmpty()) {
_title.updateSkipBlock(
_parent->skipBlockWidth(),
_parent->skipBlockHeight());
}
}
// init dimensions

View File

@@ -316,8 +316,7 @@ infoProfileSeparatorPadding: margins(
infoIconFg: windowBoldFg;
infoIconInformation: icon {{ "info/info_information", infoIconFg }};
//infoIconMembers: icon {{ "info/edit/group_manage_members", infoIconFg, point(-2px, 0px) }};
infoIconRequests: icon {{ "info/info_add_member", infoIconFg, point(0px, 2px) }};
infoIconRequests: icon {{ "info/info_add_member", infoIconFg }};
infoIconNotifications: icon {{ "info/info_notifications", infoIconFg }};
infoIconMediaPhoto: icon {{ "info/info_media_photo", infoIconFg }};
infoIconMediaVideo: icon {{ "info/info_media_video", infoIconFg }};
@@ -328,12 +327,12 @@ infoIconMediaLink: icon {{ "info/info_media_link", infoIconFg }};
infoIconMediaGroup: icon {{ "info/info_common_groups", infoIconFg }};
infoIconMediaVoice: icon {{ "info/info_media_voice", infoIconFg }};
infoIconMediaRound: icon {{ "info/info_media_round", infoIconFg }};
infoIconRecentActions: icon {{ "info/edit/group_manage_actions", infoIconFg, point(-2px, -1px) }};
infoIconAdministrators: icon {{ "info/edit/group_manage_admins", infoIconFg, point(-3px, 0px) }};
infoIconBlacklist: icon {{ "info/info_blacklist", infoIconFg, point(-2px, -2px) }};
infoIconPermissions: icon {{ "info/edit/group_manage_permissions", infoIconFg, point(0px, -2px) }};
infoIconInviteLinks: icon {{ "info/edit/group_manage_links", infoIconFg, point(-2px, 0px) }};
infoIconReactions: icon {{ "info/edit/group_manage_reactions", infoIconFg }};
infoIconRecentActions: icon {{ "info/edit/group_manage_actions", settingsIconFg }};
infoIconAdministrators: icon {{ "info/edit/group_manage_admins", settingsIconFg }};
infoIconInviteLinks: icon {{ "info/edit/group_manage_links", settingsIconFg }};
infoIconReactions: icon {{ "info/edit/group_manage_reactions", settingsIconFg }};
infoIconGroupType: icon {{ "info/edit/group_manage_type", settingsIconFg }};
infoIconSignature: icon {{ "info/edit/channel_manage_signature", settingsIconFg }};
infoIconShare: icon {{ "info/info_share", infoIconFg }};
infoIconEdit: icon {{ "info/info_edit", infoIconFg }};
infoIconDelete: icon {{ "info/info_delete", infoIconFg }};
@@ -545,23 +544,20 @@ managePeerButton: SettingsCountButton {
peerPermissionsButton: SettingsCountButton(managePeerButton) {
button: SettingsButton(infoProfileButton) {
padding: margins(24px, 12px, 24px, 10px);
padding: margins(22px, 12px, 24px, 10px);
}
iconPosition: point(24px, 5px);
}
manageGroupButton: SettingsCountButton(managePeerButton) {
button: SettingsButton(infoProfileButton) {
padding: margins(72px, 10px, 24px, 8px);
padding: margins(60px, 10px, 24px, 8px);
}
labelPosition: point(22px, 12px);
iconPosition: point(20px, 4px);
}
manageGroupTopButtonWithText: SettingsCountButton(manageGroupButton) {
button: SettingsButton(infoProfileButton) {
padding: margins(22px, 10px, 24px, 8px);
}
labelPosition: point(22px, 10px);
iconPosition: point(0px, 0px);
}
@@ -608,7 +604,9 @@ editPeerHistoryVisibilityTopSkip: 8px;
editPeerPhotoMargins: margins(22px, 16px, 22px, 8px);
editPeerTitle: defaultInputField;
editPeerTitleMargins: margins(27px, 21px, 22px, 8px);
editPeerDescription: newGroupDescription;
editPeerDescription: InputField(newGroupDescription) {
borderFg: transparent;
}
editPeerDescriptionMargins: margins(22px, 5px, 22px, 16px);
editPeerPrivaciesMargins: margins(15px, 7px, 22px, 0px);
editPeerPrivacyTopSkip: 10px;
@@ -657,8 +655,8 @@ editPeerInviteLinkBoxBottomSkip: 15px;
editPeerReactionsButton: SettingsButton(infoProfileButton) {
padding: margins(59px, 13px, 8px, 11px);
}
editPeerReactionsPreview: 48px;
editPeerReactionsIconLeft: 12px;
editPeerReactionsPreview: 24px;
editPeerReactionsIconLeft: 21px;
historyTopBarBack: IconButton(infoTopBarBack) {
width: 52px;

View File

@@ -75,12 +75,13 @@ void ContentWidget::updateControlsGeometry() {
if (!_innerWrap) {
return;
}
_innerWrap->resizeToWidth(width());
auto newScrollTop = _scroll->scrollTop() + _topDelta;
auto scrollGeometry = rect().marginsRemoved(
QMargins(0, _scrollTopSkip.current(), 0, 0));
if (_scroll->geometry() != scrollGeometry) {
_scroll->setGeometry(scrollGeometry);
_innerWrap->resizeToWidth(_scroll->width());
}
if (!_scroll->isHidden()) {

View File

@@ -109,6 +109,7 @@ void LayerWidget::setupHeightConsumers() {
std::swap(_desiredHeight, height);
if (!height
|| (_heightAnimated && !_heightAnimation.animating())) {
_heightAnimated = true;
setContentHeight(_desiredHeight);
} else {
_heightAnimated = true;

View File

@@ -437,6 +437,14 @@ void WrapWidget::checkBeforeClose(Fn<void()> close) {
void WrapWidget::addTopBarMenuButton() {
Expects(_topBar != nullptr);
{
const auto guard = gsl::finally([&] { _topBarMenu = nullptr; });
showTopBarMenu(true);
if (_topBarMenu->empty()) {
return;
}
}
_topBarMenuToggle.reset(_topBar->addButton(
base::make_unique_q<Ui::IconButton>(
_topBar,
@@ -444,7 +452,7 @@ void WrapWidget::addTopBarMenuButton() {
? st::infoLayerTopBarMenu
: st::infoTopBarMenu))));
_topBarMenuToggle->addClickHandler([this] {
showTopBarMenu();
showTopBarMenu(false);
});
}
@@ -485,7 +493,7 @@ void WrapWidget::addProfileCallsButton() {
}
}
void WrapWidget::showTopBarMenu() {
void WrapWidget::showTopBarMenu(bool check) {
if (_topBarMenu) {
_topBarMenu->hideMenu(true);
return;
@@ -500,7 +508,6 @@ void WrapWidget::showTopBarMenu() {
toggle->setForceRippled(false);
}
});
_topBarMenuToggle->setForceRippled(true);
const auto addAction = Menu::CreateAddActionCallback(_topBarMenu);
if (key().isDownloads()) {
@@ -532,6 +539,10 @@ void WrapWidget::showTopBarMenu() {
return;
}
_topBarMenu->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight);
if (check) {
return;
}
_topBarMenuToggle->setForceRippled(true);
_topBarMenu->popup(_topBarMenuToggle->mapToGlobal(
st::infoLayerTopBarMenuPosition));
}

View File

@@ -200,7 +200,7 @@ private:
void addTopBarMenuButton();
void addProfileCallsButton();
void showTopBarMenu();
void showTopBarMenu(bool check);
void deleteAllDownloads();
rpl::variable<Wrap> _wrap;

View File

@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h"
#include "data/data_changes.h"
#include "data/data_user.h"
#include "data/notify/data_notify_settings.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h"
@@ -33,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/add_contact_box.h"
#include "boxes/peers/add_bot_to_chat_box.h"
#include "boxes/peers/edit_contact_box.h"
#include "boxes/report_messages_box.h"
#include "lang/lang_keys.h"
#include "menu/menu_mute.h"
#include "info/info_controller.h"
@@ -376,9 +378,21 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupMuteToggle() {
tr::lng_profile_enable_notifications(),
st::infoNotificationsButton);
result->toggleOn(NotificationsEnabledValue(peer), true);
result->setAcceptBoth();
MuteMenu::SetupMuteMenu(
result.data(),
result->clicks() | rpl::to_empty,
result->clicks(
) | rpl::filter([=](Qt::MouseButton button) {
if (button == Qt::RightButton) {
return true;
}
if (peer->owner().notifySettings().isMuted(peer)) {
peer->owner().notifySettings().update(peer, 0);
return false;
} else {
return true;
}
}) | rpl::to_empty,
{ peer, std::make_shared<Window::Show>(_controller) });
object_ptr<FloatingIcon>(
result,
@@ -619,7 +633,7 @@ void ActionsFiller::addReportAction() {
const auto peer = _peer;
const auto controller = _controller->parentController();
const auto report = [=] {
HistoryView::ShowReportPeerBox(controller, peer);
ShowReportPeerBox(controller, peer);
};
AddActionButton(
_wrap,

View File

@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "core/click_handler_types.h"
#include "countries/countries_instance.h"
#include "main/main_session.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
@@ -81,9 +82,11 @@ rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
}
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
return user->session().changes().peerFlagsValue(
user,
UpdateFlag::PhoneNumber
return rpl::merge(
Countries::Instance().updated(),
user->session().changes().peerFlagsValue(
user,
UpdateFlag::PhoneNumber) | rpl::to_empty
) | rpl::map([=] {
return Ui::FormatPhone(user->phone());
}) | Ui::Text::ToWithEntities();

View File

@@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/gl/gl_surface.h"
#include "ui/boxes/confirm_box.h"
#include "boxes/delete_messages_box.h"
#include "boxes/report_messages_box.h"
#include "media/audio/media_audio.h"
#include "media/view/media_view_playback_controls.h"
#include "media/view/media_view_group_thumbs.h"
@@ -509,15 +510,12 @@ void OverlayWidget::updateGeometry(bool inMove) {
if (Platform::IsWayland()) {
return;
}
const auto screen = _widget->screen()
? _widget->screen()
: QApplication::primaryScreen();
const auto available = screen->geometry();
const auto available = _widget->screen()->geometry();
const auto openglWidget = _opengl
? static_cast<QOpenGLWidget*>(_widget.get())
: nullptr;
const auto useSizeHack = Platform::IsWindows()
&& openglWidget
const auto possibleSizeHack = Platform::IsWindows() && openglWidget;
const auto useSizeHack = possibleSizeHack
&& (openglWidget->format().renderableType()
!= QSurfaceFormat::OpenGLES);
const auto use = useSizeHack
@@ -530,7 +528,7 @@ void OverlayWidget::updateGeometry(bool inMove) {
return;
}
if ((_widget->geometry() == use)
&& (!useSizeHack || _widget->mask() == mask)) {
&& (!possibleSizeHack || _widget->mask() == mask)) {
return;
}
DEBUG_LOG(("Viewer Pos: Setting %1, %2, %3, %4")
@@ -541,7 +539,7 @@ void OverlayWidget::updateGeometry(bool inMove) {
_widget->setGeometry(use);
_widget->setMinimumSize(use.size());
_widget->setMaximumSize(use.size());
if (useSizeHack) {
if (possibleSizeHack) {
_widget->setMask(mask);
}
}
@@ -1037,6 +1035,25 @@ void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) {
peer->session().api().peerPhoto().set(peer, photo);
}, &st::mediaMenuIconProfile);
}();
[&] { // Report userpic.
if (!_peer
|| !_photo
|| _peer->isSelf()
|| _peer->isNotificationsUser()
|| !userPhotosKey()) {
return;
}
const auto photo = _photo;
const auto peer = _peer;
addAction(tr::lng_mediaview_report_profile_photo(tr::now), [=] {
if (const auto window = findWindow()) {
close();
window->show(
ReportProfilePhotoBox(peer, photo),
Ui::LayerOption::CloseOther);
}
}, &st::mediaMenuIconReport);
}();
}
auto OverlayWidget::computeOverviewType() const
@@ -4746,6 +4763,7 @@ void OverlayWidget::clearBeforeHide() {
_userPhotosData = std::nullopt;
_collage = nullptr;
_collageData = std::nullopt;
clearStreaming();
assignMediaPointer(nullptr);
_preloadPhotos.clear();
_preloadDocuments.clear();

View File

@@ -477,14 +477,11 @@ void PipPanel::setPositionDefault() {
if (parentScreen && myScreen && myScreen != parentScreen) {
widget()->setScreen(parentScreen);
}
const auto screen = parentScreen
? parentScreen
: QGuiApplication::primaryScreen();
auto position = Position();
position.snapped = RectPart::Top | RectPart::Left;
position.screen = screen->geometry();
position.screen = parentScreen->geometry();
position.geometry = QRect(0, 0, st::pipDefaultSize, st::pipDefaultSize);
setPositionOnScreen(position, screen->availableGeometry());
setPositionOnScreen(position, parentScreen->availableGeometry());
}
void PipPanel::setPositionOnScreen(Position position, QRect available) {

View File

@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "ui/boxes/choose_time.h"
#include "ui/boxes/confirm_box.h"
#include "ui/boxes/time_picker_box.h"
#include "ui/effects/animation_value.h"
#include "ui/layers/generic_box.h"
@@ -127,6 +128,9 @@ void MuteItem::paintEvent(QPaintEvent *e) {
st::settingsIconBg2,
progress);
p.setPen(color);
Action::paintBackground(p, Action::isSelected());
RippleButton::paintRipple(p, 0, 0);
Action::paintText(p);
const auto &icon = _isMuted ? st::menuIconUnmute : st::menuIconMute;
@@ -153,11 +157,14 @@ void MuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
? tr::lng_mute_menu_unmute()
: tr::lng_mute_menu_mute();
}) | rpl::flatten_latest();
const auto confirm = box->addButton(std::move(confirmText), [=] {
peer->owner().notifySettings().update(peer, state->lastSeconds);
box->getDelegate()->hideLayer();
Ui::ConfirmBox(box, {
.confirmed = [=] {
peer->owner().notifySettings().update(peer, state->lastSeconds);
box->getDelegate()->hideLayer();
},
.confirmText = std::move(confirmText),
.cancelText = tr::lng_cancel(),
});
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}
void PickMuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
@@ -173,14 +180,14 @@ void PickMuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
(3600 * 4),
(3600 * 8),
(3600 * 12),
(84600 * 1),
(84600 * 2),
(84600 * 3),
(84600 * 7 * 1),
(84600 * 7 * 2),
(84600 * 30 * 1),
(84600 * 30 * 2),
(84600 * 30 * 3),
(86400 * 1),
(86400 * 2),
(86400 * 3),
(86400 * 7 * 1),
(86400 * 7 * 2),
(86400 * 31 * 1),
(86400 * 31 * 2),
(86400 * 31 * 3),
};
const auto phrases = ranges::views::all(
seconds
@@ -190,18 +197,20 @@ void PickMuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
const auto pickerCallback = TimePickerBox(box, seconds, phrases, 0);
box->addButton(tr::lng_mute_menu_mute(), [=] {
const auto muteFor = pickerCallback();
peer->owner().notifySettings().update(peer, muteFor);
peer->session().settings().addMutePeriod(muteFor);
peer->session().saveSettings();
box->closeBox();
Ui::ConfirmBox(box, {
.confirmed = [=] {
const auto muteFor = pickerCallback();
peer->owner().notifySettings().update(peer, muteFor);
peer->session().settings().addMutePeriod(muteFor);
peer->session().saveSettings();
box->closeBox();
},
.confirmText = tr::lng_mute_menu_mute(),
.cancelText = tr::lng_cancel(),
});
box->setTitle(tr::lng_mute_box_title());
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
const auto top = box->addTopButton(st::infoTopBarMenu);
top->setClickedCallback([=] {
if (state->menu) {
@@ -273,9 +282,13 @@ void FillMuteMenu(
menu->addAction(std::move(item));
}
const auto callback = [=, show = args.show] {
DEBUG_LOG(("Mute Info: PickMuteBox called."));
show->showBox(Box(PickMuteBox, peer));
};
menu->addAction(
tr::lng_mute_menu_duration(tr::now),
[=, show = args.show] { show->showBox(Box(PickMuteBox, peer)); },
callback,
&st::menuIconMuteFor);
menu->addAction(

View File

@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "menu/menu_ttl.h"
#include "lang/lang_keys.h"
#include "ui/boxes/confirm_box.h"
#include "ui/boxes/time_picker_box.h"
#include "ui/layers/generic_box.h"
#include "ui/text/format_values.h"
@@ -172,13 +173,13 @@ void TTLBox(not_null<Ui::GenericBox*> box, Args args) {
(86400 * 7 * 1),
(86400 * 7 * 2),
(86400 * 7 * 3),
(86400 * 30 * 1),
(86400 * 30 * 2),
(86400 * 30 * 3),
(86400 * 30 * 4),
(86400 * 30 * 5),
(86400 * 30 * 6),
(86400 * 30 * 12),
(86400 * 31 * 1),
(86400 * 31 * 2),
(86400 * 31 * 3),
(86400 * 31 * 4),
(86400 * 31 * 5),
(86400 * 31 * 6),
(86400 * 365),
};
const auto phrases = ranges::views::all(
ttls
@@ -186,17 +187,21 @@ void TTLBox(not_null<Ui::GenericBox*> box, Args args) {
const auto pickerTtl = TimePickerBox(box, ttls, phrases, args.startTtl);
box->addButton(tr::lng_settings_save(), [=] {
args.callback(pickerTtl());
box->getDelegate()->hideLayer();
Ui::ConfirmBox(box, {
.confirmed = [=] {
args.callback(pickerTtl());
box->getDelegate()->hideLayer();
},
.confirmText = tr::lng_settings_save(),
.cancelText = tr::lng_cancel(),
});
box->setTitle(tr::lng_manage_messages_ttl_title());
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
if (args.startTtl) {
box->addLeftButton(tr::lng_manage_messages_ttl_disable(), [=] {
args.callback(0);
box->getDelegate()->hideLayer();
});
}
}

View File

@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
#include "data/data_user.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "menu/menu_ttl.h"
@@ -104,7 +105,8 @@ Args TTLValidator::createArgs() const {
bool TTLValidator::can() const {
return (_peer->isUser()
&& !_peer->isSelf()
&& !_peer->isNotificationsUser())
&& !_peer->isNotificationsUser()
&& !_peer->asUser()->isInaccessible())
|| (_peer->isChat()
&& _peer->asChat()->canDeleteMessages())
|| (_peer->isChannel()

View File

@@ -776,6 +776,9 @@ void Panel::showWebviewError(
case Error::Wayland:
rich.append(tr::lng_payments_webview_switch_wayland(tr::now));
break;
case Error::OldWindows:
rich.append(tr::lng_payments_webview_update_windows(tr::now));
break;
default:
rich.append(QString::fromStdString(information.details));
break;

View File

@@ -679,8 +679,12 @@ void NotificationData::setImage(const QString &imagePath) {
return;
}
const auto image = QImage(imagePath)
.convertToFormat(QImage::Format_RGBA8888);
const auto image = [&] {
const auto original = QImage(imagePath);
return original.hasAlphaChannel()
? original.convertToFormat(QImage::Format_RGBA8888)
: original.convertToFormat(QImage::Format_RGB888);
}();
if (image.isNull()) {
return;
@@ -690,9 +694,9 @@ void NotificationData::setImage(const QString &imagePath) {
image.width(),
image.height(),
int(image.bytesPerLine()),
true,
image.hasAlphaChannel(),
8,
4,
image.hasAlphaChannel() ? 4 : 3,
std::vector<uchar>(
image.constBits(),
image.constBits() + image.sizeInBytes()),

View File

@@ -382,12 +382,6 @@ QString GetIconName() {
std::optional<bool> IsDarkMode() {
#ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
[[maybe_unused]] static const auto Inited = [] {
static const auto Setter = [] {
crl::on_main([] {
Core::App().settings().setSystemDarkMode(IsDarkMode());
});
};
using XDPSettingWatcher = base::Platform::XDP::SettingWatcher;
static const XDPSettingWatcher Watcher(
[=](
@@ -396,7 +390,14 @@ std::optional<bool> IsDarkMode() {
const Glib::VariantBase &value) {
if (group == "org.freedesktop.appearance"
&& key == "color-scheme") {
Setter();
try {
const auto ivalue = base::Platform::GlibVariantCast<uint>(value);
crl::on_main([=] {
Core::App().settings().setSystemDarkMode(ivalue == 1);
});
} catch (...) {
}
}
});
@@ -410,10 +411,7 @@ std::optional<bool> IsDarkMode() {
if (result.has_value()) {
const auto value = base::Platform::GlibVariantCast<uint>(*result);
if (value == 1) {
return true;
}
return false;
return value == 1;
}
} catch (...) {
}

View File

@@ -630,7 +630,7 @@ void MainWindow::showFromTrayMenu() {
// It will receive input events, but it will be rendered as inactive.
using namespace rpl::mappers;
_showFromTrayLifetime = trayIconMenu->shownValue(
) | rpl::filter(_1) | rpl::take(1) | rpl::start_with_next([=] {
) | rpl::filter(!_1) | rpl::take(1) | rpl::start_with_next([=] {
showFromTray();
});
}

View File

@@ -697,8 +697,9 @@ void SetupOpenGL(
Local::writeSettings();
Core::Restart();
});
const auto cancelled = crl::guard(button, [=] {
const auto cancelled = crl::guard(button, [=](Fn<void()> close) {
toggles->fire(!enabled);
close();
});
controller->show(Ui::MakeConfirmBox({
.text = tr::lng_settings_need_restart(),

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