Skip to content

Commit

Permalink
Emoji status (closes #311 and #312) (#388)
Browse files Browse the repository at this point in the history
* Emoji status

* Support emoji status for call item

* Typo fix + crash fixes

* Fixes

* Add status for chat preview

* adding emoji statuses to some places + fixes

* Add trending emoji status

* Doubtful fix 0_o

* Fixes

* Add emoji status to admin rights activity

* Add particle effect for custom emoji status and reactions

* Bugfixes

* Fix on theme invalidate

* fix layout on screen rotation

* Fix

* Add add/remove/clear recents emoji options

* fix jumps in emojipack views when changing in the search bar

* Fixes

* Fixes

* Delay when opening emoji picker

* fix

* Fixes

* Fix

* Fix

* Crashfix

* Fix

* Fix

* Fix

* Fix

* Update app/src/main/java/org/thunderdog/challegram/util/ScrollJumpCompensator.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/util/EmojiStatusHelper.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/ui/BottomSheetViewController.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiEffect.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/component/emoji/AnimatedEmojiDrawable.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/ui/EmojiStatusListController.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/ui/EmojiStatusSelectorEmojiPage.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update TGStickerSetInfo.java

* Temporary fix for a critical issue

* fix for critical issue

* Fixes

* Fixes

* Update app/src/main/java/org/thunderdog/challegram/data/TGStickerSetInfo.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/telegram/TdlibAccount.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/telegram/TdlibAccount.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/telegram/TdlibAccount.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Update app/src/main/java/org/thunderdog/challegram/telegram/TdlibAccount.java

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>

* Fix save constructor id  in cache

* Improved display emoji status on call screen

* save emoji status thumb to cache

* Reworked emoji status cache + Store user flags (verified, premium) + Bugfixes

* Store relative path to profile photo and emoji status files instead of absolute ones

* Remove unused `ImageFile.EMOJI_START_ID`

* Added copyright

* Fixed comment

* FFixed crash handling inside `Tracer.onTdlibHandlerError` + Fixed showing empty emoji status (star) for non-loaded TDLib instances + Improved storing relative paths to profile pic and emoji status + Bugfixes

* Added an ability to share custom emoji usage repetitions + Improved premium icon / emoji status animation when switching between accounts + Fixed memory leaks related to the emoji statuses in the drawer

---------

Co-authored-by: Vyacheslav <6242627+vkryl@users.noreply.github.com>
  • Loading branch information
Arseny271 and vkryl committed Jul 10, 2023
1 parent 1846af1 commit a760ab4
Show file tree
Hide file tree
Showing 69 changed files with 5,817 additions and 375 deletions.
Expand Up @@ -1817,7 +1817,7 @@ public int getControllerWidth (View view) {
private StickerPreviewView stickerPreview;
private StickerSmallView stickerPreviewControllerView;

public void openStickerPreview (Tdlib tdlib, StickerSmallView stickerView, TGStickerObj sticker, int cx, int cy, int maxWidth, int viewportHeight, boolean disableEmojis) {
public void openStickerPreview (Tdlib tdlib, StickerSmallView stickerView, TGStickerObj sticker, int cx, int cy, int maxWidth, int viewportHeight, boolean disableEmojis, boolean isEmojiStatus) {
if (stickerPreview != null) {
return;
}
Expand All @@ -1827,6 +1827,7 @@ public void openStickerPreview (Tdlib tdlib, StickerSmallView stickerView, TGSti
stickerPreview = new StickerPreviewView(this);
stickerPreview.setControllerView(stickerPreviewControllerView);
stickerPreview.setSticker(tdlib, sticker, cx, cy, maxWidth, viewportHeight, disableEmojis);
stickerPreview.setIsEmojiStatus(isEmojiStatus);

stickerPreviewWindow = new PopupLayout(this);
stickerPreviewWindow.setBackListener(stickerPreview);
Expand Down
23 changes: 13 additions & 10 deletions app/src/main/java/org/thunderdog/challegram/MainActivity.java
Expand Up @@ -32,6 +32,7 @@
import androidx.collection.SparseArrayCompat;

import org.drinkless.tdlib.TdApi;
import org.thunderdog.challegram.config.Config;
import org.thunderdog.challegram.core.Background;
import org.thunderdog.challegram.core.Lang;
import org.thunderdog.challegram.helper.LiveLocationHelper;
Expand Down Expand Up @@ -141,17 +142,19 @@ public void onCreate (Bundle savedInstanceState) {
initController(account.tdlib(), account.tdlib().authorizationStatus());
}

Tdlib currentTdlib = TdlibManager.instance().current();
currentTdlib.awaitConnection(() -> {
long pushId = Settings.instance().newPushId();
TDLib.Tag.notifications(pushId, currentTdlib.id(), "Syncing other accounts, since user launched the app.");
AtomicBoolean sentChangeLogs = new AtomicBoolean(currentTdlib.checkChangeLogs(false, false));
TdlibManager.instance().sync(pushId, TdlibAccount.NO_ID, null, false, false, 3, tdlib -> {
if (tdlib.checkChangeLogs(sentChangeLogs.get(), false))
sentChangeLogs.set(true);
LottieCache.instance().gc();
if (Config.AWAKE_ALL_TDLIB_INSTANCES) {
Tdlib currentTdlib = TdlibManager.instance().current();
currentTdlib.awaitConnection(() -> {
long pushId = Settings.instance().newPushId();
TDLib.Tag.notifications(pushId, currentTdlib.id(), "Syncing other accounts, since user launched the app.");
AtomicBoolean sentChangeLogs = new AtomicBoolean(currentTdlib.checkChangeLogs(false, false));
TdlibManager.instance().sync(pushId, TdlibAccount.NO_ID, null, false, false, 3, tdlib -> {
if (tdlib.checkChangeLogs(sentChangeLogs.get(), false))
sentChangeLogs.set(true);
LottieCache.instance().gc();
});
});
});
}
}

public void proceedFromRecovery () {
Expand Down
Expand Up @@ -34,6 +34,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;

import org.drinkless.tdlib.TdApi;
import org.thunderdog.challegram.R;
import org.thunderdog.challegram.U;
import org.thunderdog.challegram.component.user.RemoveHelper;
Expand All @@ -53,6 +54,7 @@
import org.thunderdog.challegram.tool.UI;
import org.thunderdog.challegram.tool.Views;
import org.thunderdog.challegram.util.DrawModifier;
import org.thunderdog.challegram.util.EmojiStatusHelper;
import org.thunderdog.challegram.util.text.Counter;
import org.thunderdog.challegram.util.text.Text;
import org.thunderdog.challegram.util.text.TextColorSet;
Expand Down Expand Up @@ -106,6 +108,7 @@ public interface IconOverlay {
private CharSequence itemData;
private CharSequence displayItemData;
private Layout displayItemDataLayout;
private EmojiStatusHelper emojiStatusHelper;

private TogglerView togglerView;

Expand All @@ -131,6 +134,7 @@ public SettingView (Context context, Tdlib tdlib) {
super(context);
this.tdlib = tdlib;
this.complexReceiver = new ComplexReceiver(this);
this.emojiStatusHelper = new EmojiStatusHelper(tdlib, this, null);
setWillNotDraw(false);
}

Expand Down Expand Up @@ -199,6 +203,7 @@ public void attach () {
if (receiver != null)
receiver.attach();
complexReceiver.attach();
emojiStatusHelper.attach();
}

@Override
Expand All @@ -208,6 +213,7 @@ public void detach () {
if (receiver != null)
receiver.detach();
complexReceiver.detach();
emojiStatusHelper.detach();
}

@Override
Expand All @@ -216,6 +222,7 @@ public void performDestroy () {
if (receiver != null)
receiver.destroy();
complexReceiver.performDestroy();
emojiStatusHelper.performDestroy();
if (subscribedToEmojiUpdates) {
TGLegacyManager.instance().removeEmojiListener(this);
subscribedToEmojiUpdates = false;
Expand Down Expand Up @@ -433,6 +440,10 @@ public void setText (TextWrapper text) {
invalidate();
}

public void setEmojiStatus (@Nullable TdApi.User user) {
emojiStatusHelper.updateEmoji(user, TextColorSets.Regular.NORMAL);
}

public int getType () {
return type;
}
Expand Down Expand Up @@ -558,6 +569,8 @@ private void buildLayout (int totalWidth, int totalHeight) {
availWidth -= counter.getScaledWidth(Screen.dp(24f) + Screen.dp(8f));
}

availWidth -= emojiStatusHelper.getWidth(Screen.dp(6));

if (type == TYPE_INFO_COMPACT) {
pTop = Screen.dp(15f + 13f);
} else {
Expand Down Expand Up @@ -681,7 +694,7 @@ public void setVisuallyEnabled (boolean enabled, boolean animated) {
isEnabled.setValue(enabled, animated);
}

private static void drawText (Canvas c, CharSequence text, Layout layout, float x, float y, int textY, Paint paint, boolean rtl, int viewWidth, float textWidth, Text wrap, TextColorSet textColorSet) {
private static void drawText (Canvas c, CharSequence text, Layout layout, float x, float y, int textY, Paint paint, boolean rtl, int viewWidth, float textWidth, Text wrap, TextColorSet textColorSet, EmojiStatusHelper emojiStatusHelper) {
if (wrap != null) {
wrap.draw(c, (int) x, (int) (viewWidth - x), 0, textY, textColorSet != null ? textColorSet : TextColorSets.Regular.NEGATIVE);
} else if (layout != null) {
Expand All @@ -691,6 +704,7 @@ private static void drawText (Canvas c, CharSequence text, Layout layout, float
c.restore();
} else {
c.drawText((String) text, rtl ? viewWidth - textWidth - x : x, y, paint);
emojiStatusHelper.draw(c, (int) (x + textWidth + Screen.dp(6)), (int) textY);
}
}

Expand Down Expand Up @@ -811,10 +825,10 @@ protected void onDraw (Canvas c) {
if ((flags & FLAG_DATA_SUBTITLE) != 0) {
subtitleColor = ColorUtils.alphaColor(Theme.getSubtitleAlpha(), subtitleColor);
}
drawText(c, displayItemName, displayItemNameLayout, pLeft, pTop, (int) (pTop - Screen.dp(12f)), Paints.getRegularTextPaint(13f, subtitleColor), rtl, width, displayItemNameWidth, displayItemNameText, subtitleColorSet);
drawText(c, displayItemName, displayItemNameLayout, pLeft, pTop, (int) (pTop - Screen.dp(12f)), Paints.getRegularTextPaint(13f, subtitleColor), rtl, width, displayItemNameWidth, displayItemNameText, subtitleColorSet, emojiStatusHelper);
}
if (displayItemData != null) {
drawText(c, displayItemData, displayItemDataLayout, pDataLeft, pDataTop, (int) (pDataTop - Screen.dp(15f)), Paints.getTextPaint16(dataColor), rtl, width, displayItemDataWidth, null, null);
drawText(c, displayItemData, displayItemDataLayout, pDataLeft, pDataTop, (int) (pDataTop - Screen.dp(15f)), Paints.getTextPaint16(dataColor), rtl, width, displayItemDataWidth, null, null, emojiStatusHelper);
}
} else if (type == TYPE_INFO_MULTILINE) {
if (displayItemName != null) {
Expand All @@ -823,7 +837,7 @@ protected void onDraw (Canvas c) {
subtitleColor = ColorUtils.alphaColor(Theme.getSubtitleAlpha(), subtitleColor);
}
float top = (int) pDataTop - Screen.dp(13f) + text.getHeight() + Screen.dp(17f);
drawText(c, displayItemName, displayItemNameLayout, pLeft, (int) pDataTop - Screen.dp(13f) + text.getHeight() + Screen.dp(17f), (int) (top - Screen.dp(12f)), Paints.getRegularTextPaint(13f, subtitleColor), rtl, width, displayItemNameWidth, displayItemNameText, subtitleColorSet);
drawText(c, displayItemName, displayItemNameLayout, pLeft, (int) pDataTop - Screen.dp(13f) + text.getHeight() + Screen.dp(17f), (int) (top - Screen.dp(12f)), Paints.getRegularTextPaint(13f, subtitleColor), rtl, width, displayItemNameWidth, displayItemNameText, subtitleColorSet, emojiStatusHelper);
}
if (text != null) {
if (rtl) {
Expand All @@ -834,10 +848,10 @@ protected void onDraw (Canvas c) {
}
} else {
if (displayItemData != null) {
drawText(c, displayItemData, displayItemDataLayout, pDataLeft, pDataTop, (int) (pDataTop - Screen.dp(15)), Paints.getTextPaint16(dataColor), rtl, width, displayItemDataWidth, null, null);
drawText(c, displayItemData, displayItemDataLayout, pDataLeft, pDataTop, (int) (pDataTop - Screen.dp(15)), Paints.getTextPaint16(dataColor), rtl, width, displayItemDataWidth, null, null, emojiStatusHelper);
}
if (displayItemName != null) {
drawText(c, displayItemName, displayItemNameLayout, pLeft, pTop, (int) (pTop - Screen.dp(15f)), Paints.getTextPaint16(dataColor), rtl, width, displayItemNameWidth, displayItemNameText, this);
drawText(c, displayItemName, displayItemNameLayout, pLeft, pTop, (int) (pTop - Screen.dp(15f)), Paints.getTextPaint16(dataColor), rtl, width, displayItemNameWidth, displayItemNameText, this, emojiStatusHelper);
}
}
if (progressComponent != null) {
Expand Down
Expand Up @@ -105,11 +105,13 @@ public void setChat (Tdlib tdlib, TdApi.Chat chat, @Nullable ThreadInfo messageT
setShowMute(tdlib.chatNeedsMuteIcon(chat));
setShowLock(ChatId.isSecret(chat.id));
if (messageThread != null) {
setEmojiStatus(null);
setText(messageThread.chatHeaderTitle(), !StringUtils.isEmpty(forcedSubtitle) ? forcedSubtitle : messageThread.chatHeaderSubtitle());
setExpandedSubtitle(null);
setUseRedHighlight(false);
attachChatStatus(messageThread.getChatId(), messageThread.getMessageThreadId());
} else {
setEmojiStatus(tdlib.isSelfChat(chat) ? null: tdlib.chatUser(chat));
setText(tdlib.chatTitle(chat), !StringUtils.isEmpty(forcedSubtitle) ? forcedSubtitle : tdlib.status().chatStatus(chat));
setExpandedSubtitle(tdlib.status().chatStatusExpanded(chat));
setUseRedHighlight(tdlib.isRedTeam(chat.id));
Expand Down
Expand Up @@ -100,6 +100,7 @@ public class MessageView extends SparseDrawableView implements Destroyable, Draw
private final AvatarReceiver avatarReceiver;
private final GifReceiver gifReceiver;
private final ComplexReceiver avatarsReceiver;
private final ComplexReceiver emojiStatusReceiver;
private final ComplexReceiver reactionsComplexReceiver, textMediaReceiver, replyTextMediaReceiver;
private final DoubleImageReceiver replyReceiver;
private final RefreshRateLimiter refreshRateLimiter;
Expand All @@ -121,6 +122,8 @@ public MessageView (Context context) {
.setUpdateListener(new RefreshRateLimiter(this, 60.0f)); // Limit by 60fps
textMediaReceiver = new ComplexReceiver()
.setUpdateListener(refreshRateLimiter);
emojiStatusReceiver = new ComplexReceiver()
.setUpdateListener(refreshRateLimiter);
replyTextMediaReceiver = new ComplexReceiver()
.setUpdateListener(refreshRateLimiter);
//noinspection ContantConditions
Expand Down Expand Up @@ -157,6 +160,7 @@ public void performDestroy () {
gifReceiver.destroy();
reactionsComplexReceiver.performDestroy();
textMediaReceiver.performDestroy();
emojiStatusReceiver.performDestroy();
if (contentReceiver != null) {
contentReceiver.destroy();
}
Expand Down Expand Up @@ -204,6 +208,10 @@ public void invalidateTextMediaReceiver (@NonNull TGMessage msg, Text text, @Nul
invalidateTextMediaReceiver(msg, text, textMedia, textMediaReceiver);
}

public void invalidateEmojiStatusReceiver (@NonNull TGMessage msg, Text text, @Nullable TextMedia textMedia) {
invalidateTextMediaReceiver(msg, text, textMedia, emojiStatusReceiver);
}

public void invalidateReplyTextMediaReceiver (@NonNull TGMessage msg, @NonNull Text text, @Nullable TextMedia textMedia) {
invalidateTextMediaReceiver(msg, text, textMedia, replyTextMediaReceiver);
}
Expand Down Expand Up @@ -316,12 +324,17 @@ public ComplexReceiver getTextMediaReceiver () {
return textMediaReceiver;
}

public ComplexReceiver getEmojiStatusReceiver () {
return emojiStatusReceiver;
}

public void invalidateContentReceiver (long chatId, long messageId, int arg) {
if (msg != null && chatId == msg.getChatId()) {
if ((flags & FLAG_USE_COMPLEX_RECEIVER) != 0) {
if (msg.isDescendantOrSelf(messageId)) {
msg.requestMediaContent(complexReceiver, true, arg);
msg.requestTextMedia(textMediaReceiver);
msg.requestAuthorTextMedia(emojiStatusReceiver);
}
} else if (messageId == msg.getId()) {
if (gifReceiver != null && msg.needGifReceiver()) {
Expand All @@ -336,6 +349,7 @@ public void invalidateContentReceiver (long chatId, long messageId, int arg) {
}
}
msg.requestTextMedia(textMediaReceiver);
msg.requestAuthorTextMedia(emojiStatusReceiver);
if ((flags & FLAG_DISABLE_MEASURE) != 0 && getParent() instanceof MessageViewGroup) {
((MessageViewGroup) getParent()).invalidateContent(msg);
}
Expand Down Expand Up @@ -442,6 +456,7 @@ public void onAttachedToRecyclerView () {
gifReceiver.attach();
reactionsComplexReceiver.attach();
textMediaReceiver.attach();
emojiStatusReceiver.attach();
replyReceiver.attach();
replyTextMediaReceiver.attach();
if ((flags & FLAG_USE_COMMON_RECEIVER) != 0) {
Expand All @@ -462,6 +477,7 @@ public void onDetachedFromRecyclerView () {
gifReceiver.detach();
reactionsComplexReceiver.detach();
textMediaReceiver.detach();
emojiStatusReceiver.detach();
replyReceiver.detach();
replyTextMediaReceiver.detach();
if ((flags & FLAG_USE_COMMON_RECEIVER) != 0) {
Expand Down
Expand Up @@ -16,7 +16,6 @@

import android.content.Context;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;
import android.widget.Toast;

Expand Down Expand Up @@ -65,6 +64,7 @@
import org.thunderdog.challegram.ui.SettingHolder;
import org.thunderdog.challegram.unsorted.Settings;
import org.thunderdog.challegram.util.CancellableResultHandler;
import org.thunderdog.challegram.util.ScrollJumpCompensator;
import org.thunderdog.challegram.v.MessagesRecyclerView;

import java.util.ArrayList;
Expand Down Expand Up @@ -1517,48 +1517,10 @@ public void onMessageHeightChanged (final long chatId, final long messageId, fin
}

private void scrollCompensation (View view, int offset) {
OnGlobalLayoutListener listener = new OnGlobalLayoutListener(controller.getMessagesView(), view, offset);
ScrollJumpCompensator listener = new ScrollJumpCompensator(controller.getMessagesView(), view, offset);
listener.add();
}

public static class OnGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
private final RecyclerView recyclerView;
private final ViewTreeObserver observer;
private int offset;

public OnGlobalLayoutListener (RecyclerView r, View v, int offset) {
this.recyclerView = r;
this.observer = v.getViewTreeObserver();
this.offset = offset;
}

public void add () {
add(observer, this);
}

@Override
public void onGlobalLayout () {
if (offset != 0) {
recyclerView.scrollBy(0, offset);
offset = 0;
}

remove(observer, this);
}

public static void add (ViewTreeObserver v, OnGlobalLayoutListener listener) {
v.addOnGlobalLayoutListener(listener);
}

public static boolean remove (ViewTreeObserver v, OnGlobalLayoutListener listener) {
if (v.isAlive()) {
v.removeOnGlobalLayoutListener(listener);
return true;
}
return false;
}
}

public void modifyRecycler (Context context, RecyclerView recyclerView, LinearLayoutManager manager) {
this.manager = manager;
this.adapter = new MessagesAdapter(context, this, this.controller);
Expand Down

0 comments on commit a760ab4

Please sign in to comment.