calls_group_scheduled_labels.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 "calls/group/ui/calls_group_scheduled_labels.h"
  8. #include "ui/rp_widget.h"
  9. #include "ui/painter.h"
  10. #include "lang/lang_keys.h"
  11. #include "base/unixtime.h"
  12. #include "base/timer_rpl.h"
  13. #include "styles/style_calls.h"
  14. #include <QtCore/QDateTime>
  15. #include <QtCore/QLocale>
  16. namespace Calls::Group::Ui {
  17. rpl::producer<QString> StartsWhenText(rpl::producer<TimeId> date) {
  18. return std::move(
  19. date
  20. ) | rpl::map([](TimeId date) -> rpl::producer<QString> {
  21. const auto parsedDate = base::unixtime::parse(date);
  22. const auto dateDay = QDateTime(parsedDate.date(), QTime(0, 0));
  23. const auto previousDay = QDateTime(
  24. parsedDate.date().addDays(-1),
  25. QTime(0, 0));
  26. const auto now = QDateTime::currentDateTime();
  27. const auto kDay = int64(24 * 60 * 60);
  28. const auto tillTomorrow = int64(now.secsTo(previousDay));
  29. const auto tillToday = tillTomorrow + kDay;
  30. const auto tillAfter = tillToday + kDay;
  31. const auto time = QLocale().toString(
  32. parsedDate.time(),
  33. QLocale::ShortFormat);
  34. auto exact = tr::lng_group_call_starts_short_date(
  35. lt_date,
  36. rpl::single(langDayOfMonthFull(dateDay.date())),
  37. lt_time,
  38. rpl::single(time)
  39. ) | rpl::type_erased();
  40. auto tomorrow = tr::lng_group_call_starts_short_tomorrow(
  41. lt_time,
  42. rpl::single(time));
  43. auto today = tr::lng_group_call_starts_short_today(
  44. lt_time,
  45. rpl::single(time));
  46. auto todayAndAfter = rpl::single(
  47. std::move(today)
  48. ) | rpl::then(base::timer_once(
  49. std::min(tillAfter, kDay) * crl::time(1000)
  50. ) | rpl::map([=] {
  51. return rpl::duplicate(exact);
  52. })) | rpl::flatten_latest() | rpl::type_erased();
  53. auto tomorrowAndAfter = rpl::single(
  54. std::move(tomorrow)
  55. ) | rpl::then(base::timer_once(
  56. std::min(tillToday, kDay) * crl::time(1000)
  57. ) | rpl::map([=] {
  58. return rpl::duplicate(todayAndAfter);
  59. })) | rpl::flatten_latest() | rpl::type_erased();
  60. auto full = rpl::single(
  61. rpl::duplicate(exact)
  62. ) | rpl::then(base::timer_once(
  63. tillTomorrow * crl::time(1000)
  64. ) | rpl::map([=] {
  65. return rpl::duplicate(tomorrowAndAfter);
  66. })) | rpl::flatten_latest() | rpl::type_erased();
  67. if (tillTomorrow > 0) {
  68. return full;
  69. } else if (tillToday > 0) {
  70. return tomorrowAndAfter;
  71. } else if (tillAfter > 0) {
  72. return todayAndAfter;
  73. } else {
  74. return exact;
  75. }
  76. }) | rpl::flatten_latest();
  77. }
  78. object_ptr<Ui::RpWidget> CreateGradientLabel(
  79. QWidget *parent,
  80. rpl::producer<QString> text) {
  81. struct State {
  82. QBrush brush;
  83. QPainterPath path;
  84. };
  85. auto result = object_ptr<Ui::RpWidget>(parent);
  86. const auto raw = result.data();
  87. const auto state = raw->lifetime().make_state<State>();
  88. std::move(
  89. text
  90. ) | rpl::start_with_next([=](const QString &text) {
  91. state->path = QPainterPath();
  92. const auto &font = st::groupCallCountdownFont;
  93. state->path.addText(0, font->ascent, font->f, text);
  94. const auto width = font->width(text);
  95. raw->resize(width, font->height);
  96. auto gradient = QLinearGradient(QPoint(width, 0), QPoint());
  97. gradient.setStops(QGradientStops{
  98. { 0.0, st::groupCallForceMutedBar1->c },
  99. { .7, st::groupCallForceMutedBar2->c },
  100. { 1.0, st::groupCallForceMutedBar3->c }
  101. });
  102. state->brush = QBrush(std::move(gradient));
  103. raw->update();
  104. }, raw->lifetime());
  105. raw->paintRequest(
  106. ) | rpl::start_with_next([=] {
  107. auto p = QPainter(raw);
  108. auto hq = PainterHighQualityEnabler(p);
  109. const auto skip = st::groupCallWidth / 20;
  110. const auto available = parent->width() - 2 * skip;
  111. const auto full = raw->width();
  112. if (available > 0 && full > available) {
  113. const auto scale = available / float64(full);
  114. const auto shift = raw->rect().center();
  115. p.translate(shift);
  116. p.scale(scale, scale);
  117. p.translate(-shift);
  118. }
  119. p.setPen(Qt::NoPen);
  120. p.setBrush(state->brush);
  121. p.drawPath(state->path);
  122. }, raw->lifetime());
  123. return result;
  124. }
  125. } // namespace Calls::Group::Ui