Add phrases to lang.string.

This commit is contained in:
John Preston 2022-02-27 16:32:36 +03:00
parent 147d2e1934
commit dde4868540
22 changed files with 135 additions and 62 deletions

View file

@ -475,6 +475,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_theme_accent_title" = "Choose accent color"; "lng_settings_theme_accent_title" = "Choose accent color";
"lng_settings_data_storage" = "Data and storage"; "lng_settings_data_storage" = "Data and storage";
"lng_settings_information" = "Edit profile"; "lng_settings_information" = "Edit profile";
"lng_settings_security" = "Security";
"lng_settings_passcode_title" = "Local passcode"; "lng_settings_passcode_title" = "Local passcode";
"lng_settings_password_title" = "Two-step verification"; "lng_settings_password_title" = "Two-step verification";
"lng_settings_sessions_title" = "Active sessions"; "lng_settings_sessions_title" = "Active sessions";
@ -732,6 +733,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_faq_button" = "Go to FAQ"; "lng_settings_faq_button" = "Go to FAQ";
"lng_settings_ask_ok" = "Ask a Volunteer"; "lng_settings_ask_ok" = "Ask a Volunteer";
"lng_settings_faq" = "Telegram FAQ"; "lng_settings_faq" = "Telegram FAQ";
"lng_settings_features" = "Telegram Features";
"lng_settings_logout" = "Log Out"; "lng_settings_logout" = "Log Out";
"lng_sure_logout" = "Are you sure you want to log out?"; "lng_sure_logout" = "Are you sure you want to log out?";
@ -1831,6 +1833,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_seen_reacted_none" = "Nobody Reacted"; "lng_context_seen_reacted_none" = "Nobody Reacted";
"lng_context_seen_reacted_all" = "Show All Reactions"; "lng_context_seen_reacted_all" = "Show All Reactions";
"lng_context_set_as_quick" = "Set As Quick"; "lng_context_set_as_quick" = "Set As Quick";
"lng_context_delete_from_disk" = "Delete from disk";
"lng_context_delete_all_files" = "Delete all files";
"lng_downloads_section" = "Downloads";
"lng_downloads_view_in_chat" = "View in chat";
"lng_downloads_view_in_section" = "View in downloads";
"lng_downloads_delete_sure_one" = "Do you want to delete this file?";
"lng_downloads_delete_sure#one" = "Do you want to delete {count} file?";
"lng_downloads_delete_sure#other" = "Do you want to delete {count} files?";
"lng_send_image_empty" = "Could not send an empty file: {name}"; "lng_send_image_empty" = "Could not send an empty file: {name}";
"lng_send_image_too_large" = "Could not send a file, because it is larger than 1500 MB: {name}"; "lng_send_image_too_large" = "Could not send a file, because it is larger than 1500 MB: {name}";

View file

