Compare commits
251 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cc494fee22 | |||
| d0f793c06d | |||
| fc447bfd51 | |||
| fe463ab8fb | |||
| 6fd0fb9704 | |||
| ce00b3d950 | |||
| a87fb9160c | |||
| 132caa18c9 | |||
| 6257e990a1 | |||
| c6b42e2940 | |||
| 707146daed | |||
| c0117e72ad | |||
| 3cdb528dfe | |||
| d2164dc0d0 | |||
| 87acc921c3 | |||
| 5741bd9cca | |||
| 1e6fb202f0 | |||
| 8cbb1abff2 | |||
| d21418cf04 | |||
| d35c8232d2 | |||
| 139d1a9aa3 | |||
| f95817861a | |||
| 3e968aecc8 | |||
| 2795af8c7f | |||
| bb438880e3 | |||
| 8492b7144f | |||
| 5dd974f2ab | |||
| d3cd3bb0a4 | |||
| 04acf08d34 | |||
| 4db885d8b4 | |||
| 8718d94e7d | |||
| 24c1151101 | |||
| 0b22e5928c | |||
| 3311a50750 | |||
| 1563a85fea | |||
| 586983eb9b | |||
| 1a7a906ced | |||
| 496247c1d8 | |||
| 2f07bb3973 | |||
| 9b0f3bedff | |||
| c66b5b2490 | |||
| a1264a6088 | |||
| 4e0d770d05 | |||
| 508119a127 | |||
| 341b9e4a29 | |||
| 57789c1272 | |||
| 3845a87f2e | |||
| 3c266b6dc4 | |||
| 32a3952524 | |||
| 9c52f245ac | |||
| 393d9e9f1f | |||
| f28f498467 | |||
| b5a7a351f6 | |||
| a14c0f5253 | |||
| a278aa0f89 | |||
| 479bb2a1d6 | |||
| 538934a88a | |||
| 5d2726036f | |||
| 778317e1b2 | |||
| 99dd5507bf | |||
| 490d9bc3ec | |||
| 796e09bf13 | |||
| 588624e7a9 | |||
| a45a9e6515 | |||
| a7df074b8f | |||
| 9941a46769 | |||
| b0565f2188 | |||
| 8fb3e39881 | |||
| d788f5afac | |||
| 20123fca7f | |||
| 7c7b962c6d | |||
| 68ded1a6e0 | |||
| da7a796edb | |||
| 3b5814edae | |||
| f439443fe5 | |||
| 280d69d346 | |||
| ab74ed0fa7 | |||
| 0d740c21a2 | |||
| f65bc7c0bd | |||
| 0dd1a4973a | |||
| 05a5e62327 | |||
| 66a47137a0 | |||
| f240cbbda6 | |||
| 3d54f8ec49 | |||
| 6fe0c60204 | |||
| f7d04d668b | |||
| 57bd0d2674 | |||
| 08ee25deb2 | |||
| c82d7bd909 | |||
| 59663d6661 | |||
| 5e68dace9f | |||
| fcc9e0b2db | |||
| 3a5b3ff3bd | |||
| 1e1a48865f | |||
| b31c30b9b6 | |||
| 7886a2179f | |||
| d1a995a863 | |||
| 85554d19e4 | |||
| 7f4d13c54a | |||
| 9f67b9ba2f | |||
| 5381fe5a1a | |||
| 0887348611 | |||
| 98ce91df39 | |||
| 191c35914f | |||
| cf1d0677d1 | |||
| 3d97ea6f96 | |||
| caa4c5428a | |||
| 90e572c8b1 | |||
| b1795f8c5a | |||
| 962c64b33c | |||
| bd827d844b | |||
| ed70675e1d | |||
| e07d53725c | |||
| 1b589a35cf | |||
| 439f8d0914 | |||
| 1d7dbc4d17 | |||
| 001b055ee8 | |||
| 8534d6d7d7 | |||
| e7a7c2d267 | |||
| 8803dfcee6 | |||
| 887f10059d | |||
| d3db52ce9c | |||
| 5fa89c22bd | |||
| ea42f9545f | |||
| 8830fb70a4 | |||
| 0edf14f3a9 | |||
| 89c6bb163e | |||
| 8708598daa | |||
| c71c24a6bc | |||
| 386fb07017 | |||
| aad2961646 | |||
| 00a89883fd | |||
| 5509c1810b | |||
| 24498bc95f | |||
| 58caec8d05 | |||
| ebe331a7e4 | |||
| d481008fdb | |||
| b97d243978 | |||
| fd833dff35 | |||
| d9ed3a7d3f | |||
| b8ce79467f | |||
| 9d0457d208 | |||
| fa02e521f9 | |||
| d03d50ef0d | |||
| 58fcedab64 | |||
| 5e11c43f84 | |||
| 4b4de9d5aa | |||
| f135676d36 | |||
| cb9adad660 | |||
| 88dab47d2c | |||
| d6e4613144 | |||
| 893c09c848 | |||
| a0e0fd5b98 | |||
| 98abb3aa00 | |||
| 8982a49192 | |||
| 529eb4e954 | |||
| 846a6d8717 | |||
| 07ab875655 | |||
| 602b0b5d9b | |||
| 0e428aebdb | |||
| 4abc68ab1c | |||
| 2638ee2926 | |||
| ddaf78828a | |||
| 6d5347472d | |||
| 82fda96ed8 | |||
| 55b2b04e2e | |||
| 393f330d15 | |||
| f4ecfeaddd | |||
| ad101dc8a0 | |||
| 24e9a3ea59 | |||
| f1d8135e30 | |||
| a1a415de82 | |||
| 77dc234b2d | |||
| c3ca8c6258 | |||
| 9e18236b55 | |||
| ded7aada52 | |||
| a117c1ebf2 | |||
| d3715cc362 | |||
| 3689e7dfbc | |||
| 59e53c1edf | |||
| f2a54e3cbb | |||
| 20db635366 | |||
| b955d32970 | |||
| 5a5d89c32c | |||
| 1f0ed3bb31 | |||
| 6c083e88a3 | |||
| 2e7323d484 | |||
| 461aebd7f3 | |||
| 73ca78215f | |||
| 200bb31e08 | |||
| 396f52b8ca | |||
| a118d3d848 | |||
| f6b9702b52 | |||
| d92418dc6d | |||
| fe4b853393 | |||
| 782556495a | |||
| 5c32423597 | |||
| 5c8e6c3012 | |||
| 5133f74f67 | |||
| d5b23b5bde | |||
| bf4b4ae936 | |||
| 458b990b8c | |||
| e044753934 | |||
| c0b612c457 | |||
| 9414ef5709 | |||
| c9e566f8aa | |||
| 40bd37315a | |||
| 0410d05913 | |||
| a888b8d846 | |||
| eac5c39a96 | |||
| 202a4064a4 | |||
| ddf2369774 | |||
| 48f70a8552 | |||
| 4685b889c2 | |||
| 3e373200b1 | |||
| 7913d2a82d | |||
| e20770e256 | |||
| d43f0be0da | |||
| 7b4adc2e60 | |||
| 1eeba65ddb | |||
| 1252accef7 | |||
| 5f7c3ae20e | |||
| e1b55b560a | |||
| 315859bf7b | |||
| 0a87dbea68 | |||
| 5f3c380d56 | |||
| 8b62c37c34 | |||
| fae10cfa6b | |||
| f9069144e5 | |||
| 7755b70317 | |||
| c46f34c677 | |||
| 5c428ca502 | |||
| 51d5b7bab6 | |||
| f508ad5e75 | |||
| f9299eee2a | |||
| 212259aae3 | |||
| 6d733bb566 | |||
| 125f856e67 | |||
| 672ad64e53 | |||
| cd59f1d576 | |||
| c4fc43ccc0 | |||
| b20b3142a2 | |||
| d67f25d726 | |||
| d881019c3b | |||
| abdfa4f785 | |||
| 5394717ddc | |||
| c9d58d4259 | |||
| dba9cada83 | |||
| 0ec5181566 | |||
| 886847f457 | |||
| 79d6df2c01 |
@@ -64,7 +64,10 @@ jobs:
|
||||
- name: First set up.
|
||||
run: |
|
||||
sudo chown -R `whoami`:admin /usr/local/share
|
||||
brew install automake ninja pkg-config nasm meson
|
||||
|
||||
brew update
|
||||
brew upgrade || true
|
||||
brew install automake meson nasm ninja pkg-config
|
||||
|
||||
# Disable spotlight.
|
||||
sudo mdutil -a -i off
|
||||
|
||||
@@ -60,7 +60,7 @@ include(cmake/options.cmake)
|
||||
|
||||
if (NOT DESKTOP_APP_USE_PACKAGED)
|
||||
if (WIN32)
|
||||
set(qt_version 5.15.12)
|
||||
set(qt_version 5.15.13)
|
||||
elseif (APPLE)
|
||||
set(qt_version 6.2.7)
|
||||
endif()
|
||||
@@ -68,6 +68,7 @@ endif()
|
||||
include(cmake/external/qt/package.cmake)
|
||||
|
||||
set(desktop_app_skip_libs
|
||||
glibmm
|
||||
variant
|
||||
)
|
||||
|
||||
|
||||
@@ -30,8 +30,9 @@ include(cmake/lib_tgvoip.cmake)
|
||||
include(cmake/lib_tgcalls.cmake)
|
||||
include(cmake/lib_prisma.cmake)
|
||||
include(cmake/td_export.cmake)
|
||||
include(cmake/td_mtproto.cmake)
|
||||
include(cmake/td_iv.cmake)
|
||||
include(cmake/td_lang.cmake)
|
||||
include(cmake/td_mtproto.cmake)
|
||||
include(cmake/td_scheme.cmake)
|
||||
include(cmake/td_ui.cmake)
|
||||
include(cmake/generate_appdata_changelog.cmake)
|
||||
@@ -62,8 +63,9 @@ PRIVATE
|
||||
desktop-app::external_minizip
|
||||
|
||||
tdesktop::td_export
|
||||
tdesktop::td_mtproto
|
||||
tdesktop::td_iv
|
||||
tdesktop::td_lang
|
||||
tdesktop::td_mtproto
|
||||
tdesktop::td_scheme
|
||||
tdesktop::td_ui
|
||||
desktop-app::lib_webrtc
|
||||
@@ -91,78 +93,81 @@ PRIVATE
|
||||
desktop-app::external_xxhash
|
||||
)
|
||||
|
||||
set(ayugram_files
|
||||
ayu/ayu_worker.cpp
|
||||
ayu/ayu_worker.h
|
||||
ayu/ayu_url_handlers.cpp
|
||||
ayu/ayu_url_handlers.h
|
||||
ayu/ayu_state.cpp
|
||||
ayu/ayu_state.h
|
||||
ayu/ayu_settings.cpp
|
||||
ayu/ayu_settings.h
|
||||
ayu/ayu_lang.cpp
|
||||
ayu/ayu_lang.h
|
||||
ayu/ayu_infra.cpp
|
||||
ayu/ayu_infra.h
|
||||
ayu/ayu_constants.h
|
||||
ayu/utils/ayu_mapper.cpp
|
||||
ayu/utils/ayu_mapper.h
|
||||
ayu/utils/qt_key_modifiers_extended.h
|
||||
ayu/utils/telegram_helpers.cpp
|
||||
ayu/utils/telegram_helpers.h
|
||||
ayu/utils/windows_utils.cpp
|
||||
ayu/utils/windows_utils.h
|
||||
ayu/ui/ayu_logo.cpp
|
||||
ayu/ui/ayu_logo.h
|
||||
ayu/ui/utils/ayu_profile_values.cpp
|
||||
ayu/ui/utils/ayu_profile_values.h
|
||||
ayu/ui/settings/icon_picker.cpp
|
||||
ayu/ui/settings/icon_picker.h
|
||||
ayu/ui/settings/settings_ayu.cpp
|
||||
ayu/ui/settings/settings_ayu.h
|
||||
ayu/ui/context_menu/context_menu.cpp
|
||||
ayu/ui/context_menu/context_menu.h
|
||||
ayu/ui/context_menu/menu_item_subtext.cpp
|
||||
ayu/ui/context_menu/menu_item_subtext.h
|
||||
ayu/ui/sections/edited/edited_log_inner.cpp
|
||||
ayu/ui/sections/edited/edited_log_inner.h
|
||||
ayu/ui/sections/edited/edited_log_item.cpp
|
||||
ayu/ui/sections/edited/edited_log_item.h
|
||||
ayu/ui/sections/edited/edited_log_section.cpp
|
||||
ayu/ui/sections/edited/edited_log_section.h
|
||||
ayu/ui/boxes/server_read_confirmation_box.cpp
|
||||
ayu/ui/boxes/server_read_confirmation_box.h
|
||||
ayu/ui/boxes/edit_deleted_mark.cpp
|
||||
ayu/ui/boxes/edit_deleted_mark.h
|
||||
ayu/ui/boxes/edit_edited_mark.cpp
|
||||
ayu/ui/boxes/edit_edited_mark.h
|
||||
ayu/ui/boxes/font_selector.cpp
|
||||
ayu/ui/boxes/font_selector.h
|
||||
ayu/ui/boxes/theme_selector_box.cpp
|
||||
ayu/ui/boxes/theme_selector_box.h
|
||||
ayu/ui/boxes/message_shot_box.cpp
|
||||
ayu/ui/boxes/message_shot_box.h
|
||||
ayu/ui/components/image_view.cpp
|
||||
ayu/ui/components/image_view.h
|
||||
ayu/libs/json.hpp
|
||||
ayu/libs/json_ext.hpp
|
||||
ayu/libs/sqlite/sqlite3.c
|
||||
ayu/libs/sqlite/sqlite3.h
|
||||
ayu/libs/sqlite/sqlite_orm.h
|
||||
ayu/features/streamer_mode/streamer_mode_windows.cpp
|
||||
ayu/features/streamer_mode/streamer_mode_linux.cpp
|
||||
ayu/features/streamer_mode/streamer_mode.h
|
||||
ayu/features/messageshot/message_shot.cpp
|
||||
ayu/features/messageshot/message_shot.h
|
||||
ayu/data/messages_storage.cpp
|
||||
ayu/data/messages_storage.h
|
||||
ayu/data/entities.h
|
||||
ayu/data/ayu_database.cpp
|
||||
ayu/data/ayu_database.h
|
||||
)
|
||||
|
||||
target_precompile_headers(Telegram PRIVATE $<$<COMPILE_LANGUAGE:CXX,OBJCXX>:${src_loc}/stdafx.h>)
|
||||
nice_target_sources(Telegram ${src_loc}
|
||||
PRIVATE
|
||||
${style_files}
|
||||
|
||||
ayu/ayu_worker.cpp
|
||||
ayu/ayu_worker.h
|
||||
ayu/ayu_url_handlers.cpp
|
||||
ayu/ayu_url_handlers.h
|
||||
ayu/ayu_state.cpp
|
||||
ayu/ayu_state.h
|
||||
ayu/ayu_settings.cpp
|
||||
ayu/ayu_settings.h
|
||||
ayu/ayu_lang.cpp
|
||||
ayu/ayu_lang.h
|
||||
ayu/ayu_infra.cpp
|
||||
ayu/ayu_infra.h
|
||||
ayu/ayu_constants.h
|
||||
ayu/utils/ayu_mapper.cpp
|
||||
ayu/utils/ayu_mapper.h
|
||||
ayu/utils/qt_key_modifiers_extended.h
|
||||
ayu/utils/telegram_helpers.cpp
|
||||
ayu/utils/telegram_helpers.h
|
||||
ayu/utils/windows_utils.cpp
|
||||
ayu/utils/windows_utils.h
|
||||
ayu/ui/ayu_logo.cpp
|
||||
ayu/ui/ayu_logo.h
|
||||
ayu/ui/utils/ayu_profile_values.cpp
|
||||
ayu/ui/utils/ayu_profile_values.h
|
||||
ayu/ui/settings/icon_picker.cpp
|
||||
ayu/ui/settings/icon_picker.h
|
||||
ayu/ui/settings/settings_ayu.cpp
|
||||
ayu/ui/settings/settings_ayu.h
|
||||
ayu/ui/context_menu/context_menu.cpp
|
||||
ayu/ui/context_menu/context_menu.h
|
||||
ayu/ui/context_menu/menu_item_subtext.cpp
|
||||
ayu/ui/context_menu/menu_item_subtext.h
|
||||
ayu/ui/sections/edited/edited_log_inner.cpp
|
||||
ayu/ui/sections/edited/edited_log_inner.h
|
||||
ayu/ui/sections/edited/edited_log_item.cpp
|
||||
ayu/ui/sections/edited/edited_log_item.h
|
||||
ayu/ui/sections/edited/edited_log_section.cpp
|
||||
ayu/ui/sections/edited/edited_log_section.h
|
||||
ayu/ui/boxes/server_read_confirmation_box.cpp
|
||||
ayu/ui/boxes/server_read_confirmation_box.h
|
||||
ayu/ui/boxes/edit_deleted_mark.cpp
|
||||
ayu/ui/boxes/edit_deleted_mark.h
|
||||
ayu/ui/boxes/edit_edited_mark.cpp
|
||||
ayu/ui/boxes/edit_edited_mark.h
|
||||
ayu/ui/boxes/font_selector.cpp
|
||||
ayu/ui/boxes/font_selector.h
|
||||
ayu/ui/boxes/theme_selector_box.cpp
|
||||
ayu/ui/boxes/theme_selector_box.h
|
||||
ayu/ui/boxes/message_shot_box.cpp
|
||||
ayu/ui/boxes/message_shot_box.h
|
||||
ayu/ui/components/image_view.cpp
|
||||
ayu/ui/components/image_view.h
|
||||
ayu/libs/json.hpp
|
||||
ayu/libs/json_ext.hpp
|
||||
ayu/libs/sqlite/sqlite3.c
|
||||
ayu/libs/sqlite/sqlite3.h
|
||||
ayu/libs/sqlite/sqlite_orm.h
|
||||
ayu/features/streamer_mode/streamer_mode_windows.cpp
|
||||
ayu/features/streamer_mode/streamer_mode_linux.cpp
|
||||
ayu/features/streamer_mode/streamer_mode.h
|
||||
ayu/features/messageshot/message_shot.cpp
|
||||
ayu/features/messageshot/message_shot.h
|
||||
ayu/data/messages_storage.cpp
|
||||
ayu/data/messages_storage.h
|
||||
ayu/data/entities.h
|
||||
ayu/data/ayu_database.cpp
|
||||
ayu/data/ayu_database.h
|
||||
${ayugram_files}
|
||||
|
||||
api/api_attached_stickers.cpp
|
||||
api/api_attached_stickers.h
|
||||
@@ -176,6 +181,8 @@ PRIVATE
|
||||
api/api_chat_filters.h
|
||||
api/api_chat_invite.cpp
|
||||
api/api_chat_invite.h
|
||||
api/api_chat_links.cpp
|
||||
api/api_chat_links.h
|
||||
api/api_chat_participants.cpp
|
||||
api/api_chat_participants.h
|
||||
api/api_cloud_password.cpp
|
||||
@@ -184,6 +191,8 @@ PRIVATE
|
||||
api/api_common.h
|
||||
api/api_confirm_phone.cpp
|
||||
api/api_confirm_phone.h
|
||||
api/api_earn.cpp
|
||||
api/api_earn.h
|
||||
api/api_editing.cpp
|
||||
api/api_editing.h
|
||||
api/api_global_privacy.cpp
|
||||
@@ -458,8 +467,6 @@ PRIVATE
|
||||
chat_helpers/spellchecker_common.h
|
||||
chat_helpers/stickers_dice_pack.cpp
|
||||
chat_helpers/stickers_dice_pack.h
|
||||
chat_helpers/stickers_emoji_image_loader.cpp
|
||||
chat_helpers/stickers_emoji_image_loader.h
|
||||
chat_helpers/stickers_emoji_pack.cpp
|
||||
chat_helpers/stickers_emoji_pack.h
|
||||
chat_helpers/stickers_gift_box_pack.cpp
|
||||
@@ -786,6 +793,8 @@ PRIVATE
|
||||
history/view/media/history_view_media.h
|
||||
history/view/media/history_view_media_common.cpp
|
||||
history/view/media/history_view_media_common.h
|
||||
history/view/media/history_view_media_generic.cpp
|
||||
history/view/media/history_view_media_generic.h
|
||||
history/view/media/history_view_media_grouped.cpp
|
||||
history/view/media/history_view_media_grouped.h
|
||||
history/view/media/history_view_media_spoiler.cpp
|
||||
@@ -925,14 +934,18 @@ PRIVATE
|
||||
history/history_view_highlight_manager.h
|
||||
history/history_widget.cpp
|
||||
history/history_widget.h
|
||||
info/boosts/giveaway/giveaway_list_controllers.cpp
|
||||
info/boosts/giveaway/giveaway_list_controllers.h
|
||||
info/boosts/create_giveaway_box.cpp
|
||||
info/boosts/create_giveaway_box.h
|
||||
info/boosts/info_boosts_inner_widget.cpp
|
||||
info/boosts/info_boosts_inner_widget.h
|
||||
info/boosts/info_boosts_widget.cpp
|
||||
info/boosts/info_boosts_widget.h
|
||||
info/channel_statistics/boosts/create_giveaway_box.cpp
|
||||
info/channel_statistics/boosts/create_giveaway_box.h
|
||||
info/channel_statistics/boosts/giveaway/giveaway_list_controllers.cpp
|
||||
info/channel_statistics/boosts/giveaway/giveaway_list_controllers.h
|
||||
info/channel_statistics/boosts/info_boosts_inner_widget.cpp
|
||||
info/channel_statistics/boosts/info_boosts_inner_widget.h
|
||||
info/channel_statistics/boosts/info_boosts_widget.cpp
|
||||
info/channel_statistics/boosts/info_boosts_widget.h
|
||||
info/channel_statistics/earn/info_earn_inner_widget.cpp
|
||||
info/channel_statistics/earn/info_earn_inner_widget.h
|
||||
info/channel_statistics/earn/info_earn_widget.cpp
|
||||
info/channel_statistics/earn/info_earn_widget.h
|
||||
info/common_groups/info_common_groups_inner_widget.cpp
|
||||
info/common_groups/info_common_groups_inner_widget.h
|
||||
info/common_groups/info_common_groups_widget.cpp
|
||||
@@ -1063,6 +1076,10 @@ PRIVATE
|
||||
intro/intro_step.h
|
||||
intro/intro_widget.cpp
|
||||
intro/intro_widget.h
|
||||
iv/iv_delegate_impl.cpp
|
||||
iv/iv_delegate_impl.h
|
||||
iv/iv_instance.cpp
|
||||
iv/iv_instance.h
|
||||
lang/lang_cloud_manager.cpp
|
||||
lang/lang_cloud_manager.h
|
||||
lang/lang_instance.cpp
|
||||
@@ -1197,6 +1214,8 @@ PRIVATE
|
||||
menu/menu_mute.h
|
||||
menu/menu_send.cpp
|
||||
menu/menu_send.h
|
||||
menu/menu_sponsored.cpp
|
||||
menu/menu_sponsored.h
|
||||
menu/menu_ttl_validator.cpp
|
||||
menu/menu_ttl_validator.h
|
||||
mtproto/config_loader.cpp
|
||||
@@ -1251,8 +1270,6 @@ PRIVATE
|
||||
payments/payments_checkout_process.h
|
||||
payments/payments_form.cpp
|
||||
payments/payments_form.h
|
||||
platform/linux/linux_desktop_environment.cpp
|
||||
platform/linux/linux_desktop_environment.h
|
||||
platform/linux/linux_wayland_integration_dummy.cpp
|
||||
platform/linux/linux_wayland_integration.cpp
|
||||
platform/linux/linux_wayland_integration.h
|
||||
@@ -1359,6 +1376,10 @@ PRIVATE
|
||||
settings/business/settings_away_message.h
|
||||
settings/business/settings_shortcut_messages.cpp
|
||||
settings/business/settings_shortcut_messages.h
|
||||
settings/business/settings_chat_intro.cpp
|
||||
settings/business/settings_chat_intro.h
|
||||
settings/business/settings_chat_links.cpp
|
||||
settings/business/settings_chat_links.h
|
||||
settings/business/settings_chatbots.cpp
|
||||
settings/business/settings_chatbots.h
|
||||
settings/business/settings_greeting.cpp
|
||||
@@ -1561,8 +1582,6 @@ PRIVATE
|
||||
window/window_session_controller.cpp
|
||||
window/window_session_controller.h
|
||||
window/window_session_controller_link_info.h
|
||||
window/window_slide_animation.cpp
|
||||
window/window_slide_animation.h
|
||||
window/window_top_bar_wrap.h
|
||||
window/themes/window_theme.cpp
|
||||
window/themes/window_theme.h
|
||||
@@ -1637,6 +1656,7 @@ PRIVATE
|
||||
qrc/emoji_preview.qrc
|
||||
qrc/telegram/animations.qrc
|
||||
qrc/telegram/export.qrc
|
||||
qrc/telegram/iv.qrc
|
||||
qrc/telegram/telegram.qrc
|
||||
qrc/telegram/sounds.qrc
|
||||
winrc/Telegram.rc
|
||||
@@ -1744,13 +1764,9 @@ elseif (APPLE)
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(Telegram
|
||||
PRIVATE
|
||||
desktop-app::external_glibmm
|
||||
)
|
||||
|
||||
include(${cmake_helpers_loc}/external/glib/generate_dbus.cmake)
|
||||
generate_dbus(Telegram org.freedesktop.portal. XdpBackground ${third_party_loc}/xdg-desktop-portal/data/org.freedesktop.portal.Background.xml)
|
||||
generate_dbus(Telegram org.freedesktop. XdgNotifications ${src_loc}/platform/linux/org.freedesktop.Notifications.xml)
|
||||
|
||||
if (NOT DESKTOP_APP_DISABLE_X11_INTEGRATION)
|
||||
target_link_libraries(Telegram
|
||||
|
||||
|
After Width: | Height: | Size: 596 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 568 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 681 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 733 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 741 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 748 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 873 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 784 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 564 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 562 B |
|
After Width: | Height: | Size: 940 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 760 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 751 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 642 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 534 B |
|
After Width: | Height: | Size: 928 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 771 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 651 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 680 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 388 B |
|
After Width: | Height: | Size: 609 B |
|
After Width: | Height: | Size: 893 B |
@@ -0,0 +1 @@
|
||||
.hljs{display:block;overflow-x:auto;padding:0.5em;background:#F0F0F0}.hljs,.hljs-subst{color:#444}.hljs-comment{color:#888888}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-selector-pseudo{color:#BC6060}.hljs-literal{color:#78A960}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
|
||||
@@ -0,0 +1,657 @@
|
||||
var IV = {
|
||||
notify: function(message) {
|
||||
if (window.external && window.external.invoke) {
|
||||
window.external.invoke(JSON.stringify(message));
|
||||
}
|
||||
},
|
||||
frameClickHandler: function(e) {
|
||||
var target = e.target;
|
||||
var context = '';
|
||||
while (target) {
|
||||
if (target.id == 'menu_page_blocker') {
|
||||
IV.notify({ event: 'menu_page_blocker_click' });
|
||||
IV.menuShown(false);
|
||||
return;
|
||||
}
|
||||
if (target.tagName == 'AUDIO' || target.tagName == 'VIDEO') {
|
||||
return;
|
||||
}
|
||||
if (context === ''
|
||||
&& target.hasAttribute
|
||||
&& target.hasAttribute('data-context')) {
|
||||
context = String(target.getAttribute('data-context'));
|
||||
}
|
||||
if (target.tagName == 'A') {
|
||||
break;
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
if (!target || !target.hasAttribute('href')) {
|
||||
return;
|
||||
}
|
||||
var base = document.createElement('A');
|
||||
base.href = window.location.href;
|
||||
if (base.origin != target.origin
|
||||
|| base.pathname != target.pathname
|
||||
|| base.search != target.search) {
|
||||
IV.notify({
|
||||
event: 'link_click',
|
||||
url: target.href,
|
||||
context: context,
|
||||
});
|
||||
} else if (target.hash.length < 2) {
|
||||
IV.jumpToHash('');
|
||||
} else {
|
||||
IV.jumpToHash(decodeURIComponent(target.hash.substr(1)));
|
||||
}
|
||||
e.preventDefault();
|
||||
},
|
||||
getElementTop: function (element) {
|
||||
var top = 0;
|
||||
while (element && !element.classList.contains('page-scroll')) {
|
||||
top += element.offsetTop;
|
||||
element = element.offsetParent;
|
||||
}
|
||||
return top;
|
||||
},
|
||||
jumpToHash: function (hash, instant) {
|
||||
var current = IV.computeCurrentState();
|
||||
current.hash = hash;
|
||||
window.history.replaceState(
|
||||
current,
|
||||
'',
|
||||
'page' + IV.index + '.html');
|
||||
if (hash == '') {
|
||||
IV.scrollTo(0, instant);
|
||||
return;
|
||||
}
|
||||
|
||||
var element = document.getElementsByName(hash)[0];
|
||||
if (element) {
|
||||
IV.scrollTo(IV.getElementTop(element), instant);
|
||||
}
|
||||
},
|
||||
frameKeyDown: function (e) {
|
||||
const keyW = (e.key === 'w')
|
||||
|| (e.code === 'KeyW')
|
||||
|| (e.keyCode === 87);
|
||||
const keyQ = (e.key === 'q')
|
||||
|| (e.code === 'KeyQ')
|
||||
|| (e.keyCode === 81);
|
||||
const keyM = (e.key === 'm')
|
||||
|| (e.code === 'KeyM')
|
||||
|| (e.keyCode === 77);
|
||||
if ((e.metaKey || e.ctrlKey) && (keyW || keyQ || keyM)) {
|
||||
e.preventDefault();
|
||||
IV.notify({
|
||||
event: 'keydown',
|
||||
modifier: e.ctrlKey ? 'ctrl' : 'cmd',
|
||||
key: keyW ? 'w' : keyQ ? 'q' : 'm',
|
||||
});
|
||||
} else if (e.key === 'Escape' || e.keyCode === 27) {
|
||||
e.preventDefault();
|
||||
if (IV.position) {
|
||||
window.history.back();
|
||||
} else {
|
||||
IV.notify({
|
||||
event: 'keydown',
|
||||
key: 'escape',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
frameMouseEnter: function (e) {
|
||||
IV.notify({ event: 'mouseenter' });
|
||||
},
|
||||
frameMouseUp: function (e) {
|
||||
IV.notify({ event: 'mouseup' });
|
||||
},
|
||||
lastScrollTop: 0,
|
||||
frameScrolled: function (e) {
|
||||
const was = IV.lastScrollTop;
|
||||
IV.lastScrollTop = IV.findPageScroll().scrollTop;
|
||||
IV.updateJumpToTop(was < IV.lastScrollTop);
|
||||
IV.checkVideos();
|
||||
},
|
||||
updateJumpToTop: function (scrolledDown) {
|
||||
if (IV.lastScrollTop < 100) {
|
||||
document.getElementById('bottom_up').classList.add('hidden');
|
||||
} else if (scrolledDown && IV.lastScrollTop > 200) {
|
||||
document.getElementById('bottom_up').classList.remove('hidden');
|
||||
}
|
||||
},
|
||||
updateStyles: function (styles) {
|
||||
if (IV.styles !== styles) {
|
||||
IV.styles = styles;
|
||||
document.getElementsByTagName('html')[0].style = styles;
|
||||
}
|
||||
},
|
||||
toggleChannelJoined: function (id, joined) {
|
||||
IV.channelsJoined['channel' + id] = joined;
|
||||
IV.checkChannelButtons();
|
||||
},
|
||||
checkChannelButtons: function() {
|
||||
const channels = document.getElementsByClassName('channel');
|
||||
for (var i = 0; i < channels.length; ++i) {
|
||||
const channel = channels[i];
|
||||
const full = String(channel.getAttribute('data-context'));
|
||||
const value = IV.channelsJoined[full];
|
||||
if (value !== undefined) {
|
||||
channel.classList.toggle('joined', value);
|
||||
}
|
||||
}
|
||||
},
|
||||
slideshowSlide: function(el, delta) {
|
||||
var dir = window.getComputedStyle(el, null).direction || 'ltr';
|
||||
var marginProp = dir == 'rtl' ? 'marginRight' : 'marginLeft';
|
||||
if (delta) {
|
||||
var form = el.parentNode.firstChild;
|
||||
var s = form.s;
|
||||
const next = +s.value + delta;
|
||||
s.value = (next == s.length) ? 0 : (next == -1) ? (s.length - 1) : next;
|
||||
form.nextSibling.firstChild.style[marginProp] = (-100 * s.value) + '%';
|
||||
} else {
|
||||
el.form.nextSibling.firstChild.style[marginProp] = (-100 * el.value) + '%';
|
||||
}
|
||||
return false;
|
||||
},
|
||||
initPreBlocks: function() {
|
||||
if (!hljs) {
|
||||
return;
|
||||
}
|
||||
var pres = document.getElementsByTagName('pre');
|
||||
for (var i = 0; i < pres.length; i++) {
|
||||
if (pres[i].hasAttribute('data-language')) {
|
||||
hljs.highlightBlock(pres[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
initEmbedBlocks: function() {
|
||||
var iframes = document.getElementsByTagName('iframe');
|
||||
for (var i = 0; i < iframes.length; i++) {
|
||||
(function(iframe) {
|
||||
window.addEventListener('message', function(event) {
|
||||
if (event.source !== iframe.contentWindow ||
|
||||
event.origin != window.origin) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var data = JSON.parse(event.data);
|
||||
} catch(e) {
|
||||
var data = {};
|
||||
}
|
||||
if (data.eventType == 'resize_frame') {
|
||||
if (data.eventData.height) {
|
||||
iframe.style.height = data.eventData.height + 'px';
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
})(iframes[i]);
|
||||
}
|
||||
},
|
||||
addRipple: function (button, x, y) {
|
||||
const ripple = document.createElement('span');
|
||||
ripple.classList.add('ripple');
|
||||
|
||||
const inner = document.createElement('span');
|
||||
inner.classList.add('inner');
|
||||
x -= button.offsetLeft;
|
||||
y -= button.offsetTop;
|
||||
|
||||
const mx = button.clientWidth - x;
|
||||
const my = button.clientHeight - y;
|
||||
const sq1 = x * x + y * y;
|
||||
const sq2 = mx * mx + y * y;
|
||||
const sq3 = x * x + my * my;
|
||||
const sq4 = mx * mx + my * my;
|
||||
const radius = Math.sqrt(Math.max(sq1, sq2, sq3, sq4));
|
||||
|
||||
inner.style.width = inner.style.height = `${2 * radius}px`;
|
||||
inner.style.left = `${x - radius}px`;
|
||||
inner.style.top = `${y - radius}px`;
|
||||
inner.classList.add('inner');
|
||||
|
||||
ripple.addEventListener('animationend', function (e) {
|
||||
if (e.animationName === 'fadeOut') {
|
||||
ripple.remove();
|
||||
}
|
||||
});
|
||||
|
||||
ripple.appendChild(inner);
|
||||
button.appendChild(ripple);
|
||||
},
|
||||
stopRipples: function (button) {
|
||||
const id = button.id ? button.id : button;
|
||||
button = document.getElementById(id);
|
||||
const ripples = button.getElementsByClassName('ripple');
|
||||
for (var i = 0; i < ripples.length; ++i) {
|
||||
const ripple = ripples[i];
|
||||
if (!ripple.classList.contains('hiding')) {
|
||||
ripple.classList.add('hiding');
|
||||
}
|
||||
}
|
||||
},
|
||||
init: function () {
|
||||
var current = IV.computeCurrentState();
|
||||
window.history.replaceState(current, '', IV.pageUrl(0));
|
||||
IV.jumpToHash(current.hash, true);
|
||||
|
||||
IV.lastScrollTop = window.history.state.scroll;
|
||||
IV.findPageScroll().onscroll = IV.frameScrolled;
|
||||
|
||||
const buttons = document.getElementsByClassName('fixed_button');
|
||||
for (let i = 0; i < buttons.length; ++i) {
|
||||
const button = buttons[i];
|
||||
button.addEventListener('mousedown', function (e) {
|
||||
IV.addRipple(e.currentTarget, e.clientX, e.clientY);
|
||||
});
|
||||
button.addEventListener('mouseup', function (e) {
|
||||
const id = e.currentTarget.id;
|
||||
setTimeout(function () {
|
||||
IV.stopRipples(id);
|
||||
}, 0);
|
||||
});
|
||||
button.addEventListener('mouseleave', function (e) {
|
||||
IV.stopRipples(e.currentTarget);
|
||||
});
|
||||
}
|
||||
IV.initMedia();
|
||||
IV.notify({ event: 'ready' });
|
||||
|
||||
IV.forceScrollFocus();
|
||||
IV.frameScrolled();
|
||||
},
|
||||
initMedia: function () {
|
||||
var scroll = IV.findPageScroll();
|
||||
const photos = scroll.getElementsByClassName('photo');
|
||||
for (let i = 0; i < photos.length; ++i) {
|
||||
const photo = photos[i];
|
||||
if (photo.classList.contains('loaded')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const url = photo.style.backgroundImage;
|
||||
if (!url || url.length < 7) {
|
||||
continue;
|
||||
}
|
||||
var img = new Image();
|
||||
img.onload = function () {
|
||||
photo.classList.add('loaded');
|
||||
}
|
||||
img.src = url.substr(5, url.length - 7);
|
||||
if (img.complete) {
|
||||
photo.classList.add('loaded');
|
||||
IV.stopAnimations(photo);
|
||||
}
|
||||
}
|
||||
IV.videos = [];
|
||||
const videos = scroll.getElementsByClassName('video');
|
||||
for (let i = 0; i < videos.length; ++i) {
|
||||
const element = videos[i];
|
||||
IV.videos.push({
|
||||
element: element,
|
||||
src: String(element.getAttribute('data-src')),
|
||||
autoplay: (element.getAttribute('data-autoplay') == '1'),
|
||||
loop: (element.getAttribute('data-loop') == '1'),
|
||||
small: (element.getAttribute('data-small') == '1'),
|
||||
filled: (element.firstChild
|
||||
&& element.firstChild.tagName == 'VIDEO'),
|
||||
});
|
||||
}
|
||||
},
|
||||
checkVideos: function () {
|
||||
const visibleTop = IV.lastScrollTop;
|
||||
const visibleBottom = visibleTop + IV.findPageScroll().offsetHeight;
|
||||
const videos = IV.videos;
|
||||
for (let i = 0; i < videos.length; ++i) {
|
||||
const video = videos[i];
|
||||
const element = video.element;
|
||||
const wrap = element.offsetParent; // video-wrap
|
||||
const top = IV.getElementTop(wrap);
|
||||
const bottom = top + wrap.offsetHeight;
|
||||
if (top < visibleBottom && bottom > visibleTop) {
|
||||
if (!video.created) {
|
||||
video.created = new Date();
|
||||
video.loaded = false;
|
||||
element.innerHTML = '<video muted class="'
|
||||
+ (video.small ? 'video-small' : '')
|
||||
+ '"'
|
||||
+ (video.autoplay
|
||||
? ' preload="auto" autoplay'
|
||||
: (video.small
|
||||
? ''
|
||||
: ' controls'))
|
||||
+ (video.loop ? ' loop' : '')
|
||||
+ ' oncanplay="IV.checkVideos();"'
|
||||
+ ' onloadeddata="IV.checkVideos();">'
|
||||
+ '<source src="'
|
||||
+ video.src
|
||||
+ '" type="video/mp4" />'
|
||||
+ '</video>';
|
||||
var media = element.firstChild;
|
||||
media.oncontextmenu = function () { return false; };
|
||||
media.oncanplay = IV.checkVideos;
|
||||
media.onloadeddata = IV.checkVideos;
|
||||
}
|
||||
} else if (video.created && video.autoplay) {
|
||||
video.created = false;
|
||||
element.innerHTML = '';
|
||||
}
|
||||
if (video.created && !video.loaded) {
|
||||
var media = element.firstChild;
|
||||
const HAVE_CURRENT_DATA = 2;
|
||||
if (media && media.readyState >= HAVE_CURRENT_DATA) {
|
||||
video.loaded = true;
|
||||
media.classList.add('loaded');
|
||||
if ((new Date() - video.created) < 100) {
|
||||
IV.stopAnimations(media);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
showTooltip: function (text) {
|
||||
var toast = document.createElement('div');
|
||||
toast.classList.add('toast');
|
||||
toast.textContent = text;
|
||||
document.body.appendChild(toast);
|
||||
setTimeout(function () {
|
||||
toast.classList.add('hiding');
|
||||
}, 2000);
|
||||
setTimeout(function () {
|
||||
document.body.removeChild(toast);
|
||||
}, 3000);
|
||||
},
|
||||
scrollTo: function (y, instant) {
|
||||
if (y < 200) {
|
||||
document.getElementById('bottom_up').classList.add('hidden');
|
||||
}
|
||||
IV.findPageScroll().scrollTo({
|
||||
top: y || 0,
|
||||
behavior: instant ? 'instant' : 'smooth'
|
||||
});
|
||||
},
|
||||
computeCurrentState: function () {
|
||||
var now = IV.findPageScroll();
|
||||
return {
|
||||
position: IV.position,
|
||||
index: IV.index,
|
||||
hash: ((!window.history.state
|
||||
|| window.history.state.hash === undefined)
|
||||
? window.location.hash.substr(1)
|
||||
: window.history.state.hash),
|
||||
scroll: now ? now.scrollTop : 0
|
||||
};
|
||||
},
|
||||
pageUrl: function (index, hash) {
|
||||
var result = 'page' + index + '.html';
|
||||
if (hash) {
|
||||
result += '#' + hash;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
navigateTo: function (index, hash) {
|
||||
if (!index && !IV.index) {
|
||||
IV.navigateToDOM(IV.index, hash);
|
||||
return;
|
||||
}
|
||||
IV.pending = [index, hash];
|
||||
if (!IV.cache[index]) {
|
||||
IV.loadPage(index);
|
||||
} else if (IV.cache[index].dom) {
|
||||
IV.navigateToDOM(index, hash);
|
||||
} else if (IV.cache[index].content) {
|
||||
IV.navigateToLoaded(index, hash);
|
||||
}
|
||||
},
|
||||
applyUpdatedContent: function (index) {
|
||||
if (IV.index != index) {
|
||||
IV.cache[index].contentUpdated = (IV.cache[index].dom !== undefined);
|
||||
return;
|
||||
}
|
||||
var data = JSON.parse(IV.cache[index].content);
|
||||
var article = function (el) {
|
||||
return el.getElementsByTagName('article')[0];
|
||||
};
|
||||
var from = article(IV.findPageScroll());
|
||||
var to = article(IV.makeScrolledContent(data.html));
|
||||
morphdom(from, to, {
|
||||
onBeforeElUpdated: function (fromEl, toEl) {
|
||||
if (fromEl.classList.contains('video')
|
||||
&& toEl.classList.contains('video')
|
||||
&& fromEl.hasAttribute('data-src')
|
||||
&& toEl.hasAttribute('data-src')
|
||||
&& (fromEl.getAttribute('data-src')
|
||||
== toEl.getAttribute('data-src'))) {
|
||||
return false;
|
||||
} else if (fromEl.tagName == 'SECTION'
|
||||
&& fromEl.classList.contains('channel')
|
||||
&& fromEl.hasAttribute('data-context')
|
||||
&& toEl.tagName == 'SECTION'
|
||||
&& toEl.classList.contains('channel')
|
||||
&& toEl.hasAttribute('data-context')
|
||||
&& (String(fromEl.getAttribute('data-context'))
|
||||
== String(toEl.getAttribute('data-context')))) {
|
||||
return false;
|
||||
} else if (fromEl.classList.contains('loaded')) {
|
||||
toEl.classList.add('loaded');
|
||||
}
|
||||
return !fromEl.isEqualNode(toEl);
|
||||
}
|
||||
});
|
||||
IV.initMedia();
|
||||
eval(data.js);
|
||||
},
|
||||
loadPage: function (index) {
|
||||
if (!IV.cache[index]) {
|
||||
IV.cache[index] = {};
|
||||
}
|
||||
IV.cache[index].loading = true;
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onload = function () {
|
||||
IV.cache[index].loading = false;
|
||||
IV.cache[index].content = xhr.responseText;
|
||||
IV.applyUpdatedContent(index);
|
||||
if (IV.pending && IV.pending[0] == index) {
|
||||
IV.navigateToLoaded(index, IV.pending[1]);
|
||||
}
|
||||
if (IV.cache[index].reloadPending) {
|
||||
IV.cache[index].reloadPending = false;
|
||||
IV.reloadPage(index);
|
||||
}
|
||||
}
|
||||
|
||||
xhr.open('GET', 'page' + index + '.json');
|
||||
xhr.send();
|
||||
},
|
||||
reloadPage: function (index) {
|
||||
if (IV.cache[index] && IV.cache[index].loading) {
|
||||
IV.cache[index].reloadPending = true;
|
||||
return;
|
||||
}
|
||||
IV.loadPage(index);
|
||||
},
|
||||
|
||||
makeScrolledContent: function (html) {
|
||||
var result = document.createElement('div');
|
||||
result.className = 'page-scroll';
|
||||
result.tabIndex = '-1';
|
||||
result.innerHTML = '<div class="page-slide"><article>'
|
||||
+ html
|
||||
+ '</article></div>';
|
||||
result.onscroll = IV.frameScrolled;
|
||||
return result;
|
||||
},
|
||||
navigateToLoaded: function (index, hash) {
|
||||
if (IV.cache[index].dom) {
|
||||
IV.navigateToDOM(index, hash);
|
||||
} else {
|
||||
var data = JSON.parse(IV.cache[index].content);
|
||||
IV.cache[index].dom = IV.makeScrolledContent(data.html);
|
||||
|
||||
IV.navigateToDOM(index, hash);
|
||||
eval(data.js);
|
||||
}
|
||||
},
|
||||
navigateToDOM: function (index, hash) {
|
||||
IV.pending = null;
|
||||
if (IV.index == index) {
|
||||
IV.jumpToHash(hash);
|
||||
IV.forceScrollFocus();
|
||||
return;
|
||||
}
|
||||
window.history.replaceState(
|
||||
IV.computeCurrentState(),
|
||||
'',
|
||||
IV.pageUrl(IV.index));
|
||||
|
||||
IV.position = IV.position + 1;
|
||||
window.history.pushState(
|
||||
{ position: IV.position, index: index, hash: hash },
|
||||
'',
|
||||
IV.pageUrl(index));
|
||||
IV.showDOM(index, hash);
|
||||
},
|
||||
findPageScroll: function () {
|
||||
var all = document.getElementsByClassName('page-scroll');
|
||||
for (i = 0; i < all.length; ++i) {
|
||||
if (!all[i].classList.contains('hidden-left')
|
||||
&& !all[i].classList.contains('hidden-right')) {
|
||||
return all[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
showDOM: function (index, hash, scroll) {
|
||||
IV.pending = null;
|
||||
if (IV.index != index) {
|
||||
var initial = !window.history.state
|
||||
|| window.history.state.position === undefined;
|
||||
var back = initial
|
||||
|| IV.position > window.history.state.position;
|
||||
IV.position = initial ? 0 : window.history.state.position;
|
||||
|
||||
var now = IV.cache[index].dom;
|
||||
var was = IV.findPageScroll();
|
||||
if (!IV.cache[IV.index]) {
|
||||
IV.cache[IV.index] = {};
|
||||
}
|
||||
IV.cache[IV.index].dom = was;
|
||||
was.parentNode.appendChild(now);
|
||||
if (scroll !== undefined) {
|
||||
now.scrollTop = scroll;
|
||||
setTimeout(function () {
|
||||
// When returning by history.back to an URL with a hash
|
||||
// for the first time browser forces the scroll to the
|
||||
// hash instead of the saved scroll position.
|
||||
//
|
||||
// This workaround prevents incorrect scroll position.
|
||||
now.scrollTop = scroll;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
now.classList.add(back ? 'hidden-left' : 'hidden-right');
|
||||
now.classList.remove(back ? 'hidden-right' : 'hidden-left');
|
||||
IV.stopAnimations(now.firstChild);
|
||||
|
||||
if (!was.listening) {
|
||||
was.listening = true;
|
||||
was.firstChild.addEventListener('transitionend', function (e) {
|
||||
if (was.classList.contains('hidden-left')
|
||||
|| was.classList.contains('hidden-right')) {
|
||||
if (was.parentNode) {
|
||||
was.parentNode.removeChild(was);
|
||||
var videos = was.getElementsByClassName('video');
|
||||
for (var i = 0; i < videos.length; ++i) {
|
||||
videos[i].innerHTML = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
was.classList.add(back ? 'hidden-right' : 'hidden-left');
|
||||
now.classList.remove(back ? 'hidden-left' : 'hidden-right');
|
||||
|
||||
IV.index = index;
|
||||
IV.notify({
|
||||
event: 'location_change',
|
||||
index: IV.index,
|
||||
position: IV.position,
|
||||
hash: IV.computeCurrentState().hash,
|
||||
});
|
||||
if (IV.cache[index].contentUpdated) {
|
||||
IV.cache[index].contentUpdated = false;
|
||||
IV.applyUpdatedContent(index);
|
||||
} else {
|
||||
IV.initMedia();
|
||||
}
|
||||
IV.checkChannelButtons();
|
||||
if (scroll === undefined) {
|
||||
IV.jumpToHash(hash, true);
|
||||
} else {
|
||||
IV.lastScrollTop = scroll;
|
||||
IV.updateJumpToTop(true);
|
||||
}
|
||||
} else if (scroll !== undefined) {
|
||||
IV.scrollTo(scroll);
|
||||
IV.lastScrollTop = scroll;
|
||||
IV.updateJumpToTop(true);
|
||||
} else {
|
||||
IV.jumpToHash(hash);
|
||||
}
|
||||
|
||||
IV.forceScrollFocus();
|
||||
IV.frameScrolled();
|
||||
},
|
||||
forceScrollFocus: function () {
|
||||
IV.findPageScroll().focus();
|
||||
setTimeout(function () {
|
||||
// Doesn't work on #hash-ed pages in Windows WebView2 otherwise.
|
||||
IV.findPageScroll().focus();
|
||||
}, 100);
|
||||
},
|
||||
stopAnimations: function (element) {
|
||||
element.getAnimations().forEach(
|
||||
(animation) => animation.finish());
|
||||
},
|
||||
back: function () {
|
||||
window.history.back();
|
||||
},
|
||||
menuShown: function (shown) {
|
||||
var already = document.getElementById('menu_page_blocker');
|
||||
if (already && shown) {
|
||||
return;
|
||||
} else if (already) {
|
||||
document.body.removeChild(already);
|
||||
return;
|
||||
} else if (!shown) {
|
||||
return;
|
||||
}
|
||||
var blocker = document.createElement('div');
|
||||
blocker.id = 'menu_page_blocker';
|
||||
document.body.appendChild(blocker);
|
||||
},
|
||||
|
||||
videos: {},
|
||||
videosPlaying: {},
|
||||
|
||||
cache: {},
|
||||
channelsJoined: {},
|
||||
index: 0,
|
||||
position: 0
|
||||
};
|
||||
|
||||
document.onclick = IV.frameClickHandler;
|
||||
document.onkeydown = IV.frameKeyDown;
|
||||
document.onmouseenter = IV.frameMouseEnter;
|
||||
document.onmouseup = IV.frameMouseUp;
|
||||
document.onresize = IV.checkVideos;
|
||||
window.onmessage = IV.postMessageHandler;
|
||||
window.addEventListener('popstate', function (e) {
|
||||
if (e.state) {
|
||||
IV.showDOM(e.state.index, e.state.hash, e.state.scroll);
|
||||
}
|
||||
});
|
||||
document.addEventListener("DOMContentLoaded", IV.forceScrollFocus);
|
||||
@@ -652,6 +652,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_messages_privacy" = "Messages";
|
||||
"lng_settings_voices_privacy" = "Voice messages";
|
||||
"lng_settings_bio_privacy" = "Bio";
|
||||
"lng_settings_birthday_privacy" = "Date of Birth";
|
||||
"lng_settings_privacy_premium" = "Only subscribers of {link} can restrict receiving voice messages.";
|
||||
"lng_settings_privacy_premium_link" = "Telegram Premium";
|
||||
"lng_settings_passcode_disable" = "Disable Passcode";
|
||||
@@ -664,6 +665,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_phone_label" = "Phone number";
|
||||
"lng_settings_username_add" = "Add username";
|
||||
"lng_settings_username_about" = "Username lets people contact you on Telegram without needing your phone number.";
|
||||
"lng_settings_birthday_label" = "Date of Birth";
|
||||
"lng_settings_birthday_add" = "Add";
|
||||
"lng_settings_birthday_about" = "Choose who can see your birthday in {link}.";
|
||||
"lng_settings_birthday_about_link" = "Settings";
|
||||
"lng_settings_birthday_contacts" = "Only your contacts can see your birthday. {link}";
|
||||
"lng_settings_birthday_contacts_link" = "Change >";
|
||||
"lng_settings_birthday_saved" = "Your date of birth was updated.";
|
||||
"lng_settings_birthday_reset" = "Remove";
|
||||
"lng_settings_channel_label" = "Personal channel";
|
||||
"lng_settings_channel_add" = "Add";
|
||||
"lng_settings_channel_remove" = "Remove";
|
||||
"lng_settings_channel_no_yet" = "You don't have any public channels yet.";
|
||||
"lng_settings_channel_start" = "Start a Channel";
|
||||
"lng_settings_channel_saved" = "Your personal channel was updated.";
|
||||
"lng_settings_channel_removed" = "Your personal channel was removed.";
|
||||
"lng_settings_add_account_about" = "You can add up to four accounts with different phone numbers.";
|
||||
"lng_settings_peer_to_peer_about" = "Disabling peer-to-peer will relay all calls through Telegram servers to avoid revealing your IP address, but may slightly decrease audio quality.";
|
||||
"lng_settings_advanced" = "Advanced";
|
||||
@@ -1087,12 +1103,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_privacy_everyone" = "Everybody";
|
||||
"lng_edit_privacy_contacts" = "My contacts";
|
||||
"lng_edit_privacy_close_friends" = "Close friends";
|
||||
"lng_edit_privacy_contacts_and_premium" = "Contacts & Premium";
|
||||
"lng_edit_privacy_nobody" = "Nobody";
|
||||
"lng_edit_privacy_premium" = "Premium users";
|
||||
"lng_edit_privacy_exceptions" = "Add exceptions";
|
||||
"lng_edit_privacy_user_types" = "User types";
|
||||
"lng_edit_privacy_users_and_groups" = "Users and groups";
|
||||
"lng_edit_privacy_premium_status" = "all Telegram Premium subscribers";
|
||||
|
||||
"lng_edit_privacy_exceptions_count#one" = "{count} user";
|
||||
"lng_edit_privacy_exceptions_count#other" = "{count} users";
|
||||
"lng_edit_privacy_exceptions_premium_and" = "Premium & {users}";
|
||||
"lng_edit_privacy_exceptions_add" = "Add users or groups";
|
||||
|
||||
"lng_edit_privacy_phone_number_title" = "Phone number privacy";
|
||||
@@ -1136,6 +1157,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_privacy_about_always_title" = "Always allow";
|
||||
"lng_edit_privacy_about_never_title" = "Never allow";
|
||||
|
||||
"lng_edit_privacy_birthday_title" = "Date of birth privacy";
|
||||
"lng_edit_privacy_birthday_header" = "Who can see my date of birth";
|
||||
"lng_edit_privacy_birthday_always_empty" = "Always allow";
|
||||
"lng_edit_privacy_birthday_never_empty" = "Never allow";
|
||||
"lng_edit_privacy_birthday_exceptions" = "These users will or will not be able to see your date of birth regardless of the settings above.";
|
||||
"lng_edit_privacy_birthday_always_title" = "Always allow";
|
||||
"lng_edit_privacy_birthday_never_title" = "Never allow";
|
||||
"lng_edit_privacy_birthday_yet" = "You haven't entered your date of birth yet.\n{link}";
|
||||
"lng_edit_privacy_birthday_yet_link" = "Add my birthday >";
|
||||
|
||||
"lng_edit_privacy_calls_title" = "Voice calls privacy";
|
||||
"lng_edit_privacy_calls_header" = "Who can call you";
|
||||
"lng_edit_privacy_calls_always_empty" = "Always allow";
|
||||
@@ -1288,6 +1319,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_profile_photo_by_you" = "photo set by you";
|
||||
"lng_profile_public_photo" = "public photo";
|
||||
|
||||
"lng_invite_upgrade_title" = "Upgrade to Premium";
|
||||
"lng_invite_upgrade_group_invite#one" = "{users} only accepts invitations to groups from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_group_invite#other" = "{users} only accept invitations to groups from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_group_write#one" = "{users} only accepts messages and invitations to groups from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_group_write#other" = "{users} only accept messages and invitations to groups from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_channel_invite#one" = "{users} only accepts invitations to channels from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_channel_invite#other" = "{users} only accept invitations to channels from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_channel_write#one" = "{users} only accepts messages and invitations to channels from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_channel_write#other" = "{users} only accept messages and invitations to channels from Contacts and **Premium** users.";
|
||||
"lng_invite_upgrade_users_few" = "{users} and {last}";
|
||||
"lng_invite_upgrade_users_many#one" = "{users} and **{count}** more person";
|
||||
"lng_invite_upgrade_users_many#other" = "{users} and **{count}** more people";
|
||||
"lng_invite_upgrade_or" = "or";
|
||||
"lng_invite_upgrade_via_title" = "Invite via Link";
|
||||
"lng_invite_upgrade_via_group_about" = "You can send an invite link to the group in a private message instead.";
|
||||
"lng_invite_upgrade_via_channel_about" = "You can send an invite link to the channel in a private message instead.";
|
||||
"lng_invite_status_disabled" = "available only to Premium users";
|
||||
|
||||
"lng_via_link_group_one" = "**{user}** restricts adding them to groups.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_group_many#one" = "**{count} user** restricts adding them to groups.\nYou can send them an invite link as message instead.";
|
||||
"lng_via_link_group_many#other" = "**{count} users** restrict adding them to groups.\nYou can send them an invite link as message instead.";
|
||||
@@ -1303,12 +1352,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_via_link_shared_many#one" = "Link shared with **{count} user**.";
|
||||
"lng_via_link_shared_many#other" = "Link shared with **{count} users**.";
|
||||
|
||||
"lng_info_personal_channel_label" = "Channel";
|
||||
"lng_info_mobile_label" = "Mobile";
|
||||
"lng_info_mobile_context_menu_fragment_about" = "This number is not tied to a SIM card and was acquired on {link}.";
|
||||
"lng_info_mobile_context_menu_fragment_about_link" = "Fragment";
|
||||
"lng_info_mobile_hidden" = "Hidden";
|
||||
"lng_info_username_label" = "Username";
|
||||
"lng_info_usernames_label" = "also";
|
||||
"lng_info_birthday_label" = "Date of birth";
|
||||
"lng_info_birthday_years#one" = "{date} ({count} year old)";
|
||||
"lng_info_birthday_years#other" = "{date} ({count} years old)";
|
||||
"lng_info_birthday_today_years#one" = "{date}\n({count} year old)";
|
||||
"lng_info_birthday_today_years#other" = "{date}\n({count} years old)";
|
||||
"lng_info_birthday_today_label" = "Birthday today";
|
||||
"lng_info_birthday_today" = "{emoji} {date}";
|
||||
"lng_info_bio_label" = "Bio";
|
||||
"lng_info_link_label" = "Link";
|
||||
"lng_info_location_label" = "Location";
|
||||
@@ -1540,6 +1597,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_report_button" = "Report";
|
||||
"lng_report_thanks" = "Thank you! Your report will be reviewed by our team very soon.";
|
||||
|
||||
"lng_report_sponsored_hidden" = "Sponsored messages will be hidden.";
|
||||
"lng_report_sponsored_reported" = "We will review this ad to ensure it matches out {link}.";
|
||||
"lng_report_sponsored_reported_link" = "Ad Policies and Guidelines";
|
||||
"lng_report_sponsored_reported_learn" = "Learn more about our {link}.";
|
||||
|
||||
"lng_channel_add_members" = "Add members";
|
||||
"lng_channel_add_users" = "Add users";
|
||||
"lng_channel_add_removed" = "Remove user";
|
||||
@@ -1760,6 +1822,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_action_giveaway_results_none" = "No winners of the giveaway could be selected.";
|
||||
"lng_action_boost_apply#one" = "{from} boosted the group";
|
||||
"lng_action_boost_apply#other" = "{from} boosted the group {count} times";
|
||||
"lng_action_set_chat_intro" = "{from} added the message below for all empty chats. How?";
|
||||
|
||||
"lng_similar_channels_title" = "Similar channels";
|
||||
"lng_similar_channels_view_all" = "View all";
|
||||
@@ -1919,6 +1982,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_forwarded_imported" = "This message was imported from another app. It may not be real.";
|
||||
"lng_signed_author" = "Author: {user}";
|
||||
"lng_sponsored_message_title" = "Sponsored";
|
||||
"lng_sponsored_message_revenue_button" = "what's this?";
|
||||
"lng_recommended_message_title" = "Recommended";
|
||||
"lng_edited" = "edited";
|
||||
"lng_commented" = "commented";
|
||||
@@ -2185,6 +2249,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_business_about_away_messages" = "Define messages that are automatically sent when you are off.";
|
||||
"lng_business_subtitle_chatbots" = "Chatbots";
|
||||
"lng_business_about_chatbots" = "Add any third party chatbots that will process customer interactions.";
|
||||
"lng_business_subtitle_chat_intro" = "Custom Intro";
|
||||
"lng_business_about_chat_intro" = "Customize the message people see before they start a chat with you.";
|
||||
"lng_business_subtitle_chat_links" = "Links to Chat";
|
||||
"lng_business_about_chat_links" = "Create links that start a chat with you, suggesting the first message.";
|
||||
|
||||
"lng_location_title" = "Location";
|
||||
"lng_location_about" = "Display the location of your business on your account.";
|
||||
@@ -2286,8 +2354,52 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_chatbots_reply_about" = "The bot will be able to view all new incoming messages, but not the messages that had been sent before you added the bot.";
|
||||
"lng_chatbots_remove" = "Remove Bot";
|
||||
"lng_chatbots_not_found" = "Chatbot not found.";
|
||||
"lng_chatbots_not_supported" = "This bot doesn't support Telegram Business yet.";
|
||||
"lng_chatbots_add" = "Add";
|
||||
"lng_chatbots_info_url" = "https://telegram.org/privacy";
|
||||
"lng_chatbot_status_can_reply" = "bot manages this chat";
|
||||
"lng_chatbot_status_paused" = "bot stopped";
|
||||
"lng_chatbot_status_views" = "bot has access to this chat";
|
||||
"lng_chatbot_button_pause" = "Stop";
|
||||
"lng_chatbot_button_resume" = "Start";
|
||||
"lng_chatbot_menu_manage" = "Manage bot";
|
||||
"lng_chatbot_menu_remove" = "Remove bot from this chat";
|
||||
"lng_chatbot_menu_revoke" = "Revoke access to this chat";
|
||||
|
||||
"lng_chat_intro_title" = "Custom Intro";
|
||||
"lng_chat_intro_subtitle" = "Customize your intro";
|
||||
"lng_chat_intro_default_title" = "No messages here yet...";
|
||||
"lng_chat_intro_default_message" = "Send a message or click on the greeting below";
|
||||
"lng_chat_intro_enter_title" = "Enter Title";
|
||||
"lng_chat_intro_enter_message" = "Enter Message";
|
||||
"lng_chat_intro_choose_sticker" = "Choose Sticker";
|
||||
"lng_chat_intro_random_sticker" = "Random";
|
||||
"lng_chat_intro_about" = "You can customize the message people see before they start a chat with you.";
|
||||
"lng_chat_intro_reset" = "Reset to Default";
|
||||
|
||||
"lng_chat_links_title" = "Links to Chat";
|
||||
"lng_chat_links_about" = "Give your customers short links that start a chat with you – and suggest the first message from them to you.";
|
||||
"lng_chat_links_create_link" = "Create a Link to Chat";
|
||||
"lng_chat_links_footer" = "You can also use a simple link for a chat with you – {links}";
|
||||
"lng_chat_links_footer_both" = "{username} or {link}";
|
||||
"lng_chat_links_no_clicks" = "no clicks";
|
||||
"lng_chat_links_clicks#one" = "{count} click";
|
||||
"lng_chat_links_clicks#other" = "{count} clicks";
|
||||
"lng_chat_link_new_title" = "New Link";
|
||||
"lng_chat_link_edit_title" = "Edit Link";
|
||||
"lng_chat_link_description" = "Add a message that will be entered in the message field for anyone who starts a chat with you using this link.";
|
||||
"lng_chat_link_placeholder" = "Add Preset Message";
|
||||
"lng_chat_link_saved" = "Chat link saved.";
|
||||
"lng_chat_link_copy" = "Copy";
|
||||
"lng_chat_link_share" = "Share";
|
||||
"lng_chat_link_rename" = "Rename";
|
||||
"lng_chat_link_delete" = "Delete";
|
||||
"lng_chat_link_name" = "Link Name (optional)";
|
||||
"lng_chat_link_name_about" = "Add a name for this link that only you will see.";
|
||||
"lng_chat_link_delete_sure" = "Are you sure you want to delete this chat link?";
|
||||
"lng_chat_link_qr_title" = "Chat Link QR Code";
|
||||
"lng_chat_link_qr_about" = "Everyone on Telegram can scan this code to contact you.";
|
||||
"lng_chat_link_copied" = "Chat link copied to clipboard.";
|
||||
|
||||
"lng_boost_channel_button" = "Boost Channel";
|
||||
"lng_boost_group_button" = "Boost Group";
|
||||
@@ -2387,6 +2499,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_boost_channel_needs_level_reactions#one" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as a reaction.";
|
||||
"lng_boost_channel_needs_level_reactions#other" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as reactions.";
|
||||
|
||||
"lng_boost_channel_title_cpm" = "Boost Channel";
|
||||
"lng_boost_channel_needs_level_cpm#one" = "Your channel needs to reach **Level {count}** to switch off ads.";
|
||||
"lng_boost_channel_needs_level_cpm#other" = "Your channel needs to reach **Level {count}** to switch off ads.";
|
||||
|
||||
"lng_boost_group_title_emoji" = "Enable emoji pack";
|
||||
"lng_boost_group_needs_level_emoji#one" = "Your group needs to reach **Level {count}** to set emoji pack.";
|
||||
"lng_boost_group_needs_level_emoji#other" = "Your group needs to reach **Level {count}** to set emoji pack.";
|
||||
@@ -2593,6 +2709,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_gift_link_also_send" = "You can also {link} to a friend as a gift.";
|
||||
"lng_gift_link_also_send_link" = "send this link";
|
||||
"lng_gift_link_use" = "Use Link";
|
||||
"lng_gift_link_already_title" = "You already have Telegram Premium";
|
||||
"lng_gift_link_already_about" = "You can activate this link after {date} or {link} to a friend.";
|
||||
"lng_gift_link_already_link" = "send the link";
|
||||
"lng_gift_link_used_title" = "Used Gift Link";
|
||||
"lng_gift_link_used_about" = "This link was used to activate\na **Telegram Premium** subscription.";
|
||||
"lng_gift_link_used_footer" = "This link was used on {date}.";
|
||||
@@ -2883,6 +3002,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_bot_remove_from_side_menu_done" = "Bot removed from the main menu.";
|
||||
"lng_bot_settings" = "Settings";
|
||||
"lng_bot_open" = "Open Bot";
|
||||
"lng_bot_terms" = "Terms of Use";
|
||||
"lng_bot_reload_page" = "Reload Page";
|
||||
"lng_bot_add_to_menu" = "{bot} asks your permission to be added as an option to your attachments menu so you can access it from any chat.";
|
||||
"lng_bot_add_to_menu_done" = "Bot added to the menu.";
|
||||
@@ -3013,6 +3133,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_context_delete_msg" = "Delete Message";
|
||||
"lng_context_auto_delete_in" = "auto-delete in {duration}";
|
||||
"lng_context_select_msg" = "Select Message";
|
||||
"lng_context_select_msg_bulk" = "Select up to this message";
|
||||
"lng_context_report_msg" = "Report Message";
|
||||
"lng_context_pin_msg" = "Pin Message";
|
||||
"lng_context_unpin_msg" = "Unpin Message";
|
||||
@@ -3511,6 +3632,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_call_cancel" = "Cancel";
|
||||
|
||||
"lng_call_microphone_off" = "{user}'s microphone is off";
|
||||
"lng_call_battery_level_low" = "{user}'s battery level is low";
|
||||
|
||||
"lng_group_call_title" = "Voice Chat";
|
||||
"lng_group_call_title_channel" = "Live Stream";
|
||||
@@ -4561,6 +4683,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_view_button_external_link" = "Open link";
|
||||
"lng_view_button_boost" = "Boost";
|
||||
"lng_view_button_giftcode" = "Open";
|
||||
"lng_view_button_iv" = "Instant View";
|
||||
|
||||
"lng_sponsored_hide_ads" = "Hide";
|
||||
"lng_sponsored_title" = "What are sponsored messages?";
|
||||
@@ -4568,6 +4691,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_sponsored_info_description2" = "Sponsored Messages are currently in test mode. Once they are fully launched and allow Telegram to cover its basic costs, we will start sharing ad revenue with the owners of public channels in which sponsored messages are displayed.\n\nOnline ads should no longer be synonymous with abuse of user privacy. Let us redefine how a tech company should operate – together.";
|
||||
"lng_sponsored_info_menu" = "About this ad";
|
||||
"lng_sponsored_info_submenu" = "Advertiser: {text}";
|
||||
"lng_sponsored_menu_revenued_about" = "About These Ads";
|
||||
"lng_sponsored_menu_revenued_report" = "Report Ad";
|
||||
"lng_sponsored_revenued_subtitle" = "Telegram Ads are very different from ads on other platforms. Ads such as this one:";
|
||||
"lng_sponsored_revenued_info1_title" = "Respect Your Privacy";
|
||||
"lng_sponsored_revenued_info1_description" = "Ads on Telegram do not use your personal information and are abased on the channel in which you see them.";
|
||||
"lng_sponsored_revenued_info2_title" = "Help the Channel Creator";
|
||||
"lng_sponsored_revenued_info2_description" = "50% of the revenue from Telegram Ads goes to the owner of the channel where they are displayed.";
|
||||
"lng_sponsored_revenued_info3_title" = "Can Be Removed";
|
||||
"lng_sponsored_revenued_info3_description#one" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
|
||||
"lng_sponsored_revenued_info3_description#other" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
|
||||
"lng_sponsored_revenued_footer_title" = "Can I Launch an Ad?";
|
||||
"lng_sponsored_revenued_footer_description" = "Anyone can create an ad to display in this channel — with minimal budgets. Check out the **Telegram Ad Platform** for details. {link}";
|
||||
|
||||
"lng_telegram_features_url" = "https://t.me/TelegramTips";
|
||||
|
||||
@@ -4863,9 +4998,74 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_boosts_prepaid_giveaway_status#one" = "{count} subscription {duration}";
|
||||
"lng_boosts_prepaid_giveaway_status#other" = "{count} subscriptions {duration}";
|
||||
|
||||
"lng_channel_earn_title" = "Monetization";
|
||||
"lng_channel_earn_about" = "Telegram shares 50% of the revenue from ads displayed in your channel. {link}";
|
||||
"lng_channel_earn_about_link" = "Learn more {emoji}";
|
||||
"lng_channel_earn_overview_title" = "Proceeds overview";
|
||||
"lng_channel_earn_available" = "Balance available to withdraw";
|
||||
"lng_channel_earn_reward" = "Proceeds since last withdrawal";
|
||||
"lng_channel_earn_total" = "Total lifetime proceeds";
|
||||
"lng_channel_earn_balance_title" = "Available balance";
|
||||
"lng_channel_earn_balance_button" = "Withdraw";
|
||||
"lng_channel_earn_balance_password_title" = "Two-step verification";
|
||||
"lng_channel_earn_balance_password_description" = "Please enter your password to withdraw.";
|
||||
"lng_channel_earn_balance_about" = "Collect your reward using Fragment, a third-party platform used by the advertiser to pay for the ad. {link}";
|
||||
"lng_channel_earn_balance_about_temp" = "In the coming weeks you will be able to collect your reward using Fragment, a third-party platform used by advertisers to pay ads. {link}";
|
||||
"lng_channel_earn_transfer_sure_about1" = "Check the address of the recipient:";
|
||||
"lng_channel_earn_transfer_sure_about2" = "This action can not be undone. If the address above is incorrect you will lose your TON.";
|
||||
"lng_channel_earn_history_title" = "Transaction history";
|
||||
"lng_channel_earn_history_in" = "Proceeds from ads";
|
||||
"lng_channel_earn_history_in_about" = "Proceeds from ads displayed in";
|
||||
"lng_channel_earn_history_out" = "Withdrawal";
|
||||
"lng_channel_earn_history_out_failed" = "Not Completed";
|
||||
"lng_channel_earn_history_out_about_failed" = "Withdrawal failed";
|
||||
"lng_channel_earn_history_out_button" = "View in Blockchain Explorer";
|
||||
"lng_channel_earn_history_return" = "Refund";
|
||||
"lng_channel_earn_history_return_about" = "Refunded back";
|
||||
"lng_channel_earn_history_pending" = "Pending";
|
||||
"lng_channel_earn_history_show_more#one" = "Show {count} More Transaction";
|
||||
"lng_channel_earn_history_show_more#other" = "Show {count} More Transactions";
|
||||
"lng_channel_earn_off" = "Switch Off Ads";
|
||||
"lng_channel_earn_off_about" = "You will not be eligible for any rewards if you switch off ads.";
|
||||
"lng_channel_earn_cpm_min" = "No Ads";
|
||||
"lng_channel_earn_cpm#one" = "{emoji} {count} CPM";
|
||||
"lng_channel_earn_cpm#other" = "{emoji} {count} CPM";
|
||||
"lng_channel_earn_learn_title" = "Earn From Your Channel";
|
||||
"lng_channel_earn_learn_in_subtitle" = "Telegram Ads";
|
||||
"lng_channel_earn_learn_in_about" = "Telegram can display ads in your channel.";
|
||||
"lng_channel_earn_learn_split_subtitle" = "50:50 revenue split";
|
||||
"lng_channel_earn_learn_split_about" = "You can receive 50% of the ad revenue in TON.";
|
||||
"lng_channel_earn_learn_out_subtitle" = "Flexible withdrawals";
|
||||
"lng_channel_earn_learn_out_about" = "You can withdraw your TON any time.";
|
||||
"lng_channel_earn_learn_coin_title" = "What is {emoji} TON?";
|
||||
"lng_channel_earn_learn_coin_about" = "TON is a blockchain platform and cryptocurrency that Telegram uses for its high speed and low commissions on transactions. {link}";
|
||||
"lng_channel_earn_learn_close" = "Got it";
|
||||
"lng_channel_earn_chart_top_hours" = "Ad impressions";
|
||||
"lng_channel_earn_chart_revenue" = "Ad revenue";
|
||||
"lng_channel_earn_chart_overriden_detail_currency" = "Revenue in TON";
|
||||
"lng_channel_earn_chart_overriden_detail_usd" = "Revenue in USD";
|
||||
|
||||
"lng_contact_add" = "Add";
|
||||
"lng_contact_send_message" = "message";
|
||||
|
||||
"lng_iv_open_in_browser" = "Open in Browser";
|
||||
"lng_iv_share" = "Share";
|
||||
"lng_iv_join_channel" = "Join";
|
||||
"lng_iv_window_title" = "Instant View";
|
||||
|
||||
"lng_limit_download_title" = "Download speed limited";
|
||||
"lng_limit_download_subscribe" = "Subscribe to {link} and increase download speed {increase}.";
|
||||
"lng_limit_download_increase_times#one" = "**{count}** time";
|
||||
"lng_limit_download_increase_times#other" = "**{count}** times";
|
||||
"lng_limit_download_increase_speed" = "by **{percent}**";
|
||||
"lng_limit_download_subscribe_link" = "Telegram Premium";
|
||||
"lng_limit_upload_title" = "Upload speed limited";
|
||||
"lng_limit_upload_subscribe" = "Subscribe to {link} and increase upload speed {increase}.";
|
||||
"lng_limit_upload_increase_times#one" = "**{count}** time";
|
||||
"lng_limit_upload_increase_times#other" = "**{count}** times";
|
||||
"lng_limit_upload_increase_speed" = "by **{percent}**";
|
||||
"lng_limit_upload_subscribe_link" = "Telegram Premium";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
"lng_wnd_choose_program_menu" = "Choose Default Program...";
|
||||
@@ -4937,27 +5137,33 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
"ayu_AyuPreferences" = "AyuGram Preferences";
|
||||
"ayu_DocsText" = "Documentation";
|
||||
"ayu_CategoryGhostMode" = "Ghost Mode";
|
||||
"ayu_CategorySpy" = "Spy";
|
||||
"ayu_CategoryFilters" = "Filters";
|
||||
"ayu_CategoryCustomization" = "Customization";
|
||||
"ayu_GhostEssentialsHeader" = "Ghost essentials";
|
||||
"ayu_DontReadMessages" = "Don't read messages";
|
||||
"ayu_DontReadStories" = "Don't read stories";
|
||||
"ayu_DontSendOnlinePackets" = "Don't send online";
|
||||
"ayu_DontSendUploadProgress" = "Don't send typing";
|
||||
"ayu_SendOfflinePacketAfterOnline" = "Immediate offline after online";
|
||||
"ayu_MarkReadAfterAction" = "Mark read after actions";
|
||||
"ayu_DontReadMessages" = "Don't Read Messages";
|
||||
"ayu_DontReadStories" = "Don't Read Stories";
|
||||
"ayu_DontSendOnlinePackets" = "Don't Send Online";
|
||||
"ayu_DontSendUploadProgress" = "Don't Send Typing";
|
||||
"ayu_SendOfflinePacketAfterOnline" = "Go Offline Automatically";
|
||||
"ayu_MarkReadAfterAction" = "Read on Interact";
|
||||
"ayu_MarkReadAfterActionDescription" = "Automatically reads message when you send a new one or tap a reaction.";
|
||||
"ayu_MarkReadAfterSend" = "Send";
|
||||
"ayu_MarkReadAfterReaction" = "Reaction";
|
||||
"ayu_MarkReadAfterPoll" = "Poll";
|
||||
"ayu_UseScheduledMessages" = "Schedule messages";
|
||||
"ayu_SuggestGhostModeBeforeViewingStory" = "Alert before opening story";
|
||||
"ayu_UseScheduledMessages" = "Schedule Messages";
|
||||
"ayu_UseScheduledMessagesDescription" = "Automatically schedules outgoing messages for ~12 seconds, and more for media. Don't use on bad networks.";
|
||||
"ayu_SendWithoutSoundByDefault" = "Send without Sound";
|
||||
"ayu_SendWithoutSoundByDefaultDescription" = "Automatically sends outgoing messages without sound.";
|
||||
"ayu_SuggestGhostModeBeforeViewingStory" = "Story Ghost Mode Alert";
|
||||
"ayu_SuggestGhostModeBeforeViewingStoryDescription" = "Shows an alert before opening the story, suggesting to turn on Ghost Mode.";
|
||||
"ayu_SpyEssentialsHeader" = "Spy essentials";
|
||||
"ayu_SaveDeletedMessages" = "Save deleted messages";
|
||||
"ayu_SaveMessagesHistory" = "Save edits history";
|
||||
"ayu_SaveDeletedMessages" = "Save Deleted Messages";
|
||||
"ayu_SaveMessagesHistory" = "Save Edits History";
|
||||
"ayu_MessageSavingActionBarHeader" = "Message Saving Preferences";
|
||||
"ayu_MessageSavingBtn" = "Preferences";
|
||||
"ayu_MessageSavingSubTitle" = "Configure media & per dialog saving";
|
||||
"ayu_MessageSavingMediaHeader" = "Media";
|
||||
"ayu_MessageSavingSaveMedia" = "Save media";
|
||||
"ayu_MessageSavingSaveMediaHint" = "Click for more";
|
||||
"ayu_MessageSavingSaveMedia" = "Save Media";
|
||||
"ayu_MessageSavingSaveMediaHint" = "Click for More";
|
||||
"ayu_MessageSavingSaveMediaInPrivateChats" = "…in private chats";
|
||||
"ayu_MessageSavingSaveMediaInPublicChannels" = "…in public channels";
|
||||
"ayu_MessageSavingSaveMediaInPrivateChannels" = "…in private channels";
|
||||
@@ -4967,47 +5173,57 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_MaximumMediaSizeWiFi" = "Media size limit (WiFi)";
|
||||
"ayu_MessageSavingOtherHeader" = "Other";
|
||||
"ayu_MessageSavingSaveReactions" = "Save reactions";
|
||||
"ayu_MessageSavingSaveForBots" = "Save in bot dialogs";
|
||||
"ayu_MessageSavingSavePath" = "Attachments folder";
|
||||
"ayu_MessageSavingSaveForBots" = "Save in Bot Dialogs";
|
||||
"ayu_MessageSavingSavePath" = "Attachments Folder";
|
||||
"ayu_MessageSavingSavePathTitle" = "Choose folder";
|
||||
"ayu_SpyAllToggle" = "Spy on people";
|
||||
"ayu_SpySaveReadMarks" = "Save read date";
|
||||
"ayu_SpySaveLastActivity" = "Save last activity";
|
||||
"ayu_SpySaveReadMarks" = "Save Read Date";
|
||||
"ayu_SpySaveReadMarksDescription" = "Locally saves data about reading messages. This will be shown if Telegram does not provide read date.";
|
||||
"ayu_QoLTogglesHeader" = "Useful features";
|
||||
"ayu_KeepAliveService" = "AyuGram Push Service";
|
||||
"ayu_DisableAds" = "Disable ads";
|
||||
"ayu_DisableStories" = "Disable stories";
|
||||
"ayu_DisableCustomBackgrounds" = "Disable custom backgrounds";
|
||||
"ayu_DisableNotificationsDelay" = "Disable notify delay";
|
||||
"ayu_DisableAds" = "Disable Ads";
|
||||
"ayu_DisableStories" = "Disable Stories";
|
||||
"ayu_DisableCustomBackgrounds" = "Disable Custom Backgrounds";
|
||||
"ayu_DisableNotificationsDelay" = "Disable Notify Delay";
|
||||
"ayu_LocalPremium" = "Local Telegram Premium";
|
||||
"ayu_CopyUsernameAsLink" = "Copy username as link";
|
||||
"ayu_CopyUsernameAsLink" = "Copy Username as Link";
|
||||
"ayu_CustomizationHeader" = "Customization";
|
||||
"ayu_DeletedMarkText" = "Deleted mark";
|
||||
"ayu_DeletedMarkText" = "Deleted Mark";
|
||||
"ayu_DeletedMarkNothing" = "Nothing";
|
||||
"ayu_DeletedMarkTrashBin" = "Trash Bin";
|
||||
"ayu_DeletedMarkCross" = "Cross";
|
||||
"ayu_DeletedMarkEyeCrossed" = "Eye crossed";
|
||||
"ayu_EditedMarkText" = "Edited mark";
|
||||
"ayu_SemiTransparentDeletedMessages" = "Semi-transparent deleted messages";
|
||||
"ayu_HideNotificationCounters" = "Hide notification counters";
|
||||
"ayu_HideAllChats" = "Hide \"All chats\" folder";
|
||||
"ayu_ShowGhostToggleInDrawer" = "Show ghost mode toggle";
|
||||
"ayu_ShowKllButtonInDrawer" = "Show kill app button";
|
||||
"ayu_SettingsShowID" = "Show peer ID";
|
||||
"ayu_DeletedMarkEyeCrossed" = "Eye Crossed";
|
||||
"ayu_EditedMarkText" = "Edited Mark";
|
||||
"ayu_SemiTransparentDeletedMessages" = "Translucent Deleted Messages";
|
||||
"ayu_HideNotificationCounters" = "Hide Notification Counters";
|
||||
"ayu_HideAllChats" = "Hide \"All Chats\" Tab";
|
||||
"ayu_SettingsShowID" = "Show Peer ID";
|
||||
"ayu_SettingsShowID_Hide" = "Hide";
|
||||
"ayu_SettingsShowMessageShot" = "Show message shot";
|
||||
"ayu_SettingsRecentStickersCount" = "Recent stickers count";
|
||||
"ayu_SettingsShowMessageShot" = "Show Message Shot";
|
||||
"ayu_SettingsRecentStickersCount" = "Recent Stickers Count";
|
||||
"ayu_SettingsCustomizationHint" = "After making changes to the \"Customization\" section, you must restart the application.";
|
||||
"ayu_SettingsContextMenuTitle" = "Select item show type";
|
||||
"ayu_SettingsContextMenuTitle" = "Choose when to show the item";
|
||||
"ayu_SettingsContextMenuDescription" = "Extended menu items will be displayed if you hold CTRL or SHIFT while right-clicking on the message.";
|
||||
"ayu_SettingsContextMenuItemHidden" = "Hidden";
|
||||
"ayu_SettingsContextMenuItemShown" = "Shown";
|
||||
"ayu_SettingsContextMenuItemExtended" = "Extended menu";
|
||||
"ayu_SettingsContextMenuItemExtended" = "Extended Menu";
|
||||
"ayu_SettingsContextMenuReactionsPanel" = "Reactions Panel";
|
||||
"ayu_SettingsContextMenuViewsPanel" = "Views Panel";
|
||||
"ayu_ContextMenuElementsHeader" = "Context Menu Elements";
|
||||
"ayu_DrawerElementsHeader" = "Drawer Elements";
|
||||
"ayu_TrayElementsHeader" = "Tray Elements";
|
||||
"ayu_ExportDataTitle" = "Export AyuGram Database?";
|
||||
"ayu_ExportDataDescription" = "It will be exported to the public folder, to Saved Attachments.";
|
||||
"ayu_ExportDataConfirm" = "Yes, export";
|
||||
"ayu_ExportDataCancel" = "No, close window";
|
||||
"ayu_ExportDataSuccess" = "Database exported successfully.";
|
||||
"ayu_ExportDataFailure" = "Failed to export database.";
|
||||
"ayu_ImportDataNotFound" = "No database to import.";
|
||||
"ayu_ImportDataTitle" = "Import AyuGram Database?";
|
||||
"ayu_ImportDataDescription" = "It will replace the current database.";
|
||||
"ayu_ImportDataConfirm" = "Yes, replace existing";
|
||||
"ayu_ImportDataCancel" = "No, close window";
|
||||
"ayu_ImportDataSuccess" = "Database imported successfully.";
|
||||
"ayu_ImportDataFailure" = "Failed to import database.";
|
||||
"ayu_RegexFilters" = "Message Filters";
|
||||
"ayu_RegexFiltersAmount_zero" = "%1$d filters";
|
||||
"ayu_RegexFiltersAmount_one" = "1 filter";
|
||||
@@ -5022,40 +5238,78 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_RegexFiltersExcludedAmount_many" = "%1$d excluded";
|
||||
"ayu_RegexFiltersExcludedAmount_other" = "%1$d excluded";
|
||||
"ayu_RegexFiltersHeader" = "Filters";
|
||||
"ayu_RegexFiltersShared" = "Shared filters";
|
||||
"ayu_RegexFiltersExcluded" = "Excluded filters";
|
||||
"ayu_FiltersHideFromBlocked" = "Hide from blocked users";
|
||||
"ayu_RegexFiltersShared" = "Shared Filters";
|
||||
"ayu_RegexFiltersExcluded" = "Excluded Filters";
|
||||
"ayu_RegexFiltersEnable" = "Enable Filters";
|
||||
"ayu_FiltersHideFromBlocked" = "Hide from Blocked Users";
|
||||
"ayu_FiltersHideFromBlockedNote" = "Message filters were enabled.";
|
||||
"ayu_RegexFiltersEnableSharedInChats" = "Enable shared filters in chats";
|
||||
"ayu_RegexFiltersAdd" = "Add filter";
|
||||
"ayu_RegexFiltersEdit" = "Edit filter";
|
||||
"ayu_RegexFiltersEnableSharedInChats" = "Enable Shared Filters in Chats";
|
||||
"ayu_RegexFiltersAdd" = "Add Filter";
|
||||
"ayu_RegexFiltersEdit" = "Edit Filter";
|
||||
"ayu_RegexFiltersPlaceholder" = "Expression";
|
||||
"ayu_EnableExpression" = "Enable expression";
|
||||
"ayu_CaseInsensitiveExpression" = "Case insensitive expression";
|
||||
"ayu_RegexFiltersAddError" = "Regex syntax error";
|
||||
"ayu_RegexFilterQuickAdd" = "Add filter";
|
||||
"ayu_RegexFilterQuickAdd" = "Add Filter";
|
||||
"ayu_RegexFilterBulletinText" = "Filter added to the **Shared filters**.";
|
||||
"ayu_RegexFilterBulletinAction" = "Move to current chat";
|
||||
"ayu_AyuSyncHeader" = "AyuSync";
|
||||
"ayu_AyuSyncStatusTitle" = "Sync status";
|
||||
"ayu_AyuSyncStatusOk" = "connected";
|
||||
"ayu_AyuSyncStatusErrorDisconnected" = "disconnected";
|
||||
"ayu_AyuSyncStatusErrorNoToken" = "no token";
|
||||
"ayu_AyuSyncStatusErrorInvalidToken" = "invalid token";
|
||||
"ayu_AyuSyncServerURL" = "Server URL";
|
||||
"ayu_AyuSyncServerToken" = "Access token";
|
||||
"ayu_AyuSyncEnable" = "Enable synchronization";
|
||||
"ayu_AyuSyncVisitProfile" = "Visit profile";
|
||||
"ayu_AyuSyncForceSync" = "Force sync clients";
|
||||
"ayu_AyuSyncDeviceIdentifier" = "Device ID";
|
||||
"ayu_AyuSyncLastEventSent" = "Last sent event";
|
||||
"ayu_AyuSyncLastEventReceived" = "Last received event";
|
||||
"ayu_AyuSyncLastEventNever" = "never";
|
||||
"ayu_AyuSyncUseSecureConnection" = "Use HTTPS & WSS";
|
||||
"ayu_AyuSyncIdentifierCopied" = "Identifier copied to clipboard.";
|
||||
"ayu_AyuSyncRegisterStatusCode" = "Register status code";
|
||||
"ayu_AyuSyncOpenPreferences" = "Open preferences";
|
||||
"ayu_AyuSyncDownloadAgent" = "Download agent";
|
||||
"ayu_RegexFilterBulletinAction" = "To Current Chat";
|
||||
"ayu_FiltersMenuSelectChat" = "Select Chat";
|
||||
"ayu_FiltersMenuImport" = "Import";
|
||||
"ayu_FiltersMenuExport" = "Export";
|
||||
"ayu_FiltersMenuClear" = "Clear";
|
||||
"ayu_FiltersImportTitle" = "Select a way to import filters";
|
||||
"ayu_FiltersImportClipboard" = "Paste from Clipboard";
|
||||
"ayu_FiltersImportURL" = "Import from URL";
|
||||
"ayu_FiltersImportAction" = "Import";
|
||||
"ayu_FiltersExportTitle" = "Select a way to export filters";
|
||||
"ayu_FiltersExportClipboard" = "Copy to Clipboard";
|
||||
"ayu_FiltersExportURL" = "Publish on dpaste.com";
|
||||
"ayu_FiltersToastFailPublish" = "Failed to publish filters.";
|
||||
"ayu_FiltersToastFailFetch" = "Failed to fetch filters.";
|
||||
"ayu_FiltersToastFailImport" = "Failed to import filters.";
|
||||
"ayu_FiltersToastFailNoChanges" = "Filters are the same as current.";
|
||||
"ayu_FiltersToastSuccess" = "Filters successfully imported.";
|
||||
"ayu_FiltersSheetTitle" = "Apply filter changes?";
|
||||
"ayu_FiltersSheetNewFilters_zero" = "**%1$d** new filters";
|
||||
"ayu_FiltersSheetNewFilters_one" = "**1** new filter";
|
||||
"ayu_FiltersSheetNewFilters_two" = "**%1$d** new filters";
|
||||
"ayu_FiltersSheetNewFilters_few" = "**%1$d** new filters";
|
||||
"ayu_FiltersSheetNewFilters_many" = "**%1$d** new filters";
|
||||
"ayu_FiltersSheetNewFilters_other" = "**%1$d** new filters";
|
||||
"ayu_FiltersSheetRemovedFilters_zero" = "**%1$d** removed filters";
|
||||
"ayu_FiltersSheetRemovedFilters_one" = "**1** removed filter";
|
||||
"ayu_FiltersSheetRemovedFilters_two" = "**%1$d** removed filters";
|
||||
"ayu_FiltersSheetRemovedFilters_few" = "**%1$d** removed filters";
|
||||
"ayu_FiltersSheetRemovedFilters_many" = "**%1$d** removed filters";
|
||||
"ayu_FiltersSheetRemovedFilters_other" = "**%1$d** removed filters";
|
||||
"ayu_FiltersSheetUpdatedFilters_zero" = "**%1$d** updated filters";
|
||||
"ayu_FiltersSheetUpdatedFilters_one" = "**1** updated filter";
|
||||
"ayu_FiltersSheetUpdatedFilters_two" = "**%1$d** updated filters";
|
||||
"ayu_FiltersSheetUpdatedFilters_few" = "**%1$d** updated filters";
|
||||
"ayu_FiltersSheetUpdatedFilters_many" = "**%1$d** updated filters";
|
||||
"ayu_FiltersSheetUpdatedFilters_other" = "**%1$d** updated filters";
|
||||
"ayu_FiltersSheetNewExclusions_zero" = "**%1$d** new exclusions";
|
||||
"ayu_FiltersSheetNewExclusions_one" = "**1** new exclusion";
|
||||
"ayu_FiltersSheetNewExclusions_two" = "**%1$d** new exclusions";
|
||||
"ayu_FiltersSheetNewExclusions_few" = "**%1$d** new exclusions";
|
||||
"ayu_FiltersSheetNewExclusions_many" = "**%1$d** new exclusions";
|
||||
"ayu_FiltersSheetNewExclusions_other" = "**%1$d** new exclusions";
|
||||
"ayu_FiltersSheetRemovedExclusions_zero" = "**%1$d** removed exclusions";
|
||||
"ayu_FiltersSheetRemovedExclusions_one" = "**1** removed exclusion";
|
||||
"ayu_FiltersSheetRemovedExclusions_two" = "**%1$d** removed exclusions";
|
||||
"ayu_FiltersSheetRemovedExclusions_few" = "**%1$d** removed exclusions";
|
||||
"ayu_FiltersSheetRemovedExclusions_many" = "**%1$d** removed exclusions";
|
||||
"ayu_FiltersSheetRemovedExclusions_other" = "**%1$d** removed exclusions";
|
||||
"ayu_FiltersSheetDialogsToResolve_zero" = "**%1$d** dialogs to resolve";
|
||||
"ayu_FiltersSheetDialogsToResolve_one" = "**1** dialog to resolve";
|
||||
"ayu_FiltersSheetDialogsToResolve_two" = "**%1$d** dialogs to resolve";
|
||||
"ayu_FiltersSheetDialogsToResolve_few" = "**%1$d** dialogs to resolve";
|
||||
"ayu_FiltersSheetDialogsToResolve_many" = "**%1$d** dialogs to resolve";
|
||||
"ayu_FiltersSheetDialogsToResolve_other" = "**%1$d** dialogs to resolve";
|
||||
"ayu_FiltersClearPopupTitle" = "Clear filters";
|
||||
"ayu_FiltersClearPopupText" = "Are you sure you want to clear all filters?";
|
||||
"ayu_FiltersClearPopupActionText" = "Clear";
|
||||
"ayu_FiltersClearPopupAltActionText" = "Clear unknown";
|
||||
"ayu_IconDefault" = "Default";
|
||||
"ayu_IconAlternative" = "AyuGram Alt";
|
||||
"ayu_IconDiscord" = "Discord";
|
||||
@@ -5066,15 +5320,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_IconYaPlus" = "Yandex Plus";
|
||||
"ayu_WALMode" = "Enable WAL mode";
|
||||
"ayu_PushNotificationCount" = "FCM notifications received";
|
||||
"ayu_ClearAyuDatabase" = "Clear Ayu Database";
|
||||
"ayu_ClearAyuDatabaseNotification" = "AyuGram database cleared";
|
||||
"ayu_ClearAyuAttachments" = "Clear Ayu Attachments";
|
||||
"ayu_ClearAyuDatabase" = "Clear Messages Database";
|
||||
"ayu_ClearAyuAttachmentsNotification" = "AyuGram attachments folder cleared";
|
||||
"ayu_EraseLocalDatabase" = "Erase Local Database";
|
||||
"ayu_ClearTelegramDatabase" = "Clear Telegram Database";
|
||||
"ayu_ClearAyuDatabaseNotification" = "AyuGram database cleared";
|
||||
"ayu_ClearAyuAttachments" = "Clear Attachments Folder";
|
||||
"ayu_ConfirmationsTitle" = "Confirmations";
|
||||
"ayu_StickerConfirmation" = "For stickers";
|
||||
"ayu_StickerConfirmation" = "For Stickers";
|
||||
"ayu_GIFConfirmation" = "For GIFs";
|
||||
"ayu_VoiceConfirmation" = "For voice messages";
|
||||
"ayu_VoiceConfirmation" = "For Voice Messages";
|
||||
"ayu_MessageDetailsPC" = "Details";
|
||||
"ayu_MessageDetailsViewsPC" = "Views";
|
||||
"ayu_MessageDetailsSharesPC" = "Shares";
|
||||
@@ -5099,12 +5353,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_DisableGhostMode" = "Disable Ghost";
|
||||
"ayu_EnableGhostModeTray" = "Enable Ghost Mode";
|
||||
"ayu_DisableGhostModeTray" = "Disable Ghost Mode";
|
||||
"ayu_GhostModeEnabled" = "Ghost mode turned on";
|
||||
"ayu_GhostModeDisabled" = "Ghost mode turned off";
|
||||
"ayu_GhostModeEnabled" = "Ghost Mode turned on";
|
||||
"ayu_GhostModeDisabled" = "Ghost Mode turned off";
|
||||
"ayu_StreamerModeToggle" = "Streamer Mode";
|
||||
"ayu_EnableStreamerModeTray" = "Enable Streamer Mode";
|
||||
"ayu_DisableStreamerModeTray" = "Disable Streamer Mode";
|
||||
"ayu_EditsHistoryTitle" = "Edits history";
|
||||
"ayu_EditsHistoryTitle" = "Edits History";
|
||||
"ayu_EditsHistoryMenuText" = "History";
|
||||
"ayu_PeekOnlineMenuText" = "Peek Online";
|
||||
"ayu_ClearDeletedMenuText" = "Clear Deleted";
|
||||
@@ -5129,15 +5383,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_HideNextViewsDescriptionAyu" = "Hide my views forever, until Ghost Mode disabled.";
|
||||
"ayu_EnableGhostModeStories" = "Enable Ghost Mode";
|
||||
"ayu_GhostModeIsActive" = "Ghost Mode Is Active";
|
||||
"ayu_SimpleQuotesAndReplies" = "Disable colorful replies";
|
||||
"ayu_DisableSimilarChannels" = "Disable similar channels";
|
||||
"ayu_CollapseSimilarChannels" = "Collapse similar channels";
|
||||
"ayu_HideSimilarChannelsTab" = "Hide similar channels tab";
|
||||
"ayu_UploadSpeedBoostPC" = "Upload speed boost";
|
||||
"ayu_MainFont" = "Application font";
|
||||
"ayu_MonospaceFont" = "Monospace font";
|
||||
"ayu_SimpleQuotesAndReplies" = "Disable Colorful Replies";
|
||||
"ayu_DisableSimilarChannels" = "Disable Similar Channels";
|
||||
"ayu_CollapseSimilarChannels" = "Collapse Similar Channels";
|
||||
"ayu_HideSimilarChannelsTab" = "Hide Similar Channels Tab";
|
||||
"ayu_UploadSpeedBoostPC" = "Upload Speed Boost";
|
||||
"ayu_MainFont" = "Application Font";
|
||||
"ayu_MonospaceFont" = "Monospace Font";
|
||||
"ayu_FontDefault" = "Default";
|
||||
"ayu_CustomizeFontTitle" = "Customize font";
|
||||
"ayu_CustomizeFontTitle" = "Customize Font";
|
||||
"ayu_MessageShotTopBarText" = "Shot";
|
||||
"ayu_MessageShotPreview" = "Preview";
|
||||
"ayu_MessageShotPreferences" = "Preferences";
|
||||
@@ -5163,22 +5417,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"ayu_DeleteDateMenuText" = "Delete Date";
|
||||
"ayu_ReadDateMenuText" = "Read Date";
|
||||
"ayu_ContentsReadDateMenuText" = "Contents Read Date";
|
||||
"ayu_ForwardableMenuText" = "Forwardable";
|
||||
"ayu_ForwardableMenuTextNo" = "No";
|
||||
"ayu_UnforwardableContextMenuText" = "Plain forwarding is not allowed.";
|
||||
"ayu_LikelyOfflineStatus" = "offline ?";
|
||||
"ayu_GhostModeShortcut" = "Enter with Ghost";
|
||||
"ayu_SettingsShowMessageSeconds" = "Show message seconds";
|
||||
"ayu_SettingsShowMessageSeconds" = "Show Message Seconds";
|
||||
"ayu_ContextCopyID" = "Copy ID";
|
||||
"ayu_IDCopiedToast" = "ID copied to clipboard.";
|
||||
"ayu_ContextHideMessage" = "Hide";
|
||||
"ayu_ContextCopyCallbackData" = "Copy Callback Data";
|
||||
"ayu_RegisterURLScheme" = "Register URL scheme";
|
||||
"ayu_RegisterURLScheme" = "Register URL Scheme";
|
||||
"ayu_LocalPremiumNotice" = "You're using **local** Telegram Premium.\nIt **won't** give you any benefits, except translator.\n**Enjoy the star near your nickname!**";
|
||||
"ayu_SettingsWatermark" = "AyuGram developed and maintained by Radolyn Labs.";
|
||||
"ayu_ConfirmationSticker" = "Do you want to send this sticker?";
|
||||
"ayu_ConfirmationGIF" = "Do you want to send this GIF?";
|
||||
"ayu_ConfirmationVoice" = "Do you want to send this voice message?";
|
||||
"ayu_IntroAbout" = "Welcome to the AyuGram Desktop.\nIt's cool and looks less ugly.";
|
||||
"ayu_AboutText1" = "Just a cool Telegram client based on {api_link}.";
|
||||
"ayu_IntroAbout" = "Welcome to the AyuGram Desktop.\nMake Telegram your own.";
|
||||
"ayu_AboutText1" = "ToS breaking Telegram client based on {api_link}.";
|
||||
"ayu_UpdateAyuGram" = "Update AyuGram";
|
||||
"ayu_UtilityRestartRequired" = "App will close in 5 seconds.";
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
<file alias="writing.tgs">../../animations/writing.tgs</file>
|
||||
<file alias="hours.tgs">../../animations/hours.tgs</file>
|
||||
<file alias="phone.tgs">../../animations/phone.tgs</file>
|
||||
<file alias="chat_link.tgs">../../animations/chat_link.tgs</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<RCC>
|
||||
<qresource prefix="/iv">
|
||||
<file alias="page.css">../../iv_html/page.css</file>
|
||||
<file alias="page.js">../../iv_html/page.js</file>
|
||||
<file alias="highlight.css">../../iv_html/highlight.9.12.0.css</file>
|
||||
<file alias="highlight.js">../../iv_html/highlight.9.12.0.js</file>
|
||||
<file alias="morphdom.js">../../iv_html/morphdom-umd.min.2.7.2.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -10,7 +10,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="4.15.2.0" />
|
||||
Version="4.16.0.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,15,2,0
|
||||
PRODUCTVERSION 4,15,2,0
|
||||
FILEVERSION 4,16,0,0
|
||||
PRODUCTVERSION 4,16,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -62,10 +62,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Radolyn Labs"
|
||||
VALUE "FileDescription", "AyuGram Desktop"
|
||||
VALUE "FileVersion", "4.15.2.0"
|
||||
VALUE "FileVersion", "4.16.0.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
|
||||
VALUE "ProductName", "AyuGram Desktop"
|
||||
VALUE "ProductVersion", "4.15.2.0"
|
||||
VALUE "ProductVersion", "4.16.0.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,15,2,0
|
||||
PRODUCTVERSION 4,15,2,0
|
||||
FILEVERSION 4,16,0,0
|
||||
PRODUCTVERSION 4,16,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -53,10 +53,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Radolyn Labs"
|
||||
VALUE "FileDescription", "AyuGram Desktop Updater"
|
||||
VALUE "FileVersion", "4.15.2.0"
|
||||
VALUE "FileVersion", "4.16.0.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
|
||||
VALUE "ProductName", "AyuGram Desktop"
|
||||
VALUE "ProductVersion", "4.15.2.0"
|
||||
VALUE "ProductVersion", "4.16.0.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -421,10 +421,10 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
|
||||
MTP_int(itemId),
|
||||
MTP_int(id),
|
||||
MTP_vector_from_range(
|
||||
result
|
||||
| ranges::views::transform([](
|
||||
not_null<PeerData*> peer) {
|
||||
return MTPInputPeer(peer->input); }))
|
||||
result | ranges::views::transform([](
|
||||
not_null<PeerData*> peer) {
|
||||
return MTPInputPeer(peer->input);
|
||||
}))
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
peer->session().api().applyUpdates(result);
|
||||
}).send();
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
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_chat_links.h"
|
||||
|
||||
#include "api/api_text_entities.h"
|
||||
#include "apiwrap.h"
|
||||
#include "data/data_session.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] ChatLink FromMTP(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPBusinessChatLink &link) {
|
||||
const auto &data = link.data();
|
||||
return {
|
||||
.link = qs(data.vlink()),
|
||||
.title = qs(data.vtitle().value_or_empty()),
|
||||
.message = {
|
||||
qs(data.vmessage()),
|
||||
EntitiesFromMTP(
|
||||
session,
|
||||
data.ventities().value_or_empty())
|
||||
},
|
||||
.clicks = data.vviews().v,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] MTPInputBusinessChatLink ToMTP(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &title,
|
||||
const TextWithEntities &message) {
|
||||
auto entities = EntitiesToMTP(
|
||||
session,
|
||||
message.entities,
|
||||
ConvertOption::SkipLocal);
|
||||
using Flag = MTPDinputBusinessChatLink::Flag;
|
||||
const auto flags = (title.isEmpty() ? Flag() : Flag::f_title)
|
||||
| (entities.v.isEmpty() ? Flag() : Flag::f_entities);
|
||||
return MTP_inputBusinessChatLink(
|
||||
MTP_flags(flags),
|
||||
MTP_string(message.text),
|
||||
std::move(entities),
|
||||
MTP_string(title));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChatLinks::ChatLinks(not_null<ApiWrap*> api) : _api(api) {
|
||||
}
|
||||
|
||||
void ChatLinks::create(
|
||||
const QString &title,
|
||||
const TextWithEntities &message,
|
||||
Fn<void(Link)> done) {
|
||||
const auto session = &_api->session();
|
||||
_api->request(MTPaccount_CreateBusinessChatLink(
|
||||
ToMTP(session, title, message)
|
||||
)).done([=](const MTPBusinessChatLink &result) {
|
||||
const auto link = FromMTP(session, result);
|
||||
_list.push_back(link);
|
||||
_updates.fire({ .was = QString(), .now = link });
|
||||
if (done) done(link);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto type = error.type();
|
||||
if (done) done(Link());
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ChatLinks::edit(
|
||||
const QString &link,
|
||||
const QString &title,
|
||||
const TextWithEntities &message,
|
||||
Fn<void(Link)> done) {
|
||||
const auto session = &_api->session();
|
||||
_api->request(MTPaccount_EditBusinessChatLink(
|
||||
MTP_string(link),
|
||||
ToMTP(session, title, message)
|
||||
)).done([=](const MTPBusinessChatLink &result) {
|
||||
const auto parsed = FromMTP(session, result);
|
||||
if (parsed.link != link) {
|
||||
LOG(("API Error: EditBusinessChatLink changed the link."));
|
||||
if (done) done(Link());
|
||||
return;
|
||||
}
|
||||
const auto i = ranges::find(_list, link, &Link::link);
|
||||
if (i != end(_list)) {
|
||||
*i = parsed;
|
||||
_updates.fire({ .was = link, .now = parsed });
|
||||
if (done) done(parsed);
|
||||
} else {
|
||||
LOG(("API Error: EditBusinessChatLink link not found."));
|
||||
if (done) done(Link());
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto type = error.type();
|
||||
if (done) done(Link());
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ChatLinks::destroy(
|
||||
const QString &link,
|
||||
Fn<void()> done) {
|
||||
_api->request(MTPaccount_DeleteBusinessChatLink(
|
||||
MTP_string(link)
|
||||
)).done([=] {
|
||||
const auto i = ranges::find(_list, link, &Link::link);
|
||||
if (i != end(_list)) {
|
||||
_list.erase(i);
|
||||
_updates.fire({ .was = link });
|
||||
if (done) done();
|
||||
} else {
|
||||
LOG(("API Error: DeleteBusinessChatLink link not found."));
|
||||
if (done) done();
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto type = error.type();
|
||||
if (done) done();
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ChatLinks::preload() {
|
||||
if (_loaded || _requestId) {
|
||||
return;
|
||||
}
|
||||
_requestId = _api->request(MTPaccount_GetBusinessChatLinks(
|
||||
)).done([=](const MTPaccount_BusinessChatLinks &result) {
|
||||
const auto &data = result.data();
|
||||
const auto session = &_api->session();
|
||||
const auto owner = &session->data();
|
||||
owner->processUsers(data.vusers());
|
||||
owner->processChats(data.vchats());
|
||||
auto links = std::vector<Link>();
|
||||
links.reserve(data.vlinks().v.size());
|
||||
for (const auto &link : data.vlinks().v) {
|
||||
links.push_back(FromMTP(session, link));
|
||||
}
|
||||
_list = std::move(links);
|
||||
_loaded = true;
|
||||
_loadedUpdates.fire({});
|
||||
}).fail([=] {
|
||||
_requestId = 0;
|
||||
_loaded = true;
|
||||
_loadedUpdates.fire({});
|
||||
}).send();
|
||||
}
|
||||
|
||||
const std::vector<ChatLink> &ChatLinks::list() const {
|
||||
return _list;
|
||||
}
|
||||
|
||||
bool ChatLinks::loaded() const {
|
||||
return _loaded;
|
||||
}
|
||||
|
||||
rpl::producer<> ChatLinks::loadedUpdates() const {
|
||||
return _loadedUpdates.events();
|
||||
}
|
||||
|
||||
rpl::producer<ChatLinks::Update> ChatLinks::updates() const {
|
||||
return _updates.events();
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
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 ApiWrap;
|
||||
|
||||
namespace Api {
|
||||
|
||||
struct ChatLink {
|
||||
QString link;
|
||||
QString title;
|
||||
TextWithEntities message;
|
||||
int clicks = 0;
|
||||
};
|
||||
|
||||
struct ChatLinkUpdate {
|
||||
QString was;
|
||||
std::optional<ChatLink> now;
|
||||
};
|
||||
|
||||
class ChatLinks final {
|
||||
public:
|
||||
explicit ChatLinks(not_null<ApiWrap*> api);
|
||||
|
||||
using Link = ChatLink;
|
||||
using Update = ChatLinkUpdate;
|
||||
|
||||
void create(
|
||||
const QString &title,
|
||||
const TextWithEntities &message,
|
||||
Fn<void(Link)> done = nullptr);
|
||||
void edit(
|
||||
const QString &link,
|
||||
const QString &title,
|
||||
const TextWithEntities &message,
|
||||
Fn<void(Link)> done = nullptr);
|
||||
void destroy(
|
||||
const QString &link,
|
||||
Fn<void()> done = nullptr);
|
||||
|
||||
void preload();
|
||||
[[nodiscard]] const std::vector<ChatLink> &list() const;
|
||||
[[nodiscard]] bool loaded() const;
|
||||
[[nodiscard]] rpl::producer<> loadedUpdates() const;
|
||||
[[nodiscard]] rpl::producer<Update> updates() const;
|
||||
|
||||
private:
|
||||
const not_null<ApiWrap*> _api;
|
||||
|
||||
std::vector<Link> _list;
|
||||
rpl::event_stream<> _loadedUpdates;
|
||||
mtpRequestId _requestId = 0;
|
||||
bool _loaded = false;
|
||||
|
||||
rpl::event_stream<Update> _updates;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Api
|
||||
@@ -487,9 +487,9 @@ void ChatParticipants::requestCountDelayed(
|
||||
}
|
||||
|
||||
void ChatParticipants::add(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
bool passGroupHistory,
|
||||
Fn<void(bool)> done) {
|
||||
if (const auto chat = peer->asChat()) {
|
||||
@@ -498,19 +498,28 @@ void ChatParticipants::add(
|
||||
chat->inputChat,
|
||||
user->inputUser,
|
||||
MTP_int(passGroupHistory ? kForwardMessagesOnAdd : 0)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
chat->session().api().applyUpdates(result);
|
||||
)).done([=](const MTPmessages_InvitedUsers &result) {
|
||||
const auto &data = result.data();
|
||||
chat->session().api().applyUpdates(data.vupdates());
|
||||
if (done) done(true);
|
||||
ChatInviteForbidden(
|
||||
show,
|
||||
chat,
|
||||
CollectForbiddenUsers(&chat->session(), result));
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto type = error.type();
|
||||
ShowAddParticipantsError(type, peer, { 1, user }, show);
|
||||
ShowAddParticipantsError(show, type, peer, user);
|
||||
if (done) done(false);
|
||||
}).afterDelay(kSmallDelayMs).send();
|
||||
}
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
const auto hasBot = ranges::any_of(users, &UserData::isBot);
|
||||
if (!peer->isMegagroup() && hasBot) {
|
||||
ShowAddParticipantsError("USER_BOT", peer, users, show);
|
||||
ShowAddParticipantsError(
|
||||
show,
|
||||
u"USER_BOT"_q,
|
||||
peer,
|
||||
{ .users = users });
|
||||
return;
|
||||
}
|
||||
auto list = QVector<MTPInputUser>();
|
||||
@@ -520,8 +529,9 @@ void ChatParticipants::add(
|
||||
_api.request(MTPchannels_InviteToChannel(
|
||||
channel->inputChannel,
|
||||
MTP_vector<MTPInputUser>(list)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
channel->session().api().applyUpdates(result);
|
||||
)).done([=](const MTPmessages_InvitedUsers &result) {
|
||||
const auto &data = result.data();
|
||||
channel->session().api().applyUpdates(data.vupdates());
|
||||
requestCountDelayed(channel);
|
||||
if (callback) callback(true);
|
||||
ChatInviteForbidden(
|
||||
@@ -529,7 +539,9 @@ void ChatParticipants::add(
|
||||
channel,
|
||||
CollectForbiddenUsers(&channel->session(), result));
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
ShowAddParticipantsError(error.type(), peer, users, show);
|
||||
ShowAddParticipantsError(show, error.type(), peer, {
|
||||
.users = users,
|
||||
});
|
||||
if (callback) callback(false);
|
||||
}).afterDelay(kSmallDelayMs).send();
|
||||
};
|
||||
|
||||
@@ -97,9 +97,9 @@ public:
|
||||
not_null<ChannelData*> channel,
|
||||
const TLMembers &data);
|
||||
void add(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
std::shared_ptr<Ui::Show> show = nullptr,
|
||||
bool passGroupHistory = true,
|
||||
Fn<void(bool)> done = nullptr);
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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_earn.h"
|
||||
|
||||
#include "api/api_cloud_password.h"
|
||||
#include "apiwrap.h"
|
||||
#include "boxes/passcode_box.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_session.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "ui/basic_click_handlers.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
||||
namespace Api {
|
||||
|
||||
void RestrictSponsored(
|
||||
not_null<ChannelData*> channel,
|
||||
bool restricted,
|
||||
Fn<void(QString)> failed) {
|
||||
channel->session().api().request(MTPchannels_RestrictSponsoredMessages(
|
||||
channel->inputChannel,
|
||||
MTP_bool(restricted))
|
||||
).done([=](const MTPUpdates &updates) {
|
||||
channel->session().api().applyUpdates(updates);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
failed(error.type());
|
||||
}).send();
|
||||
}
|
||||
|
||||
void HandleWithdrawalButton(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<Ui::RippleButton*> button,
|
||||
std::shared_ptr<Ui::Show> show) {
|
||||
struct State {
|
||||
rpl::lifetime lifetime;
|
||||
bool loading = false;
|
||||
};
|
||||
|
||||
const auto state = button->lifetime().make_state<State>();
|
||||
const auto session = &channel->session();
|
||||
|
||||
session->api().cloudPassword().reload();
|
||||
button->setClickedCallback([=] {
|
||||
if (state->loading) {
|
||||
return;
|
||||
}
|
||||
state->loading = true;
|
||||
state->lifetime = session->api().cloudPassword().state(
|
||||
) | rpl::take(
|
||||
1
|
||||
) | rpl::start_with_next([=](const Core::CloudPasswordState &pass) {
|
||||
state->loading = false;
|
||||
|
||||
auto fields = PasscodeBox::CloudFields::From(pass);
|
||||
fields.customTitle =
|
||||
tr::lng_channel_earn_balance_password_title();
|
||||
fields.customDescription =
|
||||
tr::lng_channel_earn_balance_password_description(tr::now);
|
||||
fields.customSubmitButton = tr::lng_passcode_submit();
|
||||
fields.customCheckCallback = crl::guard(button, [=](
|
||||
const Core::CloudPasswordResult &result) {
|
||||
session->api().request(
|
||||
MTPstats_GetBroadcastRevenueWithdrawalUrl(
|
||||
channel->inputChannel,
|
||||
result.result
|
||||
)).done([=](const MTPstats_BroadcastRevenueWithdrawalUrl &r) {
|
||||
const auto url = qs(r.data().vurl());
|
||||
|
||||
if (!url.isEmpty()) {
|
||||
UrlClickHandler::Open(url);
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
show->showToast(error.type());
|
||||
}).send();
|
||||
});
|
||||
show->show(Box<PasscodeBox>(session, fields));
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
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 ChannelData;
|
||||
|
||||
namespace Ui {
|
||||
class RippleButton;
|
||||
class Show;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Api {
|
||||
|
||||
void RestrictSponsored(
|
||||
not_null<ChannelData*> channel,
|
||||
bool restricted,
|
||||
Fn<void(QString)> failed);
|
||||
|
||||
void HandleWithdrawalButton(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<Ui::RippleButton*> button,
|
||||
std::shared_ptr<Ui::Show> show);
|
||||
|
||||
} // namespace Api
|
||||
@@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_app_config.h"
|
||||
|
||||
namespace Api {
|
||||
@@ -40,9 +39,9 @@ void GlobalPrivacy::reload(Fn<void()> callback) {
|
||||
}
|
||||
}).send();
|
||||
|
||||
_session->account().appConfig().value(
|
||||
_session->appConfig().value(
|
||||
) | rpl::start_with_next([=] {
|
||||
_showArchiveAndMute = _session->account().appConfig().get<bool>(
|
||||
_showArchiveAndMute = _session->appConfig().get<bool>(
|
||||
u"autoarchive_setting_available"_q,
|
||||
false);
|
||||
}, _session->lifetime());
|
||||
@@ -75,12 +74,12 @@ rpl::producer<bool> GlobalPrivacy::showArchiveAndMute() const {
|
||||
}
|
||||
|
||||
rpl::producer<> GlobalPrivacy::suggestArchiveAndMute() const {
|
||||
return _session->account().appConfig().suggestionRequested(
|
||||
return _session->appConfig().suggestionRequested(
|
||||
u"AUTOARCHIVE_POPULAR"_q);
|
||||
}
|
||||
|
||||
void GlobalPrivacy::dismissArchiveAndMuteSuggestion() {
|
||||
_session->account().appConfig().dismissSuggestion(
|
||||
_session->appConfig().dismissSuggestion(
|
||||
u"AUTOARCHIVE_POPULAR"_q);
|
||||
}
|
||||
|
||||
@@ -142,6 +141,8 @@ void GlobalPrivacy::update(
|
||||
using Flag = MTPDglobalPrivacySettings::Flag;
|
||||
|
||||
_api.request(_requestId).cancel();
|
||||
const auto newRequirePremiumAllowed = _session->premium()
|
||||
|| _session->appConfig().newRequirePremiumFree();
|
||||
const auto flags = Flag()
|
||||
| (archiveAndMute
|
||||
? Flag::f_archive_and_mute_new_noncontact_peers
|
||||
@@ -153,7 +154,7 @@ void GlobalPrivacy::update(
|
||||
? Flag::f_keep_archived_folders
|
||||
: Flag())
|
||||
| (hideReadTime ? Flag::f_hide_read_marks : Flag())
|
||||
| ((newRequirePremium && _session->premium())
|
||||
| ((newRequirePremium && newRequirePremiumAllowed)
|
||||
? Flag::f_new_noncontact_peers_require_premium
|
||||
: Flag());
|
||||
_requestId = _api.request(MTPaccount_SetGlobalPrivacySettings(
|
||||
|
||||
@@ -160,7 +160,7 @@ void Polls::sendVotes(
|
||||
_session->updates().applyUpdates(result);
|
||||
|
||||
const auto settings = &AyuSettings::getInstance();
|
||||
if (!settings->sendReadMessages && settings->markReadAfterPoll && item)
|
||||
if (!settings->sendReadMessages && settings->markReadAfterAction && item)
|
||||
{
|
||||
readHistory(item);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/view/history_view_element.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
#include "payments/payments_form.h"
|
||||
@@ -109,6 +108,18 @@ rpl::producer<> Premium::cloudSetUpdated() const {
|
||||
return _cloudSetUpdated.events();
|
||||
}
|
||||
|
||||
auto Premium::helloStickers() const
|
||||
-> const std::vector<not_null<DocumentData*>> & {
|
||||
if (_helloStickers.empty()) {
|
||||
const_cast<Premium*>(this)->reloadHelloStickers();
|
||||
}
|
||||
return _helloStickers;
|
||||
}
|
||||
|
||||
rpl::producer<> Premium::helloStickersUpdated() const {
|
||||
return _helloStickersUpdated.events();
|
||||
}
|
||||
|
||||
int64 Premium::monthlyAmount() const {
|
||||
return _monthlyAmount;
|
||||
}
|
||||
@@ -225,6 +236,33 @@ void Premium::reloadCloudSet() {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void Premium::reloadHelloStickers() {
|
||||
if (_helloStickersRequestId) {
|
||||
return;
|
||||
}
|
||||
_helloStickersRequestId = _api.request(MTPmessages_GetStickers(
|
||||
MTP_string("\xf0\x9f\x91\x8b\xe2\xad\x90\xef\xb8\x8f"),
|
||||
MTP_long(_helloStickersHash)
|
||||
)).done([=](const MTPmessages_Stickers &result) {
|
||||
_helloStickersRequestId = 0;
|
||||
result.match([&](const MTPDmessages_stickersNotModified &) {
|
||||
}, [&](const MTPDmessages_stickers &data) {
|
||||
_helloStickersHash = data.vhash().v;
|
||||
const auto owner = &_session->data();
|
||||
_helloStickers.clear();
|
||||
for (const auto &sticker : data.vstickers().v) {
|
||||
const auto document = owner->processDocument(sticker);
|
||||
if (document->sticker()) {
|
||||
_helloStickers.push_back(document);
|
||||
}
|
||||
}
|
||||
_helloStickersUpdated.fire({});
|
||||
});
|
||||
}).fail([=] {
|
||||
_helloStickersRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
void Premium::checkGiftCode(
|
||||
const QString &slug,
|
||||
Fn<void(GiftCode)> done) {
|
||||
@@ -532,34 +570,34 @@ Data::SubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
|
||||
|
||||
int PremiumGiftCodeOptions::giveawayBoostsPerPremium() const {
|
||||
constexpr auto kFallbackCount = 4;
|
||||
return _peer->session().account().appConfig().get<int>(
|
||||
return _peer->session().appConfig().get<int>(
|
||||
u"giveaway_boosts_per_premium"_q,
|
||||
kFallbackCount);
|
||||
}
|
||||
|
||||
int PremiumGiftCodeOptions::giveawayCountriesMax() const {
|
||||
constexpr auto kFallbackCount = 10;
|
||||
return _peer->session().account().appConfig().get<int>(
|
||||
return _peer->session().appConfig().get<int>(
|
||||
u"giveaway_countries_max"_q,
|
||||
kFallbackCount);
|
||||
}
|
||||
|
||||
int PremiumGiftCodeOptions::giveawayAddPeersMax() const {
|
||||
constexpr auto kFallbackCount = 10;
|
||||
return _peer->session().account().appConfig().get<int>(
|
||||
return _peer->session().appConfig().get<int>(
|
||||
u"giveaway_add_peers_max"_q,
|
||||
kFallbackCount);
|
||||
}
|
||||
|
||||
int PremiumGiftCodeOptions::giveawayPeriodMax() const {
|
||||
constexpr auto kFallbackCount = 3600 * 24 * 7;
|
||||
return _peer->session().account().appConfig().get<int>(
|
||||
return _peer->session().appConfig().get<int>(
|
||||
u"giveaway_period_max"_q,
|
||||
kFallbackCount);
|
||||
}
|
||||
|
||||
bool PremiumGiftCodeOptions::giveawayGiftsPurchaseAvailable() const {
|
||||
return _peer->session().account().appConfig().get<bool>(
|
||||
return _peer->session().appConfig().get<bool>(
|
||||
u"giveaway_gifts_purchase_available"_q,
|
||||
false);
|
||||
}
|
||||
@@ -609,4 +647,24 @@ RequirePremiumState ResolveRequiresPremiumToWrite(
|
||||
return RequirePremiumState::Unknown;
|
||||
}
|
||||
|
||||
rpl::producer<DocumentData*> RandomHelloStickerValue(
|
||||
not_null<Main::Session*> session) {
|
||||
const auto premium = &session->api().premium();
|
||||
const auto random = [=] {
|
||||
const auto &v = premium->helloStickers();
|
||||
Assert(!v.empty());
|
||||
return v[base::RandomIndex(v.size())].get();
|
||||
};
|
||||
const auto &v = premium->helloStickers();
|
||||
if (!v.empty()) {
|
||||
return rpl::single(random());
|
||||
}
|
||||
return rpl::single<DocumentData*>(
|
||||
nullptr
|
||||
) | rpl::then(premium->helloStickersUpdated(
|
||||
) | rpl::filter([=] {
|
||||
return !premium->helloStickers().empty();
|
||||
}) | rpl::take(1) | rpl::map(random));
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -85,6 +85,10 @@ public:
|
||||
-> const std::vector<not_null<DocumentData*>> &;
|
||||
[[nodiscard]] rpl::producer<> cloudSetUpdated() const;
|
||||
|
||||
[[nodiscard]] auto helloStickers() const
|
||||
-> const std::vector<not_null<DocumentData*>> &;
|
||||
[[nodiscard]] rpl::producer<> helloStickersUpdated() const;
|
||||
|
||||
[[nodiscard]] int64 monthlyAmount() const;
|
||||
[[nodiscard]] QString monthlyCurrency() const;
|
||||
|
||||
@@ -111,6 +115,7 @@ private:
|
||||
void reloadPromo();
|
||||
void reloadStickers();
|
||||
void reloadCloudSet();
|
||||
void reloadHelloStickers();
|
||||
void requestPremiumRequiredSlice();
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
@@ -133,6 +138,11 @@ private:
|
||||
std::vector<not_null<DocumentData*>> _cloudSet;
|
||||
rpl::event_stream<> _cloudSetUpdated;
|
||||
|
||||
mtpRequestId _helloStickersRequestId = 0;
|
||||
uint64 _helloStickersHash = 0;
|
||||
std::vector<not_null<DocumentData*>> _helloStickers;
|
||||
rpl::event_stream<> _helloStickersUpdated;
|
||||
|
||||
int64 _monthlyAmount = 0;
|
||||
QString _monthlyCurrency;
|
||||
|
||||
@@ -215,4 +225,7 @@ enum class RequirePremiumState {
|
||||
not_null<PeerData*> peer,
|
||||
History *maybeHistory);
|
||||
|
||||
[[nodiscard]] rpl::producer<DocumentData*> RandomHelloStickerValue(
|
||||
not_null<Main::Session*> session);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/notify/data_notify_settings.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
#include "storage/file_upload.h"
|
||||
@@ -191,20 +190,20 @@ void Ringtones::remove(DocumentId id) {
|
||||
}
|
||||
|
||||
int64 Ringtones::maxSize() const {
|
||||
return _session->account().appConfig().get<int>(
|
||||
"ringtone_size_max",
|
||||
return _session->appConfig().get<int>(
|
||||
u"ringtone_size_max"_q,
|
||||
100 * 1024);
|
||||
}
|
||||
|
||||
int Ringtones::maxSavedCount() const {
|
||||
return _session->account().appConfig().get<int>(
|
||||
"ringtone_saved_count_max",
|
||||
return _session->appConfig().get<int>(
|
||||
u"ringtone_saved_count_max"_q,
|
||||
100);
|
||||
}
|
||||
|
||||
crl::time Ringtones::maxDuration() const {
|
||||
return crl::time(1000) * _session->account().appConfig().get<int>(
|
||||
"ringtone_duration_max",
|
||||
return crl::time(1000) * _session->appConfig().get<int>(
|
||||
u"ringtone_duration_max"_q,
|
||||
5);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/text/text_entity.h" // TextWithEntities.
|
||||
#include "ui/item_text_options.h" // Ui::ItemTextOptions.
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "storage/localimageloader.h"
|
||||
#include "storage/file_upload.h"
|
||||
@@ -239,8 +238,7 @@ bool SendDice(MessageToSend &message) {
|
||||
|| !message.textWithTags.tags.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
auto &account = message.action.history->session().account();
|
||||
auto &config = account.appConfig();
|
||||
auto &config = message.action.history->session().appConfig();
|
||||
static const auto hardcoded = std::vector<QString>{
|
||||
Stickers::DicePacks::kDiceString,
|
||||
Stickers::DicePacks::kDartString,
|
||||
|
||||
@@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_app_config.h"
|
||||
|
||||
namespace Api {
|
||||
@@ -22,7 +21,7 @@ constexpr auto kRefreshAppConfigTimeout = 3 * crl::time(1000);
|
||||
SensitiveContent::SensitiveContent(not_null<ApiWrap*> api)
|
||||
: _session(&api->session())
|
||||
, _api(&api->instance())
|
||||
, _appConfigReloadTimer([=] { _session->account().appConfig().refresh(); }) {
|
||||
, _appConfigReloadTimer([=] { _session->appConfig().refresh(); }) {
|
||||
}
|
||||
|
||||
void SensitiveContent::reload() {
|
||||
|
||||
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_statistics.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_stories.h"
|
||||
@@ -746,4 +747,125 @@ Data::BoostStatus Boosts::boostStatus() const {
|
||||
return _boostStatus;
|
||||
}
|
||||
|
||||
EarnStatistics::EarnStatistics(not_null<ChannelData*> channel)
|
||||
: StatisticsRequestSender(channel) {
|
||||
}
|
||||
|
||||
rpl::producer<rpl::no_value, QString> EarnStatistics::request() {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
|
||||
makeRequest(MTPstats_GetBroadcastRevenueStats(
|
||||
MTP_flags(0),
|
||||
channel()->inputChannel
|
||||
)).done([=](const MTPstats_BroadcastRevenueStats &result) {
|
||||
const auto &data = result.data();
|
||||
|
||||
_data = Data::EarnStatistics{
|
||||
.topHoursGraph = StatisticalGraphFromTL(
|
||||
data.vtop_hours_graph()),
|
||||
.revenueGraph = StatisticalGraphFromTL(data.vrevenue_graph()),
|
||||
.currentBalance = data.vcurrent_balance().v,
|
||||
.availableBalance = data.vavailable_balance().v,
|
||||
.overallRevenue = data.voverall_revenue().v,
|
||||
.usdRate = data.vusd_rate().v,
|
||||
};
|
||||
|
||||
requestHistory({}, [=](Data::EarnHistorySlice &&slice) {
|
||||
_data.firstHistorySlice = std::move(slice);
|
||||
|
||||
api().request(
|
||||
MTPchannels_GetFullChannel(channel()->inputChannel)
|
||||
).done([=](const MTPmessages_ChatFull &result) {
|
||||
result.data().vfull_chat().match([&](
|
||||
const MTPDchannelFull &d) {
|
||||
_data.switchedOff = d.is_restricted_sponsored();
|
||||
}, [](const auto &) {
|
||||
});
|
||||
consumer.put_done();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
consumer.put_error_copy(error.type());
|
||||
}).send();
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
consumer.put_error_copy(error.type());
|
||||
}).send();
|
||||
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
void EarnStatistics::requestHistory(
|
||||
const Data::EarnHistorySlice::OffsetToken &token,
|
||||
Fn<void(Data::EarnHistorySlice)> done) {
|
||||
if (_requestId) {
|
||||
return;
|
||||
}
|
||||
constexpr auto kTlFirstSlice = tl::make_int(kFirstSlice);
|
||||
constexpr auto kTlLimit = tl::make_int(kLimit);
|
||||
_requestId = api().request(MTPstats_GetBroadcastRevenueTransactions(
|
||||
channel()->inputChannel,
|
||||
MTP_int(token),
|
||||
(!token) ? kTlFirstSlice : kTlLimit
|
||||
)).done([=](const MTPstats_BroadcastRevenueTransactions &result) {
|
||||
_requestId = 0;
|
||||
|
||||
const auto &tlTransactions = result.data().vtransactions().v;
|
||||
|
||||
auto list = std::vector<Data::EarnHistoryEntry>();
|
||||
list.reserve(tlTransactions.size());
|
||||
for (const auto &tlTransaction : tlTransactions) {
|
||||
list.push_back(tlTransaction.match([&](
|
||||
const MTPDbroadcastRevenueTransactionProceeds &d) {
|
||||
return Data::EarnHistoryEntry{
|
||||
.type = Data::EarnHistoryEntry::Type::In,
|
||||
.amount = d.vamount().v,
|
||||
.date = base::unixtime::parse(d.vfrom_date().v),
|
||||
.dateTo = base::unixtime::parse(d.vto_date().v),
|
||||
};
|
||||
}, [&](const MTPDbroadcastRevenueTransactionWithdrawal &d) {
|
||||
return Data::EarnHistoryEntry{
|
||||
.type = Data::EarnHistoryEntry::Type::Out,
|
||||
.status = d.is_pending()
|
||||
? Data::EarnHistoryEntry::Status::Pending
|
||||
: d.is_failed()
|
||||
? Data::EarnHistoryEntry::Status::Failed
|
||||
: Data::EarnHistoryEntry::Status::Success,
|
||||
.amount = (std::numeric_limits<Data::EarnInt>::max()
|
||||
- d.vamount().v
|
||||
+ 1),
|
||||
.date = base::unixtime::parse(d.vdate().v),
|
||||
// .provider = qs(d.vprovider()),
|
||||
.successDate = d.vtransaction_date()
|
||||
? base::unixtime::parse(d.vtransaction_date()->v)
|
||||
: QDateTime(),
|
||||
.successLink = d.vtransaction_url()
|
||||
? qs(*d.vtransaction_url())
|
||||
: QString(),
|
||||
};
|
||||
}, [&](const MTPDbroadcastRevenueTransactionRefund &d) {
|
||||
return Data::EarnHistoryEntry{
|
||||
.type = Data::EarnHistoryEntry::Type::Return,
|
||||
.amount = d.vamount().v,
|
||||
.date = base::unixtime::parse(d.vdate().v),
|
||||
// .provider = qs(d.vprovider()),
|
||||
};
|
||||
}));
|
||||
}
|
||||
const auto nextToken = token + tlTransactions.size();
|
||||
done(Data::EarnHistorySlice{
|
||||
.list = std::move(list),
|
||||
.total = result.data().vcount().v,
|
||||
.allLoaded = (result.data().vcount().v == nextToken),
|
||||
.token = Data::EarnHistorySlice::OffsetToken(nextToken),
|
||||
});
|
||||
}).fail([=] {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
Data::EarnStatistics EarnStatistics::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "base/timer.h"
|
||||
#include "data/data_boosts.h"
|
||||
#include "data/data_channel_earn.h"
|
||||
#include "data/data_statistics.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
||||
@@ -107,6 +108,27 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class EarnStatistics final : public StatisticsRequestSender {
|
||||
public:
|
||||
explicit EarnStatistics(not_null<ChannelData*> channel);
|
||||
|
||||
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
|
||||
void requestHistory(
|
||||
const Data::EarnHistorySlice::OffsetToken &token,
|
||||
Fn<void(Data::EarnHistorySlice)> done);
|
||||
|
||||
[[nodiscard]] Data::EarnStatistics data() const;
|
||||
|
||||
static constexpr auto kFirstSlice = int(5);
|
||||
static constexpr auto kLimit = int(10);
|
||||
|
||||
private:
|
||||
Data::EarnStatistics _data;
|
||||
|
||||
mtpRequestId _requestId = 0;
|
||||
|
||||
};
|
||||
|
||||
class Boosts final {
|
||||
public:
|
||||
explicit Boosts(not_null<PeerData*> peer);
|
||||
|
||||
@@ -15,7 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
@@ -36,10 +35,10 @@ bool Transcribes::freeFor(not_null<HistoryItem*> item) const {
|
||||
|
||||
bool Transcribes::trialsSupport() {
|
||||
if (!_trialsSupport) {
|
||||
const auto count = _session->account().appConfig().get<int>(
|
||||
const auto count = _session->appConfig().get<int>(
|
||||
u"transcribe_audio_trial_weekly_number"_q,
|
||||
0);
|
||||
const auto until = _session->account().appConfig().get<int>(
|
||||
const auto until = _session->appConfig().get<int>(
|
||||
u"transcribe_audio_trial_cooldown_until"_q,
|
||||
0);
|
||||
_trialsSupport = (count > 0) || (until > 0);
|
||||
@@ -49,7 +48,7 @@ bool Transcribes::trialsSupport() {
|
||||
|
||||
TimeId Transcribes::trialsRefreshAt() {
|
||||
if (_trialsRefreshAt < 0) {
|
||||
_trialsRefreshAt = _session->account().appConfig().get<int>(
|
||||
_trialsRefreshAt = _session->appConfig().get<int>(
|
||||
u"transcribe_audio_trial_cooldown_until"_q,
|
||||
0);
|
||||
}
|
||||
@@ -58,7 +57,7 @@ TimeId Transcribes::trialsRefreshAt() {
|
||||
|
||||
int Transcribes::trialsCount() {
|
||||
if (_trialsCount < 0) {
|
||||
_trialsCount = _session->account().appConfig().get<int>(
|
||||
_trialsCount = _session->appConfig().get<int>(
|
||||
u"transcribe_audio_trial_weekly_number"_q,
|
||||
-1);
|
||||
return std::max(_trialsCount, 0);
|
||||
@@ -67,7 +66,7 @@ int Transcribes::trialsCount() {
|
||||
}
|
||||
|
||||
crl::time Transcribes::trialsMaxLengthMs() const {
|
||||
return 1000 * _session->account().appConfig().get<int>(
|
||||
return 1000 * _session->appConfig().get<int>(
|
||||
u"transcribe_audio_trial_duration_max"_q,
|
||||
300);
|
||||
}
|
||||
|
||||
@@ -1128,6 +1128,7 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
|
||||
MTPPeer(), // saved_peer_id
|
||||
d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(),
|
||||
MTP_long(d.vvia_bot_id().value_or_empty()),
|
||||
MTPlong(), // via_business_bot_id
|
||||
d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
|
||||
d.vdate(),
|
||||
d.vmessage(),
|
||||
@@ -1162,6 +1163,7 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
|
||||
MTPPeer(), // saved_peer_id
|
||||
d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(),
|
||||
MTP_long(d.vvia_bot_id().value_or_empty()),
|
||||
MTPlong(), // via_business_bot_id
|
||||
d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
|
||||
d.vdate(),
|
||||
d.vmessage(),
|
||||
@@ -1949,7 +1951,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
const auto &d = update.c_updatePeerSettings();
|
||||
const auto peerId = peerFromMTP(d.vpeer());
|
||||
if (const auto peer = session().data().peerLoaded(peerId)) {
|
||||
peer->setSettings(d.vsettings());
|
||||
peer->setBarSettings(d.vsettings());
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ using TLInputRules = MTPVector<MTPInputPrivacyRule>;
|
||||
using TLRules = MTPVector<MTPPrivacyRule>;
|
||||
|
||||
TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
|
||||
const auto collectInputUsers = [](const auto &peers) {
|
||||
using Exceptions = UserPrivacy::Exceptions;
|
||||
const auto collectInputUsers = [](const Exceptions &exceptions) {
|
||||
const auto &peers = exceptions.peers;
|
||||
auto result = QVector<MTPInputUser>();
|
||||
result.reserve(peers.size());
|
||||
for (const auto &peer : peers) {
|
||||
@@ -36,7 +38,8 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const auto collectInputChats = [](const auto &peers) {
|
||||
const auto collectInputChats = [](const Exceptions &exceptions) {
|
||||
const auto &peers = exceptions.peers;
|
||||
auto result = QVector<MTPlong>();
|
||||
result.reserve(peers.size());
|
||||
for (const auto &peer : peers) {
|
||||
@@ -47,6 +50,7 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
|
||||
return result;
|
||||
};
|
||||
|
||||
using Option = UserPrivacy::Option;
|
||||
auto result = QVector<MTPInputPrivacyRule>();
|
||||
result.reserve(kMaxRules);
|
||||
if (!rule.ignoreAlways) {
|
||||
@@ -62,6 +66,9 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
|
||||
MTP_inputPrivacyValueAllowChatParticipants(
|
||||
MTP_vector<MTPlong>(chats)));
|
||||
}
|
||||
if (rule.always.premiums && (rule.option != Option::Everyone)) {
|
||||
result.push_back(MTP_inputPrivacyValueAllowPremium());
|
||||
}
|
||||
}
|
||||
if (!rule.ignoreNever) {
|
||||
const auto users = collectInputUsers(rule.never);
|
||||
@@ -78,7 +85,6 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
|
||||
}
|
||||
}
|
||||
result.push_back([&] {
|
||||
using Option = UserPrivacy::Option;
|
||||
switch (rule.option) {
|
||||
case Option::Everyone: return MTP_inputPrivacyValueAllowAll();
|
||||
case Option::Contacts: return MTP_inputPrivacyValueAllowContacts();
|
||||
@@ -101,12 +107,14 @@ UserPrivacy::Rule TLToRules(const TLRules &rules, Data::Session &owner) {
|
||||
auto result = UserPrivacy::Rule();
|
||||
auto optionSet = false;
|
||||
const auto setOption = [&](Option option) {
|
||||
if (optionSet) return;
|
||||
if (optionSet) {
|
||||
return;
|
||||
}
|
||||
optionSet = true;
|
||||
result.option = option;
|
||||
};
|
||||
auto &always = result.always;
|
||||
auto &never = result.never;
|
||||
auto &always = result.always.peers;
|
||||
auto &never = result.never.peers;
|
||||
const auto feed = [&](const MTPPrivacyRule &rule) {
|
||||
rule.match([&](const MTPDprivacyValueAllowAll &) {
|
||||
setOption(Option::Everyone);
|
||||
@@ -114,6 +122,8 @@ UserPrivacy::Rule TLToRules(const TLRules &rules, Data::Session &owner) {
|
||||
setOption(Option::Contacts);
|
||||
}, [&](const MTPDprivacyValueAllowCloseFriends &) {
|
||||
setOption(Option::CloseFriends);
|
||||
}, [&](const MTPDprivacyValueAllowPremium &) {
|
||||
result.always.premiums = true;
|
||||
}, [&](const MTPDprivacyValueAllowUsers &data) {
|
||||
const auto &users = data.vusers().v;
|
||||
always.reserve(always.size() + users.size());
|
||||
@@ -188,6 +198,7 @@ MTPInputPrivacyKey KeyToTL(UserPrivacy::Key key) {
|
||||
case Key::ProfilePhoto: return MTP_inputPrivacyKeyProfilePhoto();
|
||||
case Key::Voices: return MTP_inputPrivacyKeyVoiceMessages();
|
||||
case Key::About: return MTP_inputPrivacyKeyAbout();
|
||||
case Key::Birthday: return MTP_inputPrivacyKeyBirthday();
|
||||
}
|
||||
Unexpected("Key in Api::UserPrivacy::KetToTL.");
|
||||
}
|
||||
@@ -215,6 +226,8 @@ std::optional<UserPrivacy::Key> TLToKey(mtpTypeId type) {
|
||||
case mtpc_inputPrivacyKeyVoiceMessages: return Key::Voices;
|
||||
case mtpc_privacyKeyAbout:
|
||||
case mtpc_inputPrivacyKeyAbout: return Key::About;
|
||||
case mtpc_privacyKeyBirthday:
|
||||
case mtpc_inputPrivacyKeyBirthday: return Key::Birthday;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
ProfilePhoto,
|
||||
Voices,
|
||||
About,
|
||||
Birthday,
|
||||
};
|
||||
enum class Option {
|
||||
Everyone,
|
||||
@@ -37,10 +38,14 @@ public:
|
||||
CloseFriends,
|
||||
Nobody,
|
||||
};
|
||||
struct Exceptions {
|
||||
std::vector<not_null<PeerData*>> peers;
|
||||
bool premiums = false;
|
||||
};
|
||||
struct Rule {
|
||||
Option option = Option::Everyone;
|
||||
std::vector<not_null<PeerData*>> always;
|
||||
std::vector<not_null<PeerData*>> never;
|
||||
Exceptions always;
|
||||
Exceptions never;
|
||||
bool ignoreAlways = false;
|
||||
bool ignoreNever = false;
|
||||
};
|
||||
|
||||
@@ -24,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "ui/controls/who_reacted_context_action.h"
|
||||
@@ -697,7 +696,7 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
|
||||
|| user->readDatesPrivate()) {
|
||||
return false;
|
||||
}
|
||||
const auto &appConfig = peer->session().account().appConfig();
|
||||
const auto &appConfig = peer->session().appConfig();
|
||||
const auto expirePeriod = appConfig.get<int>(
|
||||
"pm_read_date_expire_period",
|
||||
7 * 86400);
|
||||
@@ -713,7 +712,7 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
|
||||
&& (megagroup->flags() & ChannelDataFlag::ParticipantsHidden))) {
|
||||
return false;
|
||||
}
|
||||
const auto &appConfig = peer->session().account().appConfig();
|
||||
const auto &appConfig = peer->session().appConfig();
|
||||
const auto expirePeriod = appConfig.get<int>(
|
||||
"chat_read_mark_expire_period",
|
||||
7 * 86400);
|
||||
|
||||
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_authorizations.h"
|
||||
#include "api/api_attached_stickers.h"
|
||||
#include "api/api_blocked_peers.h"
|
||||
#include "api/api_chat_links.h"
|
||||
#include "api/api_chat_participants.h"
|
||||
#include "api/api_cloud_password.h"
|
||||
#include "api/api_hash.h"
|
||||
@@ -169,6 +170,7 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
|
||||
, _globalPrivacy(std::make_unique<Api::GlobalPrivacy>(this))
|
||||
, _userPrivacy(std::make_unique<Api::UserPrivacy>(this))
|
||||
, _inviteLinks(std::make_unique<Api::InviteLinks>(this))
|
||||
, _chatLinks(std::make_unique<Api::ChatLinks>(this))
|
||||
, _views(std::make_unique<Api::ViewsManager>(this))
|
||||
, _confirmPhone(std::make_unique<Api::ConfirmPhone>(this))
|
||||
, _peerPhoto(std::make_unique<Api::PeerPhoto>(this))
|
||||
@@ -1246,7 +1248,7 @@ void ApiWrap::requestPeerSettings(not_null<PeerData*> peer) {
|
||||
result.match([&](const MTPDmessages_peerSettings &data) {
|
||||
_session->data().processUsers(data.vusers());
|
||||
_session->data().processChats(data.vchats());
|
||||
peer->setSettings(data.vsettings());
|
||||
peer->setBarSettings(data.vsettings());
|
||||
_requestedPeerSettings.erase(peer);
|
||||
});
|
||||
}).fail([=] {
|
||||
@@ -1775,7 +1777,7 @@ void ApiWrap::joinChannel(not_null<ChannelData*> channel) {
|
||||
}
|
||||
return QString();
|
||||
}();
|
||||
if (!text.isEmpty()) {
|
||||
if (show && !text.isEmpty()) {
|
||||
show->showToast(text, kJoinErrorDuration);
|
||||
}
|
||||
}
|
||||
@@ -2581,6 +2583,10 @@ void ApiWrap::refreshFileReference(
|
||||
request(MTPaccount_GetSavedRingtones(MTP_long(0)));
|
||||
}, [&](Data::FileOriginPremiumPreviews data) {
|
||||
request(MTPhelp_GetPremiumPromo());
|
||||
}, [&](Data::FileOriginWebPage data) {
|
||||
request(MTPmessages_GetWebPage(
|
||||
MTP_string(data.url),
|
||||
MTP_int(0)));
|
||||
}, [&](Data::FileOriginStory data) {
|
||||
request(MTPstories_GetStoriesByID(
|
||||
_session->data().peer(data.peer)->input,
|
||||
@@ -3325,7 +3331,7 @@ void ApiWrap::forwardMessages(
|
||||
}
|
||||
|
||||
const auto settings = &AyuSettings::getInstance();
|
||||
if (!settings->sendReadMessages && settings->markReadAfterPoll && history->lastMessage())
|
||||
if (!settings->sendReadMessages && settings->markReadAfterAction && history->lastMessage())
|
||||
{
|
||||
readHistory(history->lastMessage());
|
||||
}
|
||||
@@ -3613,9 +3619,8 @@ void ApiWrap::sendUploadedPhoto(
|
||||
// AyuGram useScheduledMessages
|
||||
const auto settings = &AyuSettings::getInstance();
|
||||
if (settings->useScheduledMessages && !options.scheduled) {
|
||||
DEBUG_LOG(("[AyuGram] Scheduling message"));
|
||||
auto current = base::unixtime::now();
|
||||
options.scheduled = current + 18; // using 18 seconds because photo can be big
|
||||
options.scheduled = current + 12;
|
||||
}
|
||||
|
||||
const auto media = Api::PrepareUploadedPhoto(item, std::move(info));
|
||||
@@ -3639,9 +3644,8 @@ void ApiWrap::sendUploadedDocument(
|
||||
// AyuGram useScheduledMessages
|
||||
const auto settings = &AyuSettings::getInstance();
|
||||
if (settings->useScheduledMessages && !options.scheduled) {
|
||||
DEBUG_LOG(("[AyuGram] Scheduling message"));
|
||||
auto current = base::unixtime::now();
|
||||
options.scheduled = current + 60; // well, a document can be really big...
|
||||
options.scheduled = current + 12;
|
||||
}
|
||||
|
||||
const auto media = Api::PrepareUploadedDocument(
|
||||
@@ -3667,11 +3671,16 @@ void ApiWrap::cancelLocalItem(not_null<HistoryItem*> item) {
|
||||
void ApiWrap::sendShortcutMessages(
|
||||
not_null<PeerData*> peer,
|
||||
BusinessShortcutId id) {
|
||||
auto ids = QVector<MTPint>();
|
||||
auto randomIds = QVector<MTPlong>();
|
||||
request(MTPmessages_SendQuickReplyMessages(
|
||||
peer->input,
|
||||
MTP_int(id)
|
||||
MTP_int(id),
|
||||
MTP_vector<MTPint>(ids),
|
||||
MTP_vector<MTPlong>(randomIds)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
}).send();
|
||||
}
|
||||
|
||||
@@ -3903,13 +3912,14 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
}
|
||||
|
||||
void ApiWrap::sendBotStart(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<UserData*> bot,
|
||||
PeerData *chat,
|
||||
const QString &startTokenForChat) {
|
||||
Expects(bot->isBot());
|
||||
|
||||
if (chat && chat->isChannel() && !chat->isMegagroup()) {
|
||||
ShowAddParticipantsError("USER_BOT", chat, { 1, bot });
|
||||
ShowAddParticipantsError(show, "USER_BOT", chat, bot);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3943,7 +3953,7 @@ void ApiWrap::sendBotStart(
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (chat) {
|
||||
const auto type = error.type();
|
||||
ShowAddParticipantsError(type, chat, { 1, bot });
|
||||
ShowAddParticipantsError(show, type, chat, bot);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
@@ -4059,6 +4069,8 @@ void ApiWrap::uploadAlbumMedia(
|
||||
|
||||
};
|
||||
request(MTPmessages_UploadMedia(
|
||||
MTP_flags(0),
|
||||
MTPstring(), // business_connection_id
|
||||
item->history()->peer->input,
|
||||
media
|
||||
)).done([=](const MTPMessageMedia &result) {
|
||||
@@ -4148,7 +4160,6 @@ void ApiWrap::sendMediaWithRandomId(
|
||||
// AyuGram useScheduledMessages
|
||||
const auto settings = &AyuSettings::getInstance();
|
||||
if (settings->useScheduledMessages && !options.scheduled) {
|
||||
DEBUG_LOG(("[AyuGram] Scheduling message"));
|
||||
auto current = base::unixtime::now();
|
||||
options.scheduled = current + 12;
|
||||
}
|
||||
@@ -4247,15 +4258,6 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||
_sendingAlbums.remove(groupId);
|
||||
return;
|
||||
}
|
||||
|
||||
// AyuGram useScheduledMessages
|
||||
const auto settings = &AyuSettings::getInstance();
|
||||
if (settings->useScheduledMessages && !album->options.scheduled) {
|
||||
DEBUG_LOG(("[AyuGram] Scheduling message"));
|
||||
auto current = base::unixtime::now();
|
||||
album->options.scheduled = current + 12;
|
||||
}
|
||||
|
||||
auto sample = (HistoryItem*)nullptr;
|
||||
auto medias = QVector<MTPInputSingleMedia>();
|
||||
medias.reserve(album->items.size());
|
||||
@@ -4280,6 +4282,14 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||
_sendingAlbums.remove(groupId);
|
||||
return;
|
||||
}
|
||||
|
||||
// AyuGram useScheduledMessages
|
||||
const auto settings = &AyuSettings::getInstance();
|
||||
if (settings->useScheduledMessages && !album->options.scheduled) {
|
||||
auto current = base::unixtime::now();
|
||||
album->options.scheduled = current + 12;
|
||||
}
|
||||
|
||||
const auto history = sample->history();
|
||||
const auto replyTo = sample->replyTo();
|
||||
const auto sendAs = album->options.sendAs;
|
||||
@@ -4495,6 +4505,10 @@ Api::InviteLinks &ApiWrap::inviteLinks() {
|
||||
return *_inviteLinks;
|
||||
}
|
||||
|
||||
Api::ChatLinks &ApiWrap::chatLinks() {
|
||||
return *_chatLinks;
|
||||
}
|
||||
|
||||
Api::ViewsManager &ApiWrap::views() {
|
||||
return *_views;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ class Key;
|
||||
|
||||
namespace Ui {
|
||||
struct PreparedList;
|
||||
class Show;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Api {
|
||||
@@ -69,6 +70,7 @@ class SensitiveContent;
|
||||
class GlobalPrivacy;
|
||||
class UserPrivacy;
|
||||
class InviteLinks;
|
||||
class ChatLinks;
|
||||
class ViewsManager;
|
||||
class ConfirmPhone;
|
||||
class PeerPhoto;
|
||||
@@ -342,6 +344,7 @@ public:
|
||||
BusinessShortcutId id);
|
||||
void sendMessage(MessageToSend &&message);
|
||||
void sendBotStart(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<UserData*> bot,
|
||||
PeerData *chat = nullptr,
|
||||
const QString &startTokenForChat = QString());
|
||||
@@ -384,6 +387,7 @@ public:
|
||||
[[nodiscard]] Api::GlobalPrivacy &globalPrivacy();
|
||||
[[nodiscard]] Api::UserPrivacy &userPrivacy();
|
||||
[[nodiscard]] Api::InviteLinks &inviteLinks();
|
||||
[[nodiscard]] Api::ChatLinks &chatLinks();
|
||||
[[nodiscard]] Api::ViewsManager &views();
|
||||
[[nodiscard]] Api::ConfirmPhone &confirmPhone();
|
||||
[[nodiscard]] Api::PeerPhoto &peerPhoto();
|
||||
@@ -703,6 +707,7 @@ private:
|
||||
const std::unique_ptr<Api::GlobalPrivacy> _globalPrivacy;
|
||||
const std::unique_ptr<Api::UserPrivacy> _userPrivacy;
|
||||
const std::unique_ptr<Api::InviteLinks> _inviteLinks;
|
||||
const std::unique_ptr<Api::ChatLinks> _chatLinks;
|
||||
const std::unique_ptr<Api::ViewsManager> _views;
|
||||
const std::unique_ptr<Api::ConfirmPhone> _confirmPhone;
|
||||
const std::unique_ptr<Api::PeerPhoto> _peerPhoto;
|
||||
|
||||
@@ -188,13 +188,11 @@ AyuGramSettings::AyuGramSettings() {
|
||||
sendUploadProgress = true;
|
||||
sendOfflinePacketAfterOnline = false;
|
||||
|
||||
markReadAfterSend = true;
|
||||
markReadAfterReaction = true;
|
||||
markReadAfterPoll = true;
|
||||
markReadAfterAction = true;
|
||||
useScheduledMessages = false;
|
||||
|
||||
// ~ Message edits & deletion history
|
||||
saveDeletedMessages = false;
|
||||
saveDeletedMessages = true;
|
||||
saveMessagesHistory = true;
|
||||
|
||||
// ~ QoL toggles
|
||||
@@ -295,16 +293,8 @@ void AyuGramSettings::set_ghostModeEnabled(bool val) {
|
||||
}
|
||||
}
|
||||
|
||||
void AyuGramSettings::set_markReadAfterSend(bool val) {
|
||||
markReadAfterSend = val;
|
||||
}
|
||||
|
||||
void AyuGramSettings::set_markReadAfterReaction(bool val) {
|
||||
markReadAfterReaction = val;
|
||||
}
|
||||
|
||||
void AyuGramSettings::set_markReadAfterPoll(bool val) {
|
||||
markReadAfterPoll = val;
|
||||
void AyuGramSettings::set_markReadAfterAction(bool val) {
|
||||
markReadAfterAction = val;
|
||||
}
|
||||
|
||||
void AyuGramSettings::set_useScheduledMessages(bool val) {
|
||||
|
||||
@@ -23,9 +23,7 @@ public:
|
||||
bool sendUploadProgress;
|
||||
bool sendOfflinePacketAfterOnline;
|
||||
|
||||
bool markReadAfterSend;
|
||||
bool markReadAfterReaction;
|
||||
bool markReadAfterPoll;
|
||||
bool markReadAfterAction;
|
||||
bool useScheduledMessages;
|
||||
|
||||
bool saveDeletedMessages;
|
||||
@@ -85,9 +83,7 @@ public:
|
||||
|
||||
void set_ghostModeEnabled(bool val);
|
||||
|
||||
void set_markReadAfterSend(bool val);
|
||||
void set_markReadAfterReaction(bool val);
|
||||
void set_markReadAfterPoll(bool val);
|
||||
void set_markReadAfterAction(bool val);
|
||||
void set_useScheduledMessages(bool val);
|
||||
|
||||
void set_saveDeletedMessages(bool val);
|
||||
@@ -147,9 +143,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
|
||||
sendOnlinePackets,
|
||||
sendUploadProgress,
|
||||
sendOfflinePacketAfterOnline,
|
||||
markReadAfterSend,
|
||||
markReadAfterReaction,
|
||||
markReadAfterPoll,
|
||||
markReadAfterAction,
|
||||
useScheduledMessages,
|
||||
saveDeletedMessages,
|
||||
saveMessagesHistory,
|
||||
|
||||