diff --git a/Telegram/Resources/emoji/set0_preview.webp b/Telegram/Resources/emoji/set0_preview.webp new file mode 100644 index 000000000..122654fa6 Binary files /dev/null and b/Telegram/Resources/emoji/set0_preview.webp differ diff --git a/Telegram/Resources/emoji/set1_preview.webp b/Telegram/Resources/emoji/set1_preview.webp new file mode 100644 index 000000000..2a8a03bbc Binary files /dev/null and b/Telegram/Resources/emoji/set1_preview.webp differ diff --git a/Telegram/Resources/emoji/set2_preview.webp b/Telegram/Resources/emoji/set2_preview.webp new file mode 100644 index 000000000..2b682dd02 Binary files /dev/null and b/Telegram/Resources/emoji/set2_preview.webp differ diff --git a/Telegram/Resources/emoji/set3_preview.webp b/Telegram/Resources/emoji/set3_preview.webp new file mode 100644 index 000000000..0e89f3a38 Binary files /dev/null and b/Telegram/Resources/emoji/set3_preview.webp differ diff --git a/Telegram/Resources/icons/settings_emoji.png b/Telegram/Resources/icons/settings_emoji.png new file mode 100644 index 000000000..298bc39e7 Binary files /dev/null and b/Telegram/Resources/icons/settings_emoji.png differ diff --git a/Telegram/Resources/icons/settings_emoji@2x.png b/Telegram/Resources/icons/settings_emoji@2x.png new file mode 100644 index 000000000..ffbc424d4 Binary files /dev/null and b/Telegram/Resources/icons/settings_emoji@2x.png differ diff --git a/Telegram/Resources/icons/settings_emoji@3x.png b/Telegram/Resources/icons/settings_emoji@3x.png new file mode 100644 index 000000000..656a17b99 Binary files /dev/null and b/Telegram/Resources/icons/settings_emoji@3x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 0624ead80..b72099fb6 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1035,10 +1035,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_emoji_category7" = "Symbols & Flags"; "lng_emoji_hide_panel" = "Click here to hide the emoji sidebar"; "lng_emoji_manage_sets" = "Choose emoji set"; -"lng_emoji_set_available" = "Download {size}"; -"lng_emoji_set_ready" = "Ready"; -"lng_emoji_set_active" = "Active"; -"lng_emoji_set_loading" = "Downloading {progress}"; +"lng_emoji_set_ready" = "Downloaded"; +"lng_emoji_set_active" = "Current set"; +"lng_emoji_set_loading" = "{percent}, {progress}"; "lng_recent_stickers" = "Frequently used"; "lng_faved_stickers_add" = "Add to Favorites"; diff --git a/Telegram/Resources/qrc/telegram_emoji_preview.qrc b/Telegram/Resources/qrc/telegram_emoji_preview.qrc new file mode 100644 index 000000000..238abec17 --- /dev/null +++ b/Telegram/Resources/qrc/telegram_emoji_preview.qrc @@ -0,0 +1,8 @@ + + + ../emoji/set0_preview.webp + ../emoji/set1_preview.webp + ../emoji/set2_preview.webp + ../emoji/set3_preview.webp + + diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index fb545d050..548c81941 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -347,7 +347,7 @@ void ProxyRow::paintCheck(Painter &p, TimeMs ms) { } const auto loading = _progress ? _progress->computeState() - : Ui::InfiniteRadialAnimation::State{ 0., 0, FullArcLength }; + : Ui::RadialState{ 0., 0, FullArcLength }; const auto toggled = _toggled.current(ms, _view.selected ? 1. : 0.) * (1. - loading.shown); const auto _st = &st::defaultRadio; @@ -361,6 +361,7 @@ void ProxyRow::paintCheck(Painter &p, TimeMs ms) { auto pen = anim::pen(_st->untoggledFg, _st->toggledFg, toggled * set); pen.setWidth(_st->thickness); + pen.setCapStyle(Qt::RoundCap); p.setPen(pen); p.setBrush(_st->bg); const auto rect = rtlrect(QRectF(left, top, _st->diameter, _st->diameter).marginsRemoved(QMarginsF(_st->thickness / 2., _st->thickness / 2., _st->thickness / 2., _st->thickness / 2.)), outerWidth); diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index c1e80a8c9..cce561661 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -266,10 +266,10 @@ autocompleteRowTitle: semiboldTextStyle; autocompleteRowKeys: defaultTextStyle; autocompleteRowAnswer: defaultTextStyle; -manageEmojiCheck: IconButton(defaultIconButton) { - width: 18px; - height: 13px; - icon: stickersFeaturedInstalled; -} -manageEmojiRadialSize: size(20px, 20px); -manageEmojiRadialThickness: 2px; +manageEmojiPreview: 22px; +manageEmojiPreviewWidth: 48px; +manageEmojiPreviewHeight: 48px; +manageEmojiPreviewPadding: margins(23px, 9px, 19px, 9px); +manageEmojiMarginRight: 21px; +manageEmojiNameTop: 3px; +manageEmojiStatusTop: 25px; diff --git a/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp b/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp index 54ac9199b..2e459769b 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_sets_manager.cpp @@ -113,24 +113,26 @@ protected: private: [[nodiscard]] bool showOver() const; [[nodiscard]] bool showOver(State state) const; + void updateStatusColorOverride(); void setupContent(const Set &set); - void setupCheck(); void setupLabels(const Set &set); + void setupPreview(const Set &set); void setupAnimation(); + void paintPreview(Painter &p) const; + void paintRadio(Painter &p, TimeMs ms); void updateAnimation(TimeMs ms); void setupHandler(); void load(); void step_radial(TimeMs ms, bool timer); - [[nodiscard]] QRect rightPartRect(QSize size) const; - [[nodiscard]] QRect radialRect() const; - [[nodiscard]] QRect checkRect() const; - int _id = 0; bool _switching = false; rpl::variable _state; Ui::FlatLabel *_status = nullptr; + std::array _preview; + Animation _toggled; + Animation _active; std::unique_ptr _loading; }; @@ -166,13 +168,18 @@ SetState ComputeState(int id) { QString StateDescription(const SetState &state) { return state.match([](const Available &data) { - return lng_emoji_set_available(lt_size, formatSizeText(data.size)); + return formatSizeText(data.size); }, [](const Ready &data) -> QString { return lang(lng_emoji_set_ready); }, [](const Active &data) -> QString { return lang(lng_emoji_set_active); }, [](const Loading &data) { + const auto percent = (data.size > 0) + ? snap((data.already * 100) / float64(data.size), 0., 100.) + : 0.; return lng_emoji_set_loading( + lt_percent, + QString::number(int(std::round(percent))) + '%', lt_progress, formatDownloadText(data.already, data.size)); }, [](const Failed &data) { @@ -351,38 +358,94 @@ void Row::paintEvent(QPaintEvent *e) { const auto ms = getms(); paintRipple(p, 0, 0, ms); - updateAnimation(ms); - if (_loading) { - _loading->draw( - p, - radialRect(), - st::manageEmojiRadialThickness, - over ? st::windowSubTextFgOver : st::windowSubTextFg); + paintPreview(p); + paintRadio(p, ms); +} + +void Row::paintPreview(Painter &p) const { + const auto x = st::manageEmojiPreviewPadding.left(); + const auto y = st::manageEmojiPreviewPadding.top(); + const auto width = st::manageEmojiPreviewWidth; + const auto height = st::manageEmojiPreviewWidth; + auto &&preview = ranges::view::zip(_preview, ranges::view::ints(0)); + for (const auto &[pixmap, index] : preview) { + const auto row = (index / 2); + const auto column = (index % 2); + const auto left = x + (column ? width - st::manageEmojiPreview : 0); + const auto top = y + (row ? height - st::manageEmojiPreview : 0); + p.drawPixmap(left, top, pixmap); } } -QRect Row::rightPartRect(QSize size) const { - const auto x = width() - - (st::contactsPadding.right() - + st::contactsCheckPosition.x() - + st::manageEmojiCheck.width) - + (st::manageEmojiCheck.width / 2); - const auto y = st::contactsPadding.top() - + (st::contactsPhotoSize - st::manageEmojiCheck.height) / 2 - + (st::manageEmojiCheck.height / 2); - return QRect( - QPoint(x, y) - QPoint(size.width() / 2, size.height() / 2), - size); -} +void Row::paintRadio(Painter &p, TimeMs ms) { + updateAnimation(ms); -QRect Row::radialRect() const { - return rightPartRect(st::manageEmojiRadialSize); -} + const auto loading = _loading + ? _loading->computeState() + : Ui::RadialState{ 0., 0, FullArcLength }; + const auto isToggledSet = _state.current().is(); + const auto isActiveSet = isToggledSet || _state.current().is(); + const auto toggled = _toggled.current(ms, isToggledSet ? 1. : 0.); + const auto active = _active.current(ms, isActiveSet ? 1. : 0.); + const auto _st = &st::defaultRadio; -QRect Row::checkRect() const { - return rightPartRect(QSize( - st::manageEmojiCheck.width, - st::manageEmojiCheck.height)); + PainterHighQualityEnabler hq(p); + + const auto left = width() + - st::manageEmojiMarginRight + - _st->diameter + - _st->thickness; + const auto top = (height() - _st->diameter - _st->thickness) / 2; + const auto outerWidth = width(); + + auto pen = anim::pen(_st->untoggledFg, _st->toggledFg, active); + pen.setWidth(_st->thickness); + pen.setCapStyle(Qt::RoundCap); + p.setPen(pen); + p.setBrush(_st->bg); + const auto rect = rtlrect(QRectF( + left, + top, + _st->diameter, + _st->diameter + ).marginsRemoved(QMarginsF( + _st->thickness / 2., + _st->thickness / 2., + _st->thickness / 2., + _st->thickness / 2. + )), outerWidth); + if (loading.shown > 0 && anim::Disabled()) { + anim::DrawStaticLoading( + p, + rect, + _st->thickness, + pen.color(), + _st->bg); + } else if (loading.arcLength < FullArcLength) { + p.drawArc(rect, loading.arcFrom, loading.arcLength); + } else { + p.drawEllipse(rect); + } + + if (toggled > 0 && (!_loading || !anim::Disabled())) { + p.setPen(Qt::NoPen); + p.setBrush(anim::brush(_st->untoggledFg, _st->toggledFg, toggled)); + + const auto skip0 = _st->diameter / 2.; + const auto skip1 = _st->skip / 10.; + const auto checkSkip = skip0 * (1. - toggled) + skip1 * toggled; + p.drawEllipse(rtlrect(QRectF( + left, + top, + _st->diameter, + _st->diameter + ).marginsRemoved(QMarginsF( + checkSkip, + checkSkip, + checkSkip, + checkSkip + )), outerWidth)); + } } bool Row::showOver(State state) const { @@ -396,11 +459,22 @@ bool Row::showOver() const { void Row::onStateChanged(State was, StateChangeSource source) { RippleButton::onStateChanged(was, source); + if (showOver() != showOver(was)) { + updateStatusColorOverride(); + } +} + +void Row::updateStatusColorOverride() { + const auto isToggledSet = _state.current().is(); + const auto toggled = _toggled.current(isToggledSet ? 1. : 0.); const auto over = showOver(); - if (over != showOver(was)) { - _status->setTextColorOverride(over - ? std::make_optional(st::windowSubTextFgOver->c) - : std::nullopt); + if (toggled == 0. && !over) { + _status->setTextColorOverride(std::nullopt); + } else { + _status->setTextColorOverride(anim::color( + over ? st::contactsStatusFgOver : st::contactsStatusFg, + st::contactsStatusFgOnline, + toggled)); } } @@ -422,11 +496,14 @@ void Row::setupContent(const Set &set) { return !_state.current().is() || !state.is(); }); - setupCheck(); setupLabels(set); + setupPreview(set); setupAnimation(); - resize(width(), st::defaultPeerList.item.height); + const auto height = st::manageEmojiPreviewPadding.top() + + st::manageEmojiPreviewHeight + + st::manageEmojiPreviewPadding.bottom(); + resize(width(), height); } void Row::setupHandler() { @@ -463,28 +540,6 @@ void Row::load() { SetGlobalLoader(base::make_unique_q(App::main(), _id)); } -void Row::setupCheck() { - using namespace rpl::mappers; - - const auto check = Ui::CreateChild>( - this, - object_ptr( - this, - st::manageEmojiCheck)); - sizeValue( - ) | rpl::start_with_next([=](QSize size) { - const auto rect = checkRect(); - check->moveToLeft(rect.x(), rect.y()); - }, check->lifetime()); - - check->toggleOn(_state.value( - ) | rpl::map( - _1 == Active() - )); - - check->setAttribute(Qt::WA_TransparentForMouseEvents); -} - void Row::setupLabels(const Set &set) { using namespace rpl::mappers; @@ -502,16 +557,31 @@ void Row::setupLabels(const Set &set) { sizeValue( ) | rpl::start_with_next([=](QSize size) { - const auto left = st::contactsPadding.left(); - const auto namey = st::contactsPadding.top() - + st::contactsNameTop; - const auto statusy = st::contactsPadding.top() - + st::contactsStatusTop; + const auto left = st::manageEmojiPreviewPadding.left() + + st::manageEmojiPreviewWidth + + st::manageEmojiPreviewPadding.right(); + const auto namey = st::manageEmojiPreviewPadding.top() + + st::manageEmojiNameTop; + const auto statusy = st::manageEmojiPreviewPadding.top() + + st::manageEmojiStatusTop; name->moveToLeft(left, namey); _status->moveToLeft(left, statusy); }, name->lifetime()); } +void Row::setupPreview(const Set &set) { + const auto size = st::manageEmojiPreview * cIntRetinaFactor(); + const auto original = QImage(set.previewPath); + const auto full = original.height(); + auto &&preview = ranges::view::zip(_preview, ranges::view::ints(0)); + for (auto &&[pixmap, index] : preview) { + pixmap = App::pixmapFromImageInPlace(original.copy( + { full * index, 0, full, full } + ).scaledToWidth(size, Qt::SmoothTransformation)); + pixmap.setDevicePixelRatio(cRetinaFactor()); + } +} + void Row::step_radial(TimeMs ms, bool timer) { if (timer && !anim::Disabled()) { update(); @@ -519,10 +589,40 @@ void Row::step_radial(TimeMs ms, bool timer) { } void Row::setupAnimation() { + using namespace rpl::mappers; + _state.value( ) | rpl::start_with_next([=](const SetState &state) { update(); }, lifetime()); + + _state.value( + ) | rpl::map( + _1 == Active() + ) | rpl::distinct_until_changed( + ) | rpl::start_with_next([=](bool toggled) { + _toggled.start( + [=] { updateStatusColorOverride(); update(); }, + toggled ? 0. : 1., + toggled ? 1. : 0., + st::defaultRadio.duration); + }, lifetime()); + + _state.value( + ) | rpl::map([](const SetState &state) { + return state.is() || state.is(); + }) | rpl::distinct_until_changed( + ) | rpl::start_with_next([=](bool active) { + _active.start( + [=] { update(); }, + active ? 0. : 1., + active ? 1. : 0., + st::defaultRadio.duration); + }, lifetime()); + + _toggled.finish(); + _active.finish(); + updateStatusColorOverride(); } void Row::updateAnimation(TimeMs ms) { diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index 4cf66f22e..fe2668768 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -58,6 +58,7 @@ settingsIconLanguage: icon {{ "settings_language", menuIconFg }}; settingsIconInterfaceScale: icon {{ "settings_interface_scale", menuIconFg }}; settingsIconFaq: icon {{ "settings_faq", menuIconFg }}; settingsIconStickers: icon {{ "settings_stickers", menuIconFg }}; +settingsIconEmoji: icon {{ "settings_emoji", menuIconFg }}; settingsIconThemes: icon {{ "settings_themes", menuIconFg }}; settingsIconCalls: icon {{ "settings_phone_number", menuIconFg }}; diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 8c28d56ff..d9b88de2e 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -490,7 +490,7 @@ void SetupStickersEmoji(not_null container) { container, lng_emoji_manage_sets, st::settingsChatButton, - &st::settingsIconStickers, + &st::settingsIconEmoji, st::settingsChatIconLeft )->addClickHandler([] { Ui::show(Box()); diff --git a/Telegram/SourceFiles/ui/animation.h b/Telegram/SourceFiles/ui/animation.h index 470e67506..7eb6a2577 100644 --- a/Telegram/SourceFiles/ui/animation.h +++ b/Telegram/SourceFiles/ui/animation.h @@ -676,6 +676,7 @@ private: , updateCallback(std::move(updateCallback)) { } void step(float64 ms, bool timer) { + const auto callback = updateCallback; const auto dt = (ms >= duration || anim::Disabled()) ? 1. : (ms / duration); @@ -686,7 +687,7 @@ private: } else { value.update(dt, transition); } - updateCallback(); + callback(); } anim::value value; diff --git a/Telegram/SourceFiles/ui/effects/radial_animation.cpp b/Telegram/SourceFiles/ui/effects/radial_animation.cpp index bcfb86235..4133e7053 100644 --- a/Telegram/SourceFiles/ui/effects/radial_animation.cpp +++ b/Telegram/SourceFiles/ui/effects/radial_animation.cpp @@ -72,9 +72,15 @@ void RadialAnimation::step(TimeMs ms) { _animation.step(ms); } -void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, style::color color) { +void RadialAnimation::draw( + Painter &p, + const QRect &inner, + int32 thickness, + style::color color) { + const auto state = computeState(); + auto o = p.opacity(); - p.setOpacity(o * _opacity); + p.setOpacity(o * state.shown); auto pen = color->p; auto was = p.pen(); @@ -82,24 +88,27 @@ void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, styl pen.setCapStyle(Qt::RoundCap); p.setPen(pen); - auto len = MinArcLength + qRound(a_arcEnd.current()); - auto from = QuarterArcLength - - len - - (anim::Disabled() ? 0 : qRound(a_arcStart.current())); - if (rtl()) { - from = QuarterArcLength - (from - QuarterArcLength) - len; - if (from < 0) from += FullArcLength; - } - { PainterHighQualityEnabler hq(p); - p.drawArc(inner, from, len); + p.drawArc(inner, state.arcFrom, state.arcLength); } p.setPen(was); p.setOpacity(o); } +RadialState RadialAnimation::computeState() { + auto length = MinArcLength + qRound(a_arcEnd.current()); + auto from = QuarterArcLength + - length + - (anim::Disabled() ? 0 : qRound(a_arcStart.current())); + if (rtl()) { + from = QuarterArcLength - (from - QuarterArcLength) - length; + if (from < 0) from += FullArcLength; + } + return { _opacity, from, length }; +} + InfiniteRadialAnimation::InfiniteRadialAnimation( AnimationCallbacks &&callbacks, const style::InfiniteRadialAnimation &st) @@ -186,7 +195,7 @@ void InfiniteRadialAnimation::draw( p.setOpacity(o); } -auto InfiniteRadialAnimation::computeState() -> State { +RadialState InfiniteRadialAnimation::computeState() { const auto now = getms(); const auto linear = int(((now * FullArcLength) / _st.linearPeriod) % FullArcLength); diff --git a/Telegram/SourceFiles/ui/effects/radial_animation.h b/Telegram/SourceFiles/ui/effects/radial_animation.h index d4742455a..a68c77a7c 100644 --- a/Telegram/SourceFiles/ui/effects/radial_animation.h +++ b/Telegram/SourceFiles/ui/effects/radial_animation.h @@ -13,6 +13,12 @@ struct InfiniteRadialAnimation; namespace Ui { +struct RadialState { + float64 shown = 0.; + int arcFrom = 0; + int arcLength = FullArcLength; +}; + class RadialAnimation { public: RadialAnimation(AnimationCallbacks &&callbacks); @@ -33,7 +39,13 @@ public: step(getms()); } - void draw(Painter &p, const QRect &inner, int32 thickness, style::color color); + void draw( + Painter &p, + const QRect &inner, + int32 thickness, + style::color color); + + RadialState computeState(); private: TimeMs _firstStart = 0; @@ -49,11 +61,6 @@ private: class InfiniteRadialAnimation { public: - struct State { - float64 shown = 0.; - int arcFrom = 0; - int arcLength = FullArcLength; - }; InfiniteRadialAnimation( AnimationCallbacks &&callbacks, const style::InfiniteRadialAnimation &st); @@ -80,7 +87,7 @@ public: QSize size, int outerWidth); - State computeState(); + RadialState computeState(); private: const style::InfiniteRadialAnimation &_st; diff --git a/Telegram/SourceFiles/ui/emoji_config.cpp b/Telegram/SourceFiles/ui/emoji_config.cpp index 7d4d266d7..f02ca9461 100644 --- a/Telegram/SourceFiles/ui/emoji_config.cpp +++ b/Telegram/SourceFiles/ui/emoji_config.cpp @@ -30,10 +30,10 @@ constexpr auto kCacheVersion = uint32(3); constexpr auto kMaxId = uint32(1 << 8); const auto kSets = { - Set{ 0, 0, 0, "Mac" }, - Set{ 1, 205, 7'232'542, "Android" }, - Set{ 2, 206, 5'038'738, "Twemoji" }, - Set{ 3, 238, 6'992'260, "EmojiOne" }, + Set{ 0, 0, 0, "Mac", ":/gui/emoji/set0_preview.webp" }, + Set{ 1, 246, 7'336'383, "Android", ":/gui/emoji/set1_preview.webp" }, + Set{ 2, 206, 5'038'738, "Twemoji", ":/gui/emoji/set2_preview.webp" }, + Set{ 3, 238, 6'992'260, "EmojiOne", ":/gui/emoji/set3_preview.webp" }, }; // Right now we can't allow users of Ui::Emoji to create custom sizes. diff --git a/Telegram/SourceFiles/ui/emoji_config.h b/Telegram/SourceFiles/ui/emoji_config.h index a6f3fbbe3..bcf2dbb80 100644 --- a/Telegram/SourceFiles/ui/emoji_config.h +++ b/Telegram/SourceFiles/ui/emoji_config.h @@ -30,6 +30,7 @@ struct Set { int postId = 0; int size = 0; QString name; + QString previewPath; }; // Thread safe, callback is called on main thread. diff --git a/Telegram/SourceFiles/ui/special_buttons.cpp b/Telegram/SourceFiles/ui/special_buttons.cpp index a25116ad3..05dd6ac17 100644 --- a/Telegram/SourceFiles/ui/special_buttons.cpp +++ b/Telegram/SourceFiles/ui/special_buttons.cpp @@ -196,7 +196,7 @@ void EmojiButton::paintEvent(QPaintEvent *e) { const auto over = isOver(); const auto loadingState = _loading ? _loading->computeState() - : Ui::InfiniteRadialAnimation::State{ 0., 0, FullArcLength }; + : Ui::RadialState{ 0., 0, FullArcLength }; if (loadingState.shown < 1.) { p.setOpacity(1. - loadingState.shown); diff --git a/Telegram/gyp/telegram_qrc.gypi b/Telegram/gyp/telegram_qrc.gypi index a8c936d61..d9147d6d2 100644 --- a/Telegram/gyp/telegram_qrc.gypi +++ b/Telegram/gyp/telegram_qrc.gypi @@ -13,6 +13,7 @@ '<(res_loc)/qrc/telegram_emoji_3.qrc', '<(res_loc)/qrc/telegram_emoji_4.qrc', '<(res_loc)/qrc/telegram_emoji_5.qrc', + '<(res_loc)/qrc/telegram_emoji_preview.qrc', '<(res_loc)/qrc/telegram_sounds.qrc', ], },