@ -98,7 +98,7 @@ void DownloadManager::trackSession(not_null<Main::Session*> session) {
}, data.lifetime); }, data.lifetime);
} }
int64 DownloadManager::computeNextStarted() { int64 DownloadManager::computeNextStartDate() {
const auto now = base::unixtime::now(); const auto now = base::unixtime::now();
if (_lastStartedBase != now) { if (_lastStartedBase != now) {
_lastStartedBase = now; _lastStartedBase = now;
@ -111,7 +111,7 @@ int64 DownloadManager::computeNextStarted() {
void DownloadManager::addLoading(DownloadObject object) { void DownloadManager::addLoading(DownloadObject object) {
Expects(object.item != nullptr); Expects(object.item != nullptr);
Expects(object.document || object.photo); Expects(object.document != nullptr);
const auto item = object.item; const auto item = object.item;
auto &data = sessionData(item); auto &data = sessionData(item);
@ -127,13 +127,16 @@ void DownloadManager::addLoading(DownloadObject object) {
remove(data, already); remove(data, already);
} }
const auto size = object.document const auto size = object.document->size;
? object.document->size const auto path = object.document->loadingFilePath();
: object.photo->imageByteSize(PhotoSize::Large); if (path.isEmpty()) {
return;
}
data.downloading.push_back({ data.downloading.push_back({
.object = object, .object = object,
.started = computeNextStarted(), .started = computeNextStartDate(),
.path = path,
.total = size, .total = size,
}); });
_loading.emplace(item); _loading.emplace(item);

View file

@ -63,12 +63,12 @@ struct DownloadedId {
uint64 peerAccessHash = 0; uint64 peerAccessHash = 0;
std::unique_ptr<DownloadObject> object; std::unique_ptr<DownloadObject> object;
}; };
struct DownloadingId { struct DownloadingId {
DownloadObject object; DownloadObject object;
DownloadDate started = 0; DownloadDate started = 0;
QString path;
int ready = 0; int ready = 0;
int total = 0; int total = 0;
bool done = false; bool done = false;
@ -81,6 +81,8 @@ public:
void trackSession(not_null<Main::Session*> session); void trackSession(not_null<Main::Session*> session);
[[nodiscard]] DownloadDate computeNextStartDate();
void addLoading(DownloadObject object); void addLoading(DownloadObject object);
void addLoaded( void addLoaded(
DownloadObject object, DownloadObject object,
@ -127,8 +129,6 @@ private:
std::vector<DownloadingId>::iterator i); std::vector<DownloadingId>::iterator i);
void clearLoading(); void clearLoading();
[[nodiscard]] int64 computeNextStarted();
[[nodiscard]] SessionData &sessionData(not_null<Main::Session*> session); [[nodiscard]] SessionData &sessionData(not_null<Main::Session*> session);
[[nodiscard]] const SessionData &sessionData( [[nodiscard]] const SessionData &sessionData(
not_null<Main::Session*> session) const; not_null<Main::Session*> session) const;

View file

@ -100,11 +100,12 @@ void DocumentSaveClickHandler::Save(
data->save(origin, savename); data->save(origin, savename);
} }
void DocumentSaveClickHandler::onClickImpl() const { void DocumentSaveClickHandler::SaveAndTrack(
const auto document = this->document(); FullMsgId itemId,
const auto itemId = context(); not_null<DocumentData*> document,
Save(itemId, document); Mode mode) {
if (document->loading()) { Save(itemId ? itemId : Data::FileOrigin(), document, mode);
if (document->loading() && !document->loadingFilePath().isEmpty()) {
if (const auto item = document->owner().message(itemId)) { if (const auto item = document->owner().message(itemId)) {
Core::App().downloadManager().addLoading({ Core::App().downloadManager().addLoading({
.item = item, .item = item,
@ -114,6 +115,10 @@ void DocumentSaveClickHandler::onClickImpl() const {
} }
} }
void DocumentSaveClickHandler::onClickImpl() const {
SaveAndTrack(context(), document());
}
DocumentCancelClickHandler::DocumentCancelClickHandler( DocumentCancelClickHandler::DocumentCancelClickHandler(
not_null<DocumentData*> document, not_null<DocumentData*> document,
Fn<void(FullMsgId)> &&callback, Fn<void(FullMsgId)> &&callback,

View file

@ -52,6 +52,10 @@ public:
Data::FileOrigin origin, Data::FileOrigin origin,
not_null<DocumentData*> document, not_null<DocumentData*> document,
Mode mode = Mode::ToCacheOrFile); Mode mode = Mode::ToCacheOrFile);
static void SaveAndTrack(
FullMsgId itemId,
not_null<DocumentData*> document,
Mode mode = Mode::ToCacheOrFile);
protected: protected:
void onClickImpl() const override; void onClickImpl() const override;

View file

@ -2422,7 +2422,7 @@ void HistoryInner::showContextInFolder(not_null<DocumentData*> document) {
void HistoryInner::saveDocumentToFile( void HistoryInner::saveDocumentToFile(
FullMsgId contextId, FullMsgId contextId,
not_null<DocumentData*> document) { not_null<DocumentData*> document) {
DocumentSaveClickHandler::Save( DocumentSaveClickHandler::SaveAndTrack(
contextId, contextId,
document, document,
DocumentSaveClickHandler::Mode::ToNewFile); DocumentSaveClickHandler::Mode::ToNewFile);

View file

@ -205,10 +205,9 @@ void AddSaveDocumentAction(
if (list->hasCopyRestriction(item)) { if (list->hasCopyRestriction(item)) {
return; return;
} }
const auto origin = Data::FileOrigin( const auto origin = item ? item->fullId() : FullMsgId();
item ? item->fullId() : FullMsgId());
const auto save = [=] { const auto save = [=] {
DocumentSaveClickHandler::Save( DocumentSaveClickHandler::SaveAndTrack(
origin, origin,
document, document,
DocumentSaveClickHandler::Mode::ToNewFile); DocumentSaveClickHandler::Mode::ToNewFile);

View file

@ -100,7 +100,11 @@ void Provider::refreshViewer() {
const auto item = id->object.item; const auto item = id->object.item;
if (!copy.remove(item) && !_downloaded.contains(item)) { if (!copy.remove(item) && !_downloaded.contains(item)) {
_downloading.emplace(item); _downloading.emplace(item);
_elements.push_back(Element{ item, id->started }); _elements.push_back({
.item = item,
.started = id->started,
.path = id->path,
});
trackItemSession(item); trackItemSession(item);
refreshPostponed(true); refreshPostponed(true);
} }
@ -130,7 +134,9 @@ void Provider::refreshViewer() {
remove(item); remove(item);
} else { } else {
_downloaded.remove(item); _downloaded.remove(item);
_addPostponed.remove(item); _addPostponed.erase(
ranges::remove(_addPostponed, item, &Element::item),
end(_addPostponed));
} }
}, _lifetime); }, _lifetime);
@ -143,29 +149,41 @@ void Provider::addPostponed(not_null<const Data::DownloadedId*> entry) {
const auto item = entry->object->item; const auto item = entry->object->item;
trackItemSession(item); trackItemSession(item);
if (_addPostponed.emplace(item, entry->started).second const auto i = ranges::find(_addPostponed, item, &Element::item);
&& _addPostponed.size() == 1) { if (i != end(_addPostponed)) {
i->path = entry->path;
i->started = entry->started;
} else {
_addPostponed.push_back({
.item = item,
.started = entry->started,
.path = entry->path,
});
if (_addPostponed.size() == 1) {
Ui::PostponeCall(this, [=] { Ui::PostponeCall(this, [=] {
performAdd(); performAdd();
}); });
} }
}
} }
void Provider::performAdd() { void Provider::performAdd() {
if (_addPostponed.empty()) { if (_addPostponed.empty()) {
return; return;
} }
for (const auto &[item, started] : base::take(_addPostponed)) { for (auto &element : base::take(_addPostponed)) {
_downloaded.emplace(item); _downloaded.emplace(element.item);
if (!_downloading.remove(item)) { if (!_downloading.remove(element.item)) {
_elements.push_back(Element{ item, started }); _elements.push_back(std::move(element));
} }
} }
refreshPostponed(true); refreshPostponed(true);
} }
void Provider::remove(not_null<const HistoryItem*> item) { void Provider::remove(not_null<const HistoryItem*> item) {
_addPostponed.remove(item); _addPostponed.erase(
ranges::remove(_addPostponed, item, &Element::item),
end(_addPostponed));
_downloading.remove(item); _downloading.remove(item);
_downloaded.remove(item); _downloaded.remove(item);
_elements.erase( _elements.erase(
@ -361,8 +379,11 @@ bool Provider::allowSaveFileAs(
return false; return false;
} }
std::optional<QString> Provider::deleteMenuPhrase() { QString Provider::showInFolderPath(
return u"Delete from disk"_q; not_null<const HistoryItem*> item,
not_null<DocumentData*> document) {
const auto i = ranges::find(_elements, item, &Element::item);
return (i != end(_elements)) ? i->path : QString();
} }
void Provider::saveState( void Provider::saveState(

View file

@ -66,7 +66,9 @@ public:
bool allowSaveFileAs( bool allowSaveFileAs(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
not_null<DocumentData*> document) override; not_null<DocumentData*> document) override;
std::optional<QString> deleteMenuPhrase() override; QString showInFolderPath(
not_null<const HistoryItem*> item,
not_null<DocumentData*> document) override;
void saveState( void saveState(
not_null<Media::Memento*> memento, not_null<Media::Memento*> memento,
@ -79,6 +81,7 @@ private:
struct Element { struct Element {
not_null<HistoryItem*> item; not_null<HistoryItem*> item;
int64 started = 0; // unixtime * 1000 int64 started = 0; // unixtime * 1000
QString path;
}; };
bool sectionHasFloatingHeader() override; bool sectionHasFloatingHeader() override;
@ -112,7 +115,7 @@ private:
base::flat_set<not_null<const HistoryItem*>> _downloading; base::flat_set<not_null<const HistoryItem*>> _downloading;
base::flat_set<not_null<const HistoryItem*>> _downloaded; base::flat_set<not_null<const HistoryItem*>> _downloaded;
base::flat_map<not_null<HistoryItem*>, int64> _addPostponed; std::vector<Element> _addPostponed;
std::unordered_map< std::unordered_map<
not_null<const HistoryItem*>, not_null<const HistoryItem*>,

View file

@ -647,7 +647,7 @@ rpl::producer<QString> TitleValue(
: tr::lng_polls_poll_results_title(); : tr::lng_polls_poll_results_title();
case Section::Type::Downloads: case Section::Type::Downloads:
return rpl::single(u"Downloads"_q); return tr::lng_downloads_section();
} }
Unexpected("Bad section type in Info::TitleValue()"); Unexpected("Bad section type in Info::TitleValue()");

View file

@ -200,8 +200,10 @@ Key WrapWidget::key() const {
Dialogs::RowDescriptor WrapWidget::activeChat() const { Dialogs::RowDescriptor WrapWidget::activeChat() const {
if (const auto peer = key().peer()) { if (const auto peer = key().peer()) {
return Dialogs::RowDescriptor(peer->owner().history(peer), FullMsgId()); return Dialogs::RowDescriptor(
} else if (key().settingsSelf() || key().poll()) { peer->owner().history(peer),
FullMsgId());
} else if (key().settingsSelf() || key().isDownloads() || key().poll()) {
return Dialogs::RowDescriptor(); return Dialogs::RowDescriptor();
} }
Unexpected("Owner in WrapWidget::activeChat()."); Unexpected("Owner in WrapWidget::activeChat().");

View file

@ -153,7 +153,9 @@ public:
[[nodiscard]] virtual bool allowSaveFileAs( [[nodiscard]] virtual bool allowSaveFileAs(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
not_null<DocumentData*> document) = 0; not_null<DocumentData*> document) = 0;
[[nodiscard]] virtual std::optional<QString> deleteMenuPhrase() = 0; [[nodiscard]] virtual QString showInFolderPath(
not_null<const HistoryItem*> item,
not_null<DocumentData*> document) = 0;
virtual void saveState( virtual void saveState(
not_null<Memento*> memento, not_null<Memento*> memento,

View file

@ -873,7 +873,9 @@ void ListWidget::showContextMenu(
}, },
&st::menuIconCancel); &st::menuIconCancel);
} else { } else {
auto filepath = lnkDocument->filepath(true); const auto filepath = _provider->showInFolderPath(
item,
lnkDocument);
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {
auto handler = App::LambdaDelayed( auto handler = App::LambdaDelayed(
st::defaultDropdownMenu.menu.ripple.hideDuration, st::defaultDropdownMenu.menu.ripple.hideDuration,
@ -892,7 +894,7 @@ void ListWidget::showContextMenu(
st::defaultDropdownMenu.menu.ripple.hideDuration, st::defaultDropdownMenu.menu.ripple.hideDuration,
this, this,
[=] { [=] {
DocumentSaveClickHandler::Save( DocumentSaveClickHandler::SaveAndTrack(
globalId.itemId, globalId.itemId,
lnkDocument, lnkDocument,
DocumentSaveClickHandler::Mode::ToNewFile); DocumentSaveClickHandler::Mode::ToNewFile);
@ -934,7 +936,7 @@ void ListWidget::showContextMenu(
if (canDeleteAll()) { if (canDeleteAll()) {
_contextMenu->addAction( _contextMenu->addAction(
(_controller->isDownloads() (_controller->isDownloads()
? u"Delete from disk"_q ? tr::lng_context_delete_from_disk(tr::now)
: tr::lng_context_delete_selected(tr::now)), : tr::lng_context_delete_selected(tr::now)),
crl::guard(this, [this] { crl::guard(this, [this] {
deleteSelected(); deleteSelected();
@ -961,7 +963,7 @@ void ListWidget::showContextMenu(
if (selectionData.canDelete) { if (selectionData.canDelete) {
if (_controller->isDownloads()) { if (_controller->isDownloads()) {
_contextMenu->addAction( _contextMenu->addAction(
u"Delete from disk"_q, tr::lng_context_delete_from_disk(tr::now),
crl::guard(this, [=] { deleteItem(globalId); }), crl::guard(this, [=] { deleteItem(globalId); }),
&st::menuIconDelete); &st::menuIconDelete);
} else { } else {
@ -1062,9 +1064,10 @@ void ListWidget::deleteItems(SelectedItems &&items, Fn<void()> confirmed) {
if (items.list.empty()) { if (items.list.empty()) {
return; return;
} else if (_controller->isDownloads()) { } else if (_controller->isDownloads()) {
const auto phrase = (items.list.size() == 1) const auto count = items.list.size();
? u"Do you want to delete this file?"_q const auto phrase = (count == 1)
: u"Do you want to delete X files?"_q; ? tr::lng_downloads_delete_sure_one(tr::now)
: tr::lng_downloads_delete_sure(tr::now, lt_count, count);
const auto deleteSure = [=] { const auto deleteSure = [=] {
const auto ids = ranges::views::all( const auto ids = ranges::views::all(
items.list items.list
@ -1072,6 +1075,7 @@ void ListWidget::deleteItems(SelectedItems &&items, Fn<void()> confirmed) {
return item.globalId; return item.globalId;
}) | ranges::to_vector; }) | ranges::to_vector;
Core::App().downloadManager().deleteFiles(ids); Core::App().downloadManager().deleteFiles(ids);
confirmed();
if (const auto box = _actionBoxWeak.data()) { if (const auto box = _actionBoxWeak.data()) {
box->closeBox(); box->closeBox();
} }

View file

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_peer_values.h" #include "data/data_peer_values.h"
#include "data/data_document.h"
#include "styles/style_info.h" #include "styles/style_info.h"
namespace Info::Media { namespace Info::Media {
@ -476,8 +477,10 @@ bool Provider::allowSaveFileAs(
return item->allowsForward(); return item->allowsForward();
} }
std::optional<QString> Provider::deleteMenuPhrase() { QString Provider::showInFolderPath(
return std::nullopt; not_null<const HistoryItem*> item,
not_null<DocumentData*> document) {
return document->filepath(true);
} }
void Provider::applyDragSelection( void Provider::applyDragSelection(

View file

@ -59,7 +59,9 @@ public:
bool allowSaveFileAs( bool allowSaveFileAs(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
not_null<DocumentData*> document) override; not_null<DocumentData*> document) override;
std::optional<QString> deleteMenuPhrase() override; QString showInFolderPath(
not_null<const HistoryItem*> item,
not_null<DocumentData*> document) override;
void saveState( void saveState(
not_null<Memento*> memento, not_null<Memento*> memento,

View file

@ -1320,12 +1320,12 @@ void Instance::handleStreamingError(
const auto document = data->streamed->id.audio(); const auto document = data->streamed->id.audio();
const auto contextId = data->streamed->id.contextId(); const auto contextId = data->streamed->id.contextId();
if (error == Streaming::Error::NotStreamable) { if (error == Streaming::Error::NotStreamable) {
DocumentSaveClickHandler::Save( DocumentSaveClickHandler::SaveAndTrack(
(contextId ? contextId : ::Data::FileOrigin()), contextId,
document); document);
} else if (error == Streaming::Error::OpenFailed) { } else if (error == Streaming::Error::OpenFailed) {
DocumentSaveClickHandler::Save( DocumentSaveClickHandler::SaveAndTrack(
(contextId ? contextId : ::Data::FileOrigin()), contextId,
document, document,
DocumentSaveClickHandler::Mode::ToFile); DocumentSaveClickHandler::Mode::ToFile);
} }

View file

@ -55,6 +55,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document_media.h" #include "data/data_document_media.h"
#include "data/data_document_resolver.h" #include "data/data_document_resolver.h"
#include "data/data_file_click_handler.h" #include "data/data_file_click_handler.h"
#include "data/data_download_manager.h"
#include "window/themes/window_theme_preview.h" #include "window/themes/window_theme_preview.h"
#include "window/window_peer_menu.h" #include "window/window_peer_menu.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
@ -1561,14 +1562,21 @@ void OverlayWidget::saveAs() {
f.open(QIODevice::WriteOnly); f.open(QIODevice::WriteOnly);
f.write(bytes); f.write(bytes);
} }
if (_message) {
auto &manager = Core::App().downloadManager();
manager.addLoaded({
.item = _message,
.document = _document,
}, file, manager.computeNextStartDate());
}
} }
if (bytes.isEmpty()) { if (bytes.isEmpty()) {
location.accessDisable(); location.accessDisable();
} }
} else { } else {
DocumentSaveClickHandler::Save( DocumentSaveClickHandler::SaveAndTrack(
fileOrigin(), _message ? _message->fullId() : FullMsgId(),
_document, _document,
DocumentSaveClickHandler::Mode::ToNewFile); DocumentSaveClickHandler::Mode::ToNewFile);
updateControls(); updateControls();
@ -1671,14 +1679,20 @@ void OverlayWidget::downloadMedia() {
QFile(toName).remove(); QFile(toName).remove();
if (!QFile(location.name()).copy(toName)) { if (!QFile(location.name()).copy(toName)) {
toName = QString(); toName = QString();
} else if (_message) {
auto &manager = Core::App().downloadManager();
manager.addLoaded({
.item = _message,
.document = _document,
}, toName, manager.computeNextStartDate());
} }
} }
location.accessDisable(); location.accessDisable();
} else { } else {
if (_document->filepath(true).isEmpty() if (_document->filepath(true).isEmpty()
&& !_document->loading()) { && !_document->loading()) {
DocumentSaveClickHandler::Save( DocumentSaveClickHandler::SaveAndTrack(
fileOrigin(), _message ? _message->fullId() : FullMsgId(),
_document, _document,
DocumentSaveClickHandler::Mode::ToFile); DocumentSaveClickHandler::Mode::ToFile);
updateControls(); updateControls();

View file

@ -942,7 +942,7 @@ Document::Document(
_name.setMarkedText( _name.setMarkedText(
st::defaultTextStyle, st::defaultTextStyle,
(_forceFileLayout (_forceFileLayout
? TextWithEntities{ _data->filename() } ? Ui::Text::Bold(_data->filename())
: Ui::Text::FormatSongNameFor(_data).textWithEntities()), : Ui::Text::FormatSongNameFor(_data).textWithEntities()),
_documentNameOptions); _documentNameOptions);

View file

@ -898,7 +898,7 @@ void SetupDataStorage(
AddButton( AddButton(
container, container,
rpl::single(u"Downloads"_q), tr::lng_downloads_section(),
st::settingsButton, st::settingsButton,
{ &st::settingsIconDownload, kIconPurple } { &st::settingsIconDownload, kIconPurple }
)->setClickedCallback([=] { )->setClickedCallback([=] {

View file

@ -468,7 +468,7 @@ void SetupHelp(
AddButton( AddButton(
container, container,
rpl::single(u"Telegram Features"_q), tr::lng_settings_features(),
st::settingsButton, st::settingsButton,
{ &st::settingsIconTips, kIconLightOrange } { &st::settingsIconTips, kIconLightOrange }
)->setClickedCallback([=] { )->setClickedCallback([=] {

View file

@ -832,7 +832,7 @@ void SetupSecurity(
rpl::producer<> updateTrigger, rpl::producer<> updateTrigger,
Fn<void(Type)> showOther) { Fn<void(Type)> showOther) {
AddSkip(container, st::settingsPrivacySkip); AddSkip(container, st::settingsPrivacySkip);
AddSubsectionTitle(container, rpl::single(u"Security"_q)); AddSubsectionTitle(container, tr::lng_settings_security());
SetupBlockedList( SetupBlockedList(
controller, controller,

View file

@ -68,9 +68,9 @@ void DownloadBar::refreshInfo(const DownloadBarProgress &progress) {
(progress.ready < progress.total (progress.ready < progress.total
? Text::WithEntities( ? Text::WithEntities(
FormatDownloadText(progress.ready, progress.total)) FormatDownloadText(progress.ready, progress.total))
: (_content.count > 1) : Text::Link((_content.count > 1)
? Text::Link(u"View downloads"_q) ? tr::lng_downloads_view_in_section(tr::now)
: Text::Link(u"View in chat"_q))); : tr::lng_downloads_view_in_chat(tr::now))));
_button.entity()->update(); _button.entity()->update();
} }