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_data_storage" = "Data and storage";
"lng_settings_information" = "Edit profile";
"lng_settings_security" = "Security";
"lng_settings_passcode_title" = "Local passcode";
"lng_settings_password_title" = "Two-step verification";
"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_ask_ok" = "Ask a Volunteer";
"lng_settings_faq" = "Telegram FAQ";
"lng_settings_features" = "Telegram Features";
"lng_settings_logout" = "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_all" = "Show All Reactions";
"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_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);
}
int64 DownloadManager::computeNextStarted() {
int64 DownloadManager::computeNextStartDate() {
const auto now = base::unixtime::now();
if (_lastStartedBase != now) {
_lastStartedBase = now;
@ -111,7 +111,7 @@ int64 DownloadManager::computeNextStarted() {
void DownloadManager::addLoading(DownloadObject object) {
Expects(object.item != nullptr);
Expects(object.document || object.photo);
Expects(object.document != nullptr);
const auto item = object.item;
auto &data = sessionData(item);
@ -127,13 +127,16 @@ void DownloadManager::addLoading(DownloadObject object) {
remove(data, already);
}
const auto size = object.document
? object.document->size
: object.photo->imageByteSize(PhotoSize::Large);
const auto size = object.document->size;
const auto path = object.document->loadingFilePath();
if (path.isEmpty()) {
return;
}
data.downloading.push_back({
.object = object,
.started = computeNextStarted(),
.started = computeNextStartDate(),
.path = path,
.total = size,
});
_loading.emplace(item);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -153,7 +153,9 @@ public:
[[nodiscard]] virtual bool allowSaveFileAs(
not_null<const HistoryItem*> item,
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(
not_null<Memento*> memento,

View file

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

View file

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

View file

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

View file

@ -1320,12 +1320,12 @@ void Instance::handleStreamingError(
const auto document = data->streamed->id.audio();
const auto contextId = data->streamed->id.contextId();
if (error == Streaming::Error::NotStreamable) {
DocumentSaveClickHandler::Save(
(contextId ? contextId : ::Data::FileOrigin()),
DocumentSaveClickHandler::SaveAndTrack(
contextId,
document);
} else if (error == Streaming::Error::OpenFailed) {
DocumentSaveClickHandler::Save(
(contextId ? contextId : ::Data::FileOrigin()),
DocumentSaveClickHandler::SaveAndTrack(
contextId,
document,
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_resolver.h"
#include "data/data_file_click_handler.h"
#include "data/data_download_manager.h"
#include "window/themes/window_theme_preview.h"
#include "window/window_peer_menu.h"
#include "window/window_session_controller.h"
@ -1561,14 +1562,21 @@ void OverlayWidget::saveAs() {
f.open(QIODevice::WriteOnly);
f.write(bytes);
}
if (_message) {
auto &manager = Core::App().downloadManager();
manager.addLoaded({
.item = _message,
.document = _document,
}, file, manager.computeNextStartDate());
}
}
if (bytes.isEmpty()) {
location.accessDisable();
}
} else {
DocumentSaveClickHandler::Save(
fileOrigin(),
DocumentSaveClickHandler::SaveAndTrack(
_message ? _message->fullId() : FullMsgId(),
_document,
DocumentSaveClickHandler::Mode::ToNewFile);
updateControls();
@ -1671,14 +1679,20 @@ void OverlayWidget::downloadMedia() {
QFile(toName).remove();
if (!QFile(location.name()).copy(toName)) {
toName = QString();
} else if (_message) {
auto &manager = Core::App().downloadManager();
manager.addLoaded({
.item = _message,
.document = _document,
}, toName, manager.computeNextStartDate());
}
}
location.accessDisable();
} else {
if (_document->filepath(true).isEmpty()
&& !_document->loading()) {
DocumentSaveClickHandler::Save(
fileOrigin(),
DocumentSaveClickHandler::SaveAndTrack(
_message ? _message->fullId() : FullMsgId(),
_document,
DocumentSaveClickHandler::Mode::ToFile);
updateControls();

View file

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

View file

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

View file

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

View file

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

View file

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