notifications_utilities.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "window/notifications_utilities.h"
  8. #include "window/main_window.h"
  9. #include "base/platform/base_platform_file_utilities.h"
  10. #include "base/random.h"
  11. #include "core/application.h"
  12. #include "data/data_peer.h"
  13. #include "ui/empty_userpic.h"
  14. #include "styles/style_window.h"
  15. namespace Window::Notifications {
  16. namespace {
  17. // Delete notify photo file after 1 minute of not using.
  18. constexpr int kNotifyDeletePhotoAfterMs = 60000;
  19. } // namespace
  20. QImage GenerateUserpic(not_null<PeerData*> peer, Ui::PeerUserpicView &view) {
  21. return peer->isSelf()
  22. ? Ui::EmptyUserpic::GenerateSavedMessages(st::notifyMacPhotoSize)
  23. : peer->isRepliesChat()
  24. ? Ui::EmptyUserpic::GenerateRepliesMessages(st::notifyMacPhotoSize)
  25. : PeerData::GenerateUserpicImage(peer, view, st::notifyMacPhotoSize);
  26. }
  27. CachedUserpics::CachedUserpics()
  28. : _clearTimer([=] { clear(); }) {
  29. QDir().mkpath(cWorkingDir() + u"tdata/temp"_q);
  30. }
  31. CachedUserpics::~CachedUserpics() {
  32. if (_someSavedFlag) {
  33. for (const auto &item : std::as_const(_images)) {
  34. QFile(item.path).remove();
  35. }
  36. // This works about 1200ms on Windows for a folder with one image O_o
  37. //base::Platform::DeleteDirectory(cWorkingDir() + u"tdata/temp"_q);
  38. }
  39. }
  40. QString CachedUserpics::get(
  41. const InMemoryKey &key,
  42. not_null<PeerData*> peer,
  43. Ui::PeerUserpicView &view) {
  44. auto ms = crl::now();
  45. auto i = _images.find(key);
  46. if (i != _images.cend()) {
  47. if (i->until) {
  48. i->until = ms + kNotifyDeletePhotoAfterMs;
  49. clearInMs(-kNotifyDeletePhotoAfterMs);
  50. }
  51. } else {
  52. Image v;
  53. if (key.first) {
  54. v.until = ms + kNotifyDeletePhotoAfterMs;
  55. clearInMs(-kNotifyDeletePhotoAfterMs);
  56. } else {
  57. v.until = 0;
  58. }
  59. v.path = u"%1tdata/temp/%2.png"_q.arg(
  60. cWorkingDir(),
  61. QString::number(base::RandomValue<uint64>(), 16));
  62. if (key.first || key.second) {
  63. GenerateUserpic(peer, view).save(v.path, "PNG");
  64. } else {
  65. LogoNoMargin().save(v.path, "PNG");
  66. }
  67. i = _images.insert(key, v);
  68. _someSavedFlag = true;
  69. }
  70. return i->path;
  71. }
  72. crl::time CachedUserpics::clear(crl::time ms) {
  73. crl::time result = 0;
  74. for (auto i = _images.begin(); i != _images.end();) {
  75. if (!i->until) {
  76. ++i;
  77. continue;
  78. }
  79. if (i->until <= ms) {
  80. QFile(i->path).remove();
  81. i = _images.erase(i);
  82. } else {
  83. if (!result) {
  84. result = i->until;
  85. } else {
  86. accumulate_min(result, i->until);
  87. }
  88. ++i;
  89. }
  90. }
  91. return result;
  92. }
  93. void CachedUserpics::clearInMs(int ms) {
  94. if (ms < 0) {
  95. ms = -ms;
  96. if (_clearTimer.isActive() && _clearTimer.remainingTime() <= ms) {
  97. return;
  98. }
  99. }
  100. _clearTimer.callOnce(ms);
  101. }
  102. void CachedUserpics::clear() {
  103. auto ms = crl::now();
  104. auto minuntil = clear(ms);
  105. if (minuntil) {
  106. clearInMs(int(minuntil - ms));
  107. }
  108. }
  109. } // namespace Window::Notifications