update to 10.6.1 (4275)

This commit is contained in:
dkaraush 2024-01-18 12:41:46 +04:00
parent a746a072dc
commit 928146c3da
178 changed files with 12487 additions and 2890 deletions

View file

@ -1210,21 +1210,30 @@ UserStatus *UserStatus::TLdeserialize(NativeByteBuffer *stream, uint32_t constru
case 0x8c703f:
result = new TL_userStatusOffline();
break;
case 0x7bf09fc:
result = new TL_userStatusLastWeek();
break;
case 0x9d05049:
result = new TL_userStatusEmpty();
break;
case 0x77ebc742:
result = new TL_userStatusLastMonth();
break;
case 0xedb93949:
result = new TL_userStatusOnline();
break;
case 0xe26f42f1:
case 0x7b197dc8:
result = new TL_userStatusRecently();
break;
case 0x541a1d1a:
result = new TL_userStatusLastWeek();
break;
case 0x65899777:
result = new TL_userStatusLastMonth();
break;
case 0xe26f42f1:
result = new TL_userStatusRecently_layer171();
break;
case 0x7bf09fc:
result = new TL_userStatusLastWeek_layer171();
break;
case 0x77ebc742:
result = new TL_userStatusLastMonth_layer171();
break;
default:
error = true;
if (LOGS_ENABLED) DEBUG_FATAL("can't parse magic %x in UserStatus", constructor);
@ -1243,8 +1252,19 @@ void TL_userStatusOffline::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(expires);
}
void TL_userStatusLastWeek_layer171::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
}
void TL_userStatusLastWeek::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
flags = by_me ? flags | 1 : flags &~ 1;
stream->writeInt32(flags);
}
void TL_userStatusLastWeek::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
flags = stream->readInt32(&error);
by_me = (flags & 1) != 0;
}
void TL_userStatusEmpty::serializeToStream(NativeByteBuffer *stream) {
@ -1253,6 +1273,17 @@ void TL_userStatusEmpty::serializeToStream(NativeByteBuffer *stream) {
void TL_userStatusLastMonth::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
flags = by_me ? flags | 1 : flags &~ 1;
stream->writeInt32(flags);
}
void TL_userStatusLastMonth::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
flags = stream->readInt32(&error);
by_me = (flags & 1) != 0;
}
void TL_userStatusLastMonth_layer171::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
}
void TL_userStatusOnline::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
@ -1266,6 +1297,21 @@ void TL_userStatusOnline::serializeToStream(NativeByteBuffer *stream) {
void TL_userStatusRecently::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
flags = by_me ? flags | 1 : flags &~ 1;
stream->writeInt32(flags);
}
void TL_userStatusRecently::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
flags = stream->readInt32(&error);
by_me = (flags & 1) != 0;
}
void TL_userStatusRecently_layer171::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
}
void TL_userStatusHidden::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(constructor);
}
FileLocation *FileLocation::TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error) {

View file

@ -203,6 +203,18 @@ public:
class TL_userStatusLastWeek : public UserStatus {
public:
static const uint32_t constructor = 0x7bf09fc;
uint32_t flags;
bool by_me;
void serializeToStream(NativeByteBuffer *stream);
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
};
class TL_userStatusLastWeek_layer171 : public UserStatus {
public:
static const uint32_t constructor = 0x7bf09fc;
@ -219,6 +231,19 @@ public:
class TL_userStatusLastMonth : public UserStatus {
public:
static const uint32_t constructor = 0x65899777;
uint32_t flags;
bool by_me;
void serializeToStream(NativeByteBuffer *stream);
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
};
class TL_userStatusLastMonth_layer171 : public UserStatus {
public:
static const uint32_t constructor = 0x77ebc742;
@ -236,12 +261,32 @@ public:
class TL_userStatusRecently : public UserStatus {
public:
static const uint32_t constructor = 0x7b197dc8;
uint32_t flags;
bool by_me;
void serializeToStream(NativeByteBuffer *stream);
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
};
class TL_userStatusRecently_layer171 : public UserStatus {
public:
static const uint32_t constructor = 0xe26f42f1;
void serializeToStream(NativeByteBuffer *stream);
};
class TL_userStatusHidden : public UserStatus {
public:
static const uint32_t constructor = 0xcf7d64b1;
void serializeToStream(NativeByteBuffer *stream);
};
class FileLocation : public TLObject {
public:

View file

@ -569,15 +569,13 @@
<meta-data android:name="com.google.android.gms.wallet.api.enabled" android:value="true" />
<!-- <meta-data android:name="com.google.android.gms.car.notification.SmallIcon" android:resource="@drawable/ic_player" />-->
<!-- <meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" />-->
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon" android:resource="@drawable/ic_player" />
<meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" />
<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="face,barcode" />
<meta-data android:name="android.max_aspect" android:value="2.5" />
<meta-data android:name="com.google.android.actions" android:resource="@xml/actions" />
</application>
</manifest>

View file

@ -5,6 +5,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.util.Log;
import android.util.LongSparseArray;
import android.view.View;
import android.view.ViewPropertyAnimator;
@ -51,6 +52,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
private ArrayList<MessageObject.GroupedMessages> willChangedGroups = new ArrayList<>();
HashMap<RecyclerView.ViewHolder,Animator> animators = new HashMap<>();
ArrayList<View> thanosViews = new ArrayList<>();
ArrayList<Runnable> runOnAnimationsEnd = new ArrayList<>();
HashMap<Long, Long> groupIdToEnterDelay = new HashMap<>();
@ -925,7 +927,12 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
animator.removeAllListeners();
restoreTransitionParams(holder.itemView);
if (holder.itemView instanceof ChatMessageCell) {
MessageObject.GroupedMessages group = ((ChatMessageCell) view).getCurrentMessagesGroup();
ChatMessageCell cell = (ChatMessageCell) holder.itemView;
if (cell.makeVisibleAfterChange) {
cell.makeVisibleAfterChange = false;
cell.setVisibility(View.VISIBLE);
}
MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup();
if (group != null) {
group.transitionParams.reset();
}
@ -1092,6 +1099,12 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
animator.cancel();
}
}
if (!thanosViews.isEmpty()) {
ThanosEffect thanosEffect = getThanosEffectContainer.run();
if (thanosEffect != null) {
thanosEffect.kill();
}
}
}
@Override
@ -1100,6 +1113,12 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
if (animator != null) {
animator.cancel();
}
if (thanosViews.contains(item.itemView)) {
ThanosEffect thanosEffect = getThanosEffectContainer.run();
if (thanosEffect != null) {
thanosEffect.cancel(item.itemView);
}
}
super.endAnimation(item);
restoreTransitionParams(item.itemView);
}
@ -1230,6 +1249,12 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
if (a != null) {
a.cancel();
}
if (thanosViews.contains(item.itemView)) {
ThanosEffect thanosEffect = getThanosEffectContainer.run();
if (thanosEffect != null) {
thanosEffect.cancel(item.itemView);
}
}
boolean oldItem = false;
if (changeInfo.newHolder == item) {
@ -1447,7 +1472,9 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
dispatchRemoveFinished(holder);
dispatchFinishedWhenDone();
}
thanosViews.remove(view);
});
thanosViews.add(view);
} else {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 0f);
dispatchRemoveStarting(holder);
@ -1497,7 +1524,9 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
}
dispatchFinishedWhenDone();
}
thanosViews.removeAll(views);
});
thanosViews.add(views.get(0));
recyclerListView.stopScroll();
}

View file

@ -11,6 +11,10 @@ import android.content.Context;
import android.graphics.Rect;
import android.view.View;
import com.google.android.exoplayer2.util.Log;
import org.telegram.ui.Cells.ChatMessageCell;
import java.util.ArrayList;
import java.util.Arrays;
@ -68,8 +72,9 @@ public class GridLayoutManagerFixed extends GridLayoutManager {
} else {
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (mOrientationHelper.getDecoratedEnd(child) > scrollingOffset
|| mOrientationHelper.getTransformedEndWithDecoration(child) > scrollingOffset) {
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (child.getBottom() + params.bottomMargin > scrollingOffset
|| child.getTop() + child.getHeight() > scrollingOffset) {
// stop here
recycleChildren(recycler, 0, i);
return;
@ -115,12 +120,15 @@ public class GridLayoutManagerFixed extends GridLayoutManager {
final int otherDirSpecMode = mOrientationHelper.getModeInOther();
final boolean layingOutInPrimaryDirection = layoutState.mItemDirection == LayoutState.ITEM_DIRECTION_TAIL;
boolean working = true;
result.mConsumed = 0;
int yOffset = 0;
int startPosition = layoutState.mCurrentPosition;
if (layoutState.mLayoutDirection != LayoutState.LAYOUT_START && hasSiblingChild(layoutState.mCurrentPosition) && findViewByPosition(layoutState.mCurrentPosition + 1) == null) {
if (
mShouldReverseLayout &&
layoutState.mLayoutDirection != LayoutState.LAYOUT_START &&
hasSiblingChild(layoutState.mCurrentPosition) &&
findViewByPosition(layoutState.mCurrentPosition + 1) == null
) {
if (hasSiblingChild(layoutState.mCurrentPosition + 1)) {
layoutState.mCurrentPosition += 3;
} else {
@ -144,18 +152,14 @@ public class GridLayoutManagerFixed extends GridLayoutManager {
layoutState.mCurrentPosition = backupPosition;
}
boolean working = true;
while (working) {
int count = 0;
int consumedSpanCount = 0;
int remainingSpan = mSpanCount;
working = !additionalViews.isEmpty();
int firstPositionStart = layoutState.mCurrentPosition;
while (count < mSpanCount && layoutState.hasMore(state) && remainingSpan > 0) {
int pos = layoutState.mCurrentPosition;
final int spanSize = getSpanSize(recycler, state, pos);
remainingSpan -= spanSize;
if (remainingSpan < 0) {
break;
@ -171,7 +175,6 @@ public class GridLayoutManagerFixed extends GridLayoutManager {
if (view == null) {
break;
}
consumedSpanCount += spanSize;
mSet[count] = view;
count++;
if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START && remainingSpan <= 0 && hasSiblingChild(pos)) {
@ -236,9 +239,11 @@ public class GridLayoutManagerFixed extends GridLayoutManager {
}
int left, right, top, bottom;
boolean fromOpositeSide = shouldLayoutChildFromOpositeSide(mSet[0]);
if (fromOpositeSide && layoutState.mLayoutDirection == LayoutState.LAYOUT_START || !fromOpositeSide && layoutState.mLayoutDirection == LayoutState.LAYOUT_END) {
boolean fromOppositeSide = shouldLayoutChildFromOpositeSide(mSet[0]);
if (
fromOppositeSide && layoutState.mLayoutDirection == LayoutState.LAYOUT_START ||
!fromOppositeSide && layoutState.mLayoutDirection == LayoutState.LAYOUT_END
) {
if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {
bottom = layoutState.mOffset - result.mConsumed;
top = bottom - maxSize;
@ -284,7 +289,7 @@ public class GridLayoutManagerFixed extends GridLayoutManager {
left -= right;
}
layoutDecoratedWithMargins(view, left, top, left + right, bottom);
if (layoutState.mLayoutDirection != LayoutState.LAYOUT_START) {
if (layoutState.mLayoutDirection == LayoutState.LAYOUT_END) {
left += right;
}
if (params.isItemRemoved() || params.isItemChanged()) {

View file

@ -10,6 +10,8 @@ package org.telegram.SQLite;
import android.os.SystemClock;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import org.telegram.tgnet.NativeByteBuffer;

View file

@ -153,6 +153,8 @@ import org.telegram.ui.Components.HideViewAfterAnimation;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.PickerBottomLayout;
import org.telegram.ui.Components.PipRoundVideoView;
import org.telegram.ui.Components.PipVideoOverlay;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ShareAlert;
import org.telegram.ui.Components.TypefaceSpan;
@ -5225,6 +5227,9 @@ public class AndroidUtilities {
int[] location = new int[2];
for (int i = 0; i < finalViews.size(); ++i) {
View view = finalViews.get(i);
if (view instanceof PipRoundVideoView.PipFrameLayout || view instanceof PipRoundVideoView.PipFrameLayout) {
continue;
}
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
if (layoutParams instanceof WindowManager.LayoutParams) {

View file

@ -27,14 +27,14 @@ public class AnimatedFileDrawableStream implements FileLoadOperationStream {
private int debugCanceledCount;
private boolean debugReportSend;
public AnimatedFileDrawableStream(TLRPC.Document d, ImageLocation l, Object p, int a, boolean prev, int loadingPriority) {
public AnimatedFileDrawableStream(TLRPC.Document d, ImageLocation l, Object p, int a, boolean prev, int loadingPriority, int cacheType) {
document = d;
location = l;
parentObject = p;
currentAccount = a;
preview = prev;
this.loadingPriority = loadingPriority;
loadOperation = FileLoader.getInstance(currentAccount).loadStreamFile(this, document, location, parentObject, 0, preview, loadingPriority);
loadOperation = FileLoader.getInstance(currentAccount).loadStreamFile(this, document, location, parentObject, 0, preview, loadingPriority, cacheType);
}
public boolean isFinishedLoadingFile() {

View file

@ -5,12 +5,19 @@ import com.google.android.exoplayer2.util.Consumer;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.Premium.boosts.BoostRepository;
import org.telegram.ui.LaunchActivity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ChannelBoostsController {
@ -27,7 +34,6 @@ public class ChannelBoostsController {
connectionsManager = ConnectionsManager.getInstance(currentAccount);
}
public void getBoostsStats(long dialogId, Consumer<TL_stories.TL_premium_boostsStatus> consumer) {
TL_stories.TL_premium_getBoostsStatus req = new TL_stories.TL_premium_getBoostsStatus();
req.peer = messagesController.getInputPeer(dialogId);
@ -35,7 +41,22 @@ public class ChannelBoostsController {
if (response != null) {
consumer.accept((TL_stories.TL_premium_boostsStatus) response);
} else {
BulletinFactory.showForError(error);
BaseFragment fragment = LaunchActivity.getLastFragment();
if (error != null && fragment != null && "CHANNEL_PRIVATE".equals(error.text)) {
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getContext(), fragment.getResourceProvider());
builder.setTitle(LocaleController.getString(R.string.AppName));
Map<String, Integer> colorsReplacement = new HashMap<>();
colorsReplacement.put("info1.**", Theme.getColor(Theme.key_dialogTopBackground));
colorsReplacement.put("info2.**", Theme.getColor(Theme.key_dialogTopBackground));
builder.setTopAnimation(R.raw.not_available, AlertsCreator.NEW_DENY_DIALOG_TOP_ICON_SIZE, false, Theme.getColor(Theme.key_dialogTopBackground), colorsReplacement);
builder.setTopAnimationIsNew(true);
builder.setTitle(LocaleController.getString(R.string.ChannelPrivate));
builder.setMessage(LocaleController.getString("ChannelCantOpenPrivate2", R.string.ChannelCantOpenPrivate2));
builder.setPositiveButton(LocaleController.getString(R.string.Close), null);
builder.show();
} else {
BulletinFactory.global().showForError(error);
}
consumer.accept(null);
}
}));

View file

@ -1826,11 +1826,11 @@ public class ChatObject {
public static boolean canManageTopic(int currentAccount, TLRPC.Chat chat, TLRPC.TL_forumTopic topic) {
return canManageTopics(chat) || isMyTopic(currentAccount, topic);
}
public static boolean canManageTopic(int currentAccount, TLRPC.Chat chat, int topicId) {
public static boolean canManageTopic(int currentAccount, TLRPC.Chat chat, long topicId) {
return canManageTopics(chat) || isMyTopic(currentAccount, chat, topicId);
}
public static boolean canDeleteTopic(int currentAccount, TLRPC.Chat chat, int topicId) {
public static boolean canDeleteTopic(int currentAccount, TLRPC.Chat chat, long topicId) {
if (topicId == 1) {
// general topic can't be deleted
return false;
@ -1849,11 +1849,11 @@ public class ChatObject {
return topic != null && (topic.my || topic.from_id instanceof TLRPC.TL_peerUser && topic.from_id.user_id == UserConfig.getInstance(currentAccount).clientUserId);
}
public static boolean isMyTopic(int currentAccount, TLRPC.Chat chat, int topicId) {
public static boolean isMyTopic(int currentAccount, TLRPC.Chat chat, long topicId) {
return chat != null && chat.forum && isMyTopic(currentAccount, chat.id, topicId);
}
public static boolean isMyTopic(int currentAccount, long chatId, int topicId) {
public static boolean isMyTopic(int currentAccount, long chatId, long topicId) {
return isMyTopic(currentAccount, MessagesController.getInstance(currentAccount).getTopicsController().findTopic(chatId, topicId));
}

View file

@ -93,6 +93,7 @@ public class ContactsController extends BaseController {
public final static int PRIVACY_RULES_TYPE_ADDED_BY_PHONE = 7;
public final static int PRIVACY_RULES_TYPE_VOICE_MESSAGES = 8;
public final static int PRIVACY_RULES_TYPE_BIO = 9;
public final static int PRIVACY_RULES_TYPE_MESSAGES = 10;
public final static int PRIVACY_RULES_TYPE_COUNT = 10;
@ -221,6 +222,7 @@ public class ContactsController extends BaseController {
public ArrayList<Contact> phoneBookContacts = new ArrayList<>();
public HashMap<String, ArrayList<Object>> phoneBookSectionsDict = new HashMap<>();
public ArrayList<String> phoneBookSectionsArray = new ArrayList<>();
public HashMap<String, Contact> phoneBookByShortPhones = new HashMap<>();
public ArrayList<TLRPC.TL_contact> contacts = new ArrayList<>();
public ConcurrentHashMap<Long, TLRPC.TL_contact> contactsDict = new ConcurrentHashMap<>(20, 1.0f, 2);
@ -306,6 +308,7 @@ public class ContactsController extends BaseController {
contactsByShortPhone.clear();
phoneBookSectionsDict.clear();
phoneBookSectionsArray.clear();
phoneBookByShortPhones.clear();
loadingContacts = false;
contactsSyncInProgress = false;
@ -528,6 +531,7 @@ public class ContactsController extends BaseController {
sortedUsersSectionsArray.clear();
phoneBookSectionsDict.clear();
phoneBookSectionsArray.clear();
phoneBookByShortPhones.clear();
delayedContactsUpdate.clear();
sortedUsersMutualSectionsArray.clear();
contactsByPhone.clear();
@ -1717,7 +1721,7 @@ public class ContactsController extends BaseController {
if (from != 1 && !isEmpty) {
saveContactsLoadTime();
} else {
reloadContactsStatusesMaybe();
reloadContactsStatusesMaybe(false);
}
if (finalReloadContacts) {
loadContacts(false, 0);
@ -1752,11 +1756,11 @@ public class ContactsController extends BaseController {
return contactsDict.get(userId) != null;
}
public void reloadContactsStatusesMaybe() {
public void reloadContactsStatusesMaybe(boolean force) {
try {
SharedPreferences preferences = MessagesController.getMainSettings(currentAccount);
long lastReloadStatusTime = preferences.getLong("lastReloadStatusTime", 0);
if (lastReloadStatusTime < System.currentTimeMillis() - 1000 * 60 * 60 * 3) {
if (lastReloadStatusTime < System.currentTimeMillis() - 1000 * 60 * 60 * 3 || force) {
reloadContactsStatuses();
}
} catch (Exception e) {
@ -1774,29 +1778,35 @@ public class ContactsController extends BaseController {
}
private void mergePhonebookAndTelegramContacts(final HashMap<String, ArrayList<Object>> phoneBookSectionsDictFinal, final ArrayList<String> phoneBookSectionsArrayFinal, final HashMap<String, Contact> phoneBookByShortPhonesFinal) {
mergePhonebookAndTelegramContacts(phoneBookSectionsDictFinal, phoneBookSectionsArrayFinal,phoneBookByShortPhonesFinal, true);
}
private void mergePhonebookAndTelegramContacts(final HashMap<String, ArrayList<Object>> phoneBookSectionsDictFinal, final ArrayList<String> phoneBookSectionsArrayFinal, final HashMap<String, Contact> phoneBookByShortPhonesFinal, boolean needUpdateLists) {
final ArrayList<TLRPC.TL_contact> contactsCopy = new ArrayList<>(contacts);
Utilities.globalQueue.postRunnable(() -> {
for (int a = 0, size = contactsCopy.size(); a < size; a++) {
TLRPC.TL_contact value = contactsCopy.get(a);
TLRPC.User user = getMessagesController().getUser(value.user_id);
if (user == null || TextUtils.isEmpty(user.phone)) {
continue;
}
String phone = user.phone.substring(Math.max(0, user.phone.length() - 7));
Contact contact = phoneBookByShortPhonesFinal.get(phone);
if (contact != null) {
if (contact.user == null) {
contact.user = user;
if(needUpdateLists) {
for (int a = 0, size = contactsCopy.size(); a < size; a++) {
TLRPC.TL_contact value = contactsCopy.get(a);
TLRPC.User user = getMessagesController().getUser(value.user_id);
if (user == null || TextUtils.isEmpty(user.phone)) {
continue;
}
} else {
String key = Contact.getLetter(user.first_name, user.last_name);
ArrayList<Object> arrayList = phoneBookSectionsDictFinal.get(key);
if (arrayList == null) {
arrayList = new ArrayList<>();
phoneBookSectionsDictFinal.put(key, arrayList);
phoneBookSectionsArrayFinal.add(key);
String phone = user.phone.substring(Math.max(0, user.phone.length() - 7));
Contact contact = phoneBookByShortPhonesFinal.get(phone);
if (contact != null) {
if (contact.user == null) {
contact.user = user;
}
} else {
String key = Contact.getLetter(user.first_name, user.last_name);
ArrayList<Object> arrayList = phoneBookSectionsDictFinal.get(key);
if (arrayList == null) {
arrayList = new ArrayList<>();
phoneBookSectionsDictFinal.put(key, arrayList);
phoneBookSectionsArrayFinal.add(key);
}
arrayList.add(user);
}
arrayList.add(user);
}
}
final Collator collator = getLocaleCollator();
@ -1847,6 +1857,7 @@ public class ContactsController extends BaseController {
});
AndroidUtilities.runOnUIThread(() -> {
phoneBookSectionsArray = phoneBookSectionsArrayFinal;
phoneBookByShortPhones = phoneBookByShortPhonesFinal;
phoneBookSectionsDict = phoneBookSectionsDictFinal;
});
});
@ -2386,8 +2397,46 @@ public class ContactsController extends BaseController {
}
AndroidUtilities.runOnUIThread(() -> {
boolean needResort = false;
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User u = res.users.get(a);
if (u.contact) {
Contact phoneBookContact = contactsBookSPhones.get(u.phone);
if (phoneBookContact != null) {
String oldKey = phoneBookContact.getLetter();
String newKey = Contact.getLetter(user.first_name, user.last_name);
if (phoneBookContact.user == null) {
phoneBookContact.user = user;
if (!oldKey.equals(newKey)) {
ArrayList<Object> arrayList = phoneBookSectionsDict.get(newKey);
if (arrayList == null) {
arrayList = new ArrayList<>();
phoneBookSectionsDict.put(newKey, arrayList);
phoneBookSectionsArray.add(newKey);
}
arrayList.add(phoneBookContact);
arrayList = phoneBookSectionsDict.get(oldKey);
if (arrayList != null) {
for (Object obj : arrayList) {
if (obj instanceof Contact) {
Contact oldContact = (Contact) obj;
if (oldContact.contact_id == phoneBookContact.contact_id) {
boolean removed = arrayList.remove(oldContact);
if (removed && arrayList.isEmpty()) {
phoneBookSectionsDict.remove(oldKey);
phoneBookSectionsArray.remove(oldKey);
}
break;
}
}
}
}
}
needResort = true;
}
}
}
if (!u.contact || contactsDict.get(u.id) != null) {
continue;
}
@ -2397,6 +2446,9 @@ public class ContactsController extends BaseController {
contactsDict.put(newContact.user_id, newContact);
}
buildContactsSectionsArrays(true);
if (needResort) {
mergePhonebookAndTelegramContacts(phoneBookSectionsDict, phoneBookSectionsArray, phoneBookByShortPhones, false);
}
getNotificationCenter().postNotificationName(NotificationCenter.contactsDidLoad);
});
}, ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagCanCompress);
@ -2491,11 +2543,11 @@ public class ContactsController extends BaseController {
continue;
}
if (status.status instanceof TLRPC.TL_userStatusRecently) {
status.status.expires = -100;
status.status.expires = status.status.by_me ? -1000 : -100;
} else if (status.status instanceof TLRPC.TL_userStatusLastWeek) {
status.status.expires = -101;
status.status.expires = status.status.by_me ? -1001 : -101;
} else if (status.status instanceof TLRPC.TL_userStatusLastMonth) {
status.status.expires = -102;
status.status.expires = status.status.by_me ? -1002 : -102;
}
TLRPC.User user = getMessagesController().getUser(status.user_id);

View file

@ -1392,6 +1392,29 @@ public class DatabaseMigrationHelper {
version = 136;
}
if (version == 136) {
database.executeFast("CREATE TABLE saved_dialogs(did INTEGER PRIMARY KEY, date INTEGER, last_mid INTEGER, pinned INTEGER, flags INTEGER, folder_id INTEGER, last_mid_group INTEGER, count INTEGER)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_dialogs ON saved_dialogs(date);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS last_mid_idx_dialogs ON saved_dialogs(last_mid);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS folder_id_idx_dialogs ON saved_dialogs(folder_id);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS flags_idx_dialogs ON saved_dialogs(flags);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 137").stepThis().dispose();
version = 137;
}
if (version == 137) {
database.executeFast("ALTER TABLE unread_push_messages ADD COLUMN is_reaction INTEGER default 0").stepThis().dispose();
database.executeFast("PRAGMA user_version = 138").stepThis().dispose();
version = 138;
}
if (version == 138) {
database.executeFast("CREATE TABLE IF NOT EXISTS saved_reaction_tags (data BLOB);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 139").stepThis().dispose();
version = 139;
}
return version;
}

View file

@ -452,8 +452,10 @@ public class Emoji {
} else if (emojiCode.length() >= 2 && emojiCode.charAt(0) == 0xD83C && emojiCode.charAt(1) == 0xDFF4 && next == 0xDB40) {
i++;
while (true) {
emojiCode.append(cs.charAt(i));
if (i + 1 >= cs.length()) {
if (i < cs.length()) {
emojiCode.append(cs.charAt(i));
}
if (i + 1 < cs.length()) {
emojiCode.append(cs.charAt(i + 1));
}
startLength += 2;

View file

@ -1077,10 +1077,14 @@ public class FileLoader extends BaseController {
}
protected FileLoadOperation loadStreamFile(final FileLoadOperationStream stream, final TLRPC.Document document, final ImageLocation location, final Object parentObject, final long offset, final boolean priority, int loadingPriority) {
return loadStreamFile(stream, document, location, parentObject, offset, priority, loadingPriority, document == null ? 1 : 0);
}
protected FileLoadOperation loadStreamFile(final FileLoadOperationStream stream, final TLRPC.Document document, final ImageLocation location, final Object parentObject, final long offset, final boolean priority, int loadingPriority, int cacheType) {
final CountDownLatch semaphore = new CountDownLatch(1);
final FileLoadOperation[] result = new FileLoadOperation[1];
fileLoaderQueue.postRunnable(() -> {
result[0] = loadFileInternal(document, null, null, document == null && location != null ? location.location : null, location, parentObject, document == null && location != null ? "mp4" : null, document == null && location != null ? location.currentSize : 0, loadingPriority, stream, offset, priority, document == null ? 1 : 0);
result[0] = loadFileInternal(document, null, null, document == null && location != null ? location.location : null, location, parentObject, document == null && location != null ? "mp4" : null, document == null && location != null ? location.currentSize : 0, loadingPriority, stream, offset, priority, cacheType);
semaphore.countDown();
});
awaitFileLoadOperation(semaphore, true);

View file

@ -1081,13 +1081,13 @@ public class FileRefController extends BaseController {
TL_stories.StoryItem storyItem = stories.stories.get(0);
if (storyItem.media != null) {
newStoryItem = storyItem;
if (storyItem.media.photo != null) {
if (result == null && storyItem.media.photo != null) {
result = getFileReference(storyItem.media.photo, requester.location, needReplacement, locationReplacement);
}
if (storyItem.media.document != null) {
if (result == null && storyItem.media.document != null) {
result = getFileReference(storyItem.media.document, requester.location, needReplacement, locationReplacement);
}
if (storyItem.media.alt_document != null) {
if (result == null && storyItem.media.alt_document != null) {
result = getFileReference(storyItem.media.alt_document, requester.location, needReplacement, locationReplacement);
}
}

View file

@ -1115,7 +1115,12 @@ public class ImageLoader {
}
}
boolean createDecoder = fistFrame || (cacheImage.filter != null && ("d".equals(cacheImage.filter) || cacheImage.filter.contains("_d")));
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, createDecoder, 0, cacheImage.priority, notCreateStream ? null : cacheImage.imageLocation.document, null, null, seekTo, cacheImage.currentAccount, false, w, h, cacheOptions);
TLRPC.Document document = notCreateStream ? null : cacheImage.imageLocation.document;
int cacheType = document != null ? 1 : 0;
if (cacheImage.cacheType > 1) {
cacheType = cacheImage.cacheType;
}
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, createDecoder, 0, cacheImage.priority, notCreateStream ? null : cacheImage.imageLocation.document, null, null, seekTo, cacheImage.currentAccount, false, w, h, cacheOptions, cacheType);
fileDrawable.setIsWebmSticker(MessageObject.isWebM(cacheImage.imageLocation.document) || MessageObject.isVideoSticker(cacheImage.imageLocation.document) || isAnimatedAvatar(cacheImage.filter));
}
if (fistFrame) {
@ -1229,7 +1234,9 @@ public class ImageLoader {
w_filter = Float.parseFloat(args[0]) * AndroidUtilities.density;
h_filter = Float.parseFloat(args[1]) * AndroidUtilities.density;
}
if (cacheImage.filter.contains("b2")) {
if (cacheImage.filter.contains("b2r")) {
blurType = 4;
} else if (cacheImage.filter.contains("b2")) {
blurType = 3;
} else if (cacheImage.filter.contains("b1")) {
blurType = 2;
@ -1430,8 +1437,23 @@ public class ImageLoader {
if (image.getConfig() == Bitmap.Config.ARGB_8888) {
Utilities.blurBitmap(image, 1, opts.inPurgeable ? 0 : 1, image.getWidth(), image.getHeight(), image.getRowBytes());
}
} else if (blurType == 3) {
} else if (blurType == 3 || blurType == 4) {
if (image.getConfig() == Bitmap.Config.ARGB_8888) {
if (blurType == 4) {
Bitmap nbitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), image.getConfig());
Canvas canvas = new Canvas(nbitmap);
canvas.save();
final float s = 1.2f;
canvas.scale(s, s, image.getWidth() / 2f, image.getHeight() / 2f);
canvas.drawBitmap(image, 0, 0, null);
canvas.restore();
android.graphics.Path path = new android.graphics.Path();
path.addCircle(image.getWidth() / 2f, image.getHeight() / 2f, Math.min(image.getWidth(), image.getHeight()) / 2f, android.graphics.Path.Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap(image, 0, 0, null);
image.recycle();
image = nbitmap;
}
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1, image.getWidth(), image.getHeight(), image.getRowBytes());
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1, image.getWidth(), image.getHeight(), image.getRowBytes());
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1, image.getWidth(), image.getHeight(), image.getRowBytes());
@ -1829,8 +1851,24 @@ public class ImageLoader {
data[166] = photoBytes[2];
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = SharedConfig.deviceIsHigh() ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
final boolean isRound = !TextUtils.isEmpty(filter) && filter.contains("r");
options.inPreferredConfig = SharedConfig.deviceIsHigh() || isRound ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, len, options);
if (isRound) {
Bitmap nbitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(nbitmap);
canvas.save();
final float s = 1.2f;
canvas.scale(s, s, bitmap.getWidth() / 2f, bitmap.getHeight() / 2f);
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.restore();
android.graphics.Path path = new android.graphics.Path();
path.addCircle(bitmap.getWidth() / 2f, bitmap.getHeight() / 2f, Math.min(bitmap.getWidth(), bitmap.getHeight()) / 2f, android.graphics.Path.Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap(bitmap, 0, 0, null);
bitmap.recycle();
bitmap = nbitmap;
}
if (bitmap != null && !TextUtils.isEmpty(filter) && filter.contains("b")) {
Utilities.blurBitmap(bitmap, 3, 1, bitmap.getWidth(), bitmap.getHeight(), bitmap.getRowBytes());
}
@ -1852,6 +1890,7 @@ public class ImageLoader {
protected long size;
protected int imageType;
protected int type;
protected int cacheType;
protected int currentAccount;
@ -2274,6 +2313,7 @@ public class ImageLoader {
cacheImage.cacheTask = new CacheOutTask(cacheImage);
cacheImage.filter = filter;
cacheImage.imageType = img.imageType;
cacheImage.cacheType = img.cacheType;
imageLoadingByKeys.put(key, cacheImage);
tasks.add(cacheImage.cacheTask);
}
@ -3212,6 +3252,7 @@ public class ImageLoader {
img.type = type;
img.key = key;
img.cacheType = cacheType;
img.filter = filter;
img.imageLocation = imageLocation;
img.ext = ext;
@ -3727,6 +3768,7 @@ public class ImageLoader {
cacheImage.parentObject = img.parentObject;
cacheImage.isPFrame = img.isPFrame;
cacheImage.key = key;
cacheImage.cacheType = img.cacheType;
cacheImage.imageLocation = img.imageLocation;
cacheImage.type = type;
cacheImage.ext = img.ext;

View file

@ -2212,11 +2212,11 @@ public class LocaleController {
public static String formatUserStatus(int currentAccount, TLRPC.User user, boolean[] isOnline, boolean[] madeShorter) {
if (user != null && user.status != null && user.status.expires == 0) {
if (user.status instanceof TLRPC.TL_userStatusRecently) {
user.status.expires = -100;
user.status.expires = user.status.by_me ? -1000 : -100;
} else if (user.status instanceof TLRPC.TL_userStatusLastWeek) {
user.status.expires = -101;
user.status.expires = user.status.by_me ? -1001 : -101;
} else if (user.status instanceof TLRPC.TL_userStatusLastMonth) {
user.status.expires = -102;
user.status.expires = user.status.by_me ? -1002 : -102;
}
}
if (user != null && user.status != null && user.status.expires <= 0) {
@ -2239,11 +2239,11 @@ public class LocaleController {
} else {
if (user.status.expires == -1) {
return getString("Invisible", R.string.Invisible);
} else if (user.status.expires == -100) {
} else if (user.status.expires == -100 || user.status.expires == -1000) {
return getString("Lately", R.string.Lately);
} else if (user.status.expires == -101) {
} else if (user.status.expires == -101 || user.status.expires == -1001) {
return getString("WithinAWeek", R.string.WithinAWeek);
} else if (user.status.expires == -102) {
} else if (user.status.expires == -102 || user.status.expires == -1002) {
return getString("WithinAMonth", R.string.WithinAMonth);
} else {
return formatDateOnline(user.status.expires, madeShorter);
@ -2616,7 +2616,7 @@ public class LocaleController {
}
if (translitChars == null) {
translitChars = new HashMap<>(487);
translitChars = new HashMap<>(488);
translitChars.put("ȼ", "c");
translitChars.put("", "n");
translitChars.put("ɖ", "d");
@ -3103,6 +3103,8 @@ public class LocaleController {
translitChars.put("ő", "o");
translitChars.put("", "tz");
translitChars.put("", "e");
translitChars.put("і", "i");
translitChars.put("ї", "i");
}
StringBuilder dst = new StringBuilder(src.length());
int len = src.length();

View file

@ -54,6 +54,7 @@ import android.provider.OpenableColumns;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.view.HapticFeedbackConstants;
@ -121,8 +122,6 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public native byte[] getWaveform2(short[] array, int length);
public static native byte[] getMp3Waveform(String path, int samplesCount);
public boolean isBuffering() {
if (audioPlayer != null) {
return audioPlayer.isBuffering();
@ -754,6 +753,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
};
private boolean audioRecorderPaused;
private AudioRecord audioRecorder;
private TLRPC.TL_document recordingAudio;
private int recordingGuid = -1;
@ -867,7 +867,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.recordProgressChanged, recordingGuid, amplitude));
} else {
recordBuffers.add(buffer);
if (sendAfterDone != 3) {
if (sendAfterDone != 3 && sendAfterDone != 4) {
stopRecordingInternal(sendAfterDone, sendAfterDoneNotify, sendAfterDoneScheduleDate, sendAfterDoneOnce);
}
}
@ -1860,16 +1860,16 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
if (proximityTouched && wakelockAllowed) {
if (allowRecording && recordStartRunnable == null && recordingAudio == null) {
if (allowRecording && recordStartRunnable == null) {
if (!raiseToEarRecord) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("start record");
}
useFrontSpeaker = true;
if (!raiseChat.playFirstUnreadVoiceMessage()) {
if (recordingAudio != null || !raiseChat.playFirstUnreadVoiceMessage()) {
raiseToEarRecord = true;
useFrontSpeaker = false;
startRecording(raiseChat.getCurrentAccount(), raiseChat.getDialogId(), null, raiseChat.getThreadMessage(), null, raiseChat.getClassGuid(), false);
raiseToSpeakUpdated(true);
}
if (useFrontSpeaker) {
setUseFrontSpeaker(true);
@ -1915,7 +1915,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (BuildVars.LOGS_ENABLED) {
FileLog.d("stop record");
}
stopRecording(2, false, 0, false);
raiseToSpeakUpdated(false);
raiseToEarRecord = false;
ignoreOnPause = false;
// if (!ignoreAccelerometerGestures() && proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
@ -1942,6 +1942,16 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
private void raiseToSpeakUpdated(boolean raised) {
if (recordingAudio != null) {
toggleRecordingPause();
} else if (raised) {
startRecording(raiseChat.getCurrentAccount(), raiseChat.getDialogId(), null, raiseChat.getThreadMessage(), null, raiseChat.getClassGuid(), false);
} else {
stopRecording(2, false, 0, false);
}
}
private void setUseFrontSpeaker(boolean value) {
useFrontSpeaker = value;
AudioManager audioManager = NotificationsController.audioManager;
@ -2633,7 +2643,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
final File cacheFile = file != null ? file : FileLoader.getInstance(currentAccount).getPathToMessage(nextAudio.messageOwner);
boolean exist = cacheFile.exists();
if (cacheFile != file && !cacheFile.exists()) {
FileLoader.getInstance(currentAccount).loadFile(nextAudio.getDocument(), nextAudio, FileLoader.PRIORITY_LOW, 0);
FileLoader.getInstance(currentAccount).loadFile(nextAudio.getDocument(), nextAudio, FileLoader.PRIORITY_LOW, nextAudio.shouldEncryptPhotoOrVideo() ? 2 : 0);
}
}
@ -2672,7 +2682,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
final File cacheFile = file != null ? file : FileLoader.getInstance(currentAccount).getPathToMessage(nextAudio.messageOwner);
boolean exist = cacheFile.exists();
if (cacheFile != file && !cacheFile.exists() && nextAudio.isMusic()) {
FileLoader.getInstance(currentAccount).loadFile(nextAudio.getDocument(), nextAudio, FileLoader.PRIORITY_LOW, 0);
FileLoader.getInstance(currentAccount).loadFile(nextAudio.getDocument(), nextAudio, FileLoader.PRIORITY_LOW, nextAudio.shouldEncryptPhotoOrVideo() ? 2 : 0);
}
}
@ -3210,9 +3220,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
final File cacheFile = file != null ? file : FileLoader.getInstance(messageObject.currentAccount).getPathToMessage(messageObject.messageOwner);
boolean canStream = SharedConfig.streamMedia && (messageObject.isMusic() || messageObject.isRoundVideo() || messageObject.isVideo() && messageObject.canStreamVideo()) && !DialogObject.isEncryptedDialog(messageObject.getDialogId());
boolean canStream = SharedConfig.streamMedia && (messageObject.isMusic() || messageObject.isRoundVideo() || messageObject.isVideo() && messageObject.canStreamVideo()) && !messageObject.shouldEncryptPhotoOrVideo() && !DialogObject.isEncryptedDialog(messageObject.getDialogId());
if (cacheFile != file && !(exists = cacheFile.exists()) && !canStream) {
FileLoader.getInstance(messageObject.currentAccount).loadFile(messageObject.getDocument(), messageObject, FileLoader.PRIORITY_LOW, 0);
FileLoader.getInstance(messageObject.currentAccount).loadFile(messageObject.getDocument(), messageObject, FileLoader.PRIORITY_LOW, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
downloadingCurrentMessage = true;
isPaused = false;
lastProgress = 0;
@ -3814,6 +3824,55 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
public void toggleRecordingPause() {
recordQueue.postRunnable(() -> {
if (recordingAudio == null || recordingAudioFile == null) {
return;
}
audioRecorderPaused = !audioRecorderPaused;
final boolean isPaused = audioRecorderPaused;
if (isPaused) {
sendAfterDone = 4;
audioRecorder.stop();
audioRecorder.release();
audioRecorder = null;
final TLRPC.TL_document audioToSend = recordingAudio;
final File recordingAudioFileToSend = recordingAudioFile;
AndroidUtilities.runOnUIThread(() -> {
boolean fileExist = recordingAudioFileToSend.exists();
if (!fileExist && BuildVars.DEBUG_VERSION) {
FileLog.e(new RuntimeException("file not found :( recordTimeCount " + recordTimeCount + " writedFrames" + writedFrame));
}
audioToSend.date = ConnectionsManager.getInstance(recordingCurrentAccount).getCurrentTime();
audioToSend.size = (int) recordingAudioFileToSend.length();
TLRPC.TL_documentAttributeAudio attributeAudio = new TLRPC.TL_documentAttributeAudio();
attributeAudio.voice = true;
attributeAudio.waveform = getWaveform2(recordSamples, recordSamples.length);
if (attributeAudio.waveform != null) {
attributeAudio.flags |= 4;
}
attributeAudio.duration = recordTimeCount / 1000.0;
audioToSend.attributes.clear();
audioToSend.attributes.add(attributeAudio);
NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.recordPaused);
NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.audioDidSent, recordingGuid, audioToSend, recordingAudioFileToSend.getAbsolutePath());
});
} else {
recordQueue.cancelRunnable(recordRunnable);
audioRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, recordBufferSize);
recordStartTime = System.currentTimeMillis();
fileBuffer.rewind();
audioRecorder.startRecording();
recordQueue.postRunnable(recordRunnable);
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(recordingCurrentAccount).postNotificationName(NotificationCenter.recordResumed);
});
}
});
}
public void startRecording(int currentAccount, long dialogId, MessageObject replyToMsg, MessageObject replyToTopMsg, TL_stories.StoryItem replyStory, int guid, boolean manual) {
boolean paused = false;
if (playingMessageObject != null && isPlayingMessage(playingMessageObject) && !isMessagePaused()) {
@ -3877,6 +3936,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return;
}
audioRecorderPaused = false;
audioRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, recordBufferSize);
recordStartTime = System.currentTimeMillis();
recordTimeCount = 0;
@ -3951,7 +4011,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
messagesRes.messages.add(messageObject1.messageOwner);
MessagesStorage.getInstance(messageObject1.currentAccount).putMessages(messagesRes, messageObject1.getDialogId(), -1, 0, false, messageObject.scheduled, 0);
MessagesStorage.getInstance(messageObject1.currentAccount).putMessages(messagesRes, messageObject1.getDialogId(), -1, 0, false, messageObject.scheduled ? 1 : 0, 0);
ArrayList<MessageObject> arrayList = new ArrayList<>();
arrayList.add(messageObject1);
NotificationCenter.getInstance(messageObject1.currentAccount).postNotificationName(NotificationCenter.replaceMessagesObjects, messageObject1.getDialogId(), arrayList);
@ -3989,7 +4049,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
attributeAudio.flags |= 4;
}
long duration = recordTimeCount;
attributeAudio.duration = (int) (recordTimeCount / 1000);
attributeAudio.duration = recordTimeCount / 1000.0;
audioToSend.attributes.clear();
audioToSend.attributes.add(attributeAudio);
if (duration > 700) {
if (send == 1) {
@ -4024,6 +4085,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
recordingAudio = null;
recordingAudioFile = null;
manualRecording = false;
raiseToEarRecord = false;
ignoreOnPause = false;
}
public void stopRecording(final int send, boolean notify, int scheduleDate, boolean once) {
@ -4038,6 +4101,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return;
}
if (audioRecorder == null) {
recordingAudio = null;
manualRecording = false;
raiseToEarRecord = false;
ignoreOnPause = false;
return;
}
try {
@ -4236,7 +4303,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
String fileName = FileLoader.getAttachFileName(document);
loadingMessageObjects.put(fileName, messageObject);
currentAccount.getFileLoader().loadFile(document, messageObject, FileLoader.PRIORITY_LOW, 0);
currentAccount.getFileLoader().loadFile(document, messageObject, FileLoader.PRIORITY_LOW, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 0);
});
}

View file

@ -34,7 +34,6 @@ import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
@ -68,6 +67,7 @@ import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.QuoteSpan;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.StickerSetBulletinLayout;
import org.telegram.ui.Components.StickersArchiveAlert;
import org.telegram.ui.Components.TextStyleSpan;
@ -157,9 +157,9 @@ public class MediaDataController extends BaseController {
TLRPC.Message message = TLRPC.Message.TLdeserialize(serializedData, serializedData.readInt32(true), true);
if (message != null) {
message.readAttachPath(serializedData, getUserConfig().clientUserId);
SparseArray<TLRPC.Message> threads = draftMessages.get(did);
LongSparseArray<TLRPC.Message> threads = draftMessages.get(did);
if (threads == null) {
threads = new SparseArray<>();
threads = new LongSparseArray<>();
draftMessages.put(did, threads);
}
int threadId = isThread ? Utilities.parseInt(key.substring(key.lastIndexOf('_') + 1)) : 0;
@ -171,12 +171,12 @@ public class MediaDataController extends BaseController {
} else {
TLRPC.DraftMessage draftMessage = TLRPC.DraftMessage.TLdeserialize(serializedData, serializedData.readInt32(true), true);
if (draftMessage != null) {
SparseArray<TLRPC.DraftMessage> threads = drafts.get(did);
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(did);
if (threads == null) {
threads = new SparseArray<>();
threads = new LongSparseArray<>();
drafts.put(did, threads);
}
int threadId = key.startsWith("t_") ? Utilities.parseInt(key.substring(key.lastIndexOf('_') + 1)) : 0;
long threadId = key.startsWith("t_") ? Utilities.parseInt(key.substring(key.lastIndexOf('_') + 1)) : 0;
threads.put(threadId, draftMessage);
}
}
@ -2189,9 +2189,9 @@ public class MediaDataController extends BaseController {
}
public static long calcHash(long hash, long id) {
hash ^= hash >> 21;
hash ^= hash >>> 21;
hash ^= hash << 35;
hash ^= hash >> 4;
hash ^= hash >>> 4;
return hash + id;
}
@ -3337,8 +3337,9 @@ public class MediaDataController extends BaseController {
private int reqId;
private int mergeReqId;
private long lastMergeDialogId;
private int lastReplyMessageId;
private long lastReplyMessageId;
private long lastDialogId;
private ReactionsLayoutInBubble.VisibleReaction lastReaction;
private int lastReqId;
private int lastGuid;
private TLRPC.User lastSearchUser;
@ -3374,8 +3375,8 @@ public class MediaDataController extends BaseController {
return searchResultMessagesMap[mergeDialog ? 1 : 0].indexOfKey(messageId) >= 0;
}
public void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, int replyMessageId, TLRPC.User user, TLRPC.Chat chat) {
searchMessagesInChat(query, dialogId, mergeDialogId, guid, direction, replyMessageId, false, user, chat, true);
public void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, long replyMessageId, TLRPC.User user, TLRPC.Chat chat, ReactionsLayoutInBubble.VisibleReaction reaction) {
searchMessagesInChat(query, dialogId, mergeDialogId, guid, direction, replyMessageId, false, user, chat, true, reaction);
}
public void jumpToSearchedMessage(int guid, int index) {
@ -3387,18 +3388,22 @@ public class MediaDataController extends BaseController {
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1], true);
}
public boolean searchEndReached() {
return messagesSearchEndReached[0] && lastMergeDialogId == 0 && messagesSearchEndReached[1];
}
public void loadMoreSearchMessages() {
if (loadingMoreSearchMessages || messagesSearchEndReached[0] && lastMergeDialogId == 0 && messagesSearchEndReached[1]) {
return;
}
int temp = searchResultMessages.size();
lastReturnedNum = searchResultMessages.size();
searchMessagesInChat(null, lastDialogId, lastMergeDialogId, lastGuid, 1, lastReplyMessageId, false, lastSearchUser, lastSearchChat, false);
searchMessagesInChat(null, lastDialogId, lastMergeDialogId, lastGuid, 1, lastReplyMessageId, false, lastSearchUser, lastSearchChat, false, lastReaction);
lastReturnedNum = temp;
loadingMoreSearchMessages = true;
}
private void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, int replyMessageId, boolean internal, TLRPC.User user, TLRPC.Chat chat, boolean jumpToMessage) {
private void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, long replyMessageId, boolean internal, TLRPC.User user, TLRPC.Chat chat, boolean jumpToMessage, ReactionsLayoutInBubble.VisibleReaction reaction) {
int max_id = 0;
long queryWithDialog = dialogId;
boolean firstQuery = !internal;
@ -3484,8 +3489,17 @@ public class MediaDataController extends BaseController {
req.flags |= 1;
}
if (replyMessageId != 0) {
req.top_msg_id = replyMessageId;
req.flags |= 2;
if (dialogId == getUserConfig().getClientUserId()) {
req.saved_peer_id = getMessagesController().getInputPeer(replyMessageId);
req.flags |= 4;
} else {
req.top_msg_id = (int) replyMessageId;
req.flags |= 2;
}
}
if (reaction != null) {
req.saved_reaction.add(reaction.toTLReaction());
req.flags |= 8;
}
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
mergeReqId = getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
@ -3495,11 +3509,11 @@ public class MediaDataController extends BaseController {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
messagesSearchEndReached[1] = res.messages.isEmpty();
messagesSearchCount[1] = res instanceof TLRPC.TL_messages_messagesSlice ? res.count : res.messages.size();
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, chat, jumpToMessage);
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, chat, jumpToMessage, reaction);
} else {
messagesSearchEndReached[1] = true;
messagesSearchCount[1] = 0;
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, chat, jumpToMessage);
searchMessagesInChat(req.q, dialogId, mergeDialogId, guid, direction, replyMessageId, true, user, chat, jumpToMessage, reaction);
}
}
}), ConnectionsManager.RequestFlagFailOnServerErrors);
@ -3520,6 +3534,7 @@ public class MediaDataController extends BaseController {
lastSearchUser = user;
lastSearchChat = chat;
lastReplyMessageId = replyMessageId;
lastReaction = reaction;
req.limit = 21;
req.q = query != null ? query : "";
req.offset_id = max_id;
@ -3531,8 +3546,17 @@ public class MediaDataController extends BaseController {
req.flags |= 1;
}
if (lastReplyMessageId != 0) {
req.top_msg_id = lastReplyMessageId;
req.flags |= 2;
if (queryWithDialog == getUserConfig().getClientUserId()) {
req.saved_peer_id = getMessagesController().getInputPeer(lastReplyMessageId);
req.flags |= 4;
} else {
req.top_msg_id = (int) lastReplyMessageId;
req.flags |= 2;
}
}
if (reaction != null) {
req.saved_reaction.add(reaction.toTLReaction());
req.flags |= 8;
}
req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
int currentReqId = ++lastReqId;
@ -3587,7 +3611,7 @@ public class MediaDataController extends BaseController {
searchResultMessages.add(messageObject);
searchResultMessagesMap[queryWithDialogFinal == dialogId ? 0 : 1].put(messageObject.getId(), messageObject);
}
messagesSearchEndReached[queryWithDialogFinal == dialogId ? 0 : 1] = res.messages.size() < 21;
messagesSearchEndReached[queryWithDialogFinal == dialogId ? 0 : 1] = res.messages.size() < req.limit;
messagesSearchCount[queryWithDialogFinal == dialogId ? 0 : 1] = res instanceof TLRPC.TL_messages_messagesSlice || res instanceof TLRPC.TL_messages_channelMessages ? res.count : res.messages.size();
if (searchResultMessages.isEmpty()) {
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), (long) 0, 0, 0, jumpToMessage);
@ -3601,7 +3625,7 @@ public class MediaDataController extends BaseController {
}
}
if (queryWithDialogFinal == dialogId && messagesSearchEndReached[0] && mergeDialogId != 0 && !messagesSearchEndReached[1]) {
searchMessagesInChat(lastSearchQuery, dialogId, mergeDialogId, guid, 0, replyMessageId, true, user, chat, jumpToMessage);
searchMessagesInChat(lastSearchQuery, dialogId, mergeDialogId, guid, 0, replyMessageId, true, user, chat, jumpToMessage, lastReaction);
}
}
}
@ -3627,7 +3651,7 @@ public class MediaDataController extends BaseController {
public final static int MEDIA_STORIES = 8;
public void loadMedia(long dialogId, int count, int max_id, int min_id, int type, int topicId, int fromCache, int classGuid, int requestIndex) {
public void loadMedia(long dialogId, int count, int max_id, int min_id, int type, long topicId, int fromCache, int classGuid, int requestIndex) {
boolean isChannel = DialogObject.isChatDialog(dialogId) && ChatObject.isChannel(-dialogId, currentAccount);
if (BuildVars.LOGS_ENABLED) {
@ -3665,8 +3689,13 @@ public class MediaDataController extends BaseController {
req.q = "";
req.peer = getMessagesController().getInputPeer(dialogId);
if (topicId != 0) {
req.top_msg_id = topicId;
req.flags |= 2;
if (dialogId == getUserConfig().getClientUserId()) {
req.saved_peer_id = getMessagesController().getInputPeer(topicId);
req.flags |= 4;
} else {
req.top_msg_id = (int) topicId;
req.flags |= 2;
}
}
if (req.peer == null) {
return;
@ -3689,7 +3718,7 @@ public class MediaDataController extends BaseController {
}
}
public void getMediaCounts(long dialogId, int topicId, int classGuid) {
public void getMediaCounts(long dialogId, long topicId, int classGuid) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
int[] counts = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1};
@ -3728,8 +3757,13 @@ public class MediaDataController extends BaseController {
TLRPC.TL_messages_getSearchCounters req = new TLRPC.TL_messages_getSearchCounters();
req.peer = getMessagesController().getInputPeer(dialogId);
if (topicId != 0) {
req.top_msg_id = topicId;
req.flags |= 1;
if (dialogId == getUserConfig().getClientUserId()) {
req.saved_peer_id = getMessagesController().getInputPeer(topicId);
req.flags |= 4;
} else {
req.top_msg_id = (int) topicId;
req.flags |= 1;
}
}
for (int a = 0; a < counts.length; a++) {
if (req.peer == null) {
@ -3810,7 +3844,7 @@ public class MediaDataController extends BaseController {
});
}
public void getMediaCount(long dialogId, int topicId, int type, int classGuid, boolean fromCache) {
public void getMediaCount(long dialogId, long topicId, int type, int classGuid, boolean fromCache) {
if (fromCache || DialogObject.isEncryptedDialog(dialogId)) {
getMediaCountDatabase(dialogId, topicId, type, classGuid);
} else {
@ -3829,8 +3863,13 @@ public class MediaDataController extends BaseController {
req.filters.add(new TLRPC.TL_inputMessagesFilterGif());
}
if (topicId != 0) {
req.top_msg_id = topicId;
req.flags |= 1;
if (dialogId == getUserConfig().getClientUserId()) {
req.saved_peer_id = getMessagesController().getInputPeer(dialogId);
req.flags |= 4;
} else {
req.top_msg_id = (int) topicId;
req.flags |= 1;
}
}
req.peer = getMessagesController().getInputPeer(dialogId);
if (req.peer == null) {
@ -3916,7 +3955,7 @@ public class MediaDataController extends BaseController {
}
}
private void processLoadedMedia(TLRPC.messages_Messages res, long dialogId, int count, int max_id, int min_id, int type, int topicId, int fromCache, int classGuid, boolean isChannel, boolean topReached, int requestIndex) {
private void processLoadedMedia(TLRPC.messages_Messages res, long dialogId, int count, int max_id, int min_id, int type, long topicId, int fromCache, int classGuid, boolean isChannel, boolean topReached, int requestIndex) {
if (BuildVars.LOGS_ENABLED) {
int messagesCount = 0;
if (res != null && res.messages != null) {
@ -3978,7 +4017,7 @@ public class MediaDataController extends BaseController {
}
}
private void processLoadedMediaCount(int count, long dialogId, int topicId, int type, int classGuid, boolean fromCache, int old) {
private void processLoadedMediaCount(int count, long dialogId, long topicId, int type, int classGuid, boolean fromCache, int old) {
AndroidUtilities.runOnUIThread(() -> {
boolean isEncryptedDialog = DialogObject.isEncryptedDialog(dialogId);
boolean reload = fromCache && (count == -1 || count == 0 && type == 2) && !isEncryptedDialog;
@ -3994,7 +4033,7 @@ public class MediaDataController extends BaseController {
});
}
private void putMediaCountDatabase(long uid, int topicId, int type, int count) {
private void putMediaCountDatabase(long uid, long topicId, int type, int count) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
SQLitePreparedStatement state2;
@ -4007,7 +4046,7 @@ public class MediaDataController extends BaseController {
state2.requery();
state2.bindLong(pointer++, uid);
if (topicId != 0) {
state2.bindInteger(pointer++, topicId);
state2.bindLong(pointer++, topicId);
}
state2.bindInteger(pointer++, type);
state2.bindInteger(pointer++, count);
@ -4020,7 +4059,7 @@ public class MediaDataController extends BaseController {
});
}
private void getMediaCountDatabase(long dialogId, int topicId, int type, int classGuid) {
private void getMediaCountDatabase(long dialogId, long topicId, int type, int classGuid) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
int count = -1;
@ -4054,7 +4093,7 @@ public class MediaDataController extends BaseController {
});
}
private void loadMediaDatabase(long uid, int count, int max_id, int min_id, int type, int topicId, int classGuid, boolean isChannel, int fromCache, int requestIndex) {
private void loadMediaDatabase(long uid, int count, int max_id, int min_id, int type, long topicId, int classGuid, boolean isChannel, int fromCache, int requestIndex) {
Runnable runnable = new Runnable() {
@Override
public void run() {
@ -4099,7 +4138,7 @@ public class MediaDataController extends BaseController {
state.requery();
state.bindLong(pointer++, uid);
if (topicId != 0) {
state.bindInteger(pointer++, topicId);
state.bindLong(pointer++, topicId);
}
state.bindInteger(pointer++, type);
state.bindInteger(pointer++, 0);
@ -4269,7 +4308,7 @@ public class MediaDataController extends BaseController {
messagesStorage.bindTaskToGuid(runnable, classGuid);
}
private void putMediaDatabase(long uid, int topicId, int type, ArrayList<TLRPC.Message> messages, int max_id, int min_id, boolean topReached) {
private void putMediaDatabase(long uid, long topicId, int type, ArrayList<TLRPC.Message> messages, int max_id, int min_id, boolean topReached) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
if (min_id == 0 && (messages.isEmpty() || topReached)) {
@ -4296,7 +4335,7 @@ public class MediaDataController extends BaseController {
state2.bindInteger(pointer++, message.id);
state2.bindLong(pointer++, uid);
if (topicId != 0) {
state2.bindInteger(pointer++, topicId);
state2.bindLong(pointer++, topicId);
}
state2.bindInteger(pointer++, message.date);
state2.bindInteger(pointer++, type);
@ -5429,7 +5468,7 @@ public class MediaDataController extends BaseController {
}
}
public void loadReplyMessagesForMessages(ArrayList<MessageObject> messages, long dialogId, boolean scheduled, int threadMessageId, Runnable callback, int classGuid) {
public void loadReplyMessagesForMessages(ArrayList<MessageObject> messages, long dialogId, boolean scheduled, long threadMessageId, Runnable callback, int classGuid) {
if (DialogObject.isEncryptedDialog(dialogId)) {
ArrayList<Long> replyMessages = new ArrayList<>();
LongSparseArray<ArrayList<MessageObject>> replyMessageRandomOwners = new LongSparseArray<>();
@ -5573,7 +5612,7 @@ public class MediaDataController extends BaseController {
}
}
if (channelId != 0 && messageObject.getDialogId() != -channelId) {
if (dialogId != UserObject.REPLY_BOT && channelId != 0 && messageObject.getDialogId() != -channelId) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(channelId);
if (chat != null && !ChatObject.isPublic(chat)) {
continue;
@ -6591,8 +6630,8 @@ public class MediaDataController extends BaseController {
//---------------- MESSAGES END ----------------
private LongSparseArray<Integer> draftsFolderIds = new LongSparseArray<>();
private LongSparseArray<SparseArray<TLRPC.DraftMessage>> drafts = new LongSparseArray<>();
private LongSparseArray<SparseArray<TLRPC.Message>> draftMessages = new LongSparseArray<>();
private LongSparseArray<LongSparseArray<TLRPC.DraftMessage>> drafts = new LongSparseArray<>();
private LongSparseArray<LongSparseArray<TLRPC.Message>> draftMessages = new LongSparseArray<>();
private boolean inTransaction;
private SharedPreferences draftPreferences;
private boolean loadingDrafts;
@ -6629,28 +6668,28 @@ public class MediaDataController extends BaseController {
draftsFolderIds.clear();
}
public LongSparseArray<SparseArray<TLRPC.DraftMessage>> getDrafts() {
public LongSparseArray<LongSparseArray<TLRPC.DraftMessage>> getDrafts() {
return drafts;
}
public TLRPC.DraftMessage getDraft(long dialogId, int threadId) {
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
public TLRPC.DraftMessage getDraft(long dialogId, long threadId) {
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
if (threads == null) {
return null;
}
return threads.get(threadId);
}
public Pair<Integer, TLRPC.DraftMessage> getOneThreadDraft(long dialogId) {
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
public Pair<Long, TLRPC.DraftMessage> getOneThreadDraft(long dialogId) {
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
if (threads == null || threads.size() <= 0) {
return null;
}
return new Pair(threads.keyAt(0), threads.valueAt(0));
}
public TLRPC.Message getDraftMessage(long dialogId, int threadId) {
SparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
public TLRPC.Message getDraftMessage(long dialogId, long threadId) {
LongSparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
if (threads == null) {
return null;
}
@ -6661,7 +6700,7 @@ public class MediaDataController extends BaseController {
saveDraft(dialogId, threadId, message, entities, replyToMessage, null, noWebpage, false);
}
public void saveDraft(long dialogId, int threadId, CharSequence message, ArrayList<TLRPC.MessageEntity> entities, TLRPC.Message replyToMessage, ChatActivity.ReplyQuote quote, boolean noWebpage, boolean clean) {
public void saveDraft(long dialogId, long threadId, CharSequence message, ArrayList<TLRPC.MessageEntity> entities, TLRPC.Message replyToMessage, ChatActivity.ReplyQuote quote, boolean noWebpage, boolean clean) {
TLRPC.DraftMessage draftMessage;
if (getMessagesController().isForum(dialogId) && threadId == 0) {
replyToMessage = null;
@ -6708,7 +6747,7 @@ public class MediaDataController extends BaseController {
draftMessage.flags |= 8;
}
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
TLRPC.DraftMessage currentDraft = threads == null ? null : threads.get(threadId);
if (!clean) {
boolean sameDraft;
@ -6811,7 +6850,7 @@ public class MediaDataController extends BaseController {
return null;
}
public void saveDraft(long dialogId, int threadId, TLRPC.DraftMessage draft, TLRPC.Message replyToMessage, boolean fromServer) {
public void saveDraft(long dialogId, long threadId, TLRPC.DraftMessage draft, TLRPC.Message replyToMessage, boolean fromServer) {
if (getMessagesController().isForum(dialogId) && threadId == 0 && TextUtils.isEmpty(draft.message)) {
if (draft.reply_to instanceof TLRPC.TL_inputReplyToMessage) {
((TLRPC.TL_inputReplyToMessage) draft.reply_to).reply_to_msg_id = 0;
@ -6821,7 +6860,7 @@ public class MediaDataController extends BaseController {
MessagesController messagesController = getMessagesController();
if (draft == null || draft instanceof TLRPC.TL_draftMessageEmpty) {
{
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
if (threads != null) {
threads.remove(threadId);
if (threads.size() == 0) {
@ -6830,7 +6869,7 @@ public class MediaDataController extends BaseController {
}
}
{
SparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
LongSparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
if (threads != null) {
threads.remove(threadId);
if (threads.size() == 0) {
@ -6845,9 +6884,9 @@ public class MediaDataController extends BaseController {
}
messagesController.removeDraftDialogIfNeed(dialogId);
} else {
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
if (threads == null) {
threads = new SparseArray<>();
threads = new LongSparseArray<>();
drafts.put(dialogId, threads);
}
threads.put(threadId, draft);
@ -6863,7 +6902,7 @@ public class MediaDataController extends BaseController {
FileLog.e(e);
}
}
SparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
LongSparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
if (replyToMessage == null && draft != null && draft.reply_to != null) {
if (threads != null) {
replyToMessage = threads.get(threadId);
@ -6888,7 +6927,7 @@ public class MediaDataController extends BaseController {
}
} else {
if (threads == null) {
threads = new SparseArray<>();
threads = new LongSparseArray<>();
draftMessages.put(dialogId, threads);
}
threads.put(threadId, replyToMessage);
@ -6991,17 +7030,17 @@ public class MediaDataController extends BaseController {
}
}
private void saveDraftReplyMessage(long dialogId, int threadId, TLRPC.Message message) {
private void saveDraftReplyMessage(long dialogId, long threadId, TLRPC.Message message) {
if (message == null) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
TLRPC.DraftMessage draftMessage = threads != null ? threads.get(threadId) : null;
if (draftMessage != null && draftMessage.reply_to != null && draftMessage.reply_to.reply_to_msg_id == message.id) {
SparseArray<TLRPC.Message> threads2 = draftMessages.get(dialogId);
LongSparseArray<TLRPC.Message> threads2 = draftMessages.get(dialogId);
if (threads2 == null) {
threads2 = new SparseArray<>();
threads2 = new LongSparseArray<>();
draftMessages.put(dialogId, threads2);
}
threads2.put(threadId, message);
@ -7025,15 +7064,15 @@ public class MediaDataController extends BaseController {
}
}
public void cleanDraft(long dialogId, int threadId, boolean replyOnly) {
SparseArray<TLRPC.DraftMessage> threads2 = drafts.get(dialogId);
public void cleanDraft(long dialogId, long threadId, boolean replyOnly) {
LongSparseArray<TLRPC.DraftMessage> threads2 = drafts.get(dialogId);
TLRPC.DraftMessage draftMessage = threads2 != null ? threads2.get(threadId) : null;
if (draftMessage == null) {
return;
}
if (!replyOnly) {
{
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
LongSparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
if (threads != null) {
threads.remove(threadId);
if (threads.size() == 0) {
@ -7042,7 +7081,7 @@ public class MediaDataController extends BaseController {
}
}
{
SparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
LongSparseArray<TLRPC.Message> threads = draftMessages.get(dialogId);
if (threads != null) {
threads.remove(threadId);
if (threads.size() == 0) {
@ -7120,7 +7159,7 @@ public class MediaDataController extends BaseController {
if (dialogMessages != null) {
for (int i = 0; i < dialogMessages.size(); ++i) {
TLRPC.Message msg = dialogMessages.get(i);
int topicId = MessageObject.getTopicId(msg, ChatObject.isForum(currentAccount, dialogId));
long topicId = MessageObject.getTopicId(currentAccount, msg, ChatObject.isForum(currentAccount, dialogId));
MessagesStorage.TopicKey topicKey = MessagesStorage.TopicKey.of(dialogId, topicId);
botKeyboards.remove(topicKey);
getNotificationCenter().postNotificationName(NotificationCenter.botKeyboardDidLoad, null, topicKey);
@ -7238,7 +7277,7 @@ public class MediaDataController extends BaseController {
message.serializeToStream(data);
if (topicKey.topicId != 0) {
state.bindLong(1, topicKey.dialogId);
state.bindInteger(2, topicKey.topicId);
state.bindLong(2, topicKey.topicId);
state.bindInteger(3, message.id);
state.bindByteBuffer(4, data);
} else {
@ -8343,7 +8382,9 @@ public class MediaDataController extends BaseController {
ArrayList<TLRPC.Reaction> recentReactions = new ArrayList<>();
ArrayList<TLRPC.Reaction> topReactions = new ArrayList<>();
boolean loadingRecentReactions;
ArrayList<TLRPC.Reaction> savedReactions = new ArrayList<>();
boolean loadingRecentReactions, loadedRecentReactions;
boolean loadingSavedReactions, loadedSavedReactions;
public ArrayList<TLRPC.Reaction> getRecentReactions() {
return recentReactions;
@ -8367,7 +8408,7 @@ public class MediaDataController extends BaseController {
}
public void loadRecentAndTopReactions(boolean force) {
if (loadingRecentReactions || !recentReactions.isEmpty() || force) {
if (loadingRecentReactions || loadedRecentReactions && !force) {
return;
}
SharedPreferences recentReactionsPref = ApplicationLoader.applicationContext.getSharedPreferences("recent_reactions_" + currentAccount, Context.MODE_PRIVATE);
@ -8378,14 +8419,17 @@ public class MediaDataController extends BaseController {
recentReactions.addAll(loadReactionsFromPref(recentReactionsPref));
topReactions.addAll(loadReactionsFromPref(topReactionsPref));
loadingRecentReactions = true;
loadedRecentReactions = true;
boolean loadFromServer = true;
if (loadFromServer) {
boolean[] loaded = new boolean[2];
TLRPC.TL_messages_getRecentReactions recentReactionsRequest = new TLRPC.TL_messages_getRecentReactions();
recentReactionsRequest.hash = recentReactionsPref.getLong("hash", 0);
recentReactionsRequest.limit = 50;
ConnectionsManager.getInstance(currentAccount).sendRequest(recentReactionsRequest, (response, error) -> {
ConnectionsManager.getInstance(currentAccount).sendRequest(recentReactionsRequest, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
if (response instanceof TLRPC.TL_messages_reactions) {
TLRPC.TL_messages_reactions reactions = (TLRPC.TL_messages_reactions) response;
@ -8398,12 +8442,17 @@ public class MediaDataController extends BaseController {
}
}
});
loaded[0] = true;
if (loaded[1]) {
loadingRecentReactions = false;
}
}));
TLRPC.TL_messages_getTopReactions topReactionsRequest = new TLRPC.TL_messages_getTopReactions();
topReactionsRequest.hash = topReactionsPref.getLong("hash", 0);
topReactionsRequest.limit = 100;
ConnectionsManager.getInstance(currentAccount).sendRequest(topReactionsRequest, (response, error) -> {
ConnectionsManager.getInstance(currentAccount).sendRequest(topReactionsRequest, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
if (response instanceof TLRPC.TL_messages_reactions) {
TLRPC.TL_messages_reactions reactions = (TLRPC.TL_messages_reactions) response;
@ -8417,7 +8466,51 @@ public class MediaDataController extends BaseController {
}
}
});
loaded[1] = true;
if (loaded[0]) {
loadingRecentReactions = false;
}
}));
}
}
public ArrayList<TLRPC.Reaction> getSavedReactions() {
return savedReactions;
}
public void loadSavedReactions(boolean force) {
if (loadingSavedReactions || loadedSavedReactions && !force) {
return;
}
SharedPreferences savedReactionsPref = ApplicationLoader.applicationContext.getSharedPreferences("saved_reactions_" + currentAccount, Context.MODE_PRIVATE);
savedReactions.clear();
savedReactions.addAll(loadReactionsFromPref(savedReactionsPref));
loadingSavedReactions = true;
loadedSavedReactions = true;
boolean loadFromServer = true;
if (loadFromServer) {
TLRPC.TL_messages_getDefaultTagReactions recentReactionsRequest = new TLRPC.TL_messages_getDefaultTagReactions();
recentReactionsRequest.hash = savedReactionsPref.getLong("hash", 0);
ConnectionsManager.getInstance(currentAccount).sendRequest(recentReactionsRequest, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
if (response instanceof TLRPC.TL_messages_reactions) {
TLRPC.TL_messages_reactions reactions = (TLRPC.TL_messages_reactions) response;
savedReactions.clear();
savedReactions.addAll(reactions.reactions);
saveReactionsToPref(savedReactionsPref, reactions.hash, reactions.reactions);
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate);
}
if (response instanceof TLRPC.TL_messages_reactionsNotModified) {
}
}
loadingSavedReactions = false;
}));
}
}

View file

@ -33,6 +33,7 @@ import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.collection.LongSparseArray;
@ -57,6 +58,7 @@ import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.QuoteSpan;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.Reactions.ReactionsUtils;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.Text;
import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.TranscribeButton;
@ -236,6 +238,7 @@ public class MessageObject {
public boolean cancelEditing;
public boolean scheduled;
public boolean scheduledSent;
public boolean preview;
public boolean previewForward;
@ -311,6 +314,7 @@ public class MessageObject {
public boolean isRepostVideoPreview;
public boolean forceAvatar;
public Drawable customAvatarDrawable;
public boolean isSaved;
private byte[] randomWaveform;
public boolean drawServiceWithDefaultTypeface;
@ -346,11 +350,23 @@ public class MessageObject {
return false;
}
private static int getTopicId(TLRPC.Message message) {
return getTopicId(message, false);
private static long getTopicId(MessageObject message) {
if (message == null) {
return 0;
}
return getTopicId(message.currentAccount, message.messageOwner, false);
}
public static int getTopicId(TLRPC.Message message, boolean sureIsForum) {
private static long getTopicId(int currentAccount, TLRPC.Message message) {
return getTopicId(currentAccount, message, false);
}
public static long getTopicId(int currentAccount, TLRPC.Message message, boolean sureIsForum) {
final long selfId = UserConfig.getInstance(currentAccount).getClientUserId();
if (!sureIsForum && message != null && currentAccount >= 0 && DialogObject.getPeerDialogId(message.peer_id) == selfId) {
return getSavedDialogId(selfId, message);
}
if (message != null && message.action instanceof TLRPC.TL_messageActionTopicCreate) {
return message.id;
}
@ -478,7 +494,7 @@ public class MessageObject {
}
}
if (changed) {
MessagesStorage.getInstance(currentAccount).markMessageReactionsAsRead(messageOwner.dialog_id, getTopicId(messageOwner), messageOwner.id, true);
MessagesStorage.getInstance(currentAccount).markMessageReactionsAsRead(messageOwner.dialog_id, getTopicId(currentAccount, messageOwner), messageOwner.id, true);
}
}
@ -946,6 +962,8 @@ public class MessageObject {
return maxSizeWidth / sum;
}
public boolean reversed;
public void calculate() {
posArray.clear();
positions.clear();
@ -975,9 +993,9 @@ public class MessageObject {
hasCaption = false;
boolean checkCaption = true;
for (int a = 0; a < count; a++) {
for (int a = (reversed ? count - 1 : 0); (reversed ? a >= 0 : a < count);) {
MessageObject messageObject = messages.get(a);
if (a == 0) {
if (a == (reversed ? count - 1 : 0)) {
isOut = messageObject.isOutOwner();
needShare = !isOut && (
messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.saved_from_peer != null ||
@ -990,7 +1008,7 @@ public class MessageObject {
}
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize());
GroupedMessagePosition position = new GroupedMessagePosition();
position.last = a == count - 1;
position.last = (reversed ? a == 0 : a == count - 1);
position.aspectRatio = photoSize == null ? 1.0f : photoSize.w / (float) photoSize.h;
if (position.aspectRatio > 1.2f) {
@ -1019,14 +1037,21 @@ public class MessageObject {
}
hasCaption = true;
}
if (reversed) {
a--;
} else {
a++;
}
}
if (isDocuments) {
for (int a = 0; a < count; a++) {
GroupedMessagePosition pos = posArray.get(a);
pos.flags |= POSITION_FLAG_LEFT | POSITION_FLAG_RIGHT;
if (a == 0) {
pos.flags = POSITION_FLAG_LEFT | POSITION_FLAG_RIGHT;
if (!reversed && a == 0 || reversed && a == count - 1) {
pos.flags |= POSITION_FLAG_TOP;
} else if (a == count - 1) {
pos.last = false;
} else if (reversed && a == 0 || !reversed && a == count - 1) {
pos.flags |= POSITION_FLAG_BOTTOM;
pos.last = true;
}
@ -1034,8 +1059,8 @@ public class MessageObject {
pos.aspectRatio = 1.0f;
pos.minX = 0;
pos.maxX = 0;
pos.minY = (byte) a;
pos.maxY = (byte) a;
pos.minY = (byte) (reversed ? count - 1 - a : a);
pos.maxY = (byte) (reversed ? count - 1 - a : a);
pos.spanSize = 1000;
pos.pw = maxSizeWidth;
pos.ph = 100;
@ -1490,7 +1515,11 @@ public class MessageObject {
}
public MessageObject(int accountNum, TLRPC.Message message, LongSparseArray<TLRPC.User> users, LongSparseArray<TLRPC.Chat> chats, boolean generateLayout, boolean checkMediaExists) {
this(accountNum, message, null, null, null, users, chats, generateLayout, checkMediaExists, 0);
this(accountNum, message, null, null, null, users, chats, generateLayout, checkMediaExists, 0, false, false, false);
}
public MessageObject(int accountNum, TLRPC.Message message, LongSparseArray<TLRPC.User> users, LongSparseArray<TLRPC.Chat> chats, boolean generateLayout, boolean checkMediaExists, boolean isSavedMessages) {
this(accountNum, message, null, null, null, users, chats, generateLayout, checkMediaExists, 0, false, false, isSavedMessages);
}
public MessageObject(int accountNum, TLRPC.Message message, AbstractMap<Long, TLRPC.User> users, AbstractMap<Long, TLRPC.Chat> chats, boolean generateLayout, boolean checkMediaExists, long eid) {
@ -1498,14 +1527,15 @@ public class MessageObject {
}
public MessageObject(int accountNum, TLRPC.Message message, MessageObject replyToMessage, AbstractMap<Long, TLRPC.User> users, AbstractMap<Long, TLRPC.Chat> chats, LongSparseArray<TLRPC.User> sUsers, LongSparseArray<TLRPC.Chat> sChats, boolean generateLayout, boolean checkMediaExists, long eid) {
this(accountNum, message, replyToMessage, users, chats, sUsers, sChats, generateLayout, checkMediaExists, eid, false, false);
this(accountNum, message, replyToMessage, users, chats, sUsers, sChats, generateLayout, checkMediaExists, eid, false, false, false);
}
public MessageObject(int accountNum, TLRPC.Message message, MessageObject replyToMessage, AbstractMap<Long, TLRPC.User> users, AbstractMap<Long, TLRPC.Chat> chats, LongSparseArray<TLRPC.User> sUsers, LongSparseArray<TLRPC.Chat> sChats, boolean generateLayout, boolean checkMediaExists, long eid, boolean isRepostPreview, boolean isRepostVideoPreview) {
public MessageObject(int accountNum, TLRPC.Message message, MessageObject replyToMessage, AbstractMap<Long, TLRPC.User> users, AbstractMap<Long, TLRPC.Chat> chats, LongSparseArray<TLRPC.User> sUsers, LongSparseArray<TLRPC.Chat> sChats, boolean generateLayout, boolean checkMediaExists, long eid, boolean isRepostPreview, boolean isRepostVideoPreview, boolean isSavedMessages) {
Theme.createCommonMessageResources();
this.isRepostPreview = isRepostPreview;
this.isRepostVideoPreview = isRepostVideoPreview;
this.isSaved = isSavedMessages;
currentAccount = accountNum;
messageOwner = message;
@ -1633,10 +1663,14 @@ public class MessageObject {
return;
}
try {
String filter = "b";
if (isRoundVideo()) {
filter += "r";
}
for (int a = 0, N = photoThumbs.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = photoThumbs.get(a);
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
strippedThumb = new BitmapDrawable(ApplicationLoader.applicationContext.getResources(), ImageLoader.getStrippedPhotoBitmap(photoSize.bytes, "b"));
strippedThumb = new BitmapDrawable(ApplicationLoader.applicationContext.getResources(), ImageLoader.getStrippedPhotoBitmap(photoSize.bytes, filter));
break;
}
}
@ -3557,6 +3591,7 @@ public class MessageObject {
}
public void createMessageSendInfo() {
boolean notReadyYet = videoEditedInfo != null && videoEditedInfo.notReadyYet;
if (messageOwner.message != null && (messageOwner.id < 0 || isEditing()) && messageOwner.params != null) {
String param;
if ((param = messageOwner.params.get("ve")) != null && (isVideo() || isNewGif() || isRoundVideo())) {
@ -3565,6 +3600,7 @@ public class MessageObject {
videoEditedInfo = null;
} else {
videoEditedInfo.roundVideo = isRoundVideo();
videoEditedInfo.notReadyYet = notReadyYet;
}
}
if (messageOwner.send_state == MESSAGE_SEND_STATE_EDITING && (param = messageOwner.params.get("prevMedia")) != null) {
@ -4339,6 +4375,9 @@ public class MessageObject {
messageText = LocaleController.getString(R.string.ActionBotAllowedWebapp);
} else if (botApp != null) {
String botAppTitle = botApp.title;
if (botAppTitle == null) {
botAppTitle = "";
}
String text = LocaleController.getString("ActionBotAllowedApp", R.string.ActionBotAllowedApp);
int start = text.indexOf("%1$s");
SpannableString str = new SpannableString(String.format(text, botAppTitle));
@ -4473,6 +4512,10 @@ public class MessageObject {
} else {
messageText = LocaleController.getString("Poll", R.string.Poll);
}
} else if (isVoiceOnce()) {
messageText = LocaleController.getString(R.string.AttachOnceAudio);
} else if (isRoundOnce()) {
messageText = LocaleController.getString(R.string.AttachOnceRound);
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto) {
if (getMedia(messageOwner).ttl_seconds != 0 && !(messageOwner instanceof TLRPC.TL_message_secret)) {
messageText = LocaleController.getString("AttachDestructingPhoto", R.string.AttachDestructingPhoto);
@ -4483,7 +4526,13 @@ public class MessageObject {
}
} else if (isVideo() || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument && (getDocument() instanceof TLRPC.TL_documentEmpty || getDocument() == null) && getMedia(messageOwner).ttl_seconds != 0) {
if (getMedia(messageOwner).ttl_seconds != 0 && !(messageOwner instanceof TLRPC.TL_message_secret)) {
messageText = LocaleController.getString("AttachDestructingVideo", R.string.AttachDestructingVideo);
if (getMedia(messageOwner).voice) {
messageText = LocaleController.getString(R.string.AttachVoiceExpired);
} else if (getMedia(messageOwner).round) {
messageText = LocaleController.getString(R.string.AttachRoundExpired);
} else {
messageText = LocaleController.getString(R.string.AttachDestructingVideo);
}
} else {
messageText = LocaleController.getString("AttachVideo", R.string.AttachVideo);
}
@ -4563,7 +4612,7 @@ public class MessageObject {
}
if (link != null) {
SpannableString str = new SpannableString(link);
((SpannableString) str).setSpan(new URLSpanReplacement("https://" + link, new TextStyleSpan.TextStyleRun()), 0, messageText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
((SpannableString) str).setSpan(new URLSpanReplacement("https://" + link, new TextStyleSpan.TextStyleRun()), 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return str;
} else {
return "";
@ -4589,7 +4638,13 @@ public class MessageObject {
}
} else if (media != null && (isVideoDocument(media.document) || media instanceof TLRPC.TL_messageMediaDocument && (media.document instanceof TLRPC.TL_documentEmpty || media.document == null) && media.ttl_seconds != 0)) {
if (media.ttl_seconds != 0 && !(messageOwner instanceof TLRPC.TL_message_secret)) {
return LocaleController.getString("AttachDestructingVideo", R.string.AttachDestructingVideo);
if (media.voice) {
return LocaleController.getString(R.string.AttachVoiceExpired);
} else if (media.round) {
return LocaleController.getString(R.string.AttachRoundExpired);
} else {
return LocaleController.getString(R.string.AttachDestructingVideo);
}
} else {
return LocaleController.getString("AttachVideo", R.string.AttachVideo);
}
@ -6134,6 +6189,11 @@ public class MessageObject {
if (isRepostPreview) {
return false;
}
if (isSaved) {
long selfId = UserConfig.getInstance(currentAccount).clientUserId;
long dialogId = MessageObject.getSavedDialogId(selfId, messageOwner);
return dialogId != selfId && dialogId != UserObject.ANONYMOUS;
}
if (type == TYPE_JOINED_CHANNEL) {
return false;
} else if (isSponsored()) {
@ -6197,7 +6257,7 @@ public class MessageObject {
generatedWithMinSize = AndroidUtilities.isTablet() ? AndroidUtilities.getMinTabletSide() : getParentWidth();
}
generatedWithDensity = AndroidUtilities.density;
if (hasCode) {
if (hasCode && !isSaved) {
maxWidth = generatedWithMinSize - dp(45 + 15);
if (needDrawAvatarInternal() && !isOutOwner() && !messageOwner.isThreadMessage) {
maxWidth -= dp(52);
@ -6303,6 +6363,50 @@ public class MessageObject {
return addEntitiesToText(messageText, useManualParse);
}
private static StaticLayout makeStaticLayout(CharSequence text, TextPaint paint, int width, float lineSpacingMult, float lineSpacingAdd, boolean dontIncludePad) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(text, 0, text.length(), paint, width)
.setLineSpacing(lineSpacingAdd, lineSpacingMult)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(Layout.Alignment.ALIGN_NORMAL);
if (dontIncludePad) {
builder.setIncludePad(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.setUseLineSpacingFromFallbacks(false);
}
}
StaticLayout layout = builder.build();
boolean realWidthLarger = false;
for (int l = 0; l < layout.getLineCount(); ++l) {
if (layout.getLineRight(l) > width) {
realWidthLarger = true;
break;
}
}
if (realWidthLarger) {
builder = StaticLayout.Builder.obtain(text, 0, text.length(), paint, width)
.setLineSpacing(lineSpacingAdd, lineSpacingMult)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_SIMPLE)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(Layout.Alignment.ALIGN_NORMAL);
if (dontIncludePad) {
builder.setIncludePad(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.setUseLineSpacingFromFallbacks(false);
}
}
layout = builder.build();
}
return layout;
} else {
return new StaticLayout(text, paint, width, Layout.Alignment.ALIGN_NORMAL, lineSpacingMult, lineSpacingAdd, false);
}
}
public void generateLayout(TLRPC.User fromUser) {
if (type != TYPE_TEXT && type != TYPE_EMOJIS && type != TYPE_STORY_MENTION || messageOwner.peer_id == null || TextUtils.isEmpty(messageText)) {
return;
@ -6352,28 +6456,9 @@ public class MessageObject {
paint = Theme.chat_msgTextPaint;
}
final float lineSpacing = 1f;
final float lineAdd = totalAnimatedEmojiCount >= 4 ? -1 : 0;
Layout.Alignment align = Layout.Alignment.ALIGN_NORMAL; //type == TYPE_EMOJIS && isOut() ? Layout.Alignment.ALIGN_OPPOSITE : Layout.Alignment.ALIGN_NORMAL;
CharSequence text = messageText;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(text, 0, text.length(), paint, maxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
if (emojiOnlyCount > 0) {
builder.setIncludePad(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.setUseLineSpacingFromFallbacks(false);
}
}
textLayout = builder.build();
} else {
textLayout = new StaticLayout(text, paint, maxWidth, align, lineSpacing, lineAdd, false);
}
textLayout = makeStaticLayout(text, paint, maxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0);
} catch (Exception e) {
FileLog.e(e);
return;
@ -6418,23 +6503,7 @@ public class MessageObject {
}, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(text, 0, text.length(), paint, maxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
if (emojiOnlyCount > 0) {
builder.setIncludePad(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.setUseLineSpacingFromFallbacks(false);
}
}
textLayout = builder.build();
} else {
textLayout = new StaticLayout(text, paint, maxWidth, align, lineSpacing, lineAdd, false);
}
textLayout = makeStaticLayout(text, paint, maxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0);
} catch (Exception e) {
FileLog.e(e);
return;
@ -6557,23 +6626,7 @@ public class MessageObject {
} else {
sb = new SpannableString(blockText.toString());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(sb, 0, sb.length(), layoutPaint, blockMaxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
if (emojiOnlyCount > 0) {
builder.setIncludePad(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.setUseLineSpacingFromFallbacks(false);
}
}
textLayout = builder.build();
} else {
textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
}
textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0);
}
block.textLayout = textLayout;
@ -6614,17 +6667,7 @@ public class MessageObject {
} else {
sb = SpannableString.valueOf(blockText);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(sb, 0, sb.length(), layoutPaint, blockMaxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
block.textLayout = builder.build();
} else {
block.textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
}
block.textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, false);
block.textYOffset = offset;
if (a != 0 && emojiOnlyCount <= 0) {
@ -6838,17 +6881,7 @@ public class MessageObject {
final float lineAdd = 0;
Layout.Alignment align = Layout.Alignment.ALIGN_NORMAL; //type == TYPE_EMOJIS && isOut() ? Layout.Alignment.ALIGN_OPPOSITE : Layout.Alignment.ALIGN_NORMAL;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, width)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
textLayout = builder.build();
} else {
textLayout = new StaticLayout(text, textPaint, width, align, lineSpacing, lineAdd, false);
}
textLayout = makeStaticLayout(text, textPaint, width, 1f, 0f, false);
} catch (Exception e) {
FileLog.e(e);
return;
@ -6892,17 +6925,7 @@ public class MessageObject {
}, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, width)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
textLayout = builder.build();
} else {
textLayout = new StaticLayout(text, textPaint, width, align, lineSpacing, lineAdd, false);
}
textLayout = makeStaticLayout(text, textPaint, width, 1f, 0f, false);
} catch (Exception e) {
FileLog.e(e);
return;
@ -7017,17 +7040,7 @@ public class MessageObject {
} else {
sb = new SpannableString(text.subSequence(range.start, range.end));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(sb, 0, text.length(), layoutPaint, blockMaxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
textLayout = builder.build();
} else {
textLayout = new StaticLayout(sb, layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
}
textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, 0f, false);
}
block.textLayout = textLayout;
@ -7052,7 +7065,7 @@ public class MessageObject {
} else {
sb = SpannableString.valueOf(text.subSequence(startCharacter, endCharacter));
}
block.textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
block.textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, 0f, false);
block.textYOffset = offset;
if (a != 0) {
@ -7225,6 +7238,10 @@ public class MessageObject {
if (isOutOwnerCached != null) {
return isOutOwnerCached;
}
long selfUserId = UserConfig.getInstance(currentAccount).getClientUserId();
if (isSaved && messageOwner.fwd_from != null) {
return isOutOwnerCached = messageOwner.fwd_from.from_id != null && messageOwner.fwd_from.from_id.user_id == selfUserId || messageOwner.fwd_from.saved_out;
}
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(null, null, messageOwner.peer_id.channel_id) : null;
if (!messageOwner.out || !(messageOwner.from_id instanceof TLRPC.TL_peerUser) && (!(messageOwner.from_id instanceof TLRPC.TL_peerChannel) || ChatObject.isChannel(chat) && !chat.megagroup) || messageOwner.post) {
return isOutOwnerCached = false;
@ -7232,7 +7249,6 @@ public class MessageObject {
if (messageOwner.fwd_from == null) {
return isOutOwnerCached = true;
}
long selfUserId = UserConfig.getInstance(currentAccount).getClientUserId();
if (getDialogId() == selfUserId) {
return isOutOwnerCached = messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerUser && messageOwner.fwd_from.from_id.user_id == selfUserId && (messageOwner.fwd_from.saved_from_peer == null || messageOwner.fwd_from.saved_from_peer.user_id == selfUserId)
|| messageOwner.fwd_from.saved_from_peer != null && messageOwner.fwd_from.saved_from_peer.user_id == selfUserId && (messageOwner.fwd_from.from_id == null || messageOwner.fwd_from.from_id.user_id == selfUserId);
@ -7244,6 +7260,9 @@ public class MessageObject {
if (isRepostPreview) {
return true;
}
if (isSaved) {
return getSavedDialogId() < 0 || getSavedDialogId() == UserObject.ANONYMOUS;
}
if (forceAvatar || customAvatarDrawable != null) {
return true;
}
@ -7254,6 +7273,9 @@ public class MessageObject {
if (isRepostPreview) {
return true;
}
if (isSaved) {
return getSavedDialogId() < 0 || getSavedDialogId() == UserObject.ANONYMOUS;
}
if (forceAvatar || customAvatarDrawable != null) {
return true;
}
@ -7541,9 +7563,12 @@ public class MessageObject {
}
public static boolean shouldEncryptPhotoOrVideo(int currentAccount, TLRPC.Message message) {
if (MessagesController.getInstance(currentAccount).isChatNoForwards(getChatId(message)) || message != null && message.noforwards) {
if (message != null && message.media != null && (isVoiceDocument(getDocument(message)) || isRoundVideoMessage(message)) && message.media.ttl_seconds == 0x7FFFFFFF) {
return true;
}
// if (MessagesController.getInstance(currentAccount).isChatNoForwards(getChatId(message)) || message != null && message.noforwards) {
// return true;
// }
if (message instanceof TLRPC.TL_message_secret) {
return (getMedia(message) instanceof TLRPC.TL_messageMediaPhoto || isVideoMessage(message)) && message.ttl > 0 && message.ttl <= 60;
} else {
@ -7661,6 +7686,58 @@ public class MessageObject {
return message.dialog_id;
}
public long getSavedDialogId() {
return getSavedDialogId(UserConfig.getInstance(currentAccount).getClientUserId(), messageOwner);
}
public static long getSavedDialogId(long self, TLRPC.Message message) {
if (message.saved_peer_id != null) {
if (message.saved_peer_id.chat_id != 0) {
return -message.saved_peer_id.chat_id;
} else if (message.saved_peer_id.channel_id != 0) {
return -message.saved_peer_id.channel_id;
} else {
return message.saved_peer_id.user_id;
}
}
if (message.from_id.user_id == self) {
if (message.fwd_from != null && message.fwd_from.saved_from_peer != null) {
return DialogObject.getPeerDialogId(message.fwd_from.saved_from_peer);
} else if (message.fwd_from != null && message.fwd_from.from_id != null) {
return self;
} else if (message.fwd_from != null) {
return UserObject.ANONYMOUS;
} else {
return self;
}
}
return 0;
}
public static TLRPC.Peer getSavedDialogPeer(long self, TLRPC.Message message) {
if (message.saved_peer_id != null) {
return message.saved_peer_id;
}
if (message.peer_id != null && message.peer_id.user_id == self && message.from_id != null && message.from_id.user_id == self) {
if (message.fwd_from != null && message.fwd_from.saved_from_peer != null) {
return message.fwd_from.saved_from_peer;
} else if (message.fwd_from != null && message.fwd_from.from_id != null) {
TLRPC.Peer peer = new TLRPC.TL_peerUser();
peer.user_id = self;
return peer;
} else if (message.fwd_from != null) {
TLRPC.Peer peer = new TLRPC.TL_peerUser();
peer.user_id = 2666000L;
return peer;
} else {
TLRPC.Peer peer = new TLRPC.TL_peerUser();
peer.user_id = self;
return peer;
}
}
return null;
}
public boolean isSending() {
return messageOwner.send_state == MESSAGE_SEND_STATE_SENDING && messageOwner.id < 0;
}
@ -8460,7 +8537,7 @@ public class MessageObject {
public boolean isRoundVideo() {
if (isRoundVideoCached == 0) {
isRoundVideoCached = type == TYPE_ROUND_VIDEO || isRoundVideoMessage(messageOwner) ? TYPE_PHOTO : TYPE_VOICE;
isRoundVideoCached = type == TYPE_ROUND_VIDEO || isRoundVideoMessage(messageOwner) ? 1 : 2;
}
return isRoundVideoCached == 1;
}
@ -8700,6 +8777,17 @@ public class MessageObject {
}
public boolean needDrawForwarded() {
if (isSaved) {
if (messageOwner == null || messageOwner.fwd_from == null) return false;
final long selfId = UserConfig.getInstance(currentAccount).getClientUserId();
final long savedId = getSavedDialogId(selfId, messageOwner);
long fromId = DialogObject.getPeerDialogId(messageOwner.fwd_from.saved_from_peer);
if (fromId >= 0) {
fromId = DialogObject.getPeerDialogId(messageOwner.fwd_from.from_id);
}
if (fromId == 0) return savedId != UserObject.ANONYMOUS;
return savedId != fromId && fromId != selfId;
}
if (type == MessageObject.TYPE_STORY && !isExpiredStory()) {
return true;
}
@ -9078,7 +9166,7 @@ public class MessageObject {
}
if (!attachPathExists) {
File file = FileLoader.getInstance(currentAccount).getPathToMessage(messageOwner, useFileDatabaseQueue);
if (type == TYPE_VIDEO && needDrawBluredPreview()) {
if (type == TYPE_VIDEO && needDrawBluredPreview() || isVoiceOnce() || isRoundOnce()) {
mediaExists = new File(file.getAbsolutePath() + ".enc").exists();
}
if (!mediaExists) {
@ -9328,6 +9416,7 @@ public class MessageObject {
public boolean selectReaction(ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean big, boolean fromDoubleTap) {
if (messageOwner.reactions == null) {
messageOwner.reactions = new TLRPC.TL_messageReactions();
messageOwner.reactions.reactions_as_tags = MessageObject.getDialogId(messageOwner) == UserConfig.getInstance(currentAccount).getClientUserId();
messageOwner.reactions.can_see_list = isFromGroup() || isFromUser();
}
@ -9373,6 +9462,9 @@ public class MessageObject {
if (newReaction.count <= 0) {
messageOwner.reactions.results.remove(newReaction);
}
if (messageOwner.reactions.reactions_as_tags) {
MessagesController.getInstance(currentAccount).updateSavedReactionTags(visibleReaction, false);
}
}
if (messageOwner.reactions.can_see_list) {
for (int i = 0; i < messageOwner.reactions.recent_reactions.size(); i++) {
@ -9399,6 +9491,9 @@ public class MessageObject {
if (choosenReaction.count <= 0) {
messageOwner.reactions.results.remove(choosenReaction);
}
if (messageOwner.reactions.reactions_as_tags) {
MessagesController.getInstance(currentAccount).updateSavedReactionTags(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(choosenReaction.reaction), false);
}
choosenReactions.remove(choosenReaction);
if (messageOwner.reactions.can_see_list) {
@ -9412,20 +9507,16 @@ public class MessageObject {
}
if (newReaction == null) {
newReaction = new TLRPC.TL_reactionCount();
if (visibleReaction.emojicon != null) {
newReaction.reaction = new TLRPC.TL_reactionEmoji();
((TLRPC.TL_reactionEmoji) newReaction.reaction).emoticon = visibleReaction.emojicon;
messageOwner.reactions.results.add(newReaction);
} else {
newReaction.reaction = new TLRPC.TL_reactionCustomEmoji();
((TLRPC.TL_reactionCustomEmoji) newReaction.reaction).document_id = visibleReaction.documentId;
messageOwner.reactions.results.add(newReaction);
}
newReaction.reaction = visibleReaction.toTLReaction();
messageOwner.reactions.results.add(newReaction);
}
newReaction.chosen = true;
newReaction.count++;
newReaction.chosen_order = maxChoosenOrder + 1;
if (messageOwner.reactions.reactions_as_tags) {
MessagesController.getInstance(currentAccount).updateSavedReactionTags(visibleReaction, true);
}
if (messageOwner.reactions.can_see_list || (messageOwner.dialog_id > 0 && maxReactionsCount > 1)) {
TLRPC.TL_messagePeerReaction action = new TLRPC.TL_messagePeerReaction();

View file

@ -34,6 +34,7 @@ import android.os.Process;
import android.os.SystemClock;
import android.service.media.MediaBrowserService;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import androidx.collection.LongSparseArray;
@ -50,6 +51,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.annotation.Nullable;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class MusicBrowserService extends MediaBrowserService implements NotificationCenter.NotificationCenterDelegate {
@ -57,6 +60,7 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
private static final String SLOT_RESERVATION_SKIP_TO_PREV = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_SKIP_TO_PREVIOUS";
private static final String SLOT_RESERVATION_QUEUE = "com.google.android.gms.car.media.ALWAYS_RESERVE_SPACE_FOR.ACTION_QUEUE";
@Nullable
private MediaSession mediaSession;
private static final String MEDIA_ID_ROOT = "__ROOT__";
@ -91,6 +95,15 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
lastSelectedDialog = AndroidUtilities.getPrefIntOrLong(MessagesController.getNotificationsSettings(currentAccount), "auto_lastSelectedDialog", 0);
updatePlaybackState(null);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingPlayStateChanged);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidStart);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidReset);
}
private void createMediaSession() {
if (mediaSession != null) return;
mediaSession = new MediaSession(this, "MusicService");
setSessionToken(mediaSession.getSessionToken());
mediaSession.setCallback(new MediaSessionCallback());
@ -106,12 +119,6 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
extras.putBoolean(SLOT_RESERVATION_SKIP_TO_PREV, true);
extras.putBoolean(SLOT_RESERVATION_SKIP_TO_NEXT, true);
mediaSession.setExtras(extras);
updatePlaybackState(null);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingPlayStateChanged);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidStart);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.messagePlayingDidReset);
}
@Override
@ -135,7 +142,9 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
super.onDestroy();
handleStopRequest(null);
delayedStopHandler.removeCallbacksAndMessages(null);
mediaSession.release();
if (mediaSession != null) {
mediaSession.release();
}
}
@Override
@ -241,6 +250,7 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
ArrayList<MessageObject> arrayList = musicObjects.get(lastSelectedDialog);
ArrayList<MediaSession.QueueItem> arrayList1 = musicQueues.get(lastSelectedDialog);
if (arrayList != null && !arrayList.isEmpty()) {
createMediaSession();
mediaSession.setQueue(arrayList1);
if (lastSelectedDialog > 0) {
TLRPC.User user = users.get(lastSelectedDialog);
@ -413,6 +423,7 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
lastSelectedDialog = did;
MessagesController.getNotificationsSettings(currentAccount).edit().putLong("auto_lastSelectedDialog", did).commit();
MediaController.getInstance().setPlaylist(arrayList, arrayList.get(id), 0, false, null);
createMediaSession();
mediaSession.setQueue(arrayList1);
if (did > 0) {
TLRPC.User user = users.get(did);
@ -515,8 +526,9 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
} else {
stateBuilder.setActiveQueueItemId(0);
}
mediaSession.setPlaybackState(stateBuilder.build());
if (mediaSession != null) {
mediaSession.setPlaybackState(stateBuilder.build());
}
}
private long getAvailableActions() {
@ -554,7 +566,8 @@ public class MusicBrowserService extends MediaBrowserService implements Notifica
serviceStarted = true;
}
if (!mediaSession.isActive()) {
if (mediaSession == null || !mediaSession.isActive()) {
createMediaSession();
mediaSession.setActive(true);
}

View file

@ -176,6 +176,8 @@ public class NotificationCenter {
public static final int recordStarted = totalEvents++;
public static final int recordStartError = totalEvents++;
public static final int recordStopped = totalEvents++;
public static final int recordPaused = totalEvents++;
public static final int recordResumed = totalEvents++;
public static final int screenshotTook = totalEvents++;
public static final int albumsDidLoad = totalEvents++;
public static final int audioDidSent = totalEvents++;
@ -223,7 +225,9 @@ public class NotificationCenter {
public static final int unconfirmedAuthUpdate = totalEvents++;
public static final int dialogPhotosUpdate = totalEvents++;
public static final int channelRecommendationsLoaded = totalEvents++;
public static final int savedMessagesUpdate = totalEvents++;
public static final int savedMessagesDialogsUpdate = totalEvents++;
public static final int savedReactionTagsUpdate = totalEvents++;
public static final int userIsPremiumBlockedUpadted = totalEvents++;
//global
public static final int pushMessagesUpdated = totalEvents++;
@ -737,29 +741,35 @@ public class NotificationCenter {
}
}
public static void listenEmojiLoading(View view) {
if (view == null) {
return;
public Runnable listen(View view, final int id, final Utilities.Callback<Object[]> callback) {
if (view == null || callback == null) {
return () -> {};
}
final NotificationCenterDelegate delegate = (id, account, args) -> {
if (id == NotificationCenter.emojiLoaded) {
if (view != null && view.isAttachedToWindow()) {
view.invalidate();
}
final NotificationCenterDelegate delegate = (_id, account, args) -> {
if (_id == id) {
callback.run(args);
}
};
view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
final View.OnAttachStateChangeListener viewListener = new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
NotificationCenter.getGlobalInstance().addObserver(delegate, NotificationCenter.emojiLoaded);
NotificationCenter.getGlobalInstance().addObserver(delegate, id);
}
@Override
public void onViewDetachedFromWindow(View view) {
NotificationCenter.getGlobalInstance().removeObserver(delegate, NotificationCenter.emojiLoaded);
NotificationCenter.getGlobalInstance().removeObserver(delegate, id);
}
});
};
view.addOnAttachStateChangeListener(viewListener);
return () -> {
view.removeOnAttachStateChangeListener(viewListener);
NotificationCenter.getGlobalInstance().removeObserver(delegate, id);
};
}
public static void listenEmojiLoading(View view) {
getGlobalInstance().listen(view, NotificationCenter.emojiLoaded, args -> view.invalidate());
}
public void listenOnce(int id, Runnable callback) {

View file

@ -37,14 +37,12 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Xfermode;
import android.graphics.drawable.BitmapDrawable;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.Settings;
@ -54,8 +52,6 @@ import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
@ -92,7 +88,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
@ -119,7 +114,7 @@ public class NotificationsController extends BaseController {
private final ArrayList<StoryNotification> storyPushMessages = new ArrayList<>();
private final LongSparseArray<StoryNotification> storyPushMessagesDict = new LongSparseArray<>();
private long openedDialogId = 0;
private int openedTopicId = 0;
private long openedTopicId = 0;
private int lastButtonId = 5000;
private int total_unread_count = 0;
private int personalCount = 0;
@ -284,15 +279,15 @@ public class NotificationsController extends BaseController {
private static final LongSparseArray<String> sharedPrefCachedKeys = new LongSparseArray<>();
public static String getSharedPrefKey(long dialog_id, int topicId) {
public static String getSharedPrefKey(long dialog_id, long topicId) {
return getSharedPrefKey(dialog_id, topicId, false);
}
public static String getSharedPrefKey(long dialog_id, int topicId, boolean backgroundThread) {
public static String getSharedPrefKey(long dialog_id, long topicId, boolean backgroundThread) {
if (backgroundThread) {
String key;
if (topicId != 0) {
key = String.format(Locale.US, "%d_%d",dialog_id, topicId);
key = String.format(Locale.US, "%d_%d", dialog_id, topicId);
} else {
key = String.valueOf(dialog_id);
}
@ -310,7 +305,7 @@ public class NotificationsController extends BaseController {
}
String key;
if (topicId != 0) {
key = String.format(Locale.US, "%d_%d",dialog_id, topicId);
key = String.format(Locale.US, "%d_%d", dialog_id, topicId);
} else {
key = String.valueOf(dialog_id);
}
@ -318,7 +313,7 @@ public class NotificationsController extends BaseController {
return key;
}
public void muteUntil(long did, int topicId, int selectedTimeInSeconds) {
public void muteUntil(long did, long topicId, int selectedTimeInSeconds) {
if (did != 0) {
SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount);
SharedPreferences.Editor editor = preferences.edit();
@ -425,7 +420,7 @@ public class NotificationsController extends BaseController {
inChatSoundEnabled = value;
}
public void setOpenedDialogId(long dialog_id, int topicId) {
public void setOpenedDialogId(long dialog_id, long topicId) {
notificationsQueue.postRunnable(() -> {
openedDialogId = dialog_id;
openedTopicId = topicId;
@ -462,8 +457,10 @@ public class NotificationsController extends BaseController {
for (int a = 0; a < pushMessages.size(); a++) {
MessageObject messageObject = pushMessages.get(a);
long dialog_id = messageObject.getDialogId();
if (messageObject.messageOwner.mentioned && messageObject.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage ||
DialogObject.isEncryptedDialog(dialog_id) || messageObject.messageOwner.peer_id.channel_id != 0 && !messageObject.isSupergroup()) {
if (messageObject.isReactionPush ||
messageObject.messageOwner.mentioned && messageObject.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage ||
DialogObject.isEncryptedDialog(dialog_id) ||
messageObject.messageOwner.peer_id.channel_id != 0 && !messageObject.isSupergroup()) {
continue;
}
return true;
@ -1009,7 +1006,7 @@ public class NotificationsController extends BaseController {
}
long originalDialogId = dialogId;
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
long topicId = MessageObject.getTopicId(currentAccount, messageObject.messageOwner, getMessagesController().isForum(messageObject));
if (dialogId == openedDialogId && ApplicationLoader.isScreenOn) {
if (!isFcm) {
playInChatSound();
@ -1104,7 +1101,7 @@ public class NotificationsController extends BaseController {
} else if (added) {
MessageObject messageObject = messageObjects.get(0);
long dialog_id = messageObject.getDialogId();
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(dialog_id));
long topicId = MessageObject.getTopicId(currentAccount, messageObject.messageOwner, getMessagesController().isForum(dialog_id));
Boolean isChannel;
if (messageObject.isFcmMessage()) {
isChannel = messageObject.localChannel;
@ -1354,7 +1351,7 @@ public class NotificationsController extends BaseController {
}
long dialog_id = messageObject.getDialogId();
long original_dialog_id = dialog_id;
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
long topicId = MessageObject.getTopicId(currentAccount, messageObject.messageOwner, getMessagesController().isForum(messageObject));
if (messageObject.messageOwner.mentioned) {
dialog_id = messageObject.getFromChatId();
}
@ -1426,7 +1423,7 @@ public class NotificationsController extends BaseController {
}
long dialogId = messageObject.getDialogId();
long originalDialogId = dialogId;
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
long topicId = MessageObject.getTopicId(currentAccount, messageObject.messageOwner, getMessagesController().isForum(messageObject));
long randomId = messageObject.messageOwner.random_id;
if (messageObject.messageOwner.mentioned) {
dialogId = messageObject.getFromChatId();
@ -2086,6 +2083,10 @@ public class NotificationsController extends BaseController {
} else {
return LocaleController.getString("Message", R.string.Message);
}
} else if (messageObject.isVoiceOnce()) {
return LocaleController.getString(R.string.AttachOnceAudio);
} else if (messageObject.isRoundOnce()) {
return LocaleController.getString(R.string.AttachOnceRound);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(messageObject.messageOwner.message)) {
return "\uD83D\uDDBC " + replaceSpoilers(messageObject);
@ -2899,7 +2900,7 @@ public class NotificationsController extends BaseController {
&& (messageObject.messageOwner.action == null || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionEmpty);
}
private int getNotifyOverride(SharedPreferences preferences, long dialog_id, int topicId) {
private int getNotifyOverride(SharedPreferences preferences, long dialog_id, long topicId) {
int notifyOverride = dialogsNotificationsFacade.getProperty(NotificationsSettingsFacade.PROPERTY_NOTIFY, dialog_id, topicId, -1);
if (notifyOverride == 3) {
int muteUntil = dialogsNotificationsFacade.getProperty(NotificationsSettingsFacade.PROPERTY_NOTIFY_UNTIL, dialog_id, topicId, 0);
@ -3041,11 +3042,11 @@ public class NotificationsController extends BaseController {
return true;
}
public void deleteNotificationChannel(long dialogId, int topicId) {
public void deleteNotificationChannel(long dialogId, long topicId) {
deleteNotificationChannel(dialogId, topicId, -1);
}
private void deleteNotificationChannelInternal(long dialogId, int topicId, int what) {
private void deleteNotificationChannelInternal(long dialogId, long topicId, int what) {
if (Build.VERSION.SDK_INT < 26) {
return;
}
@ -3091,7 +3092,7 @@ public class NotificationsController extends BaseController {
}
}
public void deleteNotificationChannel(long dialogId, int topicId, int what) {
public void deleteNotificationChannel(long dialogId, long topicId, int what) {
if (Build.VERSION.SDK_INT < 26) {
return;
}
@ -3406,7 +3407,7 @@ public class NotificationsController extends BaseController {
}
@TargetApi(26)
private String validateChannelId(long dialogId, int topicId, String name, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int type) {
private String validateChannelId(long dialogId, long topicId, String name, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int type) {
ensureGroupsCreated();
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
@ -3778,7 +3779,7 @@ public class NotificationsController extends BaseController {
}
long dialog_id = lastMessageObject.getDialogId();
int topicId = MessageObject.getTopicId(lastMessageObject.messageOwner, getMessagesController().isForum(lastMessageObject));
long topicId = MessageObject.getTopicId(currentAccount, lastMessageObject.messageOwner, getMessagesController().isForum(lastMessageObject));
boolean story = lastMessageObject.isStoryPush;
boolean isChannel = false;
@ -4324,7 +4325,7 @@ public class NotificationsController extends BaseController {
}
}
private void resetNotificationSound(NotificationCompat.Builder notificationBuilder, long dialogId, int topicId, String chatName, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int chatType) {
private void resetNotificationSound(NotificationCompat.Builder notificationBuilder, long dialogId, long topicId, String chatName, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int chatType) {
Uri defaultSound = Settings.System.DEFAULT_RINGTONE_URI;
if (defaultSound != null && sound != null && !TextUtils.equals(defaultSound.toString(), sound.toString())) {
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
@ -4365,7 +4366,7 @@ public class NotificationsController extends BaseController {
}
@SuppressLint("InlinedApi")
private void showExtraNotifications(NotificationCompat.Builder notificationBuilder, String summary, long lastDialogId, int lastTopicId, String chatName, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int chatType) {
private void showExtraNotifications(NotificationCompat.Builder notificationBuilder, String summary, long lastDialogId, long lastTopicId, String chatName, long[] vibrationPattern, int ledColor, Uri sound, int importance, boolean isDefault, boolean isInApp, boolean isSilent, int chatType) {
if (Build.VERSION.SDK_INT >= 26) {
notificationBuilder.setChannelId(validateChannelId(lastDialogId, lastTopicId, chatName, vibrationPattern, ledColor, sound, importance, isDefault, isInApp, isSilent, chatType));
}
@ -4388,7 +4389,7 @@ public class NotificationsController extends BaseController {
for (int a = 0; a < pushMessages.size(); a++) {
MessageObject messageObject = pushMessages.get(a);
long dialog_id = messageObject.getDialogId();
int topicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
long topicId = MessageObject.getTopicId(currentAccount, messageObject.messageOwner, getMessagesController().isForum(messageObject));
int dismissDate = preferences.getInt("dismissDate" + dialog_id, 0);
if (!messageObject.isStoryPush && messageObject.messageOwner.date <= dismissDate) {
continue;
@ -4412,14 +4413,14 @@ public class NotificationsController extends BaseController {
class NotificationHolder {
int id;
long dialogId;
int topicId;
long topicId;
boolean story;
String name;
TLRPC.User user;
TLRPC.Chat chat;
NotificationCompat.Builder notification;
NotificationHolder(int i, long li, boolean story, int topicId, String n, TLRPC.User u, TLRPC.Chat c, NotificationCompat.Builder builder) {
NotificationHolder(int i, long li, boolean story, long topicId, String n, TLRPC.User u, TLRPC.Chat c, NotificationCompat.Builder builder) {
id = i;
name = n;
user = u;
@ -4462,7 +4463,8 @@ public class NotificationsController extends BaseController {
}
DialogKey dialogKey = sortedDialogs.get(b);
long dialogId;
int topicId, maxId;
long topicId;
int maxId;
MessageObject lastMessageObject = null;
ArrayList<MessageObject> messageObjects;
if (dialogKey.story) {
@ -4525,7 +4527,7 @@ public class NotificationsController extends BaseController {
photoPath = user.photo.photo_small;
}
} else if (!DialogObject.isEncryptedDialog(dialogId)) {
canReply = dialogId != 777000;
canReply = (lastMessageObject != null && !lastMessageObject.isReactionPush) && dialogId != 777000;
if (DialogObject.isUserDialog(dialogId)) {
user = getMessagesController().getUser(dialogId);
if (user == null) {
@ -4758,7 +4760,7 @@ public class NotificationsController extends BaseController {
} else {
for (int a = messageObjects.size() - 1; a >= 0; a--) {
MessageObject messageObject = messageObjects.get(a);
int messageTopicId = MessageObject.getTopicId(messageObject.messageOwner, getMessagesController().isForum(messageObject));
long messageTopicId = MessageObject.getTopicId(currentAccount, messageObject.messageOwner, getMessagesController().isForum(messageObject));
if (topicId != messageTopicId) {
continue;
}
@ -5374,7 +5376,7 @@ public class NotificationsController extends BaseController {
public static final int SETTING_MUTE_UNMUTE = 4;
public static final int SETTING_MUTE_CUSTOM = 5;
public void clearDialogNotificationsSettings(long did, int topicId) {
public void clearDialogNotificationsSettings(long did, long topicId) {
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
SharedPreferences.Editor editor = preferences.edit();
String prefKey = NotificationsController.getSharedPrefKey(did, topicId);
@ -5388,7 +5390,7 @@ public class NotificationsController extends BaseController {
getNotificationsController().updateServerNotificationsSettings(did, topicId,true);
}
public void setDialogNotificationsSettings(long dialog_id, int topicId, int setting) {
public void setDialogNotificationsSettings(long dialog_id, long topicId, int setting) {
SharedPreferences preferences = getAccountInstance().getNotificationsSettings();
SharedPreferences.Editor editor = preferences.edit();
TLRPC.Dialog dialog = MessagesController.getInstance(UserConfig.selectedAccount).dialogs_dict.get(dialog_id);
@ -5435,11 +5437,11 @@ public class NotificationsController extends BaseController {
updateServerNotificationsSettings(dialog_id, topicId);
}
public void updateServerNotificationsSettings(long dialog_id, int topicId) {
public void updateServerNotificationsSettings(long dialog_id, long topicId) {
updateServerNotificationsSettings(dialog_id, topicId, true);
}
public void updateServerNotificationsSettings(long dialogId, int topicId, boolean post) {
public void updateServerNotificationsSettings(long dialogId, long topicId, boolean post) {
if (post) {
getNotificationCenter().postNotificationName(NotificationCenter.notificationsSettingsUpdated);
}
@ -5492,10 +5494,10 @@ public class NotificationsController extends BaseController {
} else {
req.settings.sound = new TLRPC.TL_notificationSoundDefault();
}
if (topicId != 0) {
if (topicId != 0 && dialogId != getUserConfig().getClientUserId()) {
TLRPC.TL_inputNotifyForumTopic topicPeer = new TLRPC.TL_inputNotifyForumTopic();
topicPeer.peer = getMessagesController().getInputPeer(dialogId);
topicPeer.top_msg_id = topicId;
topicPeer.top_msg_id = (int) topicId;
req.peer = topicPeer;
} else {
req.peer = new TLRPC.TL_inputNotifyPeer();
@ -5625,7 +5627,7 @@ public class NotificationsController extends BaseController {
}
}
public void muteDialog(long dialog_id, int topicId, boolean mute) {
public void muteDialog(long dialog_id, long topicId, boolean mute) {
if (mute) {
NotificationsController.getInstance(currentAccount).muteUntil(dialog_id, topicId, Integer.MAX_VALUE);
} else {
@ -5683,10 +5685,10 @@ public class NotificationsController extends BaseController {
private static class DialogKey {
final long dialogId;
final int topicId;
final long topicId;
final boolean story;
private DialogKey(long dialogId, int topicId, boolean story) {
private DialogKey(long dialogId, long topicId, boolean story) {
this.dialogId = dialogId;
this.topicId = topicId;
this.story = story;

View file

@ -24,12 +24,12 @@ public class NotificationsSettingsFacade {
}
public boolean isDefault(long dialogId, int topicId) {
public boolean isDefault(long dialogId, long topicId) {
String key = NotificationsController.getSharedPrefKey(dialogId, topicId, true);
return false;
}
public void clearPreference(long dialogId, int topicId) {
public void clearPreference(long dialogId, long topicId) {
String key = NotificationsController.getSharedPrefKey(dialogId, topicId, true);
getPreferences().edit()
.remove(PROPERTY_NOTIFY + key)
@ -43,7 +43,7 @@ public class NotificationsSettingsFacade {
}
public int getProperty(String property, long dialogId, int topicId, int defaultValue) {
public int getProperty(String property, long dialogId, long topicId, int defaultValue) {
String key = NotificationsController.getSharedPrefKey(dialogId, topicId, true);
if (getPreferences().contains(property + key)) {
return getPreferences().getInt(property + key, defaultValue);
@ -52,7 +52,7 @@ public class NotificationsSettingsFacade {
return getPreferences().getInt(property + key, defaultValue);
}
public long getProperty(String property, long dialogId, int topicId, long defaultValue) {
public long getProperty(String property, long dialogId, long topicId, long defaultValue) {
String key = NotificationsController.getSharedPrefKey(dialogId, topicId, true);
if (getPreferences().contains(property + key)) {
return getPreferences().getLong(property + key, defaultValue);
@ -61,7 +61,7 @@ public class NotificationsSettingsFacade {
return getPreferences().getLong(property + key, defaultValue);
}
public boolean getProperty(String property, long dialogId, int topicId, boolean defaultValue) {
public boolean getProperty(String property, long dialogId, long topicId, boolean defaultValue) {
String key = NotificationsController.getSharedPrefKey(dialogId, topicId);
if (getPreferences().contains(property + key)) {
return getPreferences().getBoolean(property + key, defaultValue);
@ -70,7 +70,7 @@ public class NotificationsSettingsFacade {
return getPreferences().getBoolean(property + key, defaultValue);
}
public String getPropertyString(String property, long dialogId, int topicId, String defaultValue) {
public String getPropertyString(String property, long dialogId, long topicId, String defaultValue) {
String key = NotificationsController.getSharedPrefKey(dialogId, topicId);
if (getPreferences().contains(property + key)) {
return getPreferences().getString(property + key, defaultValue);
@ -80,7 +80,7 @@ public class NotificationsSettingsFacade {
}
public void removeProperty(String property, long dialogId, int topicId) {
public void removeProperty(String property, long dialogId, long topicId) {
String key = NotificationsController.getSharedPrefKey(dialogId, topicId);
getPreferences().edit().remove(property + key).apply();
}
@ -89,7 +89,7 @@ public class NotificationsSettingsFacade {
return MessagesController.getNotificationsSettings(currentAccount);
}
public void applyDialogNotificationsSettings(long dialogId, int topicId, TLRPC.PeerNotifySettings notify_settings) {
public void applyDialogNotificationsSettings(long dialogId, long topicId, TLRPC.PeerNotifySettings notify_settings) {
if (notify_settings == null) {
return;
}
@ -183,7 +183,7 @@ public class NotificationsSettingsFacade {
});
}
public void applySoundSettings(TLRPC.NotificationSound settings, SharedPreferences.Editor editor, long dialogId, int topicId, int globalType, boolean serverUpdate) {
public void applySoundSettings(TLRPC.NotificationSound settings, SharedPreferences.Editor editor, long dialogId, long topicId, int globalType, boolean serverUpdate) {
if (settings == null) {
return;
}

View file

@ -154,7 +154,7 @@ public class SecretChatHelper extends BaseController {
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg);
getMessagesStorage().putMessages(arr, false, true, true, 0, false, 0);
getMessagesStorage().putMessages(arr, false, true, true, 0, false, 0, 0);
return newMsg;
}
@ -534,7 +534,7 @@ public class SecretChatHelper extends BaseController {
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2, ImageLocation.getForPhoto(size, newMsg.media.photo), true);
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg);
getMessagesStorage().putMessages(arr, false, true, false, 0, false, 0);
getMessagesStorage().putMessages(arr, false, true, false, 0, false, 0, 0);
//getMessagesStorage().putSentFile(originalPath, newMsg.media.photo, 3);
} else if (newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) {
@ -568,7 +568,7 @@ public class SecretChatHelper extends BaseController {
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg);
getMessagesStorage().putMessages(arr, false, true, false, 0, false, 0);
getMessagesStorage().putMessages(arr, false, true, false, 0, 0, 0);
}
}
}

View file

@ -1134,7 +1134,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ArrayList<TLRPC.Message> messages = new ArrayList<>();
messages.add(obj.messageOwner);
getMessagesStorage().putMessages(messages, false, true, false, 0, obj.scheduled, 0);
getMessagesStorage().putMessages(messages, false, true, false, 0, obj.scheduled ? 1 : 0, 0);
break;
}
}
@ -1145,7 +1145,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ArrayList<TLRPC.Message> messages = new ArrayList<>();
messages.add(message.obj.messageOwner);
getMessagesStorage().putMessages(messages, false, true, false, 0, message.obj.scheduled, 0);
getMessagesStorage().putMessages(messages, false, true, false, 0, message.obj.scheduled ? 1 : 0, 0);
break;
}
}
@ -1216,7 +1216,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
messageObject.messageOwner.attachPath = cacheFile.toString();
ArrayList<TLRPC.Message> messages = new ArrayList<>();
messages.add(messageObject.messageOwner);
getMessagesStorage().putMessages(messages, false, true, false, 0, messageObject.scheduled, 0);
getMessagesStorage().putMessages(messages, false, true, false, 0, messageObject.scheduled ? 1 : 0, 0);
getNotificationCenter().postNotificationName(NotificationCenter.updateMessageMedia, messageObject.messageOwner);
message.photoSize = photo.sizes.get(photo.sizes.size() - 1);
message.locationParent = photo;
@ -1265,7 +1265,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
ArrayList<TLRPC.Message> messages = new ArrayList<>();
messages.add(messageObject.messageOwner);
getMessagesStorage().putMessages(messages, false, true, false, 0, messageObject.scheduled, 0);
getMessagesStorage().putMessages(messages, false, true, false, 0, messageObject.scheduled ? 1 : 0, 0);
message.performMediaUpload = true;
performSendDelayedMessage(message);
getNotificationCenter().postNotificationName(NotificationCenter.updateMessageMedia, message.obj.messageOwner);
@ -1328,7 +1328,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(object.messageOwner);
getMessagesStorage().putMessages(arr, false, true, false, 0, object.scheduled, 0);
getMessagesStorage().putMessages(arr, false, true, false, 0, object.scheduled ? 1 : 0, 0);
ArrayList<MessageObject> arrayList = new ArrayList<>();
arrayList.add(object);
@ -1406,7 +1406,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
messagesRes.messages.add(prevMessage.messageOwner);
getMessagesStorage().putMessages(messagesRes, message.peer, -2, 0, false, scheduled, 0);
getMessagesStorage().putMessages(messagesRes, message.peer, -2, 0, false, scheduled ? 1 : 0, 0);
}
if (!checkReadyToSendGroups.contains(message)) {
checkReadyToSendGroups.add(message);
@ -1620,7 +1620,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(message);
getMessagesStorage().putMessages(arr, false, true, false, 0, false, 0);
getMessagesStorage().putMessages(arr, false, true, false, 0, false, 0, 0);
performSendMessageRequest(req, newMsgObj, null, null, null, null, false);
}
@ -2140,7 +2140,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
if (arr.size() == 100 || a == messages.size() - 1 || a != messages.size() - 1 && messages.get(a + 1).getDialogId() != msgObj.getDialogId()) {
getMessagesStorage().putMessages(new ArrayList<>(arr), false, true, false, 0, scheduleDate != 0, 0);
getMessagesStorage().putMessages(new ArrayList<>(arr), false, true, false, 0, scheduleDate != 0 ? 1 : 0, 0);
getMessagesController().updateInterfaceWithMessages(peer, objArr, scheduleDate != 0);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
getUserConfig().saveConfig(false);
@ -2261,7 +2261,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
messageIds.add(oldId);
getMessagesController().deleteMessages(messageIds, null, null, newMsgObj1.dialog_id, false, true);
getMessagesStorage().getStorageQueue().postRunnable(() -> {
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, false, 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, 0, 0);
AndroidUtilities.runOnUIThread(() -> {
ArrayList<MessageObject> messageObjects = new ArrayList<>();
messageObjects.add(new MessageObject(msgObj.currentAccount, msgObj.messageOwner, true, true));
@ -2275,7 +2275,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} else {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
getMessagesStorage().updateMessageStateAndId(newMsgObj1.random_id, MessageObject.getPeerId(peer_id), oldId, newMsgObj1.id, 0, false, scheduleDate != 0 ? 1 : 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, scheduleDate != 0, 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, scheduleDate != 0 ? 1 : 0, 0);
AndroidUtilities.runOnUIThread(() -> {
newMsgObj1.send_state = MessageObject.MESSAGE_SEND_STATE_SENT;
getMediaDataController().increasePeerRaiting(peer);
@ -2542,7 +2542,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg);
getMessagesStorage().putMessages(arr, false, true, false, 0, messageObject.scheduled, MessageObject.getTopicId(newMsg, getMessagesController().isForum(newMsg)));
getMessagesStorage().putMessages(arr, false, true, false, 0, messageObject.scheduled ? 1 : 0, 0);
getMessagesController().getTopicsController().processEditedMessage(newMsg);
messageObject.type = -1;
@ -3971,7 +3971,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
}
if (isForum) {
anotherTopic = replyToTopMsg.getId() != replyToMsg.getId() && MessageObject.getTopicId(replyToMsg.messageOwner, true) != replyToTopMsg.getId();
anotherTopic = replyToTopMsg.getId() != replyToMsg.getId() && MessageObject.getTopicId(currentAccount, replyToMsg.messageOwner, true) != replyToTopMsg.getId();
}
}
if (anotherChat || anotherTopic) {
@ -4036,6 +4036,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
if (newMsgObj.videoEditedInfo != null && videoEditedInfo == null) {
videoEditedInfo = newMsgObj.videoEditedInfo;
} else if (videoEditedInfo != null && videoEditedInfo.notReadyYet) {
newMsgObj.videoEditedInfo.notReadyYet = videoEditedInfo.notReadyYet;
}
if (groupId == 0) {
@ -4043,7 +4045,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
objArr.add(newMsgObj);
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg);
MessagesStorage.getInstance(currentAccount).putMessages(arr, false, true, false, 0, scheduleDate != 0, 0);
MessagesStorage.getInstance(currentAccount).putMessages(arr, false, true, false, 0, scheduleDate != 0 ? 1 : 0, 0);
MessagesController.getInstance(currentAccount).updateInterfaceWithMessages(peer, objArr, scheduleDate != 0);
if (scheduleDate == 0) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogsNeedReload);
@ -5057,10 +5059,12 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
location = FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + document.id + ".mp4";
}
putToDelayedMessages(location, message);
if (message.obj.videoEditedInfo != null && message.obj.videoEditedInfo.needConvert()) {
getFileLoader().uploadFile(location, false, false, document.size, ConnectionsManager.FileTypeVideo, false);
} else {
getFileLoader().uploadFile(location, false, false, ConnectionsManager.FileTypeVideo);
if (message.obj.videoEditedInfo == null || !message.obj.videoEditedInfo.notReadyYet) {
if (message.obj.videoEditedInfo != null && message.obj.videoEditedInfo.needConvert()) {
getFileLoader().uploadFile(location, false, false, document.size, ConnectionsManager.FileTypeVideo, false);
} else {
getFileLoader().uploadFile(location, false, false, ConnectionsManager.FileTypeVideo);
}
}
putToUploadingMessages(message.obj);
} else {
@ -5392,7 +5396,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
return;
} else if (add) {
delayedMessages.remove(key);
getMessagesStorage().putMessages(message.messages, false, true, false, 0, message.scheduled, 0);
getMessagesStorage().putMessages(message.messages, false, true, false, 0, message.scheduled ? 1 : 0, 0);
getMessagesController().updateInterfaceWithMessages(message.peer, message.messageObjects, message.scheduled);
if (!message.scheduled) {
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
@ -5731,7 +5735,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newMsgObj.id, newMsgObj, newMsgObj.dialog_id, grouped_id, existFlags, scheduled);
getMessagesStorage().getStorageQueue().postRunnable(() -> {
getMessagesStorage().updateMessageStateAndId(newMsgObj.random_id, MessageObject.getPeerId(newMsgObj.peer_id), oldId, newMsgObj.id, 0, false, scheduled ? 1 : 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, scheduled, 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, scheduled ? 1 : 0, 0);
AndroidUtilities.runOnUIThread(() -> {
getMediaDataController().increasePeerRaiting(newMsgObj.dialog_id);
getNotificationCenter().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newMsgObj.id, newMsgObj, newMsgObj.dialog_id, grouped_id, existFlags, scheduled);
@ -6035,7 +6039,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
messageIds.add(oldId);
getMessagesController().deleteMessages(messageIds, null, null, newMsgObj.dialog_id, false, true);
getMessagesStorage().getStorageQueue().postRunnable(() -> {
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, false, 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, false, 0, 0);
AndroidUtilities.runOnUIThread(() -> {
ArrayList<MessageObject> messageObjects = new ArrayList<>();
messageObjects.add(new MessageObject(msgObj.currentAccount, msgObj.messageOwner, true, true));
@ -6049,7 +6053,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newMsgObj.id, newMsgObj, newMsgObj.dialog_id, 0L, existFlags, scheduled);
getMessagesStorage().getStorageQueue().postRunnable(() -> {
getMessagesStorage().updateMessageStateAndId(newMsgObj.random_id, MessageObject.getPeerId(newMsgObj.peer_id), oldId, newMsgObj.id, 0, false, scheduled ? 1 : 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, scheduled, 0);
getMessagesStorage().putMessages(sentMessages, true, false, false, 0, scheduled ? 1 : 0, 0);
AndroidUtilities.runOnUIThread(() -> {
getMediaDataController().increasePeerRaiting(newMsgObj.dialog_id);
getNotificationCenter().postNotificationName(NotificationCenter.messageReceivedByServer, oldId, newMsgObj.id, newMsgObj, newMsgObj.dialog_id, 0L, existFlags, scheduled);
@ -6987,7 +6991,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
messagesRes.messages.add(prevMessage.messageOwner);
accountInstance.getMessagesStorage().putMessages(messagesRes, message.peer, -2, 0, false, scheduleDate != 0, 0);
accountInstance.getMessagesStorage().putMessages(messagesRes, message.peer, -2, 0, false, scheduleDate != 0 ? 1 : 0, 0);
instance.sendReadyToSendGroup(message, true, true);
}
});
@ -7478,7 +7482,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
@UiThread
public static void prepareSendingText(AccountInstance accountInstance, String text, long dialogId, int topicId, boolean notify, int scheduleDate) {
public static void prepareSendingText(AccountInstance accountInstance, String text, long dialogId, long topicId, boolean notify, int scheduleDate) {
accountInstance.getMessagesStorage().getStorageQueue().postRunnable(() -> Utilities.stageQueue.postRunnable(() -> AndroidUtilities.runOnUIThread(() -> {
String textFinal = getTrimmedString(text);
if (textFinal.length() != 0) {
@ -8625,7 +8629,12 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
}
if (document == null) {
thumb = createVideoThumbnailAtTime(videoPath, startTime);
if (videoEditedInfo != null && videoEditedInfo.notReadyYet) {
thumb = videoEditedInfo.thumb;
}
if (thumb == null) {
thumb = createVideoThumbnailAtTime(videoPath, startTime);
}
if (thumb == null) {
thumb = createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MINI_KIND);
}
@ -8669,14 +8678,19 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
attributeVideo.round_message = isRound;
document.attributes.add(attributeVideo);
if (videoEditedInfo != null && videoEditedInfo.needConvert()) {
if (videoEditedInfo != null && videoEditedInfo.notReadyYet) {
attributeVideo.w = videoEditedInfo.resultWidth;
attributeVideo.h = videoEditedInfo.resultHeight;
attributeVideo.duration = videoEditedInfo.estimatedDuration / 1000.0;
document.size = videoEditedInfo.estimatedSize;
} else if (videoEditedInfo != null && videoEditedInfo.needConvert()) {
if (videoEditedInfo.muted) {
document.attributes.add(new TLRPC.TL_documentAttributeAnimated());
fillVideoAttribute(videoPath, attributeVideo, videoEditedInfo);
videoEditedInfo.originalWidth = attributeVideo.w;
videoEditedInfo.originalHeight = attributeVideo.h;
} else {
attributeVideo.duration = (int) (videoEditedInfo.estimatedDuration / 1000);
attributeVideo.duration = videoEditedInfo.estimatedDuration / 1000.0;
}
int w, h;

View file

@ -118,7 +118,7 @@ public class TopicsController extends BaseController {
topicsIsLoading.put(chatId, 0);
processTopics(chatId, topics.topics, messagesMap, false, loadType, ((TLRPC.TL_messages_forumTopics) response).count);
getMessagesStorage().putMessages(topics.messages, false, true, false, 0, false, 0);
getMessagesStorage().putMessages(topics.messages, false, true, false, 0, false, 0, 0);
sortTopics(chatId);
getMessagesStorage().saveTopics(-chatId, topicsByChatId.get(chatId), true, true);
@ -390,7 +390,7 @@ public class TopicsController extends BaseController {
getMessagesController().putChats(((TLRPC.TL_messages_forumTopics) response).chats, false);
processTopics(chatId, topics.topics, messagesMap, false, LOAD_TYPE_LOAD_UNKNOWN, -1);
getMessagesStorage().putMessages(topics.messages, false, true, false, 0, false, 0);
getMessagesStorage().putMessages(topics.messages, false, true, false, 0, false, 0, 0);
getMessagesStorage().saveTopics(-chatId, topicsByChatId.get(chatId), true, true);
if (callback != null) {
callback.run();
@ -400,7 +400,7 @@ public class TopicsController extends BaseController {
}));
}
public void updateMaxReadId(long chatId, int topicId, int readMaxId, int unreadCount, int mentionsUnread) {
public void updateMaxReadId(long chatId, long topicId, int readMaxId, int unreadCount, int mentionsUnread) {
TLRPC.TL_forumTopic topic = findTopic(chatId, topicId);
if (topic != null) {
topic.read_inbox_max_id = readMaxId;
@ -412,7 +412,7 @@ public class TopicsController extends BaseController {
}
}
public TLRPC.TL_forumTopic findTopic(long chatId, int topicId) {
public TLRPC.TL_forumTopic findTopic(long chatId, long topicId) {
LongSparseArray<TLRPC.TL_forumTopic> topicsMap = topicsMapByChatId.get(chatId);
if (topicsMap != null) {
return topicsMap.get(topicId);
@ -717,7 +717,7 @@ public class TopicsController extends BaseController {
ConnectionsManager.getInstance(currentAccount).sendRequest(req, null);
}
public void updateMentionsUnread(long dialogId, int topicId, int topicMentionsCount) {
public void updateMentionsUnread(long dialogId, long topicId, int topicMentionsCount) {
AndroidUtilities.runOnUIThread(() -> {
TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId);
if (topic != null) {
@ -727,7 +727,7 @@ public class TopicsController extends BaseController {
});
}
public int updateReactionsUnread(long dialogId, int topicId, int count, boolean increment) {
public int updateReactionsUnread(long dialogId, long topicId, int count, boolean increment) {
TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId);
int totalCount = -1;
if (topic != null) {
@ -745,7 +745,7 @@ public class TopicsController extends BaseController {
return totalCount;
}
public void markAllReactionsAsRead(long chatId, int topicId) {
public void markAllReactionsAsRead(long chatId, long topicId) {
TLRPC.TL_forumTopic topic = findTopic(chatId, topicId);
if (topic != null && topic.unread_reactions_count > 0) {
topic.unread_reactions_count = 0;
@ -811,7 +811,7 @@ public class TopicsController extends BaseController {
topicsToReload.put(update.dialogId, arrayList);
}
TLRPC.TL_forumTopic forumTopic = new TLRPC.TL_forumTopic();
forumTopic.id = update.topicId;
forumTopic.id = (int) update.topicId;
arrayList.add(forumTopic);
} else {
TLRPC.TL_forumTopic topic = findTopic(-update.dialogId, update.topicId);
@ -1031,7 +1031,7 @@ public class TopicsController extends BaseController {
public static class TopicUpdate {
public int totalMessagesCount = -1;
long dialogId;
int topicId;
long topicId;
int unreadMentions;
int unreadCount;
int topMessageId;
@ -1057,13 +1057,13 @@ public class TopicsController extends BaseController {
openedTopicsBuChatId.put(chatId, v);
}
public void getTopicRepliesCount(long dialogId, int topicId) {
public void getTopicRepliesCount(long dialogId, long topicId) {
TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId);
if (topic != null) {
if (topic.totalMessagesCount == 0) {
TLRPC.TL_messages_getReplies req = new TLRPC.TL_messages_getReplies();
req.peer = getMessagesController().getInputPeer(dialogId);
req.msg_id = topicId;
req.msg_id = (int) topicId;
req.limit = 1;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response != null) {

View file

@ -18,6 +18,7 @@ import org.telegram.tgnet.TLRPC;
public class UserObject {
public static final long REPLY_BOT = 1271266957L;
public static final long ANONYMOUS = 2666000L;
public static boolean isDeleted(TLRPC.User user) {
return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || user.deleted;
@ -32,7 +33,11 @@ public class UserObject {
}
public static boolean isReplyUser(TLRPC.User user) {
return user != null && (user.id == 708513 || user.id == REPLY_BOT);
return user != null && (user.id == 708513L || user.id == REPLY_BOT);
}
public static boolean isAnonymous(TLRPC.User user) {
return user != null && user.id == ANONYMOUS;
}
public static boolean isReplyUser(long did) {

View file

@ -12,6 +12,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom;
@ -86,12 +87,21 @@ public class Utilities {
public static native void setupNativeCrashesListener(String path);
public static Bitmap stackBlurBitmapMax(Bitmap bitmap) {
return stackBlurBitmapMax(bitmap, false);
}
public static Bitmap stackBlurBitmapMax(Bitmap bitmap, boolean round) {
int w = AndroidUtilities.dp(20);
int h = (int) (AndroidUtilities.dp(20) * (float) bitmap.getHeight() / bitmap.getWidth());
Bitmap scaledBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(scaledBitmap);
canvas.save();
canvas.scale((float) scaledBitmap.getWidth() / bitmap.getWidth(), (float) scaledBitmap.getHeight() / bitmap.getHeight());
if (round) {
Path path = new Path();
path.addCircle(bitmap.getWidth() / 2f, bitmap.getHeight() / 2f, Math.min(bitmap.getWidth(), bitmap.getHeight()) / 2f - 1, Path.Direction.CW);
canvas.clipPath(path);
}
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.restore();
Utilities.stackBlurBitmap(scaledBitmap, Math.max(10, Math.max(w, h) / 150));

View file

@ -62,6 +62,9 @@ public class VideoEditedInfo {
public boolean isStory;
public StoryEntry.HDRInfo hdrInfo;
public Bitmap thumb;
public boolean notReadyYet;
public Integer gradientTopColor, gradientBottomColor;
public int account;
public boolean isDark;

View file

@ -31,8 +31,12 @@ public class VideoEncodingService extends Service implements NotificationCenter.
public static void start(boolean cancelled) {
if (instance == null) {
Intent intent = new Intent(ApplicationLoader.applicationContext, VideoEncodingService.class);
ApplicationLoader.applicationContext.startService(intent);
try {
Intent intent = new Intent(ApplicationLoader.applicationContext, VideoEncodingService.class);
ApplicationLoader.applicationContext.startService(intent);
} catch (Exception e) {
FileLog.e(e);
}
} else if (cancelled) {
MediaController.VideoConvertMessage messageInController = MediaController.getInstance().getCurrentForegroundConverMessage();
if (instance.currentMessage != messageInController) {

View file

@ -33,7 +33,7 @@ public class WearReplyReceiver extends BroadcastReceiver {
}
long dialogId = intent.getLongExtra("dialog_id", 0);
int maxId = intent.getIntExtra("max_id", 0);
int topicId = intent.getIntExtra("topic_id", 0);
long topicId = intent.getLongExtra("topic_id", 0);
int currentAccount = intent.getIntExtra("currentAccount", 0);
if (dialogId == 0 || maxId == 0 || !UserConfig.isValidAccount(currentAccount)) {
return;
@ -67,19 +67,27 @@ public class WearReplyReceiver extends BroadcastReceiver {
sendMessage(accountInstance, text, dialogId, topicId, maxId);
}
private void sendMessage(AccountInstance accountInstance, CharSequence text, long dialog_id, int topicId, int max_id) {
private void sendMessage(AccountInstance accountInstance, CharSequence text, long dialog_id, long topicId, int max_id) {
MessageObject replyToMsgId = null;
MessageObject replyToTopMsgId = null;
if (max_id != 0) {
TLRPC.TL_message replyMessage = new TLRPC.TL_message();
replyMessage.message = "";
replyMessage.id = max_id;
replyMessage.peer_id = accountInstance.getMessagesController().getPeer(dialog_id);
replyToMsgId = new MessageObject(accountInstance.getCurrentAccount(), replyMessage, false, false);
}
if (topicId != 0) {
TLRPC.TL_message topicStartMessage = new TLRPC.TL_message();
topicStartMessage.message = "";
topicStartMessage.id = topicId;
topicStartMessage.id = (int) topicId;
topicStartMessage.peer_id = accountInstance.getMessagesController().getPeer(dialog_id);
topicStartMessage.action = new TLRPC.TL_messageActionTopicCreate();
topicStartMessage.action.title = "";
replyToMsgId = new MessageObject(accountInstance.getCurrentAccount(), topicStartMessage, false, false);
replyToTopMsgId = new MessageObject(accountInstance.getCurrentAccount(), topicStartMessage, false, false);
}
accountInstance.getSendMessagesHelper().sendMessage(SendMessagesHelper.SendMessageParams.of(text.toString(), dialog_id, replyToMsgId, null, null, true, null, null, null, true, 0, null, false));
accountInstance.getSendMessagesHelper().sendMessage(SendMessagesHelper.SendMessageParams.of(text.toString(), dialog_id, replyToMsgId, replyToTopMsgId, null, true, null, null, null, true, 0, null, false));
//TODO handle topics
if (topicId == 0) {
accountInstance.getMessagesController().markDialogAsRead(dialog_id, max_id, max_id, 0, false, topicId, 0, true, 0);

View file

@ -449,6 +449,16 @@ public class Browser {
return false;
}
public static boolean isTMe(String url) {
try {
final String linkPrefix = MessagesController.getInstance(UserConfig.selectedAccount).linkPrefix;
return TextUtils.equals(AndroidUtilities.getHostAuthority(url), linkPrefix);
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
public static boolean isInternalUri(Uri uri, boolean[] forceBrowser) {
return isInternalUri(uri, false, forceBrowser);
}

View file

@ -10,6 +10,7 @@ package org.telegram.messenger.video;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.util.Log;
import com.coremedia.iso.BoxParser;
import com.coremedia.iso.IsoFile;
@ -38,11 +39,18 @@ import com.coremedia.iso.boxes.TrackHeaderBox;
import com.googlecode.mp4parser.DataSource;
import com.googlecode.mp4parser.util.Matrix;
import org.telegram.messenger.AndroidUtilities;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
@ -207,6 +215,47 @@ public class MP4Builder {
fos.close();
}
public void finishMovie(File into) throws Exception {
if (into == null) {
finishMovie();
return;
}
fos.flush();
final long wasPosition = fc.position();
if (allowSyncFiles) {
fos.getFD().sync();
}
AndroidUtilities.copyFile(currentMp4Movie.getCacheFile(), into);
try (RandomAccessFile raf = new RandomAccessFile(into, "rw");
FileChannel copiedFc = raf.getChannel()) {
// put mdat box
copiedFc.position(wasPosition);
if (mdat.getContentSize() != 0) {
copiedFc.position(mdat.getOffset());
mdat.getBox(copiedFc);
copiedFc.position(wasPosition);
}
// put moov box
track2SampleSizes.clear();
for (Track track : currentMp4Movie.getTracks()) {
List<Sample> samples = track.getSamples();
long[] sizes = new long[samples.size()];
for (int i = 0; i < sizes.length; i++) {
sizes[i] = samples.get(i).getSize();
}
track2SampleSizes.put(track, sizes);
}
Box moov = createMovieBox(currentMp4Movie);
moov.getBox(copiedFc);
}
}
protected FileTypeBox createFileTypeBox(boolean hevc) {
LinkedList<String> minorBrands = new LinkedList<>();
minorBrands.add("isom");

View file

@ -11,6 +11,7 @@ package org.telegram.messenger.video;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;
import com.coremedia.iso.boxes.AbstractMediaHeaderBox;
import com.coremedia.iso.boxes.SampleDescriptionBox;
@ -330,6 +331,8 @@ public class Track {
}
public void prepare() {
duration = 0;
ArrayList<SamplePresentationTime> original = new ArrayList<>(samplePresentationTimes);
Collections.sort(samplePresentationTimes, (o1, o2) -> {
if (o1.presentationTime > o2.presentationTime) {

View file

@ -3029,7 +3029,8 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
} else {
ringtonePlayer.setAudioStreamType(AudioManager.STREAM_RING);
if (!USE_CONNECTION_SERVICE) {
am.requestAudioFocus(this, AudioManager.STREAM_RING, AudioManager.AUDIOFOCUS_GAIN);
int focusResult = am.requestAudioFocus(this, AudioManager.STREAM_RING, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
hasAudioFocus = focusResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
}
}
try {
@ -3156,8 +3157,8 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
}
cpuWakelock.release();
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
if (!playingSound) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
VoipAudioManager vam = VoipAudioManager.get();
if (!USE_CONNECTION_SERVICE) {
if (isBtHeadsetConnected || bluetoothScoActive || bluetoothScoConnecting) {
@ -3194,15 +3195,16 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
if (audioDeviceCallback != null) {
am.unregisterAudioDeviceCallback(audioDeviceCallback);
}
if (hasAudioFocus) {
am.abandonAudioFocus(this);
}
Utilities.globalQueue.postRunnable(() -> {
if (soundPool != null) {
soundPool.release();
}
});
}
if (hasAudioFocus) {
am.abandonAudioFocus(this);
}
if (USE_CONNECTION_SERVICE) {
if (!didDeleteConnectionServiceContact) {
@ -3574,7 +3576,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
try {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER) != null) {
if (am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER) != null) {
int outFramesPerBuffer = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
Instance.setBufferSize(outFramesPerBuffer);
} else {
@ -3763,7 +3765,8 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
FileLog.e(e);
}
AndroidUtilities.runOnUIThread(() -> {
am.requestAudioFocus(VoIPService.this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
int focusResult = am.requestAudioFocus(VoIPService.this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
hasAudioFocus = focusResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
final VoipAudioManager vam = VoipAudioManager.get();
if (isBluetoothHeadsetConnected() && hasEarpiece()) {
switch (audioRouteToSet) {

View file

@ -76,7 +76,7 @@ public class TLRPC {
public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800;
public static final int MESSAGE_FLAG_EDITED = 0x00008000;
public static final int LAYER = 170;
public static final int LAYER = 172;
public static class TL_stats_megagroupStats extends TLObject {
public static final int constructor = 0xef7ff916;
@ -10217,6 +10217,8 @@ public class TLRPC {
public boolean archive_and_mute_new_noncontact_peers;
public boolean keep_archived_unmuted;
public boolean keep_archived_folders;
public boolean hide_read_marks;
public boolean new_noncontact_peers_require_premium;
public static TL_globalPrivacySettings TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_globalPrivacySettings.constructor != constructor) {
@ -10236,6 +10238,8 @@ public class TLRPC {
archive_and_mute_new_noncontact_peers = (flags & 1) != 0;
keep_archived_unmuted = (flags & 2) != 0;
keep_archived_folders = (flags & 4) != 0;
hide_read_marks = (flags & 8) != 0;
new_noncontact_peers_require_premium = (flags & 16) != 0;
}
public void serializeToStream(AbstractSerializedData stream) {
@ -10243,6 +10247,8 @@ public class TLRPC {
flags = archive_and_mute_new_noncontact_peers ? (flags | 1) : (flags &~ 1);
flags = keep_archived_unmuted ? (flags | 2) : (flags &~ 2);
flags = keep_archived_folders ? (flags | 4) : (flags &~ 4);
flags = hide_read_marks ? (flags | 8) : (flags &~ 8);
flags = new_noncontact_peers_require_premium ? (flags | 16) : (flags &~ 16);
stream.writeInt32(flags);
}
}
@ -24088,6 +24094,7 @@ public class TLRPC {
public boolean close_friend;
public boolean stories_unavailable;
public boolean stories_hidden;
public boolean contact_require_premium;
public int bot_info_version;
public String bot_inline_placeholder;
public String lang_code;
@ -24282,6 +24289,7 @@ public class TLRPC {
close_friend = (flags2 & 4) != 0;
stories_hidden = (flags2 & 8) != 0;
stories_unavailable = (flags2 & 16) != 0;
contact_require_premium = (flags2 & 1024) != 0;
id = stream.readInt64(exception);
if ((flags & 1) != 0) {
access_hash = stream.readInt64(exception);
@ -24393,6 +24401,7 @@ public class TLRPC {
flags2 = close_friend ? (flags2 | 4) : (flags2 &~ 4);
flags2 = stories_hidden ? (flags2 | 8) : (flags2 &~ 8);
flags2 = stories_unavailable ? (flags2 | 16) : (flags2 &~ 16);
flags2 = contact_require_premium ? (flags2 | 1024) : (flags2 &~ 1024);
stream.writeInt32(flags2);
stream.writeInt64(id);
if ((flags & 1) != 0) {
@ -28754,6 +28763,7 @@ public class TLRPC {
public int flags;
public boolean min;
public boolean can_see_list;
public boolean reactions_as_tags;
public ArrayList<ReactionCount> results = new ArrayList<>();
public ArrayList<MessagePeerReaction> recent_reactions = new ArrayList<>();
@ -28787,6 +28797,7 @@ public class TLRPC {
flags = stream.readInt32(exception);
min = (flags & 1) != 0;
can_see_list = (flags & 4) != 0;
reactions_as_tags = (flags & 8) != 0;
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
@ -28825,6 +28836,7 @@ public class TLRPC {
stream.writeInt32(constructor);
flags = min ? (flags | 1) : (flags &~ 1);
flags = can_see_list ? (flags | 4) : (flags &~ 4);
flags = reactions_as_tags ? (flags | 8) : (flags &~ 8);
stream.writeInt32(flags);
stream.writeInt32(0x1cb5c415);
int count = results.size();
@ -28843,6 +28855,144 @@ public class TLRPC {
}
}
public static class TL_savedReactionTag extends TLObject {
public static final int constructor = 0xcb6ff828;
public int flags;
public Reaction reaction;
public String title;
public int count;
public static TL_savedReactionTag TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_savedReactionTag.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_savedReactionTag", constructor));
} else {
return null;
}
}
TL_savedReactionTag result = new TL_savedReactionTag();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
reaction = Reaction.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 1) != 0) {
title = stream.readString(exception);
}
count = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
reaction.serializeToStream(stream);
if ((flags & 1) != 0) {
stream.writeString(title);
}
stream.writeInt32(count);
}
}
public static class messages_SavedReactionTags extends TLObject {
public ArrayList<TL_savedReactionTag> tags = new ArrayList<>();
public long hash;
public static messages_SavedReactionTags TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
messages_SavedReactionTags result = null;
switch (constructor) {
case TL_messages_savedReactionsTagsNotModified.constructor:
result = new TL_messages_savedReactionsTagsNotModified();
break;
case TL_messages_savedReactionsTags.constructor:
result = new TL_messages_savedReactionsTags();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in messages_SavedReactionTags", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_messages_savedReactionsTagsNotModified extends messages_SavedReactionTags {
public static final int constructor = 0x889b59ef;
public void readParams(AbstractSerializedData stream, boolean exception) {
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_messages_savedReactionsTags extends messages_SavedReactionTags {
public static final int constructor = 0x3259950a;
public void readParams(AbstractSerializedData stream, boolean exception) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_savedReactionTag object = TL_savedReactionTag.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
tags.add(object);
}
hash = stream.readInt64(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(0x1cb5c415);
int count = tags.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
tags.get(a).serializeToStream(stream);
}
stream.writeInt64(hash);
}
}
public static class TL_outboxReadDate extends TLObject {
public static final int constructor = 0x3bb842ac;
public int date;
public static TL_outboxReadDate TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_outboxReadDate.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_outboxReadDate", constructor));
} else {
return null;
}
}
TL_outboxReadDate result = new TL_outboxReadDate();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
date = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(date);
}
}
public static class TL_messageReactionsOld extends TL_messageReactions {
public static final int constructor = 0x87b6e36;
@ -33558,7 +33708,9 @@ public class TLRPC {
}
public static abstract class UserStatus extends TLObject {
public int flags;
public int expires;
public boolean by_me;
public static UserStatus TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
UserStatus result = null;
@ -33566,21 +33718,33 @@ public class TLRPC {
case 0x8c703f:
result = new TL_userStatusOffline();
break;
case 0x7bf09fc:
case TL_userStatusLastWeek.constructor:
result = new TL_userStatusLastWeek();
break;
case TL_userStatusLastWeek_layer171.constructor:
result = new TL_userStatusLastWeek_layer171();
break;
case 0x9d05049:
result = new TL_userStatusEmpty();
break;
case 0x77ebc742:
case TL_userStatusLastMonth.constructor:
result = new TL_userStatusLastMonth();
break;
case TL_userStatusLastMonth_layer171.constructor:
result = new TL_userStatusLastMonth_layer171();
break;
case 0xedb93949:
result = new TL_userStatusOnline();
break;
case 0xe26f42f1:
case TL_userStatusRecently.constructor:
result = new TL_userStatusRecently();
break;
case TL_userStatusRecently_layer171.constructor:
result = new TL_userStatusRecently_layer171();
break;
case TL_userStatusHidden.constructor:
result = new TL_userStatusHidden();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in UserStatus", constructor));
@ -33592,6 +33756,19 @@ public class TLRPC {
}
}
public static class TL_userStatusHidden extends UserStatus {
public static final int constructor = 0xcf7d64b1;
public void readParams(AbstractSerializedData stream, boolean exception) {
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_userStatusOffline extends UserStatus {
public static final int constructor = 0x8c703f;
@ -33607,8 +33784,29 @@ public class TLRPC {
}
public static class TL_userStatusLastWeek extends UserStatus {
public static final int constructor = 0x541a1d1a;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
by_me = (flags & 1) != 0;
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = by_me ? flags | 1 : flags &~ 1;
stream.writeInt32(flags);
}
}
public static class TL_userStatusLastWeek_layer171 extends TL_userStatusLastWeek {
public static final int constructor = 0x7bf09fc;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
@ -33625,8 +33823,28 @@ public class TLRPC {
}
public static class TL_userStatusLastMonth extends UserStatus {
public static final int constructor = 0x65899777;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
by_me = (flags & 1) != 0;
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = by_me ? flags | 1 : flags &~ 1;
stream.writeInt32(flags);
}
}
public static class TL_userStatusLastMonth_layer171 extends TL_userStatusLastMonth {
public static final int constructor = 0x77ebc742;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
@ -33648,8 +33866,28 @@ public class TLRPC {
}
public static class TL_userStatusRecently extends UserStatus {
public static final int constructor = 0x7b197dc8;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
by_me = (flags & 1) != 0;
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = by_me ? flags | 1 : flags &~ 1;
stream.writeInt32(flags);
}
}
public static class TL_userStatusRecently_layer171 extends TL_userStatusRecently {
public static final int constructor = 0xe26f42f1;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
@ -34180,6 +34418,9 @@ public class TLRPC {
case TL_updateRecentReactions.constructor:
result = new TL_updateRecentReactions();
break;
case TL_updateSavedReactionTags.constructor:
result = new TL_updateSavedReactionTags();
break;
case TL_updateWebPage.constructor:
result = new TL_updateWebPage();
break;
@ -35306,6 +35547,14 @@ public class TLRPC {
}
}
public static class TL_updateSavedReactionTags extends Update {
public static final int constructor = 0x39c67432;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_updateWebPage extends Update {
public static final int constructor = 0x7f891213;
@ -51431,6 +51680,8 @@ public class TLRPC {
public boolean stories_pinned_available;
public boolean blocked_my_stories_from;
public boolean wallpaper_overridden;
public boolean contact_require_premium;
public boolean read_dates_private;
public User user;
public String about;
public TL_contacts_link_layer101 link;
@ -51456,7 +51707,7 @@ public class TLRPC {
public static UserFull TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
UserFull result = null;
switch (constructor) {
case 0xb9b12c6c:
case TL_userFull.constructor:
result = new TL_userFull();
break;
case 0x4fe1cc86:
@ -51522,6 +51773,8 @@ public class TLRPC {
stories_pinned_available = (flags & 67108864) != 0;
blocked_my_stories_from = (flags & 134217728) != 0;
wallpaper_overridden = (flags & 268435456) != 0;
contact_require_premium = (flags & 536870912) != 0;
read_dates_private = (flags & 1073741824) != 0;
id = stream.readInt64(exception);
if ((flags & 2) != 0) {
about = stream.readString(exception);
@ -51600,6 +51853,8 @@ public class TLRPC {
flags = stories_pinned_available ? (flags | 67108864) : (flags &~ 67108864);
flags = blocked_my_stories_from ? (flags | 134217728) : (flags &~ 134217728);
flags = wallpaper_overridden ? (flags | 268435456) : (flags &~ 268435456);
flags = contact_require_premium ? (flags | 536870912) : (flags &~ 536870912);
flags = read_dates_private ? (flags | 1073741824) : (flags &~ 1073741824);
stream.writeInt32(flags);
stream.writeInt64(id);
if ((flags & 2) != 0) {
@ -56182,6 +56437,35 @@ public class TLRPC {
id.serializeToStream(stream);
}
}
public static class TL_users_getIsPremiumRequiredToContact extends TLObject {
public static final int constructor = 0xa622aa10;
public ArrayList<InputUser> id = new ArrayList<>();
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
Vector vector = new Vector();
int size = stream.readInt32(exception);
for (int a = 0; a < size; a++) {
Bool object = Bool.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return vector;
}
vector.objects.add(object);
}
return vector;
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(0x1cb5c415);
int count = id.size();
stream.writeInt32(count);
for (int i = 0; i < count; ++i) {
id.get(i).serializeToStream(stream);
}
}
}
public static class TL_contacts_getStatuses extends TLObject {
public static final int constructor = 0xc4a353ee;
@ -56587,13 +56871,14 @@ public class TLRPC {
}
public static class TL_messages_search extends TLObject {
public static final int constructor = 0xa7b4e929;
public static final int constructor = 0x29ee847a;
public int flags;
public InputPeer peer;
public String q;
public InputPeer from_id;
public InputPeer saved_peer_id;
public ArrayList<Reaction> saved_reaction = new ArrayList<>();
public int top_msg_id;
public MessagesFilter filter;
public int min_date;
@ -56620,6 +56905,14 @@ public class TLRPC {
if ((flags & 4) != 0) {
saved_peer_id.serializeToStream(stream);
}
if ((flags & 8) != 0) {
stream.writeInt32(0x1cb5c415);
int count = saved_reaction.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
saved_reaction.get(a).serializeToStream(stream);
}
}
if ((flags & 2) != 0) {
stream.writeInt32(top_msg_id);
}
@ -71481,6 +71774,23 @@ public class TLRPC {
}
}
public static class TL_messages_getDefaultTagReactions extends TLObject {
public static final int constructor = 0xbdf93428;
public long hash;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return messages_Reactions.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(hash);
}
}
public static abstract class ForumTopic extends TLObject {
public static ForumTopic TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
@ -74750,6 +75060,66 @@ public class TLRPC {
}
}
public static class TL_messages_getSavedReactionTags extends TLObject {
public static final int constructor = 0x761ddacf;
public long hash;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return messages_SavedReactionTags.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(hash);
}
}
public static class TL_messages_updateSavedReactionTag extends TLObject {
public static final int constructor = 0x60297dec;
public int flags;
public Reaction reaction;
public String title;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return Bool.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
reaction.serializeToStream(stream);
if ((flags & 1) != 0) {
stream.writeString(title);
}
}
}
public static class TL_messages_getOutboxReadDate extends TLObject {
public static final int constructor = 0x8c4bfe5d;
public InputPeer peer;
public int msg_id;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_outboxReadDate.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
peer.serializeToStream(stream);
stream.writeInt32(msg_id);
}
}
public static class Vector extends TLObject {
public static final int constructor = 0x1cb5c415;
public ArrayList<Object> objects = new ArrayList<>();

View file

@ -1003,6 +1003,10 @@ public class ActionBar extends FrameLayout {
}
}
public int getBackgroundColor() {
return actionBarColor;
}
public boolean isActionModeShowed() {
return actionMode != null && actionModeVisible;
}
@ -1159,6 +1163,12 @@ public class ActionBar extends FrameLayout {
}
}
public void clearSearchFilters() {
if (menu != null) {
menu.clearSearchFilters();
}
}
public void setSearchFieldText(String text) {
menu.setSearchFieldText(text);
}

View file

@ -566,7 +566,17 @@ public class ActionBarMenu extends LinearLayout {
}
public void clearSearchFilters() {
int count = getChildCount();
for (int a = 0; a < count; a++) {
View view = getChildAt(a);
if (view instanceof ActionBarMenuItem) {
ActionBarMenuItem item = (ActionBarMenuItem) view;
if (item.isSearchField()) {
item.clearSearchFilters();
break;
}
}
}
}
private Runnable onLayoutListener;

View file

@ -8,6 +8,8 @@
package org.telegram.ui.ActionBar;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@ -65,6 +67,7 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Adapters.FiltersView;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CloseProgressDrawable2;
import org.telegram.ui.Components.CombinedDrawable;
@ -73,6 +76,7 @@ import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import java.util.ArrayList;
import java.util.HashMap;
@ -1052,7 +1056,7 @@ public class ActionBarMenuItem extends FrameLayout {
}
for (int i = 0; i < searchFilterLayout.getChildCount(); i++) {
boolean removed = localFilters.remove(((SearchFilterView)searchFilterLayout.getChildAt(i)).getFilter());
boolean removed = localFilters.remove(((SearchFilterView) searchFilterLayout.getChildAt(i)).getFilter());
if (!removed) {
searchFilterLayout.removeViewAt(i);
i--;
@ -1060,8 +1064,14 @@ public class ActionBarMenuItem extends FrameLayout {
}
for (int i = 0; i < localFilters.size(); i++) {
SearchFilterView searchFilterView = new SearchFilterView(getContext(), resourcesProvider);
searchFilterView.setData(localFilters.get(i));
FiltersView.MediaFilterData filter = localFilters.get(i);
SearchFilterView searchFilterView;
if (filter.reaction != null) {
searchFilterView = new ReactionFilterView(getContext(), resourcesProvider);
} else {
searchFilterView = new SearchFilterView(getContext(), resourcesProvider);
}
searchFilterView.setData(filter);
searchFilterView.setOnClickListener(view -> {
int index = currentSearchFilters.indexOf(searchFilterView.getFilter());
if (selectedFilterIndex != index) {
@ -2014,6 +2024,78 @@ public class ActionBarMenuItem extends FrameLayout {
return Theme.getColor(key, resourcesProvider);
}
private static class ReactionFilterView extends SearchFilterView {
private ReactionsLayoutInBubble.ReactionButton reactionButton;
public ReactionFilterView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context, resourcesProvider);
removeAllViews();
setBackground(null);
setWillNotDraw(false);
}
public void setData(FiltersView.MediaFilterData data) {
TLRPC.TL_reactionCount reactionCount = new TLRPC.TL_reactionCount();
reactionCount.count = 1;
reactionCount.reaction = data.reaction.toTLReaction();
reactionButton = new ReactionsLayoutInBubble.ReactionButton(null, UserConfig.selectedAccount, this, reactionCount, false, resourcesProvider) {
@Override
protected void updateColors(float progress) {
lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, Theme.getColor(Theme.key_chat_inReactionButtonBackground, resourcesProvider), progress);
}
@Override
protected int getCacheType() {
return AnimatedEmojiDrawable.CACHE_TYPE_ALERT_EMOJI_STATUS;
}
};
reactionButton.width = dp(44.33f);
reactionButton.height = dp(28);
reactionButton.choosen = true;
if (attached) {
reactionButton.attach();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(dp(45 + 4), dp(32));
}
@Override
protected void onDraw(Canvas canvas) {
if (reactionButton != null) {
reactionButton.draw(canvas, (getWidth() - dp(4) - reactionButton.width) / 2f, (getHeight() - reactionButton.height) / 2f, 1f, 1f, false);
}
}
private boolean attached;
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!attached) {
if (reactionButton != null) {
reactionButton.attach();
}
attached = true;
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (attached) {
if (reactionButton != null) {
reactionButton.detach();
}
attached = false;
}
}
}
private static class SearchFilterView extends FrameLayout {
Drawable thumbDrawable;
@ -2036,7 +2118,7 @@ public class ActionBarMenuItem extends FrameLayout {
}
};
private final Theme.ResourcesProvider resourcesProvider;
protected final Theme.ResourcesProvider resourcesProvider;
public SearchFilterView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context);

View file

@ -12,6 +12,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
@ -19,6 +20,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.CornerPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
@ -53,6 +55,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
@ -198,7 +202,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
protected boolean supportsNativeBlur() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && LaunchActivity.systemBlurEnabled;
return false; // Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && LaunchActivity.systemBlurEnabled;
}
public void redPositive() {

View file

@ -67,7 +67,7 @@ public abstract class BaseFragment {
protected Dialog visibleDialog;
protected int currentAccount = UserConfig.selectedAccount;
protected View fragmentView;
public View fragmentView;
protected INavigationLayout parentLayout;
protected ActionBar actionBar;
protected boolean inPreviewMode;

View file

@ -97,6 +97,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
private boolean wasLayout;
private boolean rightDrawableOutside;
private boolean rightDrawableInside;
private boolean ellipsizeByGradient, ellipsizeByGradientLeft;
private Boolean forceEllipsizeByGradientLeft;
private int ellipsizeByGradientWidthDp = 16;
@ -317,7 +318,16 @@ public class SimpleTextView extends View implements Drawable.Callback {
offsetX = -AndroidUtilities.dp(8);
}
offsetX += getPaddingLeft();
textDoesNotFit = textWidth > (width - paddingRight);
int rightDrawableWidth = 0;
if (rightDrawableInside) {
if (rightDrawable != null && !rightDrawableOutside) {
rightDrawableWidth += (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
}
if (rightDrawable2 != null && !rightDrawableOutside) {
rightDrawableWidth += (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
}
}
textDoesNotFit = textWidth + rightDrawableWidth > (width - paddingRight);
if (fullLayout != null && fullLayoutAdditionalWidth > 0) {
fullLayoutLeftCharactersOffset = fullLayout.getPrimaryHorizontal(0) - firstLineLayout.getPrimaryHorizontal(0);
@ -342,15 +352,17 @@ public class SimpleTextView extends View implements Drawable.Callback {
width -= drawablePadding;
}
int rightDrawableWidth = 0;
if (rightDrawable != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (rightDrawable2 != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
if (!rightDrawableInside) {
if (rightDrawable != null && !rightDrawableOutside) {
rightDrawableWidth += (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (rightDrawable2 != null && !rightDrawableOutside) {
rightDrawableWidth += (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
}
if (replacedText != null && replacedDrawable != null) {
replacingDrawableTextIndex = text.toString().indexOf(replacedText);
@ -487,7 +499,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
public int getTextWidth() {
return textWidth;
return textWidth + (rightDrawableInside ? (rightDrawable != null ? (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale) : 0) + (rightDrawable2 != null ? (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale) : 0) : 0);
}
public int getRightDrawableWidth() {
@ -742,15 +754,17 @@ public class SimpleTextView extends View implements Drawable.Callback {
width -= drawablePadding;
}
int rightDrawableWidth = 0;
if (rightDrawable != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (rightDrawable2 != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
if (!rightDrawableInside) {
if (rightDrawable != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (rightDrawable2 != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
}
if (replacedText != null && replacedDrawable != null) {
if ((replacingDrawableTextIndex = text.toString().indexOf(replacedText)) < 0) {
@ -823,7 +837,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
}
if (rightDrawable != null && !rightDrawableHidden && rightDrawableScale > 0 && !rightDrawableOutside) {
if (rightDrawable != null && !rightDrawableHidden && rightDrawableScale > 0 && !rightDrawableOutside && !rightDrawableInside) {
int x = textOffsetX + textWidth + drawablePadding + (int) -scrollingOffset;
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.CENTER_HORIZONTAL ||
(gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.RIGHT) {
@ -843,7 +857,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
rightDrawable.draw(canvas);
totalWidth += drawablePadding + dw;
}
if (rightDrawable2 != null && !rightDrawableHidden && rightDrawableScale > 0 && !rightDrawableOutside) {
if (rightDrawable2 != null && !rightDrawableHidden && rightDrawableScale > 0 && !rightDrawableOutside && !rightDrawableInside) {
int x = textOffsetX + textWidth + drawablePadding + (int) -scrollingOffset;
if (rightDrawable != null) {
x += (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale) + drawablePadding;
@ -963,6 +977,47 @@ public class SimpleTextView extends View implements Drawable.Callback {
if (offsetX + textOffsetX != 0 || offsetY != 0 || scrollingOffset != 0) {
canvas.restore();
}
if (rightDrawable != null && !rightDrawableHidden && rightDrawableScale > 0 && !rightDrawableOutside && rightDrawableInside) {
int x = textOffsetX + textWidth + drawablePadding + (int) -scrollingOffset;
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.CENTER_HORIZONTAL ||
(gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.RIGHT) {
x += offsetX;
}
int dw = (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
int dh = (int) (rightDrawable.getIntrinsicHeight() * rightDrawableScale);
int y;
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.CENTER_VERTICAL) {
y = (getMeasuredHeight() - dh) / 2 + rightDrawableTopPadding;
} else {
y = getPaddingTop() + (textHeight - dh) / 2 + rightDrawableTopPadding;
}
rightDrawable.setBounds(x, y, x + dw, y + dh);
rightDrawableX = x + (dw >> 1);
rightDrawableY = y + (dh >> 1);
rightDrawable.draw(canvas);
totalWidth += drawablePadding + dw;
}
if (rightDrawable2 != null && !rightDrawableHidden && rightDrawableScale > 0 && !rightDrawableOutside && rightDrawableInside) {
int x = textOffsetX + textWidth + drawablePadding + (int) -scrollingOffset;
if (rightDrawable != null) {
x += (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale) + drawablePadding;
}
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.CENTER_HORIZONTAL ||
(gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.RIGHT) {
x += offsetX;
}
int dw = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
int dh = (int) (rightDrawable2.getIntrinsicHeight() * rightDrawableScale);
int y;
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.CENTER_VERTICAL) {
y = (getMeasuredHeight() - dh) / 2 + rightDrawableTopPadding;
} else {
y = getPaddingTop() + (textHeight - dh) / 2 + rightDrawableTopPadding;
}
rightDrawable2.setBounds(x, y, x + dw, y + dh);
rightDrawable2.draw(canvas);
totalWidth += drawablePadding + dw;
}
if (fade) {
if (scrollingOffset < AndroidUtilities.dp(10)) {
fadePaint.setAlpha((int) (255 * (scrollingOffset / AndroidUtilities.dp(10))));
@ -1170,6 +1225,12 @@ public class SimpleTextView extends View implements Drawable.Callback {
rightDrawableOutside = outside;
}
// right drawable is ellipsized with text
public void setRightDrawableInside(boolean inside) {
rightDrawableInside = inside;
}
public boolean getRightDrawableOutside() {
return rightDrawableOutside;
}
@ -1187,14 +1248,23 @@ public class SimpleTextView extends View implements Drawable.Callback {
touchDownX = event.getX();
touchDownY = event.getY();
getParent().requestDisallowInterceptTouchEvent(true);
if (rightDrawable instanceof PressableDrawable) {
((PressableDrawable) rightDrawable).setPressed(true);
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE && maybeClick) {
if (Math.abs(event.getX() - touchDownX) >= AndroidUtilities.touchSlop || Math.abs(event.getY() - touchDownY) >= AndroidUtilities.touchSlop) {
maybeClick = false;
getParent().requestDisallowInterceptTouchEvent(false);
if (rightDrawable instanceof PressableDrawable) {
((PressableDrawable) rightDrawable).setPressed(false);
}
}
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (maybeClick && event.getAction() == MotionEvent.ACTION_UP) {
rightDrawableOnClickListener.onClick(this);
if (rightDrawable instanceof PressableDrawable) {
((PressableDrawable) rightDrawable).setPressed(false);
}
}
maybeClick = false;
getParent().requestDisallowInterceptTouchEvent(false);
@ -1202,4 +1272,9 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
return super.onTouchEvent(event) || maybeClick;
}
public static interface PressableDrawable {
public void setPressed(boolean value);
public boolean isPressed();
}
}

View file

@ -863,6 +863,7 @@ public class Theme {
rad = heightHalf;
}
if (isOut) {
// LEFT-BOTTOM <- RIGHT-BOTTOM
if (drawFullBubble || currentType == TYPE_PREVIEW || customPaint || drawFullBottom) {
int radToUse = botButtonsBottom ? nearRad : rad;
if (currentType == TYPE_MEDIA) {
@ -878,10 +879,12 @@ public class Theme {
path.lineTo(bounds.left + padding, top - topY + currentBackgroundHeight);
}
if (drawFullBubble || currentType == TYPE_PREVIEW || customPaint || drawFullTop) {
// LEFT-BOTTOM -> LEFT-TOP
path.lineTo(bounds.left + padding, bounds.top + padding + rad);
rect.set(bounds.left + padding, bounds.top + padding, bounds.left + padding + rad * 2, bounds.top + padding + rad * 2);
path.arcTo(rect, 180, 90, false);
// LEFT-TOP -> RIGHT-TOP
int radToUse = isTopNear ? nearRad : rad;
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.right - padding - radToUse, bounds.top + padding);
@ -892,13 +895,17 @@ public class Theme {
}
path.arcTo(rect, 270, 90, false);
} else {
// LEFT-BOTTOM -> LEFT-TOP
path.lineTo(bounds.left + padding, top - topY - dp(2));
// LEFT-TOP -> RIGHT-TOP
if (currentType == TYPE_MEDIA) {
path.lineTo(bounds.right - padding, top - topY - dp(2));
} else {
path.lineTo(bounds.right - dp(8), top - topY - dp(2));
}
}
// RIGHT-TOP -> RIGHT-BOTTOM
if (currentType == TYPE_MEDIA) {
if (customPaint || drawFullBottom) {
int radToUse = isBottomNear ? nearRad : rad;
@ -3098,7 +3105,7 @@ public class Theme {
public static Paint avatar_backgroundPaint;
public static Drawable listSelector;
public static Drawable[] avatarDrawables = new Drawable[18];
public static Drawable[] avatarDrawables = new Drawable[20];
public static Drawable moveUpDrawable;
@ -3635,6 +3642,9 @@ public class Theme {
public static final int key_chat_inBubbleSelectedOverlay = colorsCount++;
public static final int key_chat_inBubbleShadow = colorsCount++;
public static final int key_actionBarActionModeReaction = colorsCount++;
public static final int key_actionBarActionModeReactionDot = colorsCount++;
//my messages bubbles
public static final int myMessagesBubblesStartIndex = colorsCount;
public static final int key_chat_outBubble = colorsCount++;
@ -4384,6 +4394,8 @@ public class Theme {
fallbackKeys.put(key_statisticChartLine_indigo, key_color_purple);
fallbackKeys.put(key_statisticChartLine_cyan, key_color_cyan);
fallbackKeys.put(key_actionBarActionModeReaction, key_windowBackgroundGray);
for (int i = 0; i < keys_avatar_background.length; i++) {
themeAccentExclusionKeys.add(keys_avatar_background[i]);
}
@ -8134,6 +8146,8 @@ public class Theme {
avatarDrawables[15] = resources.getDrawable(R.drawable.filled_unknown);
avatarDrawables[16] = resources.getDrawable(R.drawable.filled_unclaimed);
avatarDrawables[17] = resources.getDrawable(R.drawable.large_repost_story);
avatarDrawables[18] = resources.getDrawable(R.drawable.large_hidden);
avatarDrawables[19] = resources.getDrawable(R.drawable.large_notes);
if (dialogs_archiveAvatarDrawable != null) {
dialogs_archiveAvatarDrawable.setCallback(null);
@ -8683,7 +8697,7 @@ public class Theme {
chat_shareIconDrawable = resources.getDrawable(R.drawable.filled_button_share).mutate();
chat_replyIconDrawable = resources.getDrawable(R.drawable.filled_button_reply);
chat_closeIconDrawable = resources.getDrawable(R.drawable.msg_voiceclose).mutate();
chat_goIconDrawable = resources.getDrawable(R.drawable.message_arrow);
chat_goIconDrawable = resources.getDrawable(R.drawable.filled_open_message);
int rad = AndroidUtilities.dp(2);
RectF rect = new RectF();
@ -9867,7 +9881,7 @@ public class Theme {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(backgroundColor, gradientToColor1, gradientToColor2, gradientToColor3, false);
Bitmap patternBitmap = null;
if (wallpaperFile != null && !isCustomTheme()) {
if (wallpaperFile != null) {
if (wallpaperDocument != null) {
File f = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(wallpaperDocument, true);
patternBitmap = SvgHelper.getBitmap(f, AndroidUtilities.dp(360), AndroidUtilities.dp(640), false);

View file

@ -188,6 +188,8 @@ public class ThemeColors {
defaultColors[key_actionBarDefaultSubmenuBackground] = 0xffffffff;
defaultColors[key_actionBarDefaultSubmenuSeparator] = 0xfff5f5f5;
defaultColors[key_actionBarActionModeDefaultSelector] = 0xffe2e2e2;
defaultColors[key_actionBarActionModeReaction] = 0xfff0f0f0;
defaultColors[key_actionBarActionModeReactionDot] = 0xffc0c0c0;
defaultColors[key_actionBarTabActiveText] = 0xffffffff;
defaultColors[key_actionBarTabUnactiveText] = 0xffd5e8f7;
defaultColors[key_actionBarTabLine] = 0xffffffff;
@ -954,6 +956,8 @@ public class ThemeColors {
colorKeysMap.put(key_actionBarActionModeDefaultTop, "actionBarActionModeDefaultTop");
colorKeysMap.put(key_actionBarActionModeDefaultIcon, "actionBarActionModeDefaultIcon");
colorKeysMap.put(key_actionBarActionModeDefaultSelector, "actionBarActionModeDefaultSelector");
colorKeysMap.put(key_actionBarActionModeReaction, "actionBarActionModeReaction");
colorKeysMap.put(key_actionBarActionModeReactionDot, "actionBarActionModeReactionDot");
colorKeysMap.put(key_actionBarDefaultTitle, "actionBarDefaultTitle");
colorKeysMap.put(key_actionBarDefaultSubtitle, "actionBarDefaultSubtitle");
colorKeysMap.put(key_actionBarDefaultSearch, "actionBarDefaultSearch");

View file

@ -151,6 +151,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
public interface DialogsSearchAdapterDelegate {
void searchStateChanged(boolean searching, boolean animated);
void didPressedOnSubDialog(long did);
void didPressedBlockedDialog(View view, long did);
void needRemoveHint(long did);
void needClearList();
void runResultsEnterAnimation();
@ -164,12 +165,14 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private final int currentAccount;
private boolean drawChecked;
private boolean forceDarkTheme;
private boolean showPremiumBlock;
private Theme.ResourcesProvider resourcesProvider;
public CategoryAdapterRecycler(Context context, int account, boolean drawChecked, Theme.ResourcesProvider resourcesProvider) {
public CategoryAdapterRecycler(Context context, int account, boolean drawChecked, boolean showPremiumBlock, Theme.ResourcesProvider resourcesProvider) {
this.drawChecked = drawChecked;
mContext = context;
currentAccount = account;
this.showPremiumBlock = showPremiumBlock;
this.resourcesProvider = resourcesProvider;
}
@ -180,6 +183,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
HintDialogCell cell = new HintDialogCell(mContext, drawChecked, resourcesProvider);
if (showPremiumBlock) {
cell.showPremiumBlocked();
}
cell.setLayoutParams(new RecyclerView.LayoutParams(AndroidUtilities.dp(80), AndroidUtilities.dp(86)));
return new RecyclerListView.Holder(cell);
}
@ -1374,7 +1380,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
View view;
switch (viewType) {
case VIEW_TYPE_PROFILE_CELL:
view = new ProfileSearchCell(mContext);
view = new ProfileSearchCell(mContext).showPremiumBlock(dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD);
break;
case VIEW_TYPE_GRAY_SECTION:
view = new GraySectionCell(mContext);
@ -1422,8 +1428,14 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
horizontalListView.setLayoutManager(layoutManager);
//horizontalListView.setDisallowInterceptTouchEvents(true);
horizontalListView.setAdapter(new CategoryAdapterRecycler(mContext, currentAccount, false, resourcesProvider));
horizontalListView.setAdapter(new CategoryAdapterRecycler(mContext, currentAccount, false, dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD, resourcesProvider));
horizontalListView.setOnItemClickListener((view1, position) -> {
if (view1 instanceof HintDialogCell && ((HintDialogCell) view1).isBlocked()) {
if (delegate != null) {
delegate.didPressedBlockedDialog(view1, ((HintDialogCell) view1).getDialogId());
}
return;
}
if (delegate != null) {
delegate.didPressedOnSubDialog((Long) view1.getTag());
}

View file

@ -36,6 +36,7 @@ import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.RecyclerListView;
import java.text.SimpleDateFormat;
@ -786,15 +787,21 @@ public class FiltersView extends RecyclerListView {
public static class MediaFilterData {
public final int iconResFilled;
public ReactionsLayoutInBubble.VisibleReaction reaction;
public int iconResFilled;
public int titleResId;
private String title;
public final int filterType;
public final TLRPC.MessagesFilter filter;
public int filterType;
public TLRPC.MessagesFilter filter;
public TLObject chat;
public DateData dateData;
public boolean removable = true;
public MediaFilterData(ReactionsLayoutInBubble.VisibleReaction reaction) {
this.reaction = reaction;
}
public MediaFilterData(int iconResFilled, String title, TLRPC.MessagesFilter filter, int filterType) {
this.iconResFilled = iconResFilled;
this.title = title;

View file

@ -83,7 +83,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
private int currentAccount = UserConfig.selectedAccount;
private Context mContext;
private long dialog_id;
private int threadMessageId;
private long threadMessageId;
private TLRPC.ChatFull info;
private SearchAdapterHelper searchAdapterHelper;
private ArrayList<TLObject> searchResultUsernames;
@ -181,7 +181,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
}
};
public MentionsAdapter(Context context, boolean darkTheme, long did, int threadMessageId, MentionsAdapterDelegate mentionsAdapterDelegate, Theme.ResourcesProvider resourcesProvider) {
public MentionsAdapter(Context context, boolean darkTheme, long did, long threadMessageId, MentionsAdapterDelegate mentionsAdapterDelegate, Theme.ResourcesProvider resourcesProvider) {
this.resourcesProvider = resourcesProvider;
mContext = context;
delegate = mentionsAdapterDelegate;
@ -1145,7 +1145,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
}
}
final TLRPC.Chat chat;
int threadId;
long threadId;
if (parentFragment != null) {
chat = parentFragment.getCurrentChat();
threadId = parentFragment.getThreadId();
@ -1333,7 +1333,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
channelParticipantsMentions.q = usernameString;
if (threadId != 0) {
channelParticipantsMentions.flags |= 2;
channelParticipantsMentions.top_msg_id = threadId;
channelParticipantsMentions.top_msg_id = (int) threadId;
}
req.filter = channelParticipantsMentions;
final int currentReqId = ++channelLastReqId;

View file

@ -4262,7 +4262,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
messageObject.messageOwner.media.webpage = webPage;
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
messagesRes.messages.add(messageObject.messageOwner);
MessagesStorage.getInstance(currentAccount).putMessages(messagesRes, messageObject.getDialogId(), -2, 0, false, messageObject.scheduled, 0);
MessagesStorage.getInstance(currentAccount).putMessages(messagesRes, messageObject.getDialogId(), -2, 0, false, messageObject.scheduled ? 1 : 0, 0);
}
pagesStack.set(0, webPage);
if (pagesStack.size() == 1) {
@ -4295,7 +4295,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
if (messageObject != null) {
TLRPC.TL_messages_messages messagesRes = new TLRPC.TL_messages_messages();
messagesRes.messages.add(messageObject.messageOwner);
MessagesStorage.getInstance(currentAccount).putMessages(messagesRes, messageObject.getDialogId(), -2, 0, false, messageObject.scheduled, 0);
MessagesStorage.getInstance(currentAccount).putMessages(messagesRes, messageObject.getDialogId(), -2, 0, false, messageObject.scheduled ? 1 : 0, 0);
}
}
}

View file

@ -95,7 +95,7 @@ public class CalendarActivity extends BaseFragment implements NotificationCenter
Paint blackoutPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private long dialogId;
private int topicId;
private long topicId;
private boolean loading;
private boolean checkEnterItems;
private boolean inSelectionMode;
@ -157,7 +157,7 @@ public class CalendarActivity extends BaseFragment implements NotificationCenter
@Override
public boolean onFragmentCreate() {
dialogId = getArguments().getLong("dialog_id");
topicId = getArguments().getInt("topic_id");
topicId = getArguments().getLong("topic_id");
calendarType = getArguments().getInt("type");
if (calendarType == TYPE_PROFILE_STORIES) {

View file

@ -68,7 +68,6 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.TLObject;
@ -205,7 +204,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
return 0;
}
default int getTopicId() {
default long getTopicId() {
return 0;
}
@ -1198,7 +1197,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
text = StoriesUtilities.createExpiredStoryString(true, "ExpiredStoryMentioned", R.string.ExpiredStoryMentioned, MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId()).first_name);
}
} else if (delegate.getTopicId() == 0 && MessageObject.isTopicActionMessage(messageObject)) {
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), MessageObject.getTopicId(messageObject.messageOwner, true));
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), MessageObject.getTopicId(currentAccount, messageObject.messageOwner, true));
text = ForumUtilities.createActionTextWithTopic(topic, messageObject);
}
if (text == null) {

View file

@ -8,6 +8,8 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@ -68,6 +70,7 @@ import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
@ -81,6 +84,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.DialogsAdapter;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BubbleCounterPath;
import org.telegram.ui.Components.CanvasButton;
@ -166,6 +170,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
private Paint timerPaint;
private Paint timerPaint2;
SharedResources sharedResources;
public boolean isSavedDialog;
public final StoriesUtilities.AvatarStoryParams storyParams = new StoriesUtilities.AvatarStoryParams(false) {
@Override
@ -399,6 +404,13 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
private int printingStringType;
private TLRPC.DraftMessage draftMessage;
private final AnimatedFloat premiumBlockedT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
private boolean premiumBlocked;
public boolean isBlocked() {
return premiumBlocked;
}
protected CheckBox2 checkBox;
public boolean useForceThreeLines;
@ -596,6 +608,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
currentDialogFolderId = 0;
}
dialogsType = type;
showPremiumBlocked(dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD);
folderId = folder;
messageId = 0;
if (update(0, false)) {
@ -1469,7 +1482,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
messageString = message.messageText;
}
if (message.topicIconDrawable[0] instanceof ForumBubbleDrawable) {
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-message.getDialogId(), MessageObject.getTopicId(message.messageOwner, true));
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-message.getDialogId(), MessageObject.getTopicId(currentAccount, message.messageOwner, true));
if (topic != null) {
((ForumBubbleDrawable) message.topicIconDrawable[0]).setColor(topic.icon_color);
}
@ -1621,7 +1634,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
}
}
}
if (message.isForwarded()) {
if (message.isForwarded() && message.needDrawForwarded()) {
drawForwardIcon = true;
SpannableStringBuilder builder = new SpannableStringBuilder(messageString);
builder.insert(0, "d ");
@ -1647,10 +1660,10 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
timeString = LocaleController.stringForMessageListDate(message.messageOwner.date);
}
if (message == null) {
if (message == null || isSavedDialog) {
drawCheck1 = false;
drawCheck2 = false;
drawClock = false;
drawClock = message != null && message.isSending() && currentDialogId == UserConfig.getInstance(currentAccount).getClientUserId();
drawCount = false;
drawMention = false;
drawReactionMention = false;
@ -1775,8 +1788,12 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else if (user != null) {
if (UserObject.isReplyUser(user)) {
nameString = LocaleController.getString("RepliesTitle", R.string.RepliesTitle);
} else if (UserObject.isAnonymous(user)) {
nameString = LocaleController.getString(R.string.AnonymousForward);
} else if (UserObject.isUserSelf(user)) {
if (useMeForMyMessages) {
if (isSavedDialog) {
nameString = LocaleController.getString(R.string.MyNotes);
} else if (useMeForMyMessages) {
nameString = LocaleController.getString("FromYou", R.string.FromYou);
} else {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD) {
@ -2918,6 +2935,12 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
if (UserObject.isReplyUser(user)) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else if (UserObject.isAnonymous(user)) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_ANONYMOUS);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else if (UserObject.isUserSelf(user) && isSavedDialog) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_MY_NOTES);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else if (UserObject.isUserSelf(user) && !useMeForMyMessages) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
@ -3050,6 +3073,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
updateLayout = true;
}
}
updatePremiumBlocked(animated);
return requestLayout;
}
@ -3568,7 +3592,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
});
}
if (lastTopicMessageUnread && topMessageTopicEndIndex != topMessageTopicStartIndex) {
if (lastTopicMessageUnread && topMessageTopicEndIndex != topMessageTopicStartIndex && (dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT || dialogsType == DialogsActivity.DIALOGS_TYPE_7 || dialogsType == DialogsActivity.DIALOGS_TYPE_8)) {
canvasButton.setColor(ColorUtils.setAlphaComponent(currentMessagePaint.getColor(), Theme.isCurrentThemeDark() ? 36 : 26));
if (!buttonCreated) {
canvasButton.rewind();
@ -4021,8 +4045,39 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
}
}
private PremiumGradient.PremiumGradientTools premiumGradient;
private Drawable lockDrawable;
public boolean drawAvatarOverlays(Canvas canvas) {
boolean needInvalidate = false;
float lockT = premiumBlockedT.set(premiumBlocked);
if (lockT > 0) {
float top = avatarImage.getCenterY() + dp(18);
float left = avatarImage.getCenterX() + dp(18);
canvas.save();
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider));
canvas.drawCircle(left, top, dp(10 + 1.33f) * lockT, Theme.dialogs_onlineCirclePaint);
if (premiumGradient == null) {
premiumGradient = new PremiumGradient.PremiumGradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, -1, -1, -1, resourcesProvider);
}
premiumGradient.gradientMatrix((int) (left - dp(10)), (int) (top - dp(10)), (int) (left + dp(10)), (int) (top + dp(10)), 0, 0);
canvas.drawCircle(left, top, dp(10) * lockT, premiumGradient.paint);
if (lockDrawable == null) {
lockDrawable = getContext().getResources().getDrawable(R.drawable.msg_mini_lock2).mutate();
lockDrawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
}
lockDrawable.setBounds(
(int) (left - lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top - lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT),
(int) (left + lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top + lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT)
);
lockDrawable.setAlpha((int) (0xFF * lockT));
lockDrawable.draw(canvas);
canvas.restore();
return false;
}
if (isDialogCell && currentDialogFolderId == 0) {
showTtl = ttlPeriod > 0 && !isOnline() && !hasCall;
if (rightFragmentOpenedProgress != 1f && (showTtl || ttlProgress > 0)) {
@ -4534,6 +4589,8 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else if (user != null) {
if (UserObject.isReplyUser(user)) {
sb.append(LocaleController.getString("RepliesTitle", R.string.RepliesTitle));
} else if (UserObject.isAnonymous(user)) {
sb.append(LocaleController.getString(R.string.AnonymousForward));
} else {
if (user.bot) {
sb.append(LocaleController.getString("Bot", R.string.Bot));
@ -4740,6 +4797,12 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
TLRPC.User fromUser = null;
TLRPC.Chat fromChat = null;
long fromId = message.getFromChatId();
if (isSavedDialog && message.messageOwner != null && message.messageOwner.fwd_from != null) {
fromId = DialogObject.getPeerDialogId(message.messageOwner.fwd_from.saved_from_id);
if (fromId == 0) {
fromId = DialogObject.getPeerDialogId(message.messageOwner.fwd_from.from_id);
}
}
if (DialogObject.isUserDialog(fromId)) {
fromUser = MessagesController.getInstance(currentAccount).getUser(fromId);
} else {
@ -4748,7 +4811,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
if (message.isOutOwner()) {
return LocaleController.getString("FromYou", R.string.FromYou);
} else if (message != null && message.messageOwner != null && message.messageOwner.from_id instanceof TLRPC.TL_peerUser && (user = MessagesController.getInstance(currentAccount).getUser(message.messageOwner.from_id.user_id)) != null) {
} else if (!isSavedDialog && message != null && message.messageOwner != null && message.messageOwner.from_id instanceof TLRPC.TL_peerUser && (user = MessagesController.getInstance(currentAccount).getUser(message.messageOwner.from_id.user_id)) != null) {
return UserObject.getFirstName(user).replace("\n", "");
} else if (message != null && message.messageOwner != null && message.messageOwner.fwd_from != null && message.messageOwner.fwd_from.from_name != null) {
return message.messageOwner.fwd_from.from_name;
@ -4786,7 +4849,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
if (MessageObject.isTopicActionMessage(message)) {
stringBuilder = formatInternal(messageFormatType, mess, messageNameString);
if (message.topicIconDrawable[0] instanceof ForumBubbleDrawable) {
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-message.getDialogId(), MessageObject.getTopicId(message.messageOwner, true));
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(-message.getDialogId(), MessageObject.getTopicId(currentAccount, message.messageOwner, true));
if (topic != null) {
((ForumBubbleDrawable) message.topicIconDrawable[0]).setColor(topic.icon_color);
}
@ -4957,7 +5020,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
return true;
}
if (delegate == null || delegate.canClickButtonInside()) {
if (lastTopicMessageUnread && canvasButton != null && buttonLayout != null && canvasButton.checkTouchEvent(event)) {
if (lastTopicMessageUnread && canvasButton != null && buttonLayout != null && dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT && canvasButton.checkTouchEvent(event)) {
return true;
}
}
@ -5193,10 +5256,10 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
topics = new ArrayList<>(topics);
Collections.sort(topics, Comparator.comparingInt(o -> -o.top_message));
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
int topMessageTopicId = 0;
long topMessageTopicId = 0;
int boldLen = 0;
if (message != null) {
topMessageTopicId = MessageObject.getTopicId(message.messageOwner, true);
topMessageTopicId = MessageObject.getTopicId(currentAccount, message.messageOwner, true);
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(chat.id, topMessageTopicId);
if (topic != null) {
CharSequence topicString = ForumUtilities.getTopicSpannedName(topic, currentMessagePaint, false);
@ -5272,4 +5335,29 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
}
return adaptiveEmojiColorFilter[n];
}
private Runnable unsubscribePremiumBlocked;
public void showPremiumBlocked(boolean show) {
if (show != (unsubscribePremiumBlocked != null)) {
if (!show && unsubscribePremiumBlocked != null) {
unsubscribePremiumBlocked.run();
unsubscribePremiumBlocked = null;
} else if (show) {
unsubscribePremiumBlocked = NotificationCenter.getInstance(currentAccount).listen(this, NotificationCenter.userIsPremiumBlockedUpadted, args -> {
updatePremiumBlocked(true);
});
}
}
}
private void updatePremiumBlocked(boolean animated) {
final boolean wasPremiumBlocked = premiumBlocked;
premiumBlocked = (unsubscribePremiumBlocked != null) && user != null && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(user.id);
if (wasPremiumBlocked != premiumBlocked) {
if (!animated) {
premiumBlockedT.set(premiumBlocked, true);
}
invalidate();
}
}
}

View file

@ -8,12 +8,18 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.accessibility.AccessibilityNodeInfo;
@ -33,11 +39,13 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Premium.PremiumGradient;
public class GroupCreateUserCell extends FrameLayout {
@ -71,6 +79,34 @@ public class GroupCreateUserCell extends FrameLayout {
private boolean showSelfAsSaved;
Theme.ResourcesProvider resourcesProvider;
private final AnimatedFloat premiumBlockedT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
private boolean premiumBlocked;
private boolean showPremiumBlocked;
public boolean isBlocked() {
return premiumBlocked;
}
public GroupCreateUserCell showPremiumBlocked() {
if (showPremiumBlocked) return this;
showPremiumBlocked = true;
NotificationCenter.getInstance(currentAccount).listen(this, NotificationCenter.userIsPremiumBlockedUpadted, args -> {
updatePremiumBlocked(true);
});
return this;
}
private void updatePremiumBlocked(boolean animated) {
final boolean wasPremiumBlocked = premiumBlocked;
premiumBlocked = showPremiumBlocked && currentObject instanceof TLRPC.User && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(((TLRPC.User) currentObject).id);
if (wasPremiumBlocked != premiumBlocked) {
if (!animated) {
premiumBlockedT.set(premiumBlocked, true);
}
invalidate();
}
}
public GroupCreateUserCell(Context context, int checkBoxType, int pad, boolean selfAsSaved) {
this(context, checkBoxType, pad, selfAsSaved, false, null);
}
@ -414,19 +450,26 @@ public class GroupCreateUserCell extends FrameLayout {
}
}
avatarImageView.setRoundRadius(currentChat != null && currentChat.forum ? AndroidUtilities.dp(14) : AndroidUtilities.dp(24));
if (currentStatus != null) {
statusTextView.setText(currentStatus, true);
statusTextView.setTag(Theme.key_windowBackgroundWhiteGrayText);
statusTextView.setTextColor(Theme.getColor(forceDarkTheme ? Theme.key_voipgroup_lastSeenText : Theme.key_windowBackgroundWhiteGrayText, resourcesProvider));
}
updatePremiumBlocked(false);
}
private PremiumGradient.PremiumGradientTools premiumGradient;
private Drawable lockDrawable;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (checkBoxType == 2 && (isChecked || checkProgress > 0.0f)) {
float lockT = premiumBlockedT.set(premiumBlocked);
if (lockT > 0) {
} else if (checkBoxType == 2 && (isChecked || checkProgress > 0.0f)) {
paint.setColor(Theme.getColor(Theme.key_checkboxSquareBackground, resourcesProvider));
float cx = avatarImageView.getLeft() + avatarImageView.getMeasuredWidth() / 2;
float cy = avatarImageView.getTop() + avatarImageView.getMeasuredHeight() / 2;
@ -444,6 +487,39 @@ public class GroupCreateUserCell extends FrameLayout {
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
float lockT = premiumBlockedT.set(premiumBlocked);
if (lockT > 0) {
float top = avatarImageView.getY() + avatarImageView.getHeight() / 2f + dp(18);
float left = avatarImageView.getX() + avatarImageView.getWidth() / 2f + dp(18);
canvas.save();
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider));
canvas.drawCircle(left, top, dp(10 + 1.33f) * lockT, Theme.dialogs_onlineCirclePaint);
if (premiumGradient == null) {
premiumGradient = new PremiumGradient.PremiumGradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, -1, -1, -1, resourcesProvider);
}
premiumGradient.gradientMatrix((int) (left - dp(10)), (int) (top - dp(10)), (int) (left + dp(10)), (int) (top + dp(10)), 0, 0);
canvas.drawCircle(left, top, dp(10) * lockT, premiumGradient.paint);
if (lockDrawable == null) {
lockDrawable = getContext().getResources().getDrawable(R.drawable.msg_mini_lock2).mutate();
lockDrawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
}
lockDrawable.setBounds(
(int) (left - lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top - lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT),
(int) (left + lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top + lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT)
);
lockDrawable.setAlpha((int) (0xFF * lockT));
lockDrawable.draw(canvas);
canvas.restore();
}
}
@Override
public boolean hasOverlappingRendering() {
return false;

View file

@ -8,9 +8,15 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
@ -23,16 +29,20 @@ import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CounterView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Premium.PremiumGradient;
public class HintDialogCell extends FrameLayout {
@ -54,6 +64,14 @@ public class HintDialogCell extends FrameLayout {
CheckBox2 checkBox;
private final boolean drawCheckbox;
private final AnimatedFloat premiumBlockedT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
private boolean showPremiumBlocked;
private boolean premiumBlocked;
public boolean isBlocked() {
return premiumBlocked;
}
public HintDialogCell(Context context, boolean drawCheckbox, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.drawCheckbox = drawCheckbox;
@ -100,6 +118,25 @@ public class HintDialogCell extends FrameLayout {
}
}
public void showPremiumBlocked() {
if (showPremiumBlocked) return;
showPremiumBlocked = true;
NotificationCenter.getInstance(currentAccount).listen(this, NotificationCenter.userIsPremiumBlockedUpadted, args -> {
updatePremiumBlocked(true);
});
}
private void updatePremiumBlocked(boolean animated) {
final boolean wasPremiumBlocked =premiumBlocked;
premiumBlocked = showPremiumBlocked && currentUser != null && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(currentUser.id);
if (wasPremiumBlocked != premiumBlocked) {
if (!animated) {
premiumBlockedT.set(premiumBlocked, true);
}
invalidate();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY));
@ -138,6 +175,7 @@ public class HintDialogCell extends FrameLayout {
avatarDrawable.setInfo(currentAccount, chat);
currentUser = null;
}
updatePremiumBlocked(true);
}
public void setColors(int textColorKey, int backgroundColorKey) {
@ -176,6 +214,7 @@ public class HintDialogCell extends FrameLayout {
currentUser = null;
imageView.setForUserOrChat(chat, avatarDrawable);
}
updatePremiumBlocked(false);
if (counter) {
update(0);
}
@ -183,11 +222,14 @@ public class HintDialogCell extends FrameLayout {
private int backgroundColorKey = Theme.key_windowBackgroundWhite;
private PremiumGradient.PremiumGradientTools premiumGradient;
private Drawable lockDrawable;
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
if (child == imageView) {
boolean showOnline = currentUser != null && !currentUser.bot && (currentUser.status != null && currentUser.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(currentUser.id));
boolean showOnline = !premiumBlocked && currentUser != null && !currentUser.bot && (currentUser.status != null && currentUser.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(currentUser.id));
if (!wasDraw) {
showOnlineProgress = showOnline ? 1f : 0f;
}
@ -204,7 +246,34 @@ public class HintDialogCell extends FrameLayout {
}
invalidate();
}
if (showOnlineProgress != 0) {
final float lockT = premiumBlockedT.set(premiumBlocked);
if (lockT > 0) {
float top = child.getY() + child.getHeight() / 2f + dp(18);
float left = child.getX() + child.getWidth() / 2f + dp(18);
canvas.save();
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(backgroundColorKey, resourcesProvider));
canvas.drawCircle(left, top, dp(10 + 1.33f) * lockT, Theme.dialogs_onlineCirclePaint);
if (premiumGradient == null) {
premiumGradient = new PremiumGradient.PremiumGradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, -1, -1, -1, resourcesProvider);
}
premiumGradient.gradientMatrix((int) (left - dp(10)), (int) (top - dp(10)), (int) (left + dp(10)), (int) (top + dp(10)), 0, 0);
canvas.drawCircle(left, top, dp(10) * lockT, premiumGradient.paint);
if (lockDrawable == null) {
lockDrawable = getContext().getResources().getDrawable(R.drawable.msg_mini_lock2).mutate();
lockDrawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
}
lockDrawable.setBounds(
(int) (left - lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top - lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT),
(int) (left + lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top + lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT)
);
lockDrawable.setAlpha((int) (0xFF * lockT));
lockDrawable.draw(canvas);
canvas.restore();
} else if (showOnlineProgress != 0) {
int top = AndroidUtilities.dp(53);
int left = AndroidUtilities.dp(59);
canvas.save();

View file

@ -8,9 +8,14 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.Layout;
@ -40,10 +45,12 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.CanvasButton;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.NotificationsSettingsActivity;
@ -101,6 +108,10 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
private boolean drawCheck;
private boolean drawPremium;
private final AnimatedFloat premiumBlockedT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
private boolean showPremiumBlocked;
private boolean premiumBlocked;
private int statusLeft;
private StaticLayout statusLayout;
private AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable statusDrawable;
@ -132,6 +143,11 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
statusDrawable.setCallback(this);
}
public ProfileSearchCell showPremiumBlock(boolean show) {
showPremiumBlocked = show;
return this;
}
private boolean customPaints;
private TextPaint namePaint, statusPaint;
public ProfileSearchCell useCustomPaints() {
@ -150,14 +166,17 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
user = (TLRPC.User) object;
chat = null;
contact = null;
premiumBlocked = showPremiumBlocked && user != null && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(user.id);
} else if (object instanceof TLRPC.Chat) {
chat = (TLRPC.Chat) object;
user = null;
contact = null;
premiumBlocked = false;
} else if (object instanceof ContactsController.Contact) {
contact = (ContactsController.Contact) object;
chat = null;
user = null;
premiumBlocked = showPremiumBlocked && contact != null && contact.user != null && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(contact.user.id);
}
encryptedChat = ec;
subLabel = s;
@ -235,6 +254,9 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
super.onDetachedFromWindow();
avatarImage.onDetachedFromWindow();
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
if (showPremiumBlocked) {
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.userIsPremiumBlockedUpadted);
}
statusDrawable.detach();
}
@ -243,6 +265,9 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
super.onAttachedToWindow();
avatarImage.onAttachedToWindow();
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
if (showPremiumBlocked) {
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.userIsPremiumBlockedUpadted);
}
statusDrawable.attach();
}
@ -250,6 +275,12 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.emojiLoaded) {
invalidate();
} else if (id == NotificationCenter.userIsPremiumBlockedUpadted) {
final boolean wasPremiumBlocked = premiumBlocked;
premiumBlocked = showPremiumBlocked && (user != null && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(user.id) || contact != null && contact.user != null && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(contact.user.id));
if (premiumBlocked != wasPremiumBlocked) {
invalidate();
}
}
}
@ -709,6 +740,9 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
postInvalidate();
}
private PremiumGradient.PremiumGradientTools premiumGradient;
private Drawable lockDrawable;
@Override
protected void onDraw(Canvas canvas) {
if (user == null && chat == null && encryptedChat == null && contact == null) {
@ -786,6 +820,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
actionLayout.draw(canvas);
canvas.restore();
}
if (user != null) {
StoriesUtilities.drawAvatarWithStory(user.id, canvas, avatarImage, avatarStoryParams);
} else if (chat != null) {
@ -794,6 +829,38 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
avatarImage.setImageCoords(avatarStoryParams.originalAvatarRect);
avatarImage.draw(canvas);
}
final float lockT = premiumBlockedT.set(premiumBlocked);
if (lockT > 0) {
float top = avatarImage.getCenterY() + dp(14);
float left = avatarImage.getCenterX() + dp(16);
canvas.save();
Theme.dialogs_onlineCirclePaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider));
canvas.drawCircle(left, top, dp(10 + 1.33f) * lockT, Theme.dialogs_onlineCirclePaint);
if (premiumGradient == null) {
premiumGradient = new PremiumGradient.PremiumGradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, -1, -1, -1, resourcesProvider);
}
premiumGradient.gradientMatrix((int) (left - dp(10)), (int) (top - dp(10)), (int) (left + dp(10)), (int) (top + dp(10)), 0, 0);
canvas.drawCircle(left, top, dp(10) * lockT, premiumGradient.paint);
if (lockDrawable == null) {
lockDrawable = getContext().getResources().getDrawable(R.drawable.msg_mini_lock2).mutate();
lockDrawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
}
lockDrawable.setBounds(
(int) (left - lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top - lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT),
(int) (left + lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top + lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT)
);
lockDrawable.setAlpha((int) (0xFF * lockT));
lockDrawable.draw(canvas);
canvas.restore();
}
}
public boolean isBlocked() {
return premiumBlocked;
}
@Override

View file

@ -12,6 +12,7 @@ import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
@ -75,6 +76,10 @@ public class RadioCell extends FrameLayout {
addView(radioButton, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP, (LocaleController.isRTL ? padding + 1 : 0), 14, (LocaleController.isRTL ? 0 : padding + 1), 0));
}
public void setRadioIcon(Drawable icon) {
radioButton.setIcon(icon);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(50) + (needDivider ? 1 : 0));

View file

@ -10,6 +10,7 @@ package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.app.Notification;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@ -51,14 +52,17 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.RLottieDrawable;
public class ShareDialogCell extends FrameLayout {
public class ShareDialogCell extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
private final BackupImageView imageView;
private final TextView nameTextView;
@ -88,6 +92,13 @@ public class ShareDialogCell extends FrameLayout {
public static final int TYPE_CALL = 1;
public static final int TYPE_CREATE = 2;
private final AnimatedFloat premiumBlockedT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
private boolean premiumBlocked;
public boolean isBlocked() {
return premiumBlocked;
}
public BackupImageView getImageView() {
return imageView;
}
@ -115,7 +126,7 @@ public class ShareDialogCell extends FrameLayout {
}
};
NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextColor(getThemedColor(type == TYPE_CALL ? Theme.key_voipgroup_nameText : Theme.key_dialogTextBlack));
nameTextView.setTextColor(getThemedColor(premiumBlocked ? Theme.key_windowBackgroundWhiteGrayText5 : currentType == TYPE_CALL ? Theme.key_voipgroup_nameText : Theme.key_dialogTextBlack));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
nameTextView.setMaxLines(2);
nameTextView.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
@ -146,6 +157,30 @@ public class ShareDialogCell extends FrameLayout {
setBackground(Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_listSelector, resourcesProvider), dp(2), dp(2)));
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.userIsPremiumBlockedUpadted);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.userIsPremiumBlockedUpadted);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.userIsPremiumBlockedUpadted) {
final boolean wasPremiumBlocked = premiumBlocked;
premiumBlocked = user != null && MessagesController.getInstance(currentAccount).isUserPremiumBlocked(user.id);
nameTextView.setTextColor(getThemedColor(premiumBlocked ? Theme.key_windowBackgroundWhiteGrayText5 : currentType == TYPE_CALL ? Theme.key_voipgroup_nameText : Theme.key_dialogTextBlack));
if (premiumBlocked != wasPremiumBlocked) {
invalidate();
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dp(currentType == TYPE_CREATE ? 95 : 103), MeasureSpec.EXACTLY));
@ -164,6 +199,10 @@ public class ShareDialogCell extends FrameLayout {
imageView.setImage(null, null, repostStoryDrawable, null);
} else if (DialogObject.isUserDialog(uid)) {
user = MessagesController.getInstance(currentAccount).getUser(uid);
premiumBlocked = MessagesController.getInstance(currentAccount).isUserPremiumBlocked(uid);
nameTextView.setTextColor(getThemedColor(premiumBlocked ? Theme.key_windowBackgroundWhiteGrayText5 : currentType == TYPE_CALL ? Theme.key_voipgroup_nameText : Theme.key_dialogTextBlack));
premiumBlockedT.set(premiumBlocked, true);
invalidate();
avatarDrawable.setInfo(currentAccount, user);
if (currentType != TYPE_CREATE && UserObject.isReplyUser(user)) {
nameTextView.setText(LocaleController.getString("RepliesTitle", R.string.RepliesTitle));
@ -186,6 +225,8 @@ public class ShareDialogCell extends FrameLayout {
imageView.setRoundRadius(dp(28));
} else {
user = null;
premiumBlocked = false;
premiumBlockedT.set(0, true);
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-uid);
if (name != null) {
nameTextView.setText(name);
@ -263,6 +304,9 @@ public class ShareDialogCell extends FrameLayout {
}
}
private PremiumGradient.PremiumGradientTools premiumGradient;
private Drawable lockDrawable;
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
@ -275,31 +319,59 @@ public class ShareDialogCell extends FrameLayout {
}
lastUpdateTime = newTime;
boolean isOnline = !user.self && !user.bot && (user.status != null && user.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(user.id));
if (isOnline || onlineProgress != 0) {
int top = imageView.getBottom() - dp(6);
int left = imageView.getRight() - dp(10);
final float lockT = premiumBlockedT.set(premiumBlocked);
if (lockT > 0) {
int top = imageView.getBottom() - dp(9);
int left = imageView.getRight() - dp(9.33f);
canvas.save();
Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(currentType == TYPE_CALL ? Theme.key_voipgroup_inviteMembersBackground : Theme.key_windowBackgroundWhite));
canvas.drawCircle(left, top, dp(7) * onlineProgress, Theme.dialogs_onlineCirclePaint);
Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(Theme.key_chats_onlineCircle));
canvas.drawCircle(left, top, dp(5) * onlineProgress, Theme.dialogs_onlineCirclePaint);
if (isOnline) {
if (onlineProgress < 1.0f) {
onlineProgress += dt / 150.0f;
if (onlineProgress > 1.0f) {
onlineProgress = 1.0f;
canvas.drawCircle(left, top, dp(12) * lockT, Theme.dialogs_onlineCirclePaint);
if (premiumGradient == null) {
premiumGradient = new PremiumGradient.PremiumGradientTools(Theme.key_premiumGradient1, Theme.key_premiumGradient2, -1, -1, -1, resourcesProvider);
}
premiumGradient.gradientMatrix(left - dp(10), top - dp(10), left + dp(10), top + dp(10), 0, 0);
canvas.drawCircle(left, top, dp(10) * lockT, premiumGradient.paint);
if (lockDrawable == null) {
lockDrawable = getContext().getResources().getDrawable(R.drawable.msg_mini_lock2).mutate();
lockDrawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
}
lockDrawable.setBounds(
(int) (left - lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top - lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT),
(int) (left + lockDrawable.getIntrinsicWidth() / 2f * .875f * lockT),
(int) (top + lockDrawable.getIntrinsicHeight() / 2f * .875f * lockT)
);
lockDrawable.setAlpha((int) (0xFF * lockT));
lockDrawable.draw(canvas);
canvas.restore();
} else {
boolean isOnline = !premiumBlocked && !user.self && !user.bot && (user.status != null && user.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(user.id));
if (isOnline || onlineProgress != 0) {
int top = imageView.getBottom() - dp(6);
int left = imageView.getRight() - dp(10);
Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(currentType == TYPE_CALL ? Theme.key_voipgroup_inviteMembersBackground : Theme.key_windowBackgroundWhite));
canvas.drawCircle(left, top, dp(7) * onlineProgress, Theme.dialogs_onlineCirclePaint);
Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(Theme.key_chats_onlineCircle));
canvas.drawCircle(left, top, dp(5) * onlineProgress, Theme.dialogs_onlineCirclePaint);
if (isOnline) {
if (onlineProgress < 1.0f) {
onlineProgress += dt / 150.0f;
if (onlineProgress > 1.0f) {
onlineProgress = 1.0f;
}
imageView.invalidate();
invalidate();
}
imageView.invalidate();
invalidate();
}
} else {
if (onlineProgress > 0.0f) {
onlineProgress -= dt / 150.0f;
if (onlineProgress < 0.0f) {
onlineProgress = 0.0f;
} else {
if (onlineProgress > 0.0f) {
onlineProgress -= dt / 150.0f;
if (onlineProgress < 0.0f) {
onlineProgress = 0.0f;
}
imageView.invalidate();
invalidate();
}
imageView.invalidate();
invalidate();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
package org.telegram.ui;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import com.google.android.exoplayer2.util.Log;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.DrawerLayoutContainer;
import org.telegram.ui.ActionBar.INavigationLayout;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.BackButtonMenu;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RecyclerListView;
import java.util.List;
public class ChatActivityContainer extends FrameLayout {
public final ChatActivity chatActivity;
private final INavigationLayout parentLayout;
private View fragmentView;
public ChatActivityContainer(Context context, INavigationLayout parentLayout, Bundle args) {
super(context);
this.parentLayout = parentLayout;
chatActivity = new ChatActivity(args);
chatActivity.isInsideContainer = true;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (!chatActivity.onFragmentCreate()) {
return;
}
fragmentView = chatActivity.fragmentView;
chatActivity.setParentLayout(parentLayout);
if (fragmentView == null) {
fragmentView = chatActivity.createView(getContext());
} else {
ViewGroup parent = (ViewGroup) fragmentView.getParent();
if (parent != null) {
chatActivity.onRemoveFromParent();
parent.removeView(fragmentView);
}
}
addView(fragmentView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
if (isActive) {
chatActivity.onResume();
}
}
private boolean isActive = true;
public void onPause() {
isActive = false;
if (fragmentView != null) {
chatActivity.onPause();
}
}
public void onResume() {
isActive = true;
if (fragmentView != null) {
chatActivity.onResume();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
}

View file

@ -318,8 +318,13 @@ public class CodeNumberField extends EditTextBoldCursor {
if (clipboard == null) {
return;
}
clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
// ClipDescription clipDescription = clipboard.getPrimaryClipDescription();
// clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
ClipData clipData = clipboard.getPrimaryClip();
if (clipData == null) {
return;
}
ClipData.Item item = clipData.getItemAt(0);
int i = -1;
String text = item.getText().toString();
try {

View file

@ -240,7 +240,24 @@ public class AlertsCreator {
if (error == null || error.code == 406 || error.text == null) {
return null;
}
if (request instanceof TLRPC.TL_messages_initHistoryImport || request instanceof TLRPC.TL_messages_checkHistoryImportPeer || request instanceof TLRPC.TL_messages_checkHistoryImport || request instanceof TLRPC.TL_messages_startHistoryImport) {
if (request instanceof TLRPC.TL_messages_sendMessage && error.text.contains("PRIVACY_PREMIUM_REQUIRED")) {
TLRPC.TL_messages_sendMessage req = (TLRPC.TL_messages_sendMessage) request;
long dialogId = DialogObject.getPeerDialogId(req.peer);
String username = "";
if (dialogId >= 0) {
username = UserObject.getFirstName(MessagesController.getInstance(currentAccount).getUser(dialogId));
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
if (chat != null) {
username = chat.title;
}
}
if (fragment == null) {
fragment = LaunchActivity.getLastFragment();
}
showSimpleAlert(fragment, LocaleController.getString(R.string.MessagePremiumErrorTitle), LocaleController.formatString(R.string.MessagePremiumErrorMessage, username));
MessagesController.getInstance(currentAccount).invalidateUserPremiumBlocked(dialogId, 0);
} else if (request instanceof TLRPC.TL_messages_initHistoryImport || request instanceof TLRPC.TL_messages_checkHistoryImportPeer || request instanceof TLRPC.TL_messages_checkHistoryImport || request instanceof TLRPC.TL_messages_startHistoryImport) {
TLRPC.InputPeer peer;
if (request instanceof TLRPC.TL_messages_initHistoryImport) {
peer = ((TLRPC.TL_messages_initHistoryImport) request).peer;
@ -4094,7 +4111,7 @@ public class AlertsCreator {
return builder;
}
public static BottomSheet createMuteAlert(BaseFragment fragment, final long dialog_id, int topicId, Theme.ResourcesProvider resourcesProvider) {
public static BottomSheet createMuteAlert(BaseFragment fragment, final long dialog_id, long topicId, Theme.ResourcesProvider resourcesProvider) {
if (fragment == null || fragment.getParentActivity() == null) {
return null;
}
@ -4615,7 +4632,7 @@ public class AlertsCreator {
return createColorSelectDialog(parentActivity, dialog_id, topicId, globalType, onSelect, null);
}
public static Dialog createColorSelectDialog(Activity parentActivity, final long dialog_id, final int topicId, final int globalType, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
public static Dialog createColorSelectDialog(Activity parentActivity, final long dialog_id, final long topicId, final int globalType, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
int currentColor;
SharedPreferences preferences = MessagesController.getNotificationsSettings(UserConfig.selectedAccount);
String key = NotificationsController.getSharedPrefKey(dialog_id, topicId);
@ -4725,11 +4742,11 @@ public class AlertsCreator {
return builder.create();
}
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, int topicId, final boolean globalGroup, final boolean globalAll, final Runnable onSelect) {
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, long topicId, final boolean globalGroup, final boolean globalAll, final Runnable onSelect) {
return createVibrationSelectDialog(parentActivity, dialogId, topicId, globalGroup, globalAll, onSelect, null);
}
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, int topicId, final boolean globalGroup, final boolean globalAll, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, long topicId, final boolean globalGroup, final boolean globalAll, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
String prefix;
if (dialogId != 0) {
prefix = "vibrate_" + dialogId;
@ -4739,11 +4756,11 @@ public class AlertsCreator {
return createVibrationSelectDialog(parentActivity, dialogId, topicId, prefix, onSelect, resourcesProvider);
}
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, int topicId, final String prefKeyPrefix, final Runnable onSelect) {
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, long topicId, final String prefKeyPrefix, final Runnable onSelect) {
return createVibrationSelectDialog(parentActivity, dialogId, topicId, prefKeyPrefix, onSelect, null);
}
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, int topicId, final String prefKeyPrefix, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
public static Dialog createVibrationSelectDialog(Activity parentActivity, final long dialogId, long topicId, final String prefKeyPrefix, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
SharedPreferences preferences = MessagesController.getNotificationsSettings(UserConfig.selectedAccount);
final int[] selected = new int[1];
String[] descriptions;
@ -5092,7 +5109,7 @@ public class AlertsCreator {
return createPrioritySelectDialog(parentActivity, dialog_id, topicId, globalType, onSelect, null);
}
public static Dialog createPrioritySelectDialog(Activity parentActivity, final long dialog_id, int topicId, final int globalType, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
public static Dialog createPrioritySelectDialog(Activity parentActivity, final long dialog_id, long topicId, final int globalType, final Runnable onSelect, Theme.ResourcesProvider resourcesProvider) {
SharedPreferences preferences = MessagesController.getNotificationsSettings(UserConfig.selectedAccount);
final int[] selected = new int[1];
String[] descriptions;
@ -5398,7 +5415,7 @@ public class AlertsCreator {
void didPressedNewCard();
}
public static void createDeleteMessagesAlert(BaseFragment fragment, TLRPC.User user, TLRPC.Chat chat, TLRPC.EncryptedChat encryptedChat, TLRPC.ChatFull chatInfo, long mergeDialogId, MessageObject selectedMessage, SparseArray<MessageObject>[] selectedMessages, MessageObject.GroupedMessages selectedGroup, boolean scheduled, int loadParticipant, Runnable onDelete, Runnable hideDim, Theme.ResourcesProvider resourcesProvider) {
public static void createDeleteMessagesAlert(BaseFragment fragment, TLRPC.User user, TLRPC.Chat chat, TLRPC.EncryptedChat encryptedChat, TLRPC.ChatFull chatInfo, long mergeDialogId, MessageObject selectedMessage, SparseArray<MessageObject>[] selectedMessages, MessageObject.GroupedMessages selectedGroup, boolean scheduled, boolean isSavedMessages, int loadParticipant, Runnable onDelete, Runnable hideDim, Theme.ResourcesProvider resourcesProvider) {
if (fragment == null || user == null && chat == null && encryptedChat == null) {
return;
}
@ -5459,7 +5476,7 @@ public class AlertsCreator {
boolean hasNotOut = false;
int myMessagesCount = 0;
boolean canDeleteInbox = encryptedChat == null && user != null && canRevokeInbox && revokeTimeLimit == 0x7fffffff;
if (chat != null && chat.megagroup && !scheduled) {
if (chat != null && chat.megagroup && !scheduled && !isSavedMessages) {
boolean canBan = ChatObject.canBlockUsers(chat);
if (selectedMessage != null) {
if (selectedMessage.messageOwner.action == null || selectedMessage.messageOwner.action instanceof TLRPC.TL_messageActionEmpty ||
@ -5535,7 +5552,7 @@ public class AlertsCreator {
} else if (error != null && "USER_NOT_PARTICIPANT".equals(error.text)) {
loadType = 0;
}
createDeleteMessagesAlert(fragment, user, chat, encryptedChat, chatInfo, mergeDialogId, selectedMessage, selectedMessages, selectedGroup, scheduled, loadType, onDelete, hideDim, resourcesProvider);
createDeleteMessagesAlert(fragment, user, chat, encryptedChat, chatInfo, mergeDialogId, selectedMessage, selectedMessages, selectedGroup, scheduled, isSavedMessages, loadType, onDelete, hideDim, resourcesProvider);
}));
AndroidUtilities.runOnUIThread(() -> {
if (progressDialog[0] == null) {
@ -5599,7 +5616,7 @@ public class AlertsCreator {
} else {
actionUser = null;
}
} else if (!scheduled && !ChatObject.isChannel(chat) && encryptedChat == null) {
} else if (!scheduled && !isSavedMessages && !ChatObject.isChannel(chat) && encryptedChat == null) {
if (user != null && user.id != UserConfig.getInstance(currentAccount).getClientUserId() && (!user.bot || user.support) || chat != null) {
if (selectedMessage != null) {
boolean hasOutgoing = !selectedMessage.isSendError() && (
@ -5664,6 +5681,10 @@ public class AlertsCreator {
DialogInterface.OnClickListener deleteAction = (dialogInterface, i) -> {
ArrayList<Integer> ids = null;
long thisDialogId = dialogId;
if (isSavedMessages) {
thisDialogId = UserConfig.getInstance(currentAccount).getClientUserId();
}
if (selectedMessage != null) {
ids = new ArrayList<>();
ArrayList<Long> random_ids = null;
@ -5685,7 +5706,7 @@ public class AlertsCreator {
random_ids.add(selectedMessage.messageOwner.random_id);
}
}
MessagesController.getInstance(currentAccount).deleteMessages(ids, random_ids, encryptedChat, dialogId, deleteForAll[0], scheduled);
MessagesController.getInstance(currentAccount).deleteMessages(ids, random_ids, encryptedChat, thisDialogId, deleteForAll[0], scheduled);
} else {
for (int a = 1; a >= 0; a--) {
ids = new ArrayList<>();
@ -5702,7 +5723,7 @@ public class AlertsCreator {
}
}
}
MessagesController.getInstance(currentAccount).deleteMessages(ids, random_ids, encryptedChat, dialogId, deleteForAll[0], scheduled);
MessagesController.getInstance(currentAccount).deleteMessages(ids, random_ids, encryptedChat, thisDialogId, deleteForAll[0], scheduled);
selectedMessages[a].clear();
}
}
@ -5732,19 +5753,33 @@ public class AlertsCreator {
}
};
if (count == 1) {
builder.setTitle(LocaleController.getString("DeleteSingleMessagesTitle", R.string.DeleteSingleMessagesTitle));
if (isSavedMessages) {
if (count == 1) {
builder.setTitle(LocaleController.getString(R.string.UnsaveSingleMessagesTitle));
} else {
builder.setTitle(LocaleController.formatString(R.string.UnsaveMessagesTitle, LocaleController.formatPluralString("messages", count)));
}
} else {
builder.setTitle(LocaleController.formatString("DeleteMessagesTitle", R.string.DeleteMessagesTitle, LocaleController.formatPluralString("messages", count)));
if (count == 1) {
builder.setTitle(LocaleController.getString(R.string.DeleteSingleMessagesTitle));
} else {
builder.setTitle(LocaleController.formatString(R.string.DeleteMessagesTitle, LocaleController.formatPluralString("messages", count)));
}
}
if (chat != null && hasNotOut) {
if (hasDeleteForAllCheck && myMessagesCount != count) {
builder.setMessage(LocaleController.formatString("DeleteMessagesTextGroupPart", R.string.DeleteMessagesTextGroupPart, LocaleController.formatPluralString("messages", myMessagesCount)));
} else if (count == 1) {
builder.setMessage(LocaleController.getString("AreYouSureDeleteSingleMessage", R.string.AreYouSureDeleteSingleMessage));
if (isSavedMessages) {
if (count == 1) {
builder.setMessage(LocaleController.getString(R.string.AreYouSureUnsaveSingleMessage));
} else {
builder.setMessage(LocaleController.getString("AreYouSureDeleteFewMessages", R.string.AreYouSureDeleteFewMessages));
builder.setMessage(LocaleController.getString(R.string.AreYouSureUnsaveFewMessages));
}
} else if (chat != null && hasNotOut) {
if (hasDeleteForAllCheck && myMessagesCount != count) {
builder.setMessage(LocaleController.formatString(R.string.DeleteMessagesTextGroupPart, LocaleController.formatPluralString("messages", myMessagesCount)));
} else if (count == 1) {
builder.setMessage(LocaleController.getString(R.string.AreYouSureDeleteSingleMessage));
} else {
builder.setMessage(LocaleController.getString(R.string.AreYouSureDeleteFewMessages));
}
} else if (hasDeleteForAllCheck && !canDeleteInbox && myMessagesCount != count) {
if (chat != null) {
@ -5793,12 +5828,12 @@ public class AlertsCreator {
}
}
if (isActiveGiveawayAndOwner) {
if (isActiveGiveawayAndOwner && !isSavedMessages) {
builder.setTitle(LocaleController.getString("BoostingGiveawayDeleteMsgTitle", R.string.BoostingGiveawayDeleteMsgTitle));
builder.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingGiveawayDeleteMsgText", R.string.BoostingGiveawayDeleteMsgText, giveawayEndDate)));
builder.setNeutralButton(LocaleController.getString("Delete", R.string.Delete), deleteAction);
} else {
builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), deleteAction);
builder.setPositiveButton(LocaleController.getString(isSavedMessages ? R.string.Remove : R.string.Delete), deleteAction);
}
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.setOnPreDismissListener(di -> {

View file

@ -72,6 +72,7 @@ public class AnimatedEmojiDrawable extends Drawable {
public static final int CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2 = 15;
public static final int CACHE_TYPE_ALERT_PREVIEW_STATIC_WITH_THUMB = 16;
public static final int CACHE_TYPE_EMOJI_CALL = 17;
public static final int CACHE_TYPE_SAVED_REACTION = 18;
public int rawDrawIndex;
@ -625,7 +626,7 @@ public class AnimatedEmojiDrawable extends Drawable {
private void updateAutoRepeat(ImageReceiver imageReceiver) {
if (cacheType == CACHE_TYPE_EMOJI_STATUS || cacheType == CACHE_TYPE_ALERT_EMOJI_STATUS || cacheType == CACHE_TYPE_FORUM_TOPIC) {
imageReceiver.setAutoRepeatCount(2);
} else if (cacheType == CACHE_TYPE_FORUM_TOPIC_LARGE || cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW || cacheType == CACHE_TYPE_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP) {
} else if (cacheType == CACHE_TYPE_FORUM_TOPIC_LARGE || cacheType == CACHE_TYPE_SAVED_REACTION || cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW || cacheType == CACHE_TYPE_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP) {
imageReceiver.setAutoRepeatCount(1);
} else if (cacheType == CACHE_TYPE_EMOJI_CALL){
imageReceiver.setAutoRepeatCount(0);

View file

@ -483,6 +483,10 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
}
public AnimatedFileDrawable(File file, boolean createDecoder, long streamSize, int streamLoadingPriority, TLRPC.Document document, ImageLocation location, Object parentObject, long seekTo, int account, boolean preview, int w, int h, BitmapsCache.CacheOptions cacheOptions) {
this(file, createDecoder, streamSize, streamLoadingPriority, document, location, parentObject, seekTo, account, preview, w, h, cacheOptions, document != null ? 1 : 0);
}
public AnimatedFileDrawable(File file, boolean createDecoder, long streamSize, int streamLoadingPriority, TLRPC.Document document, ImageLocation location, Object parentObject, long seekTo, int account, boolean preview, int w, int h, BitmapsCache.CacheOptions cacheOptions, int cacheType) {
path = file;
PRERENDER_FRAME = SharedConfig.deviceIsAboveAverage();
streamFileSize = streamSize;
@ -494,7 +498,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
this.document = document;
getPaint().setFlags(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
if (streamSize != 0 && (document != null || location != null)) {
stream = new AnimatedFileDrawableStream(document, location, parentObject, account, preview, streamLoadingPriority);
stream = new AnimatedFileDrawableStream(document, location, parentObject, account, preview, streamLoadingPriority, cacheType);
}
if (createDecoder && !this.precache) {
nativePtr = createDecoder(file.getAbsolutePath(), metaData, currentAccount, streamFileSize, stream, preview);

View file

@ -124,6 +124,7 @@ public class AnimatedFloat {
// set() must be called inside onDraw/dispatchDraw
// the main purpose of AnimatedFloat is to interpolate between abrupt changing states
public float set(float mustBe) {
return this.set(mustBe, false);
}
@ -132,6 +133,8 @@ public class AnimatedFloat {
return this.set(mustBe ? 1 : 0, false);
}
// do set(value, true) when it's needed to skip animation
public float set(boolean mustBe, boolean force) {
return this.set(mustBe ? 1 : 0, force);
}

View file

@ -46,7 +46,9 @@ public class AvatarDrawable extends Drawable {
private TextPaint namePaint;
private boolean hasGradient;
private boolean hasAdvancedGradient;
private int color, color2;
private GradientTools advancedGradient;
private boolean needApplyColorAccent;
private StaticLayout textLayout;
private float textWidth;
@ -75,7 +77,6 @@ public class AvatarDrawable extends Drawable {
public static final int AVATAR_TYPE_ARCHIVED = 2;
public static final int AVATAR_TYPE_SHARES = 3;
public static final int AVATAR_TYPE_REPLIES = 12;
public static final int AVATAR_TYPE_STORY = 20;
public static final int AVATAR_TYPE_FILTER_CONTACTS = 4;
public static final int AVATAR_TYPE_FILTER_NON_CONTACTS = 5;
@ -92,6 +93,9 @@ public class AvatarDrawable extends Drawable {
public static final int AVATAR_TYPE_COUNTRY = 17;
public static final int AVATAR_TYPE_UNCLAIMED = 18;
public static final int AVATAR_TYPE_TO_BE_DISTRIBUTED = 19;
public static final int AVATAR_TYPE_STORY = 20;
public static final int AVATAR_TYPE_ANONYMOUS = 21;
public static final int AVATAR_TYPE_MY_NOTES = 22;
private int alpha = 255;
private Theme.ResourcesProvider resourcesProvider;
@ -231,11 +235,11 @@ public class AvatarDrawable extends Drawable {
public void setAvatarType(int value) {
avatarType = value;
rotate45Background = false;
hasAdvancedGradient = false;
hasGradient = false;
if (avatarType == AVATAR_TYPE_REGISTER) {
hasGradient = false;
color = color2 = Theme.getColor(Theme.key_chats_actionBackground);
} else if (avatarType == AVATAR_TYPE_ARCHIVED) {
hasGradient = false;
color = color2 = getThemedColor(Theme.key_avatar_backgroundArchivedHidden);
} else if (avatarType == AVATAR_TYPE_REPLIES || avatarType == AVATAR_TYPE_SAVED || avatarType == AVATAR_TYPE_OTHER_CHATS) {
hasGradient = true;
@ -282,12 +286,24 @@ public class AvatarDrawable extends Drawable {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(5)]);
} else if (avatarType == AVATAR_TYPE_ANONYMOUS) {
hasAdvancedGradient = true;
if (advancedGradient == null) {
advancedGradient = new GradientTools();
}
advancedGradient.setColors(0xFF837CFF, 0xFFB063FF, 0xFFFF72A9, 0xFFE269FF);
} else if (avatarType == AVATAR_TYPE_MY_NOTES) {
hasAdvancedGradient = true;
if (advancedGradient == null) {
advancedGradient = new GradientTools();
}
advancedGradient.setColors(0xFF4D8DFF, 0xFF2BBFFF, 0xFF20E2CD, 0xFF0EE1F1);
} else {
hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(4)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(4)]);
}
needApplyColorAccent = avatarType != AVATAR_TYPE_ARCHIVED && avatarType != AVATAR_TYPE_SAVED && avatarType != AVATAR_TYPE_STORY && avatarType != AVATAR_TYPE_REPLIES && avatarType != AVATAR_TYPE_OTHER_CHATS;
needApplyColorAccent = avatarType != AVATAR_TYPE_ARCHIVED && avatarType != AVATAR_TYPE_SAVED && avatarType != AVATAR_TYPE_STORY && avatarType != AVATAR_TYPE_ANONYMOUS && avatarType != AVATAR_TYPE_REPLIES && avatarType != AVATAR_TYPE_OTHER_CHATS;
}
public void setArchivedAvatarHiddenProgress(float progress) {
@ -318,12 +334,14 @@ public class AvatarDrawable extends Drawable {
public void setColor(int value) {
hasGradient = false;
hasAdvancedGradient = false;
color = color2 = value;
needApplyColorAccent = false;
}
public void setColor(int value, int value2) {
hasGradient = true;
hasAdvancedGradient = false;
color = value;
color2 = value2;
needApplyColorAccent = false;
@ -359,6 +377,7 @@ public class AvatarDrawable extends Drawable {
public void setInfo(long id, String firstName, String lastName, String custom, Integer customColor, MessagesController.PeerColor profileColor) {
hasGradient = true;
hasAdvancedGradient = false;
invalidateTextLayout = true;
if (profileColor != null) {
color = profileColor.getAvatarColor1();
@ -438,16 +457,20 @@ public class AvatarDrawable extends Drawable {
}
int size = bounds.width();
namePaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_avatar_text), alpha));
if (hasGradient) {
Paint backgroundPaint = Theme.avatar_backgroundPaint;
if (hasAdvancedGradient && advancedGradient != null) {
advancedGradient.setBounds(bounds.left, bounds.top, bounds.left + size, bounds.top + size);
backgroundPaint = advancedGradient.paint;
} else if (hasGradient) {
int color = ColorUtils.setAlphaComponent(getColor(), alpha);
int color2 = ColorUtils.setAlphaComponent(getColor2(), alpha);
if (gradient == null || gradientBottom != bounds.height() || gradientColor1 != color || gradientColor2 != color2) {
gradient = new LinearGradient(0, 0, 0, gradientBottom = bounds.height(), gradientColor1 = color, gradientColor2 = color2, Shader.TileMode.CLAMP);
}
Theme.avatar_backgroundPaint.setShader(gradient);
backgroundPaint.setShader(gradient);
} else {
Theme.avatar_backgroundPaint.setShader(null);
Theme.avatar_backgroundPaint.setColor(ColorUtils.setAlphaComponent(getColor(), alpha));
backgroundPaint.setShader(null);
backgroundPaint.setColor(ColorUtils.setAlphaComponent(getColor(), alpha));
}
canvas.save();
canvas.translate(bounds.left, bounds.top);
@ -459,9 +482,9 @@ public class AvatarDrawable extends Drawable {
}
if (roundRadius > 0) {
AndroidUtilities.rectTmp.set(0, 0, size, size);
canvas.drawRoundRect(AndroidUtilities.rectTmp, roundRadius, roundRadius, Theme.avatar_backgroundPaint);
canvas.drawRoundRect(AndroidUtilities.rectTmp, roundRadius, roundRadius, backgroundPaint);
} else {
canvas.drawCircle(size / 2.0f, size / 2.0f, size / 2.0f, Theme.avatar_backgroundPaint);
canvas.drawCircle(size / 2.0f, size / 2.0f, size / 2.0f, backgroundPaint);
}
if (rotate45Background) {
canvas.restore();
@ -470,8 +493,8 @@ public class AvatarDrawable extends Drawable {
if (avatarType == AVATAR_TYPE_ARCHIVED) {
if (archivedAvatarProgress != 0) {
Theme.avatar_backgroundPaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_avatar_backgroundArchived), alpha));
canvas.drawCircle(size / 2.0f, size / 2.0f, size / 2.0f * archivedAvatarProgress, Theme.avatar_backgroundPaint);
backgroundPaint.setColor(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_avatar_backgroundArchived), alpha));
canvas.drawCircle(size / 2.0f, size / 2.0f, size / 2.0f * archivedAvatarProgress, backgroundPaint);
if (Theme.dialogs_archiveAvatarDrawableRecolored) {
Theme.dialogs_archiveAvatarDrawable.beginApplyLayerColors();
Theme.dialogs_archiveAvatarDrawable.setLayerColor("Arrow1.**", Theme.getNonAnimatedColor(Theme.key_avatar_backgroundArchived));
@ -531,6 +554,10 @@ public class AvatarDrawable extends Drawable {
drawable = Theme.avatarDrawables[16];
} else if (avatarType == AVATAR_TYPE_STORY) {
drawable = Theme.avatarDrawables[17];
} else if (avatarType == AVATAR_TYPE_ANONYMOUS) {
drawable = Theme.avatarDrawables[18];
} else if (avatarType == AVATAR_TYPE_MY_NOTES) {
drawable = Theme.avatarDrawables[19];
} else {
drawable = Theme.avatarDrawables[9];
}

View file

@ -209,6 +209,9 @@ public class AvatarsDrawable {
}
public void animateFromState(AvatarsDrawable avatarsDrawable, int currentAccount, boolean createAnimator) {
if (avatarsDrawable == null) {
return;
}
if (avatarsDrawable.transitionProgressAnimator != null) {
avatarsDrawable.transitionProgressAnimator.cancel();
if (transitionInProgress) {

View file

@ -48,7 +48,7 @@ public class BackButtonMenu {
int filterId;
}
public static ActionBarPopupWindow show(BaseFragment thisFragment, View backButton, long currentDialogId, int topicId, Theme.ResourcesProvider resourcesProvider) {
public static ActionBarPopupWindow show(BaseFragment thisFragment, View backButton, long currentDialogId, long topicId, Theme.ResourcesProvider resourcesProvider) {
if (thisFragment == null) {
return null;
}
@ -219,7 +219,7 @@ public class BackButtonMenu {
return scrimPopupWindow;
}
private static ArrayList<PulledDialog> getStackedHistoryForTopic(BaseFragment thisFragment, long currentDialogId, int topicId) {
private static ArrayList<PulledDialog> getStackedHistoryForTopic(BaseFragment thisFragment, long currentDialogId, long topicId) {
ArrayList<PulledDialog> dialogs = new ArrayList<>();
if (thisFragment.getParentLayout().getFragmentStack().size() > 1 && thisFragment.getParentLayout().getFragmentStack().get(thisFragment.getParentLayout().getFragmentStack().size() - 2) instanceof TopicsFragment) {
PulledDialog pulledDialog = new PulledDialog();

View file

@ -123,6 +123,7 @@ public class BlurBehindDrawable {
canvas.drawBitmap(bitmap[0], 0, 0, emptyPaint);
canvas.restore();
wasDraw = true;
canvas.drawColor(0x1a000000);
}
canvas.restore();

View file

@ -43,10 +43,13 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
}
public BottomSheetWithRecyclerListView(BaseFragment fragment, boolean needFocus, boolean hasFixedSize, boolean useNested, Theme.ResourcesProvider resourcesProvider) {
super(fragment.getParentActivity(), needFocus, resourcesProvider);
this(fragment.getParentActivity(), fragment, needFocus, hasFixedSize, useNested, resourcesProvider);
}
public BottomSheetWithRecyclerListView(Context context, BaseFragment fragment, boolean needFocus, boolean hasFixedSize, boolean useNested, Theme.ResourcesProvider resourcesProvider) {
super(context, needFocus, resourcesProvider);
this.baseFragment = fragment;
this.hasFixedSize = hasFixedSize;
Context context = fragment.getParentActivity();
headerShadowDrawable = ContextCompat.getDrawable(context, R.drawable.header_shadow).mutate();
FrameLayout containerView;
if (useNested) {

View file

@ -32,6 +32,7 @@ import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationsController;
import org.telegram.messenger.R;
import org.telegram.messenger.SavedMessagesController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
@ -66,20 +67,16 @@ public final class BulletinFactory {
public static BulletinFactory global() {
BaseFragment baseFragment = LaunchActivity.getLastFragment();
if (baseFragment == null) {
return null;
return BulletinFactory.of(Bulletin.BulletinWindow.make(ApplicationLoader.applicationContext), null);
}
return BulletinFactory.of(baseFragment);
}
public static void showForError(TLRPC.TL_error error) {
BulletinFactory bulletinFactory = BulletinFactory.global();
if (bulletinFactory == null) {
return;
}
public void showForError(TLRPC.TL_error error) {
if (BuildVars.DEBUG_VERSION) {
bulletinFactory.createErrorBulletin(error.code + " " + error.text).show();
createErrorBulletin(error.code + " " + error.text).show();
} else {
bulletinFactory.createErrorBulletin(LocaleController.getString("UnknownError", R.string.UnknownError)).show();
createErrorBulletin(LocaleController.getString("UnknownError", R.string.UnknownError)).show();
}
}
@ -1039,9 +1036,9 @@ public final class BulletinFactory {
if (dialogsCount <= 1) {
if (did == UserConfig.getInstance(UserConfig.selectedAccount).clientUserId) {
if (messagesCount <= 1) {
text = AndroidUtilities.replaceTags(LocaleController.getString("FwdMessageToSavedMessages", R.string.FwdMessageToSavedMessages));
text = AndroidUtilities.replaceSingleTag(LocaleController.getString(R.string.FwdMessageToSavedMessages), SavedMessagesController::openSavedMessages);
} else {
text = AndroidUtilities.replaceTags(LocaleController.getString("FwdMessagesToSavedMessages", R.string.FwdMessagesToSavedMessages));
text = AndroidUtilities.replaceSingleTag(LocaleController.getString(R.string.FwdMessagesToSavedMessages), SavedMessagesController::openSavedMessages);
}
layout.setAnimation(R.raw.saved_messages, 30, 30);
} else {

View file

@ -37,7 +37,7 @@ public interface ChatActivityInterface {
return 0;
}
default int getTopicId() {
default long getTopicId() {
return 0;
}

View file

@ -3884,7 +3884,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
actionBarAnimation = null;
}
boolean needsSearchItem = searchItem != null && (avatarSearch || currentAttachLayout == photoLayout && !menuShowed && baseFragment instanceof ChatActivity && ((ChatActivity) baseFragment).allowSendGifs() && ((ChatActivity) baseFragment).allowSendPhotos());
boolean needsSearchItem = searchItem != null && (avatarSearch || false && currentAttachLayout == photoLayout && !menuShowed && baseFragment instanceof ChatActivity && ((ChatActivity) baseFragment).allowSendGifs() && ((ChatActivity) baseFragment).allowSendPhotos());
boolean needMoreItem = !isPhotoPicker && (avatarPicker != 0 || !menuShowed) && currentAttachLayout == photoLayout && (photosEnabled || videosEnabled);
if (currentAttachLayout == restrictedLayout) {
needsSearchItem = false;
@ -4045,7 +4045,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
menuAnimator.cancel();
menuAnimator = null;
}
boolean needsSearchItem = searchItem != null && actionBar.getTag() != null && baseFragment instanceof ChatActivity && ((ChatActivity) baseFragment).allowSendGifs();
boolean needsSearchItem = avatarPicker != 0 && searchItem != null && actionBar.getTag() != null && baseFragment instanceof ChatActivity && ((ChatActivity) baseFragment).allowSendGifs();
if (menuShowed) {
if (avatarPicker == 0) {
selectedMenuItem.setVisibility(View.VISIBLE);

View file

@ -20,6 +20,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.MotionEvent;
@ -67,6 +68,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
private SimpleTextView titleTextView;
private AtomicReference<SimpleTextView> titleTextLargerCopyView = new AtomicReference<>();
private SimpleTextView subtitleTextView;
private AnimatedTextView animatedSubtitleTextView;
private AtomicReference<SimpleTextView> subtitleTextLargerCopyView = new AtomicReference<>();
private ImageView timeItem;
private TimerDrawable timerDrawable;
@ -104,8 +106,14 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
private AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable emojiStatusDrawable;
protected boolean useAnimatedSubtitle() {
return false;
}
public void hideSubtitle() {
subtitleTextView.setVisibility(View.GONE);
if (getSubtitleTextView() != null) {
getSubtitleTextView().setVisibility(View.GONE);
}
}
public void setStoriesForceState(Integer storiesForceState) {
@ -241,14 +249,27 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
titleTextView.setPadding(0, AndroidUtilities.dp(6), 0, AndroidUtilities.dp(12));
addView(titleTextView);
subtitleTextView = new SimpleTextConnectedView(context, subtitleTextLargerCopyView);
subtitleTextView.setEllipsizeByGradient(true);
subtitleTextView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubtitle));
subtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle);
subtitleTextView.setTextSize(14);
subtitleTextView.setGravity(Gravity.LEFT);
subtitleTextView.setPadding(0, 0, AndroidUtilities.dp(10), 0);
addView(subtitleTextView);
if (useAnimatedSubtitle()) {
animatedSubtitleTextView = new AnimatedTextView(context, true, true, true);
animatedSubtitleTextView.setAnimationProperties(.3f, 0, 320, CubicBezierInterpolator.EASE_OUT_QUINT);
animatedSubtitleTextView.setEllipsizeByGradient(true);
animatedSubtitleTextView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubtitle));
animatedSubtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle);
animatedSubtitleTextView.setTextSize(AndroidUtilities.dp(14));
animatedSubtitleTextView.setGravity(Gravity.LEFT);
animatedSubtitleTextView.setPadding(0, 0, AndroidUtilities.dp(10), 0);
animatedSubtitleTextView.setTranslationY(-AndroidUtilities.dp(1));
addView(animatedSubtitleTextView);
} else {
subtitleTextView = new SimpleTextConnectedView(context, subtitleTextLargerCopyView);
subtitleTextView.setEllipsizeByGradient(true);
subtitleTextView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubtitle));
subtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle);
subtitleTextView.setTextSize(14);
subtitleTextView.setGravity(Gravity.LEFT);
subtitleTextView.setPadding(0, 0, AndroidUtilities.dp(10), 0);
addView(subtitleTextView);
}
if (parentFragment != null) {
timeItem = new ImageView(context);
@ -276,8 +297,8 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
}
}
if (parentFragment != null && parentFragment.getChatMode() == 0) {
if ((!parentFragment.isThreadChat() || parentFragment.isTopic) && !UserObject.isReplyUser(parentFragment.getCurrentUser())) {
if (parentFragment != null && (parentFragment.getChatMode() == 0 || parentFragment.getChatMode() == ChatActivity.MODE_SAVED)) {
if ((!parentFragment.isThreadChat() || parentFragment.isTopic) && !UserObject.isReplyUser(parentFragment.getCurrentUser()) && parentFragment.getChatMode() != ChatActivity.MODE_SAVED) {
setOnClickListener(v -> openProfile(false));
}
@ -406,7 +427,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (user != null) {
Bundle args = new Bundle();
if (UserObject.isUserSelf(user)) {
if (UserObject.isUserSelf(user) && parentFragment.getChatMode() != ChatActivity.MODE_SAVED) {
args.putLong("dialog_id", parentFragment.getDialogId());
int[] media = new int[MediaDataController.MEDIA_TYPES_COUNT];
System.arraycopy(sharedMediaPreloader.getLastMediaCount(), 0, media, 0, media.length);
@ -414,11 +435,21 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
fragment.setChatInfo(parentFragment.getCurrentChatInfo());
parentFragment.presentFragment(fragment);
} else {
args.putLong("user_id", user.id);
args.putBoolean("reportSpam", parentFragment.hasReportSpam());
if (timeItem != null) {
args.putLong("dialog_id", parentFragment.getDialogId());
if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
long dialogId = parentFragment.getSavedDialogId();
args.putBoolean("saved", true);
if (dialogId >= 0) {
args.putLong("user_id", dialogId);
} else {
args.putLong("chat_id", -dialogId);
}
} else {
args.putLong("user_id", user.id);
if (timeItem != null) {
args.putLong("dialog_id", parentFragment.getDialogId());
}
}
args.putBoolean("reportSpam", parentFragment.hasReportSpam());
args.putInt("actionBarColor", getThemedColor(Theme.key_actionBarDefault));
ProfileActivity fragment = new ProfileActivity(args, sharedMediaPreloader);
fragment.setUserInfo(parentFragment.getCurrentUserInfo());
@ -430,8 +461,10 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
} else if (chat != null) {
Bundle args = new Bundle();
args.putLong("chat_id", chat.id);
if (parentFragment.isTopic) {
args.putInt("topic_id", parentFragment.getThreadMessage().getId());
if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
args.putLong("topic_id", parentFragment.getSavedDialogId());
} else if (parentFragment.isTopic) {
args.putLong("topic_id", parentFragment.getThreadMessage().getId());
}
ProfileActivity fragment = new ProfileActivity(args, sharedMediaPreloader);
fragment.setChatInfo(parentFragment.getCurrentChatInfo());
@ -458,7 +491,11 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
int availableWidth = width - AndroidUtilities.dp((avatarImageView.getVisibility() == VISIBLE ? 54 : 0) + 16);
avatarImageView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY));
titleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(24 + 8) + titleTextView.getPaddingRight(), MeasureSpec.AT_MOST));
subtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
if (subtitleTextView != null) {
subtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
} else if (animatedSubtitleTextView != null) {
animatedSubtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
}
if (timeItem != null) {
timeItem.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(34), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(34), MeasureSpec.EXACTLY));
}
@ -511,7 +548,11 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
subtitleTextLargerCopyView.setTag(Theme.key_actionBarDefaultSubtitle);
subtitleTextLargerCopyView.setTextSize(14);
subtitleTextLargerCopyView.setGravity(Gravity.LEFT);
subtitleTextLargerCopyView.setText(subtitleTextView.getText());
if (subtitleTextView != null) {
subtitleTextLargerCopyView.setText(subtitleTextView.getText());
} else if (animatedSubtitleTextView != null) {
subtitleTextLargerCopyView.setText(animatedSubtitleTextView.getText());
}
subtitleTextLargerCopyView.animate().alpha(0).setDuration(350).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).withEndAction(() -> {
SimpleTextView subtitleTextLargerCopyView2 = this.subtitleTextLargerCopyView.get();
if (subtitleTextLargerCopyView2 != null) {
@ -534,7 +575,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
avatarImageView.layout(leftPadding, viewTop + 1, leftPadding + AndroidUtilities.dp(42), viewTop + 1 + AndroidUtilities.dp(42));
int l = leftPadding + (avatarImageView.getVisibility() == VISIBLE ? AndroidUtilities.dp( 54) : 0) + rightAvatarPadding;
SimpleTextView titleTextLargerCopyView = this.titleTextLargerCopyView.get();
if (subtitleTextView.getVisibility() != GONE) {
if (getSubtitleTextView().getVisibility() != GONE) {
titleTextView.layout(l, viewTop + AndroidUtilities.dp(1.3f) - titleTextView.getPaddingTop(), l + titleTextView.getMeasuredWidth(), viewTop + titleTextView.getTextHeight() + AndroidUtilities.dp(1.3f) - titleTextView.getPaddingTop() + titleTextView.getPaddingBottom());
if (titleTextLargerCopyView != null) {
titleTextLargerCopyView.layout(l, viewTop + AndroidUtilities.dp(1.3f), l + titleTextLargerCopyView.getMeasuredWidth(), viewTop + titleTextLargerCopyView.getTextHeight() + AndroidUtilities.dp(1.3f));
@ -548,7 +589,11 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (timeItem != null) {
timeItem.layout(leftPadding + AndroidUtilities.dp(16), viewTop + AndroidUtilities.dp(15), leftPadding + AndroidUtilities.dp(16 + 34), viewTop + AndroidUtilities.dp(15 + 34));
}
subtitleTextView.layout(l, viewTop + AndroidUtilities.dp(24), l + subtitleTextView.getMeasuredWidth(), viewTop + subtitleTextView.getTextHeight() + AndroidUtilities.dp(24));
if (subtitleTextView != null) {
subtitleTextView.layout(l, viewTop + AndroidUtilities.dp(24), l + subtitleTextView.getMeasuredWidth(), viewTop + subtitleTextView.getTextHeight() + AndroidUtilities.dp(24));
} else if (animatedSubtitleTextView != null) {
animatedSubtitleTextView.layout(l, viewTop + AndroidUtilities.dp(24), l + animatedSubtitleTextView.getMeasuredWidth(), viewTop + animatedSubtitleTextView.getTextHeight() + AndroidUtilities.dp(24));
}
SimpleTextView subtitleTextLargerCopyView = this.subtitleTextLargerCopyView.get();
if (subtitleTextLargerCopyView != null) {
subtitleTextLargerCopyView.layout(l, viewTop + AndroidUtilities.dp(24), l + subtitleTextLargerCopyView.getMeasuredWidth(), viewTop + subtitleTextLargerCopyView.getTextHeight() + AndroidUtilities.dp(24));
@ -692,7 +737,11 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
public void setSubtitle(CharSequence value) {
if (lastSubtitle == null) {
subtitleTextView.setText(value);
if (subtitleTextView != null) {
subtitleTextView.setText(value);
} else if (animatedSubtitleTextView != null) {
animatedSubtitleTextView.setText(value);
}
} else {
lastSubtitle = value;
}
@ -706,8 +755,18 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
return titleTextView;
}
public SimpleTextView getSubtitleTextView() {
return subtitleTextView;
public View getSubtitleTextView() {
if (subtitleTextView != null) {
return subtitleTextView;
}
if (animatedSubtitleTextView != null) {
return animatedSubtitleTextView;
}
return null;
}
public TextPaint getSubtitlePaint() {
return subtitleTextView != null ? subtitleTextView.getTextPaint() : animatedSubtitleTextView.getPaint();
}
public void onDestroy() {
@ -717,6 +776,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
}
private void setTypingAnimation(boolean start) {
if (subtitleTextView == null) return;
if (start) {
try {
int type = MessagesController.getInstance(currentAccount).getPrintingStringType(parentFragment.getDialogId(), parentFragment.getThreadId());
@ -759,9 +819,9 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
return;
}
TLRPC.User user = parentFragment.getCurrentUser();
if (UserObject.isUserSelf(user) || UserObject.isReplyUser(user) || parentFragment.getChatMode() != 0) {
if (subtitleTextView.getVisibility() != GONE) {
subtitleTextView.setVisibility(GONE);
if ((UserObject.isUserSelf(user) || UserObject.isReplyUser(user) || parentFragment.getChatMode() != 0) && parentFragment.getChatMode() != ChatActivity.MODE_SAVED) {
if (getSubtitleTextView().getVisibility() != GONE) {
getSubtitleTextView().setVisibility(GONE);
}
return;
}
@ -786,7 +846,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
titleAnimation = new AnimatorSet();
titleAnimation.playTogether(
ObjectAnimator.ofFloat(titleTextView, View.TRANSLATION_Y, AndroidUtilities.dp(9.7f)),
ObjectAnimator.ofFloat(subtitleTextView, View.ALPHA, 0.0f));
ObjectAnimator.ofFloat(getSubtitleTextView(), View.ALPHA, 0.0f));
titleAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
@ -796,7 +856,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
@Override
public void onAnimationEnd(Animator animation) {
if (titleAnimation == animation) {
subtitleTextView.setVisibility(INVISIBLE);
getSubtitleTextView().setVisibility(INVISIBLE);
titleAnimation = null;
}
}
@ -805,13 +865,16 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
titleAnimation.start();
} else {
titleTextView.setTranslationY(AndroidUtilities.dp(9.7f));
subtitleTextView.setAlpha(0.0f);
subtitleTextView.setVisibility(INVISIBLE);
getSubtitleTextView().setAlpha(0.0f);
getSubtitleTextView().setVisibility(INVISIBLE);
}
return;
}
setTypingAnimation(false);
if (parentFragment.isTopic && chat != null) {
if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
int messagesCount = parentFragment.getMessagesController().getSavedMessagesController().getMessagesCount(parentFragment.getSavedDialogId());
newSubtitle = LocaleController.formatPluralString("SavedMessagesCount", Math.max(1, messagesCount));
} else if (parentFragment.isTopic && chat != null) {
TLRPC.TL_forumTopic topic = MessagesController.getInstance(currentAccount).getTopicsController().findTopic(chat.id, parentFragment.getTopicId());
int count = 0;
if (topic != null) {
@ -854,7 +917,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (parentFragment.isThreadChat()) {
if (titleTextView.getTag() != null) {
titleTextView.setTag(null);
subtitleTextView.setVisibility(VISIBLE);
getSubtitleTextView().setVisibility(VISIBLE);
if (titleAnimation != null) {
titleAnimation.cancel();
titleAnimation = null;
@ -863,7 +926,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
titleAnimation = new AnimatorSet();
titleAnimation.playTogether(
ObjectAnimator.ofFloat(titleTextView, View.TRANSLATION_Y, 0),
ObjectAnimator.ofFloat(subtitleTextView, View.ALPHA, 1.0f));
ObjectAnimator.ofFloat(getSubtitleTextView(), View.ALPHA, 1.0f));
titleAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@ -874,25 +937,35 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
titleAnimation.start();
} else {
titleTextView.setTranslationY(0.0f);
subtitleTextView.setAlpha(1.0f);
getSubtitleTextView().setAlpha(1.0f);
}
}
}
newSubtitle = printString;
if (MessagesController.getInstance(currentAccount).getPrintingStringType(parentFragment.getDialogId(), parentFragment.getThreadId()) == 5) {
newSubtitle = Emoji.replaceEmoji(newSubtitle, subtitleTextView.getTextPaint().getFontMetricsInt(), AndroidUtilities.dp(15), false);
newSubtitle = Emoji.replaceEmoji(newSubtitle, getSubtitlePaint().getFontMetricsInt(), AndroidUtilities.dp(15), false);
}
useOnlineColor = true;
setTypingAnimation(true);
}
lastSubtitleColorKey = useOnlineColor ? Theme.key_chat_status : Theme.key_actionBarDefaultSubtitle;
if (lastSubtitle == null) {
subtitleTextView.setText(newSubtitle);
if (overrideSubtitleColor == null) {
subtitleTextView.setTextColor(getThemedColor(lastSubtitleColorKey));
subtitleTextView.setTag(lastSubtitleColorKey);
if (subtitleTextView != null) {
subtitleTextView.setText(newSubtitle);
if (overrideSubtitleColor == null) {
subtitleTextView.setTextColor(getThemedColor(lastSubtitleColorKey));
subtitleTextView.setTag(lastSubtitleColorKey);
} else {
subtitleTextView.setTextColor(overrideSubtitleColor);
}
} else {
subtitleTextView.setTextColor(overrideSubtitleColor);
animatedSubtitleTextView.setText(newSubtitle, animated);
if (overrideSubtitleColor == null) {
animatedSubtitleTextView.setTextColor(getThemedColor(lastSubtitleColorKey));
animatedSubtitleTextView.setTag(lastSubtitleColorKey);
} else {
animatedSubtitleTextView.setTextColor(overrideSubtitleColor);
}
}
} else {
lastSubtitle = newSubtitle;
@ -984,6 +1057,12 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (avatarImageView != null) {
avatarImageView.setImage(null, null, avatarDrawable, user);
}
} else if (UserObject.isAnonymous(user)) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_ANONYMOUS);
avatarDrawable.setScaleSize(.8f);
if (avatarImageView != null) {
avatarImageView.setImage(null, null, avatarDrawable, user);
}
} else if (UserObject.isUserSelf(user) && !showSelf) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
avatarDrawable.setScaleSize(.8f);
@ -1004,6 +1083,16 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
}
TLRPC.User user = parentFragment.getCurrentUser();
TLRPC.Chat chat = parentFragment.getCurrentChat();
if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
long dialogId = parentFragment.getSavedDialogId();
if (dialogId >= 0) {
user = parentFragment.getMessagesController().getUser(dialogId);
chat = null;
} else {
user = null;
chat = parentFragment.getMessagesController().getChat(-dialogId);
}
}
if (user != null) {
avatarDrawable.setInfo(currentAccount, user);
if (UserObject.isReplyUser(user)) {
@ -1012,6 +1101,18 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (avatarImageView != null) {
avatarImageView.setImage(null, null, avatarDrawable, user);
}
} else if (UserObject.isAnonymous(user)) {
avatarDrawable.setScaleSize(.8f);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_ANONYMOUS);
if (avatarImageView != null) {
avatarImageView.setImage(null, null, avatarDrawable, user);
}
} else if (UserObject.isUserSelf(user) && parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
avatarDrawable.setScaleSize(.8f);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_MY_NOTES);
if (avatarImageView != null) {
avatarImageView.setImage(null, null, avatarDrawable, user);
}
} else if (UserObject.isUserSelf(user)) {
avatarDrawable.setScaleSize(.8f);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
@ -1062,6 +1163,9 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (parentFragment != null) {
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.didUpdateConnectionState);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.savedMessagesDialogsUpdate);
}
currentConnectionState = ConnectionsManager.getInstance(currentAccount).getConnectionState();
updateCurrentConnectionState();
}
@ -1076,6 +1180,9 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (parentFragment != null) {
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.didUpdateConnectionState);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.savedMessagesDialogsUpdate);
}
}
if (emojiStatusDrawable != null) {
emojiStatusDrawable.detach();
@ -1094,10 +1201,12 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (titleTextView != null) {
titleTextView.invalidate();
}
if (subtitleTextView != null) {
subtitleTextView.invalidate();
if (getSubtitleTextView() != null) {
getSubtitleTextView().invalidate();
}
invalidate();
} else if (id == NotificationCenter.savedMessagesDialogsUpdate) {
updateSubtitle(true);
}
}
@ -1114,25 +1223,49 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
}
if (title == null) {
if (lastSubtitle != null) {
subtitleTextView.setText(lastSubtitle);
lastSubtitle = null;
if (overrideSubtitleColor != null) {
subtitleTextView.setTextColor(overrideSubtitleColor);
} else if (lastSubtitleColorKey >= 0) {
subtitleTextView.setTextColor(getThemedColor(lastSubtitleColorKey));
subtitleTextView.setTag(lastSubtitleColorKey);
if (subtitleTextView != null) {
subtitleTextView.setText(lastSubtitle);
lastSubtitle = null;
if (overrideSubtitleColor != null) {
subtitleTextView.setTextColor(overrideSubtitleColor);
} else if (lastSubtitleColorKey >= 0) {
subtitleTextView.setTextColor(getThemedColor(lastSubtitleColorKey));
subtitleTextView.setTag(lastSubtitleColorKey);
}
} else if (animatedSubtitleTextView != null) {
animatedSubtitleTextView.setText(lastSubtitle, !LocaleController.isRTL);
lastSubtitle = null;
if (overrideSubtitleColor != null) {
animatedSubtitleTextView.setTextColor(overrideSubtitleColor);
} else if (lastSubtitleColorKey >= 0) {
animatedSubtitleTextView.setTextColor(getThemedColor(lastSubtitleColorKey));
animatedSubtitleTextView.setTag(lastSubtitleColorKey);
}
}
}
} else {
if (lastSubtitle == null) {
lastSubtitle = subtitleTextView.getText();
}
subtitleTextView.setText(title);
if (overrideSubtitleColor != null) {
subtitleTextView.setTextColor(overrideSubtitleColor);
} else {
subtitleTextView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubtitle));
subtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle);
if (subtitleTextView != null) {
if (lastSubtitle == null) {
lastSubtitle = subtitleTextView.getText();
}
subtitleTextView.setText(title);
if (overrideSubtitleColor != null) {
subtitleTextView.setTextColor(overrideSubtitleColor);
} else {
subtitleTextView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubtitle));
subtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle);
}
} else if (animatedSubtitleTextView != null) {
if (lastSubtitle == null) {
lastSubtitle = animatedSubtitleTextView.getText();
}
animatedSubtitleTextView.setText(title, !LocaleController.isRTL);
if (overrideSubtitleColor != null) {
animatedSubtitleTextView.setTextColor(overrideSubtitleColor);
} else {
animatedSubtitleTextView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubtitle));
animatedSubtitleTextView.setTag(Theme.key_actionBarDefaultSubtitle);
}
}
}
}
@ -1151,7 +1284,11 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
sb.append(rightDrawable2ContentDescription);
}
sb.append("\n");
sb.append(subtitleTextView.getText());
if (subtitleTextView != null) {
sb.append(subtitleTextView.getText());
} else if (animatedSubtitleTextView != null) {
sb.append(animatedSubtitleTextView.getText());
}
info.setContentDescription(sb);
if (info.isClickable() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, LocaleController.getString("OpenProfile", R.string.OpenProfile)));

View file

@ -1,24 +1,46 @@
package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.text.Layout;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.Premium.PremiumButtonView;
import org.telegram.ui.Components.Premium.StarParticlesView;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.recorder.ButtonWithCounterView;
import org.telegram.ui.Stories.recorder.HintView2;
import java.util.Locale;
@ -44,18 +66,16 @@ public class ChatGreetingsView extends LinearLayout {
titleView = new TextView(context);
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleView.setGravity(Gravity.CENTER_HORIZONTAL);
titleView.setTextAlignment(TEXT_ALIGNMENT_CENTER);
titleView.setGravity(Gravity.CENTER);
descriptionView = new TextView(context);
descriptionView.setTextAlignment(TEXT_ALIGNMENT_CENTER);
descriptionView.setGravity(Gravity.CENTER);
descriptionView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
descriptionView.setGravity(Gravity.CENTER_HORIZONTAL);
stickerToSendView = new BackupImageView(context);
addView(titleView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 20, 14, 20, 14));
addView(descriptionView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 20, 12, 20, 0));
addView(stickerToSendView, LayoutHelper.createLinear(112, 112, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 16));
updateLayout();
updateColors();
@ -66,6 +86,7 @@ public class ChatGreetingsView extends LinearLayout {
titleView.setText(LocaleController.formatString("NearbyPeopleGreetingsMessage", R.string.NearbyPeopleGreetingsMessage, user.first_name, LocaleController.formatDistance(distance, 1)));
descriptionView.setText(LocaleController.getString("NearbyPeopleGreetingsDescription", R.string.NearbyPeopleGreetingsDescription));
}
descriptionView.setMaxWidth(HintView2.cutInFancyHalf(descriptionView.getText(), descriptionView.getPaint()));
stickerToSendView.setContentDescription(descriptionView.getText());
preloadedGreetingsSticker = sticker;
@ -74,6 +95,126 @@ public class ChatGreetingsView extends LinearLayout {
}
}
private ImageView premiumIconView;
private TextView premiumTextView;
private TextView premiumButtonView;
private boolean premiumLock;
public void setPremiumLock(boolean lock, long dialogId) {
if (premiumLock == lock) return;
premiumLock = lock;
if (premiumLock) {
if (premiumIconView == null) {
premiumIconView = new ImageView(getContext());
premiumIconView.setScaleType(ImageView.ScaleType.CENTER);
premiumIconView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
premiumIconView.setBackground(Theme.createCircleDrawable(dp(78), 0x1c000000));
premiumIconView.setImageResource(R.drawable.large_message_lock);
}
if (premiumTextView == null) {
premiumTextView = new TextView(getContext());
premiumTextView.setTextAlignment(TEXT_ALIGNMENT_CENTER);
premiumTextView.setGravity(Gravity.CENTER);
premiumTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
}
String username = "";
if (dialogId >= 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
if (user != null) {
username = UserObject.getUserName(user);
}
}
String text;
if (MessagesController.getInstance(currentAccount).premiumFeaturesBlocked()) {
text = LocaleController.formatString(R.string.MessageLockedPremiumLocked, username);
} else {
text = LocaleController.formatString(R.string.MessageLockedPremium, username);
}
premiumTextView.setText(AndroidUtilities.replaceTags(text));
premiumTextView.setMaxWidth(HintView2.cutInFancyHalf(premiumTextView.getText(), premiumTextView.getPaint()));
premiumTextView.setTextColor(getThemedColor(Theme.key_chat_serviceText));
premiumTextView.setLineSpacing(dp(2f), 1f);
if (premiumButtonView == null) {
premiumButtonView = new TextView(getContext()) {
StarParticlesView.Drawable starParticlesDrawable;
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
starParticlesDrawable = new StarParticlesView.Drawable(10);
starParticlesDrawable.type = 100;
starParticlesDrawable.isCircle = false;
starParticlesDrawable.roundEffect = true;
starParticlesDrawable.useRotate = false;
starParticlesDrawable.useBlur = true;
starParticlesDrawable.checkBounds = true;
starParticlesDrawable.size1 = 1;
starParticlesDrawable.k1 = starParticlesDrawable.k2 = starParticlesDrawable.k3 = 0.98f;
starParticlesDrawable.paused = false;
starParticlesDrawable.speedScale = 0f;
starParticlesDrawable.minLifeTime = 750;
starParticlesDrawable.randLifeTime = 750;
starParticlesDrawable.init();
AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
starParticlesDrawable.rect.set(AndroidUtilities.rectTmp);
starParticlesDrawable.rect2.set(AndroidUtilities.rectTmp);
starParticlesDrawable.resetPositions();
clipPath.reset();
clipPath.addRoundRect(AndroidUtilities.rectTmp, getHeight() / 2f, getHeight() / 2f, Path.Direction.CW);
}
private final Path clipPath = new Path();
@Override
protected void onDraw(Canvas canvas) {
if (starParticlesDrawable != null) {
canvas.save();
canvas.clipPath(clipPath);
starParticlesDrawable.onDraw(canvas);
canvas.restore();
invalidate();
}
super.onDraw(canvas);
}
};
premiumButtonView.setTextAlignment(TEXT_ALIGNMENT_CENTER);
premiumButtonView.setGravity(Gravity.CENTER);
premiumButtonView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
premiumButtonView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
premiumButtonView.setPadding(dp(13), dp(6.66f), dp(13), dp(7));
premiumButtonView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(15), 0x1e000000, 0x33000000));
ScaleStateListAnimator.apply(premiumButtonView);
}
premiumButtonView.setText(LocaleController.getString(R.string.MessagePremiumUnlock));
premiumButtonView.setTextColor(getThemedColor(Theme.key_chat_serviceText));
premiumButtonView.setOnClickListener(v -> {
BaseFragment fragment = LaunchActivity.getLastFragment();
if (fragment != null) {
fragment.presentFragment(new PremiumPreviewFragment("contact"));
}
});
}
updateLayout();
}
private void updateLayout() {
removeAllViews();
if (premiumLock) {
addView(premiumIconView, LayoutHelper.createLinear(78, 78, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 20, 17, 20, 9));
final boolean premiumLocked = MessagesController.getInstance(currentAccount).premiumFeaturesBlocked();
addView(premiumTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 20, 0, 20, premiumLocked ? 13 : 9));
if (!premiumLocked) {
addView(premiumButtonView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 30, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 20, 2, 20, 13));
}
} else {
addView(titleView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 20, 14, 20, 6));
addView(descriptionView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 20, 6, 20, 0));
addView(stickerToSendView, LayoutHelper.createLinear(112, 112, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 16));
}
}
private void setSticker(TLRPC.Document sticker) {
if (sticker == null) {
return;
@ -116,7 +257,7 @@ public class ChatGreetingsView extends LinearLayout {
if (photoWidth == 0) {
photoHeight = (int) maxHeight;
photoWidth = photoHeight + AndroidUtilities.dp(100);
photoWidth = photoHeight + dp(100);
}
photoHeight *= maxWidth / photoWidth;
photoWidth = (int) maxWidth;
@ -202,4 +343,59 @@ public class ChatGreetingsView extends LinearLayout {
private int getThemedColor(int key) {
return Theme.getColor(key, resourcesProvider);
}
public static void showPremiumSheet(Context context, int currentAccount, long dialogId, Theme.ResourcesProvider resourcesProvider) {
BottomSheet sheet = new BottomSheet(context, false, resourcesProvider);
sheet.fixNavigationBar(Theme.getColor(Theme.key_dialogBackground, resourcesProvider));
LinearLayout layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(dp(16), 0, dp(16), 0);
RLottieImageView imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setAnimation(R.raw.large_message_lock, 80, 80);
imageView.playAnimation();
imageView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
imageView.setBackground(Theme.createCircleDrawable(dp(80), Theme.getColor(Theme.key_featuredStickers_addButton, resourcesProvider)));
layout.addView(imageView, LayoutHelper.createLinear(80, 80, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 16));
final boolean premiumLocked = MessagesController.getInstance(currentAccount).premiumFeaturesBlocked();
TextView headerView = new TextView(context);
headerView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
headerView.setGravity(Gravity.CENTER);
headerView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
headerView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
headerView.setText(LocaleController.getString(premiumLocked ? R.string.PremiumMessageHeaderLocked : R.string.PremiumMessageHeader));
layout.addView(headerView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 12, 0, 12, 0));
TextView descriptionView = new TextView(context);
descriptionView.setGravity(Gravity.CENTER);
descriptionView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
descriptionView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
String username = "";
if (dialogId > 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
username = UserObject.getFirstName(user);
}
descriptionView.setText(AndroidUtilities.replaceTags(LocaleController.formatString(premiumLocked ? R.string.PremiumMessageTextLocked : R.string.PremiumMessageText, username, username)));
layout.addView(descriptionView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 12, 9, 12, 19));
if (!premiumLocked) {
PremiumButtonView button2 = new PremiumButtonView(context, true, resourcesProvider);
button2.setOnClickListener(v2 -> {
BaseFragment lastFragment = LaunchActivity.getLastFragment();
if (lastFragment != null) {
lastFragment.presentFragment(new PremiumPreviewFragment("contact"));
sheet.dismiss();
}
});
button2.setOverlayText(LocaleController.getString(R.string.PremiumMessageButton), false, false);
layout.addView(button2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 4));
}
sheet.setCustomView(layout);
sheet.show();
}
}

View file

@ -158,7 +158,7 @@ public class ChatNotificationsPopupWrapper {
lastDismissTime = System.currentTimeMillis();
}
public void update(long dialogId, int topicId, HashSet<Integer> topicExceptions) {
public void update(long dialogId, long topicId, HashSet<Integer> topicExceptions) {
if (System.currentTimeMillis() - lastDismissTime < 200) {
//do on popup close
AndroidUtilities.runOnUIThread(() -> {

View file

@ -0,0 +1,330 @@
package org.telegram.ui.Components;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Build;
import android.os.PowerManager;
import androidx.annotation.NonNull;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.NotificationsController;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.voip.VoIPService;
import org.telegram.ui.PhotoViewer;
public class EarListener implements SensorEventListener {
private final Context context;
private final SensorManager sensorManager;
private final PowerManager powerManager;
private final AudioManager audioManager;
private Sensor proximitySensor;
private Sensor accelerometerSensor;
private Sensor linearSensor;
private Sensor gravitySensor;
private PowerManager.WakeLock proximityWakeLock;
public EarListener(@NonNull Context context) {
this.context = context;
sensorManager = (SensorManager) ApplicationLoader.applicationContext.getSystemService(Context.SENSOR_SERVICE);
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
linearSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
gravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
if (linearSensor == null || gravitySensor == null) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("gravity or linear sensor not found");
}
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
linearSensor = null;
gravitySensor = null;
}
powerManager = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE);
proximityWakeLock = powerManager.newWakeLock(0x00000020, "telegram:proximity_lock2");
audioManager = (AudioManager) ApplicationLoader.applicationContext.getSystemService(Context.AUDIO_SERVICE);
}
private boolean attached;
public void attach() {
if (!attached) {
if (gravitySensor != null) {
sensorManager.registerListener(this, gravitySensor, 30000);
}
if (linearSensor != null) {
sensorManager.registerListener(this, linearSensor, 30000);
}
if (accelerometerSensor != null) {
sensorManager.registerListener(this, accelerometerSensor, 30000);
}
sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
if (proximityWakeLock != null && !disableWakeLockWhenNotUsed()) {
proximityWakeLock.acquire();
}
attached = true;
}
}
public void detach() {
if (attached) {
if (gravitySensor != null) {
sensorManager.unregisterListener(this, gravitySensor);
}
if (linearSensor != null) {
sensorManager.unregisterListener(this, linearSensor);
}
if (accelerometerSensor != null) {
sensorManager.unregisterListener(this, accelerometerSensor);
}
sensorManager.unregisterListener(this, proximitySensor);
if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
attached = false;
}
}
private boolean raised;
public boolean isRaised() {
return raised;
}
private VideoPlayer currentPlayer;
public void attachPlayer(VideoPlayer player) {
currentPlayer = player;
updateRaised();
}
protected void updateRaised() {
if (currentPlayer == null) {
return;
}
currentPlayer.setStreamType(raised ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
}
private boolean accelerometerVertical;
private long lastAccelerometerDetected;
private int raisedToTop;
private int raisedToTopSign;
private int raisedToBack;
private int countLess;
private long timeSinceRaise;
private long lastTimestamp = 0;
private boolean proximityTouched;
private boolean proximityHasDifferentValues;
private float lastProximityValue = -100;
private float previousAccValue;
private float[] gravity = new float[3];
private float[] gravityFast = new float[3];
private float[] linearAcceleration = new float[3];
@Override
public void onSensorChanged(SensorEvent event) {
if (!attached || VoIPService.getSharedInstance() != null) {
return;
}
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("proximity changed to " + event.values[0] + " max value = " + event.sensor.getMaximumRange());
}
if (lastProximityValue != event.values[0]) {
proximityHasDifferentValues = true;
}
lastProximityValue = event.values[0];
if (proximityHasDifferentValues) {
proximityTouched = isNearToSensor(event.values[0]);
}
} else if (event.sensor == accelerometerSensor) {
final double alpha = lastTimestamp == 0 ? 0.98f : 1.0 / (1.0 + (event.timestamp - lastTimestamp) / 1000000000.0);
final float alphaFast = 0.8f;
lastTimestamp = event.timestamp;
gravity[0] = (float) (alpha * gravity[0] + (1.0 - alpha) * event.values[0]);
gravity[1] = (float) (alpha * gravity[1] + (1.0 - alpha) * event.values[1]);
gravity[2] = (float) (alpha * gravity[2] + (1.0 - alpha) * event.values[2]);
gravityFast[0] = (alphaFast * gravity[0] + (1.0f - alphaFast) * event.values[0]);
gravityFast[1] = (alphaFast * gravity[1] + (1.0f - alphaFast) * event.values[1]);
gravityFast[2] = (alphaFast * gravity[2] + (1.0f - alphaFast) * event.values[2]);
linearAcceleration[0] = event.values[0] - gravity[0];
linearAcceleration[1] = event.values[1] - gravity[1];
linearAcceleration[2] = event.values[2] - gravity[2];
} else if (event.sensor == linearSensor) {
linearAcceleration[0] = event.values[0];
linearAcceleration[1] = event.values[1];
linearAcceleration[2] = event.values[2];
} else if (event.sensor == gravitySensor) {
gravityFast[0] = gravity[0] = event.values[0];
gravityFast[1] = gravity[1] = event.values[1];
gravityFast[2] = gravity[2] = event.values[2];
}
final float minDist = 15.0f;
final int minCount = 6;
final int countLessMax = 10;
if (event.sensor == linearSensor || event.sensor == gravitySensor || event.sensor == accelerometerSensor) {
float val = gravity[0] * linearAcceleration[0] + gravity[1] * linearAcceleration[1] + gravity[2] * linearAcceleration[2];
if (raisedToBack != minCount) {
if (val > 0 && previousAccValue > 0 || val < 0 && previousAccValue < 0) {
boolean goodValue;
int sign;
if (val > 0) {
goodValue = val > minDist;
sign = 1;
} else {
goodValue = val < -minDist;
sign = 2;
}
if (raisedToTopSign != 0 && raisedToTopSign != sign) {
if (raisedToTop == minCount && goodValue) {
if (raisedToBack < minCount) {
raisedToBack++;
if (raisedToBack == minCount) {
raisedToTop = 0;
raisedToTopSign = 0;
countLess = 0;
timeSinceRaise = System.currentTimeMillis();
if (BuildVars.LOGS_ENABLED && BuildVars.DEBUG_PRIVATE_VERSION) {
FileLog.d("motion detected");
}
}
}
} else {
if (!goodValue) {
countLess++;
}
if (countLess == countLessMax || raisedToTop != minCount || raisedToBack != 0) {
raisedToTop = 0;
raisedToTopSign = 0;
raisedToBack = 0;
countLess = 0;
}
}
} else {
if (goodValue && raisedToBack == 0 && (raisedToTopSign == 0 || raisedToTopSign == sign)) {
if (raisedToTop < minCount && !proximityTouched) {
raisedToTopSign = sign;
raisedToTop++;
if (raisedToTop == minCount) {
countLess = 0;
}
}
} else {
if (!goodValue) {
countLess++;
}
if (raisedToTopSign != sign || countLess == countLessMax || raisedToTop != minCount || raisedToBack != 0) {
raisedToBack = 0;
raisedToTop = 0;
raisedToTopSign = 0;
countLess = 0;
}
}
}
}
}
previousAccValue = val;
accelerometerVertical = gravityFast[1] > 2.5f && Math.abs(gravityFast[2]) < 4.0f && Math.abs(gravityFast[0]) > 1.5f;
}
if (raisedToBack == minCount || accelerometerVertical) {
lastAccelerometerDetected = System.currentTimeMillis();
}
final boolean accelerometerDetected = raisedToBack == minCount || accelerometerVertical || System.currentTimeMillis() - lastAccelerometerDetected < 60;
final boolean wakelockAllowed = accelerometerDetected && !forbidRaiseToListen() && !VoIPService.isAnyKindOfCallActive() && !PhotoViewer.getInstance().isVisible();
if (proximityWakeLock != null && disableWakeLockWhenNotUsed()) {
final boolean held = proximityWakeLock.isHeld();
if (held && !wakelockAllowed) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("wake lock releasing");
}
proximityWakeLock.release();
} else if (!held && wakelockAllowed) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("wake lock acquiring");
}
proximityWakeLock.acquire();
}
}
if (proximityTouched && wakelockAllowed) {
if (!raised) {
raised = true;
updateRaised();
}
raisedToBack = 0;
raisedToTop = 0;
raisedToTopSign = 0;
countLess = 0;
} else if (proximityTouched && ((accelerometerSensor == null || linearSensor == null) && gravitySensor == null) && !VoIPService.isAnyKindOfCallActive()) {
if (!raised) {
raised = true;
updateRaised();
}
} else if (!proximityTouched) {
if (raised) {
raised = false;
updateRaised();
}
}
if (timeSinceRaise != 0 && raisedToBack == minCount && Math.abs(System.currentTimeMillis() - timeSinceRaise) > 1000) {
raisedToBack = 0;
raisedToTop = 0;
raisedToTopSign = 0;
countLess = 0;
timeSinceRaise = 0;
}
}
private boolean isNearToSensor(float value) {
return value < 5.0f && value != proximitySensor.getMaximumRange();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private boolean disableWakeLockWhenNotUsed() {
// Pixel devices cap phone fps to 60 when wake lock is held
// Samsung devices do much worse proximity detection when wake lock is not held
// Solution: enable wake lock only when accelerometer detects raising, except for Samsung
return !Build.MANUFACTURER.equalsIgnoreCase("samsung");
}
protected boolean forbidRaiseToListen() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
for (AudioDeviceInfo device : devices) {
final int type = device.getType();
if ((
type == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP ||
type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO ||
type == AudioDeviceInfo.TYPE_BLE_HEADSET ||
type == AudioDeviceInfo.TYPE_BLE_SPEAKER ||
type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES ||
type == AudioDeviceInfo.TYPE_WIRED_HEADSET
) && device.isSink()) {
return true;
}
}
return false;
} else {
return audioManager.isWiredHeadsetOn() || audioManager.isBluetoothA2dpOn() || audioManager.isBluetoothScoOn();
}
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
}

View file

@ -1140,7 +1140,7 @@ public class EmojiPacksAlert extends BottomSheet implements NotificationCenter.N
removeButtonView.setOnClickListener(ev -> {
dismiss();
if (fragment != null) {
MediaDataController.getInstance(fragment.getCurrentAccount()).removeMultipleStickerSets(fragment.getFragmentView().getContext(), fragment, installedPacks);
MediaDataController.getInstance(fragment.getCurrentAccount()).removeMultipleStickerSets(fragment.getContext(), fragment, installedPacks);
} else {
for (int i = 0; i < installedPacks.size(); ++i) {
TLRPC.TL_messages_stickerSet stickerSet = installedPacks.get(i);

View file

@ -8985,9 +8985,9 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
private final int currentAccount;
private final long dialogId;
private final int threadId;
private final long threadId;
public ChooseStickerActionTracker(int currentAccount, long dialogId, int threadId) {
public ChooseStickerActionTracker(int currentAccount, long dialogId, long threadId) {
this.currentAccount = currentAccount;
this.dialogId = dialogId;
this.threadId = threadId;

View file

@ -16,13 +16,10 @@ import android.text.TextUtils;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.util.SparseArray;
import android.util.SparseIntArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ContactsController;
@ -87,12 +84,12 @@ public class ForumUtilities {
return new GeneralTopicDrawable(context, scale, color, isDialog);
}
public static void filterMessagesByTopic(int threadMessageId, ArrayList<MessageObject> messageObjects) {
public static void filterMessagesByTopic(long threadMessageId, ArrayList<MessageObject> messageObjects) {
if (messageObjects == null) {
return;
}
for (int i = 0; i < messageObjects.size(); i++) {
if (threadMessageId != MessageObject.getTopicId(messageObjects.get(i).messageOwner, true)) {
if (threadMessageId != MessageObject.getTopicId(messageObjects.get(i).currentAccount, messageObjects.get(i).messageOwner, true)) {
messageObjects.remove(i);
i--;
}
@ -368,7 +365,7 @@ public class ForumUtilities {
if (messageObject.getDialogId() > 0) {
return;
}
TLRPC.TL_forumTopic topic = MessagesController.getInstance(messageObject.currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), MessageObject.getTopicId(messageObject.messageOwner, true));
TLRPC.TL_forumTopic topic = MessagesController.getInstance(messageObject.currentAccount).getTopicsController().findTopic(-messageObject.getDialogId(), MessageObject.getTopicId(messageObject.currentAccount, messageObject.messageOwner, true));
if (topic != null && messageObject.topicIconDrawable[0] instanceof ForumBubbleDrawable) {
((ForumBubbleDrawable) messageObject.topicIconDrawable[0]).setColor(topic.icon_color);
}

View file

@ -135,8 +135,8 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
}
if (this.sharedMediaPreloader == null) {
this.sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(this);
this.sharedMediaPreloader.addDelegate(this);
}
this.sharedMediaPreloader.addDelegate(this);
return super.onFragmentCreate();
}
@ -537,6 +537,9 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
hideFloatingButton(true, false);
}
if (type == TYPE_MEDIA && dialogId == getUserConfig().getClientUserId() && !getMessagesController().getSavedMessagesController().unsupported && getMessagesController().getSavedMessagesController().getAllCount() > 0) {
initialTab = SharedMediaLayout.TAB_SAVED_DIALOGS;
}
sharedMediaLayout = new SharedMediaLayout(context, dialogId, sharedMediaPreloader, 0, null, currentChatInfo, currentUserInfo, initialTab, this, new SharedMediaLayout.Delegate() {
@Override
public void scrollToSharedMedia() {
@ -582,7 +585,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
@Override
protected boolean canShowSearchItem() {
return false;
return type != TYPE_STORIES && type != TYPE_ARCHIVED_CHANNEL_STORIES;
}
@Override
@ -611,6 +614,11 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
return type == TYPE_STORIES || type == TYPE_ARCHIVED_CHANNEL_STORIES;
}
@Override
protected boolean includeSavedDialogs() {
return type == TYPE_MEDIA && dialogId == getUserConfig().getClientUserId();
}
@Override
protected boolean isArchivedOnlyStoriesView() {
return type == TYPE_ARCHIVED_CHANNEL_STORIES;
@ -937,6 +945,12 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
return;
}
if (id == SharedMediaLayout.TAB_SAVED_DIALOGS) {
showSubtitle(i, true, true);
int count = getMessagesController().getSavedMessagesController().getAllCount();
subtitleTextView[i].setText(LocaleController.formatPluralString("SavedDialogsTabCount", count), animated);
return;
}
if (id < 0 || id < mediaCount.length && mediaCount[id] < 0) {
return;
}

View file

@ -69,7 +69,7 @@ public class MentionsContainerView extends BlurredFrameLayout implements Notific
private RecyclerListView.OnItemClickListener mentionsOnItemClickListener;
private Delegate delegate;
public MentionsContainerView(@NonNull Context context, long dialogId, int threadMessageId, BaseFragment baseFragment, SizeNotifierFrameLayout container, Theme.ResourcesProvider resourcesProvider) {
public MentionsContainerView(@NonNull Context context, long dialogId, long threadMessageId, BaseFragment baseFragment, SizeNotifierFrameLayout container, Theme.ResourcesProvider resourcesProvider) {
super(context, container);
this.baseFragment = baseFragment;
this.sizeNotifierFrameLayout = container;

View file

@ -0,0 +1,323 @@
package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.ui.ActionBar.Theme.key_dialogGrayLine;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.Premium.PremiumButtonView;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.recorder.ButtonWithCounterView;
import org.telegram.ui.Stories.recorder.HintView2;
public class MessagePrivateSeenView extends FrameLayout {
private final int currentAccount;
private final Theme.ResourcesProvider resourcesProvider;
private final LinearLayout valueLayout;
private final TextView valueTextView;
private final TextView premiumTextView;
private final TextView loadingView;
private final long dialogId;
private final int messageId;
private final Runnable dismiss;
public MessagePrivateSeenView(Context context, @NonNull MessageObject messageObject, Runnable dismiss, Theme.ResourcesProvider resourcesProvider) {
super(context);
currentAccount = messageObject.currentAccount;
this.resourcesProvider = resourcesProvider;
this.dismiss = dismiss;
dialogId = messageObject.getDialogId();
messageId = messageObject.getId();
ImageView iconView = new ImageView(context);
addView(iconView, LayoutHelper.createFrame(24, 24, Gravity.LEFT | Gravity.CENTER_VERTICAL, 11, 0, 0, 0));
Drawable drawable = ContextCompat.getDrawable(context, messageObject.isVoice() ? R.drawable.msg_played : R.drawable.msg_seen).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
iconView.setImageDrawable(drawable);
loadingView = new TextView(context);
SpannableStringBuilder text = new SpannableStringBuilder("loading text ");
text.setSpan(new LoadingSpan(loadingView, dp(96), dp(2), resourcesProvider), 0, text.length() - 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
loadingView.setTextColor(Theme.multAlpha(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider), .7f));
loadingView.setText(text);
loadingView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
addView(loadingView, LayoutHelper.createFrame(96, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 40, -1, 8, 0));
valueLayout = new LinearLayout(context);
valueLayout.setOrientation(LinearLayout.HORIZONTAL);
valueLayout.setAlpha(0f);
addView(valueLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 38, 0, 8, 0));
valueTextView = new TextView(context);
valueTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
valueLayout.addView(valueTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 0, -1, 0, 0));
premiumTextView = new TextView(context);
premiumTextView.setBackground(Theme.createRoundRectDrawable(dp(20), Theme.multAlpha(Theme.getColor(Theme.key_divider, resourcesProvider), .75f)));
premiumTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
premiumTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 11);
premiumTextView.setPadding(dp(5.33f), dp(2), dp(5.33f), dp(2.33f));
valueLayout.addView(premiumTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, 4, 0, 0, 0));
request();
}
private void request() {
setOnClickListener(null);
valueLayout.setAlpha(0f);
loadingView.setAlpha(1f);
premiumTextView.setVisibility(View.VISIBLE);
TLRPC.TL_messages_getOutboxReadDate req = new TLRPC.TL_messages_getOutboxReadDate();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
req.msg_id = messageId;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (err != null) {
if ("USER_PRIVACY_RESTRICTED".equals(err.text)) {
valueTextView.setText(LocaleController.getString(R.string.PmReadUnknown));
premiumTextView.setVisibility(View.GONE);
} else if ("YOUR_PRIVACY_RESTRICTED".equals(err.text)) {
isPremiumLocked = true;
valueTextView.setText(LocaleController.getString(R.string.PmRead));
premiumTextView.setText(LocaleController.getString(R.string.PmReadShowWhen));
} else {
valueTextView.setText(LocaleController.getString("UnknownError"));
premiumTextView.setVisibility(View.GONE);
BulletinFactory.of(Bulletin.BulletinWindow.make(getContext()), resourcesProvider).showForError(err);
}
} else if (res instanceof TLRPC.TL_outboxReadDate) {
TLRPC.TL_outboxReadDate r = (TLRPC.TL_outboxReadDate) res;
valueTextView.setText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatSeenDate(r.date)));
premiumTextView.setVisibility(View.GONE);
}
valueLayout.animate().alpha(1f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(320).start();
loadingView.animate().alpha(0f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(320).start();
if (isPremiumLocked) {
setBackground(Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_listSelector, resourcesProvider), 6, 0));
setOnClickListener(v -> showSheet(getContext(), currentAccount, dialogId, false, dismiss, this::request, resourcesProvider));
} else {
setBackground(null);
setOnClickListener(null);
}
}));
}
public boolean isPremiumLocked = false;
public static void showSheet(Context context, int currentAccount, long dialogId, boolean lastSeen, Runnable dismiss, Runnable updated, Theme.ResourcesProvider resourcesProvider) {
BottomSheet sheet = new BottomSheet(context, false, resourcesProvider);
sheet.fixNavigationBar(Theme.getColor(Theme.key_dialogBackground, resourcesProvider));
final boolean premiumLocked = MessagesController.getInstance(currentAccount).premiumFeaturesBlocked();
LinearLayout layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(dp(16), 0, dp(16), 0);
RLottieImageView imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setAnimation(lastSeen ? R.raw.large_lastseen : R.raw.large_readtime, 70, 70);
imageView.playAnimation();
imageView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
imageView.setBackground(Theme.createCircleDrawable(dp(80), Theme.getColor(Theme.key_featuredStickers_addButton, resourcesProvider)));
layout.addView(imageView, LayoutHelper.createLinear(80, 80, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 16));
TextView headerView = new TextView(context);
headerView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
headerView.setGravity(Gravity.CENTER);
headerView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
headerView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
headerView.setText(LocaleController.getString(lastSeen ? R.string.PremiumLastSeenHeader1 : R.string.PremiumReadHeader1));
layout.addView(headerView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 12, 0, 12, 0));
TextView descriptionView = new TextView(context);
descriptionView.setGravity(Gravity.CENTER);
descriptionView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
descriptionView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
String username = "";
if (dialogId > 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
username = UserObject.getFirstName(user);
}
descriptionView.setText(AndroidUtilities.replaceTags(LocaleController.formatString(lastSeen ? (premiumLocked ? R.string.PremiumLastSeenText1Locked : R.string.PremiumLastSeenText1) : (premiumLocked ? R.string.PremiumReadText1Locked : R.string.PremiumReadText1), username)));
layout.addView(descriptionView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 32, 9, 32, 19));
ButtonWithCounterView button1 = new ButtonWithCounterView(context, resourcesProvider);
button1.setText(LocaleController.getString(lastSeen ? R.string.PremiumLastSeenButton1 : R.string.PremiumReadButton1), false);
layout.addView(button1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.CENTER_HORIZONTAL));
button1.setOnClickListener(v -> {
button1.setLoading(true);
if (lastSeen) {
TLRPC.TL_account_setPrivacy req = new TLRPC.TL_account_setPrivacy();
req.key = new TLRPC.TL_inputPrivacyKeyStatusTimestamp();
req.rules.add(new TLRPC.TL_inputPrivacyValueAllowAll());
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (err != null) {
BulletinFactory.global().showForError(err);
return;
}
button1.setLoading(false);
sheet.dismiss();
BulletinFactory.global().createSimpleBulletin(R.raw.chats_infotip, LocaleController.getString(R.string.PremiumLastSeenSet)).show();
if (updated != null) {
updated.run();
}
}));
} else {
TLRPC.TL_account_setGlobalPrivacySettings req = new TLRPC.TL_account_setGlobalPrivacySettings();
req.settings = ContactsController.getInstance(currentAccount).getGlobalPrivacySettings();
if (req.settings == null) {
req.settings = new TLRPC.TL_globalPrivacySettings();
}
req.settings.hide_read_marks = false;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (err != null) {
BulletinFactory.of(Bulletin.BulletinWindow.make(context), resourcesProvider).showForError(err);
return;
}
button1.setLoading(false);
sheet.dismiss();
BulletinFactory.of(Bulletin.BulletinWindow.make(context), resourcesProvider).createSimpleBulletin(R.raw.chats_infotip, LocaleController.getString(R.string.PremiumReadSet)).show();
if (updated != null) {
updated.run();
}
}));
}
});
if (!premiumLocked) {
SimpleTextView or = new SimpleTextView(context) {
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
@Override
protected void dispatchDraw(Canvas canvas) {
paint.setColor(Theme.getColor(Theme.key_dialogGrayLine, resourcesProvider));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
final float cy = getHeight() / 2f;
canvas.drawLine(0, cy, getWidth() / 2f - getTextWidth() / 2f - dp(8), cy, paint);
canvas.drawLine(getWidth() / 2f + getTextWidth() / 2f + dp(8), cy, getWidth(), cy, paint);
super.dispatchDraw(canvas);
}
};
or.setGravity(Gravity.CENTER);
or.setAlignment(Layout.Alignment.ALIGN_CENTER);
or.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
or.setText(" " + LocaleController.getString(R.string.PremiumOr) + " ");
or.setTextSize(14);
layout.addView(or, LayoutHelper.createLinear(270, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 12, 17, 12, 17));
TextView headerView2 = new TextView(context);
headerView2.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
headerView2.setGravity(Gravity.CENTER);
headerView2.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
headerView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
headerView2.setText(LocaleController.getString(lastSeen ? R.string.PremiumLastSeenHeader2 : R.string.PremiumReadHeader2));
layout.addView(headerView2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 12, 0, 12, 0));
TextView descriptionView2 = new TextView(context);
descriptionView2.setGravity(Gravity.CENTER);
descriptionView2.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
descriptionView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
descriptionView2.setText(AndroidUtilities.replaceTags(LocaleController.formatString(lastSeen ? R.string.PremiumLastSeenText2 : R.string.PremiumReadText2, username)));
layout.addView(descriptionView2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 32, 9, 32, 19));
PremiumButtonView button2 = new PremiumButtonView(context, true, resourcesProvider);
button2.setOnClickListener(v2 -> {
BaseFragment lastFragment = LaunchActivity.getLastFragment();
if (lastFragment != null) {
lastFragment.presentFragment(new PremiumPreviewFragment(lastSeen ? "lastseen" : "readtime"));
sheet.dismiss();
if (dismiss != null) {
dismiss.run();
}
}
});
button2.setOverlayText(LocaleController.getString(lastSeen ? R.string.PremiumLastSeenButton2 : R.string.PremiumReadButton2), false, false);
layout.addView(button2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 4));
}
sheet.setCustomView(layout);
sheet.show();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Bulletin.hideVisible();
}
float minWidth = -1;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
View parent = (View) getParent();
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (minWidth < 0) {
minWidth = 0;
minWidth = Math.max(minWidth, dp(40 + 96 + 8));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.getString(R.string.PmReadUnknown)));
minWidth = Math.max(minWidth, dp(40 + 16 + 8) + valueTextView.getPaint().measureText(LocaleController.getString(R.string.PmRead) + premiumTextView.getPaint().measureText(LocaleController.getString(R.string.PmReadShowWhen))));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatString(R.string.TodayAtFormattedWithToday, "99:99"))));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatString(R.string.YesterdayAtFormatted, "99:99"))));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatString(R.string.formatDateAtTime, "99.99.99", "99:99"))));
}
if (width < minWidth) {
width = (int) minWidth;
}
if (parent != null && parent.getWidth() > 0) {
width = parent.getWidth();
widthMode = MeasureSpec.EXACTLY;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

View file

@ -2742,23 +2742,25 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
parent.addView(flipView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
}
TextView duplicateView = new TextView(getContext());
duplicateView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
duplicateView.setBackgroundDrawable(Theme.getSelectorDrawable(false));
duplicateView.setGravity(Gravity.CENTER_VERTICAL);
duplicateView.setEllipsize(TextUtils.TruncateAt.END);
duplicateView.setPadding(AndroidUtilities.dp(14), 0, AndroidUtilities.dp(16), 0);
duplicateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
duplicateView.setTag(2);
duplicateView.setText(LocaleController.getString("PaintDuplicate", R.string.PaintDuplicate));
duplicateView.setOnClickListener(v -> {
duplicateSelectedEntity();
if (!(entityView instanceof PhotoView)) {
TextView duplicateView = new TextView(getContext());
duplicateView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
duplicateView.setBackgroundDrawable(Theme.getSelectorDrawable(false));
duplicateView.setGravity(Gravity.CENTER_VERTICAL);
duplicateView.setEllipsize(TextUtils.TruncateAt.END);
duplicateView.setPadding(AndroidUtilities.dp(14), 0, AndroidUtilities.dp(16), 0);
duplicateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
duplicateView.setTag(2);
duplicateView.setText(LocaleController.getString("PaintDuplicate", R.string.PaintDuplicate));
duplicateView.setOnClickListener(v -> {
duplicateSelectedEntity();
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss(true);
}
});
parent.addView(duplicateView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss(true);
}
});
parent.addView(duplicateView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 48));
}
if (entityView instanceof PhotoView && ((PhotoView) entityView).hasSegmentedImage()) {
PhotoView photoView = (PhotoView) entityView;

View file

@ -97,7 +97,7 @@ public class MessageEntityView extends EntityView {
messageOwner.fwd_from = null;
}
messageOwner.voiceTranscriptionOpen = false;
MessageObject newMsg = new MessageObject(msg.currentAccount, messageOwner, msg.replyMessageObject, MessagesController.getInstance(msg.currentAccount).getUsers(), MessagesController.getInstance(msg.currentAccount).getChats(), null, null, true, true, 0, true, isRepostVideoPreview);
MessageObject newMsg = new MessageObject(msg.currentAccount, messageOwner, msg.replyMessageObject, MessagesController.getInstance(msg.currentAccount).getUsers(), MessagesController.getInstance(msg.currentAccount).getChats(), null, null, true, true, 0, true, isRepostVideoPreview, false);
messageObjects.add(newMsg);
}
// dateCell = new ChatActionCell(context, false, resourcesProvider) {

View file

@ -638,8 +638,8 @@ public class PhonebookShareAlert extends BottomSheet {
buttonTextView.setText(LocaleController.getString("ShareContactTitle", R.string.ShareContactTitle));
}
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), getThemedColor(Theme.key_featuredStickers_addButton), getThemedColor(Theme.key_featuredStickers_addButtonPressed)));
frameLayout.addView(buttonTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 42, Gravity.LEFT | Gravity.BOTTOM, 16, 16, 16, 16));
buttonTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), getThemedColor(Theme.key_featuredStickers_addButton), getThemedColor(Theme.key_featuredStickers_addButtonPressed)));
frameLayout.addView(buttonTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 14, 14, 14, 14));
buttonTextView.setOnClickListener(v -> {
if (isImport) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());

View file

@ -77,13 +77,19 @@ public class PipRoundVideoView implements NotificationCenter.NotificationCenterD
@SuppressLint("StaticFieldLeak")
private static PipRoundVideoView instance;
public class PipFrameLayout extends FrameLayout {
public PipFrameLayout(Context context) {
super(context);
}
}
public void show(Activity activity, Runnable closeRunnable) {
if (activity == null) {
return;
}
instance = this;
onCloseRunnable = closeRunnable;
windowView = new FrameLayout(activity) {
windowView = new PipFrameLayout(activity) {
private float startX;
private float startY;

View file

@ -967,7 +967,7 @@ public class PipVideoOverlay {
path.addRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(ROUNDED_CORNERS_DP), AndroidUtilities.dp(ROUNDED_CORNERS_DP), Path.Direction.CW);
}
};
contentView = new ViewGroup(context) {
contentView = new PipVideoViewGroup(context) {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
contentFrameLayout.layout(0, 0, pipWidth, pipHeight);
@ -1240,4 +1240,15 @@ public class PipVideoOverlay {
return mPrefs.getFloat("y", -1);
}
}
public static class PipVideoViewGroup extends ViewGroup {
public PipVideoViewGroup(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
}
}

View file

@ -268,7 +268,7 @@ public class PollVotesAlert extends BottomSheet {
private TLRPC.User currentUser;
private TLRPC.Chat currentChat;
private String lastName;
private CharSequence lastName;
private int lastStatus;
private TLRPC.FileLocation lastAvatar;
@ -296,9 +296,10 @@ public class PollVotesAlert extends BottomSheet {
nameTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setTextSize(16);
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 28 : 65, 14, LocaleController.isRTL ? 65 : 28, 0));
statusBadgeComponent = new StatusBadgeComponent(nameTextView);
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 24, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 28 : 65, 12, LocaleController.isRTL ? 65 : 28, 0));
statusBadgeComponent = new StatusBadgeComponent(nameTextView, 20);
}
public void setData(TLObject object, int num, boolean divider) {
@ -390,7 +391,7 @@ public class PollVotesAlert extends BottomSheet {
} else if (currentChat != null) {
newName = currentChat.title;
}
if (!newName.equals(lastName)) {
if (!TextUtils.equals(newName, lastName)) {
continueUpdate = true;
}
}
@ -412,13 +413,15 @@ public class PollVotesAlert extends BottomSheet {
if (currentUser != null) {
lastName = newName == null ? UserObject.getUserName(currentUser) : newName;
lastName = Emoji.replaceEmoji(lastName, nameTextView.getPaint().getFontMetricsInt(), false);
} else if (currentChat != null) {
lastName = currentChat.title;
lastName = Emoji.replaceEmoji(lastName, nameTextView.getPaint().getFontMetricsInt(), false);
} else {
lastName = "";
}
nameTextView.setText(lastName);
nameTextView.setRightDrawable(statusBadgeComponent.updateDrawable(currentUser, currentChat, Theme.getColor(Theme.key_chats_verifiedBackground), false));
nameTextView.setRightDrawable(statusBadgeComponent.updateDrawable(currentUser, currentChat, Theme.getColor(Theme.key_chats_verifiedBackground, resourcesProvider), false));
lastAvatar = photo;
if (currentChat != null) {

View file

@ -130,6 +130,8 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
public static final int TYPE_BOOSTS_FOR_REPLY_ICON = 26;
public static final int TYPE_BOOSTS_FOR_PROFILE_ICON = 27;
public static final int TYPE_PIN_SAVED_DIALOGS = 28;
private boolean canSendLink;
private int linkRow = -1;
private long dialogId;
@ -280,7 +282,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
private int requiredLvl = 0;
public LimitReachedBottomSheet(BaseFragment fragment, Context context, int type, int currentAccount, Theme.ResourcesProvider resourcesProvider) {
super(fragment, false, hasFixedSize(type), false, resourcesProvider);
super(context, fragment, false, hasFixedSize(type), false, resourcesProvider);
fixNavigationBar(Theme.getColor(Theme.key_dialogBackground, this.resourcesProvider));
this.parentFragment = fragment;
this.currentAccount = currentAccount;
@ -826,6 +828,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
private static boolean hasFixedSize(int type) {
return (
type == TYPE_PIN_DIALOGS ||
type == TYPE_PIN_SAVED_DIALOGS ||
type == TYPE_FOLDERS ||
type == TYPE_CHATS_IN_FOLDER ||
type == TYPE_LARGE_FILE ||
@ -1358,8 +1361,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
currentValue = MessagesController.getInstance(currentAccount).dialogFilters.size() - 1;
} else if (type == TYPE_ACCOUNTS) {
currentValue = UserConfig.getActivatedAccountsCount();
}
if (type == TYPE_PIN_DIALOGS) {
} else if (type == TYPE_PIN_DIALOGS) {
int pinnedCount = 0;
ArrayList<TLRPC.Dialog> dialogs = MessagesController.getInstance(currentAccount).getDialogs(0);
for (int a = 0, N = dialogs.size(); a < N; a++) {
@ -1685,6 +1687,13 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
limitParams.descriptionStr = LocaleController.formatString("LimitReachedPinDialogs", R.string.LimitReachedPinDialogs, limitParams.defaultLimit, limitParams.premiumLimit);
limitParams.descriptionStrPremium = LocaleController.formatString("LimitReachedPinDialogsPremium", R.string.LimitReachedPinDialogsPremium, limitParams.premiumLimit);
limitParams.descriptionStrLocked = LocaleController.formatString("LimitReachedPinDialogsLocked", R.string.LimitReachedPinDialogsLocked, limitParams.defaultLimit);
} else if (type == TYPE_PIN_SAVED_DIALOGS) {
limitParams.defaultLimit = MessagesController.getInstance(currentAccount).savedDialogsPinnedLimitDefault;
limitParams.premiumLimit = MessagesController.getInstance(currentAccount).savedDialogsPinnedLimitPremium;
limitParams.icon = R.drawable.msg_limit_pin;
limitParams.descriptionStr = LocaleController.formatString(R.string.LimitReachedPinSavedDialogs, limitParams.defaultLimit, limitParams.premiumLimit);
limitParams.descriptionStrPremium = LocaleController.formatString(R.string.LimitReachedPinSavedDialogsPremium, limitParams.premiumLimit);
limitParams.descriptionStrLocked = LocaleController.formatString(R.string.LimitReachedPinSavedDialogsLocked, limitParams.defaultLimit);
} else if (type == TYPE_PUBLIC_LINKS) {
limitParams.defaultLimit = MessagesController.getInstance(currentAccount).publicLinksLimitDefault;
limitParams.premiumLimit = MessagesController.getInstance(currentAccount).publicLinksLimitPremium;

View file

@ -417,7 +417,7 @@ public class UserSelectorBottomSheet extends BottomSheetWithRecyclerListView imp
View child = recyclerListView.getChildAt(i);
if (child instanceof SelectorUserCell) {
int position = recyclerListView.getChildAdapterPosition(child);
if (position <= 0) {
if (position - 1 < 0 || position - 1 >= items.size()) {
continue;
}
if (visibleItemsFrom == -1) {

View file

@ -1191,6 +1191,9 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
drawInternal(canvas, paint, false, 0, 0);
}
public boolean scaleByCanvas;
public Rect srcRect = new Rect();
public void drawInternal(Canvas canvas, Paint overridePaint, boolean drawInBackground, long time, int threadIndex) {
if (!canLoadFrames() || destroyWhenDone) {
return;
@ -1228,11 +1231,17 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable, Bitma
if (!needScale) {
canvas.drawBitmap(renderingBitmap, rect.left, rect.top, paint);
} else {
canvas.save();
canvas.translate(rect.left, rect.top);
canvas.scale(scaleX, scaleY);
canvas.drawBitmap(renderingBitmap, 0, 0, paint);
canvas.restore();
if (scaleByCanvas) {
// save-restore breaks cutting with xfer
srcRect.set(0, 0, renderingBitmap.getWidth(), renderingBitmap.getHeight());
canvas.drawBitmap(renderingBitmap, srcRect, rect, paint);
} else {
canvas.save();
canvas.translate(rect.left, rect.top);
canvas.scale(scaleX, scaleY);
canvas.drawBitmap(renderingBitmap, 0, 0, paint);
canvas.restore();
}
}
if (isRunning && !drawInBackground) {

View file

@ -15,8 +15,11 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import androidx.annotation.Keep;
import android.graphics.drawable.Drawable;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
@ -81,6 +84,15 @@ public class RadioButton extends View {
size = value;
}
private Drawable icon;
public void setIcon(Drawable drawable) {
icon = drawable;
if (icon != null) {
icon.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
invalidate();
}
public int getColor() {
return color;
}
@ -88,11 +100,17 @@ public class RadioButton extends View {
public void setColor(int color1, int color2) {
color = color1;
checkedColor = color2;
if (icon != null) {
icon.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
invalidate();
}
public void setBackgroundColor(int color1) {
color = color1;
if (icon != null) {
icon.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
invalidate();
}
@ -175,6 +193,15 @@ public class RadioButton extends View {
paint.setColor(c);
checkedPaint.setColor(c);
}
if (icon != null) {
icon.setBounds(
(int) (getWidth() / 2f - icon.getIntrinsicWidth() / 2f),
(int) (getHeight() / 2f - icon.getIntrinsicHeight() / 2f),
(int) (getWidth() / 2f + icon.getIntrinsicWidth() / 2f),
(int) (getHeight() / 2f + icon.getIntrinsicHeight() / 2f)
);
icon.draw(canvas);
}
if (bitmap != null) {
bitmap.eraseColor(0);
float rad = size / 2 - (1 + circleProgress) * AndroidUtilities.density;

View file

@ -1,15 +1,22 @@
package org.telegram.ui.Components.Reactions;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.dpf2;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import androidx.core.graphics.ColorUtils;
@ -48,6 +55,8 @@ public class ReactionsLayoutInBubble {
public float drawServiceShaderBackground;
private static Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static Paint tagPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static Paint cutTagPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
public boolean isSmall;
@ -104,14 +113,16 @@ public class ReactionsLayoutInBubble {
return 0;
}
public boolean tags;
public ReactionsLayoutInBubble(ChatMessageCell parentView) {
this.parentView = parentView;
currentAccount = UserConfig.selectedAccount;
paint.setColor(Theme.getColor(Theme.key_chat_inLoader, resourcesProvider));
textPaint.setColor(Theme.getColor(Theme.key_featuredStickers_buttonText, resourcesProvider));
textPaint.setTextSize(AndroidUtilities.dp(12));
textPaint.setTextSize(dp(12));
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
touchSlop = ViewConfiguration.get(ApplicationLoader.applicationContext).getScaledTouchSlop();
cutTagPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public static boolean equalsTLReaction(TLRPC.Reaction reaction, TLRPC.Reaction reaction1) {
@ -148,7 +159,7 @@ public class ReactionsLayoutInBubble {
// break;
// }
// }
ReactionButton button = new ReactionButton(old, reactionCount, isSmall);
ReactionButton button = new ReactionLayoutButton(old, reactionCount, isSmall);
reactionButtons.add(button);
if (!isSmall && messageObject.messageOwner.reactions.recent_reactions != null) {
ArrayList<TLObject> users = null;
@ -201,8 +212,8 @@ public class ReactionsLayoutInBubble {
}
}
if (isSmall && reactionCount.count > 1 && reactionCount.chosen) {
// TODO: also reuse here
reactionButtons.add(new ReactionButton(null, reactionCount, isSmall));
ReactionButton button2 = new ReactionLayoutButton(null, reactionCount, isSmall);
reactionButtons.add(button2);
reactionButtons.get(0).isSelected = false;
reactionButtons.get(1).isSelected = true;
reactionButtons.get(0).realCount = 1;
@ -248,29 +259,29 @@ public class ReactionsLayoutInBubble {
for (int i = 0; i < reactionButtons.size(); i++) {
ReactionButton button = reactionButtons.get(i);
if (button.isSmall) {
button.width = AndroidUtilities.dp(14);
button.height = AndroidUtilities.dp(14);
button.width = dp(14);
button.height = dp(14);
} else {
button.width = (int) (AndroidUtilities.dp(8) + AndroidUtilities.dp(20) + AndroidUtilities.dp(4));
button.width = (int) (dp(8) + dp(20) + dp(4));
if (button.avatarsDrawable != null && button.users.size() > 0) {
button.users.size();
int c1 = 1;
int c2 = button.users.size() > 1 ? button.users.size() - 1 : 0;
button.width += AndroidUtilities.dp(2) + c1 * AndroidUtilities.dp(20) + c2 * AndroidUtilities.dp(20) * 0.8f + AndroidUtilities.dp(1);
button.avatarsDrawable.height = AndroidUtilities.dp(26);
button.width += dp(2) + c1 * dp(20) + c2 * dp(20) * 0.8f + dp(1);
button.avatarsDrawable.height = dp(26);
} else {
button.width += button.counterDrawable.textPaint.measureText(button.countText) + AndroidUtilities.dp(8);
button.width += button.counterDrawable.textPaint.measureText(button.countText) + dp(8);
}
button.height = AndroidUtilities.dp(26);
button.height = dp(26);
}
if (currentX + button.width > availableWidth) {
currentX = 0;
currentY += button.height + AndroidUtilities.dp(4);
currentY += button.height + dp(4);
}
button.x = currentX;
button.y = currentY;
currentX += button.width + AndroidUtilities.dp(4);
currentX += button.width + dp(4);
if (currentX > maxWidth) {
maxWidth = currentX;
}
@ -299,7 +310,7 @@ public class ReactionsLayoutInBubble {
} else {
width = maxWidth;
}
height = currentY + (reactionButtons.size() == 0 ? 0 : AndroidUtilities.dp(26));
height = currentY + (reactionButtons.size() == 0 ? 0 : dp(26));
drawServiceShaderBackground = 0f;
}
@ -388,7 +399,7 @@ public class ReactionsLayoutInBubble {
button.fromBackgroundColor = lastButton.lastDrawnBackgroundColor;
button.animationType = ANIMATION_TYPE_MOVE;
if (button.count != lastButton.count) {
if (button.count != lastButton.count && button.counterDrawable != null) {
button.counterDrawable.setCount(lastButton.count, false);
button.counterDrawable.setCount(button.count, true);
}
@ -399,7 +410,7 @@ public class ReactionsLayoutInBubble {
if (lastButton.avatarsDrawable == null) {
lastButton.setUsers(new ArrayList<>());
}
if (!equalsUsersList(lastButton.users, button.users)) {
if (!equalsUsersList(lastButton.users, button.users) && button.avatarsDrawable != null) {
button.avatarsDrawable.animateFromState(lastButton.avatarsDrawable, currentAccount, false);
}
}
@ -485,7 +496,43 @@ public class ReactionsLayoutInBubble {
this.scrimViewReaction = scrimViewReaction;
}
public class ReactionButton {
public class ReactionLayoutButton extends ReactionButton {
public ReactionLayoutButton(ReactionButton reuseFrom, TLRPC.ReactionCount reactionCount, boolean isSmall) {
super(reuseFrom, currentAccount, parentView, reactionCount, isSmall, resourcesProvider);
}
@Override
protected boolean isPlaying() {
return ReactionsEffectOverlay.isPlaying(messageObject.getId(), messageObject.getGroupId(), visibleReaction);
}
@Override
protected boolean isOutOwner() {
return messageObject.isOutOwner();
}
@Override
protected float getDrawServiceShaderBackground() {
return drawServiceShaderBackground;
}
@Override
protected boolean supportsImageReceiverCache() {
return true;
}
@Override
protected ImageReceiver getImageReceiver() {
return animatedReactions.get(visibleReaction);
}
@Override
protected void removeImageReceiver() {
animatedReactions.remove(visibleReaction);
}
}
public static class ReactionButton {
private final TLRPC.ReactionCount reactionCount;
private final boolean isSmall;
@ -503,12 +550,12 @@ public class ReactionsLayoutInBubble {
public String key;
public boolean choosen;
String countText;
public String countText;
TLRPC.Reaction reaction;
VisibleReaction visibleReaction;
android.graphics.Rect drawingImageRect = new Rect();
int count;
public int count;
public int x;
public int y;
public int width;
@ -516,19 +563,31 @@ public class ReactionsLayoutInBubble {
ImageReceiver imageReceiver;
AnimatedEmojiDrawable animatedEmojiDrawable;
int animatedEmojiDrawableColor;
CounterView.CounterDrawable counterDrawable;
public CounterView.CounterDrawable counterDrawable;
int backgroundColor;
int textColor;
int serviceBackgroundColor;
int serviceTextColor;
int lastDrawnTextColor;
int lastDrawnBackgroundColor;
public int lastDrawnTextColor;
public int lastDrawnBackgroundColor;
boolean isSelected;
AvatarsDrawable avatarsDrawable;
ArrayList<TLObject> users;
public ReactionButton(ReactionButton reuseFrom, TLRPC.ReactionCount reactionCount, boolean isSmall) {
private final int currentAccount;
private final View parentView;
private final Theme.ResourcesProvider resourcesProvider;
protected int getCacheType() {
return AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW;
}
public ReactionButton(ReactionButton reuseFrom, int currentAccount, View parentView, TLRPC.ReactionCount reactionCount, boolean isSmall, Theme.ResourcesProvider resourcesProvider) {
this.currentAccount = currentAccount;
this.parentView = parentView;
this.resourcesProvider = resourcesProvider;
if (reuseFrom != null) {
counterDrawable = reuseFrom.counterDrawable;
}
@ -568,23 +627,31 @@ public class ReactionsLayoutInBubble {
imageReceiver.setImage(ImageLocation.getForDocument(r.center_icon), "40_40_lastreactframe", svgThumb, "webp", r, 1);
}
} else if (visibleReaction.documentId != 0) {
animatedEmojiDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW, currentAccount, visibleReaction.documentId);
animatedEmojiDrawable = new AnimatedEmojiDrawable(getCacheType(), currentAccount, visibleReaction.documentId);
}
}
counterDrawable.setSize(AndroidUtilities.dp(26), AndroidUtilities.dp(100));
counterDrawable.setSize(dp(26), dp(100));
counterDrawable.textPaint = textPaint;
counterDrawable.setCount(count, false);
counterDrawable.setType(CounterView.CounterDrawable.TYPE_CHAT_REACTIONS);
counterDrawable.gravity = Gravity.LEFT;
}
protected boolean isOutOwner() {
return false;
}
protected boolean drawCounter() {
return count != 0 || counterDrawable.countChangeProgress != 1f;
}
public void draw(Canvas canvas, float x, float y, float progress, float alpha, boolean drawOverlayScrim) {
wasDrawn = true;
ImageReceiver imageReceiver = animatedEmojiDrawable != null ? animatedEmojiDrawable.getImageReceiver() : this.imageReceiver;
if (isSmall && imageReceiver != null) {
imageReceiver.setAlpha(alpha);
drawingImageRect.set((int) x, (int) y, AndroidUtilities.dp(14), AndroidUtilities.dp(14));
drawingImageRect.set((int) x, (int) y, dp(14), dp(14));
imageReceiver.setImageCoords(drawingImageRect);
imageReceiver.setRoundRadius(0);
drawImage(canvas, alpha);
@ -592,13 +659,13 @@ public class ReactionsLayoutInBubble {
}
if (choosen) {
backgroundColor = Theme.getColor(messageObject.isOutOwner() ? Theme.key_chat_outReactionButtonBackground : Theme.key_chat_inReactionButtonBackground, resourcesProvider);
textColor = Theme.getColor(messageObject.isOutOwner() ? Theme.key_chat_outReactionButtonTextSelected : Theme.key_chat_inReactionButtonTextSelected, resourcesProvider);
serviceTextColor = Theme.getColor(messageObject.isOutOwner() ? Theme.key_chat_outReactionButtonBackground : Theme.key_chat_inReactionButtonBackground, resourcesProvider);
serviceBackgroundColor = Theme.getColor(messageObject.isOutOwner() ? Theme.key_chat_outBubble : Theme.key_chat_inBubble);
backgroundColor = Theme.getColor(isOutOwner() ? Theme.key_chat_outReactionButtonBackground : Theme.key_chat_inReactionButtonBackground, resourcesProvider);
textColor = Theme.getColor(isOutOwner() ? Theme.key_chat_outReactionButtonTextSelected : Theme.key_chat_inReactionButtonTextSelected, resourcesProvider);
serviceTextColor = Theme.getColor(isOutOwner() ? Theme.key_chat_outReactionButtonBackground : Theme.key_chat_inReactionButtonBackground, resourcesProvider);
serviceBackgroundColor = Theme.getColor(isOutOwner() ? Theme.key_chat_outBubble : Theme.key_chat_inBubble);
} else {
textColor = Theme.getColor(messageObject.isOutOwner() ? Theme.key_chat_outReactionButtonText : Theme.key_chat_inReactionButtonText, resourcesProvider);
backgroundColor = Theme.getColor(messageObject.isOutOwner() ? Theme.key_chat_outReactionButtonBackground : Theme.key_chat_inReactionButtonBackground, resourcesProvider);
textColor = Theme.getColor(isOutOwner() ? Theme.key_chat_outReactionButtonText : Theme.key_chat_inReactionButtonText, resourcesProvider);
backgroundColor = Theme.getColor(isOutOwner() ? Theme.key_chat_outReactionButtonBackground : Theme.key_chat_inReactionButtonBackground, resourcesProvider);
backgroundColor = ColorUtils.setAlphaComponent(backgroundColor, (int) (Color.alpha(backgroundColor) * 0.156f));
serviceTextColor = Theme.getColor(Theme.key_chat_serviceText, resourcesProvider);
serviceBackgroundColor = Color.TRANSPARENT;
@ -607,7 +674,6 @@ public class ReactionsLayoutInBubble {
textPaint.setColor(lastDrawnTextColor);
paint.setColor(lastDrawnBackgroundColor);
if (alpha != 1f) {
textPaint.setAlpha((int) (textPaint.getAlpha() * alpha));
paint.setAlpha((int) (paint.getAlpha() * alpha));
@ -622,22 +688,22 @@ public class ReactionsLayoutInBubble {
}
AndroidUtilities.rectTmp.set(x, y, x + w, y + height);
float rad = height / 2f;
if (drawServiceShaderBackground > 0) {
Paint paint1 = getThemedPaint(Theme.key_paint_chatActionBackground);
Paint paint2 = getThemedPaint(Theme.key_paint_chatActionBackgroundDarken);
if (getDrawServiceShaderBackground() > 0) {
Paint paint1 = Theme.getThemePaint(Theme.key_paint_chatActionBackground, resourcesProvider);
Paint paint2 = Theme.getThemePaint(Theme.key_paint_chatActionBackgroundDarken, resourcesProvider);
int oldAlpha = paint1.getAlpha();
int oldAlpha2 = paint2.getAlpha();
paint1.setAlpha((int) (oldAlpha * alpha * drawServiceShaderBackground));
paint2.setAlpha((int) (oldAlpha2 * alpha * drawServiceShaderBackground));
paint1.setAlpha((int) (oldAlpha * alpha * getDrawServiceShaderBackground()));
paint2.setAlpha((int) (oldAlpha2 * alpha * getDrawServiceShaderBackground()));
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, paint1);
if (hasGradientService()) {
if (resourcesProvider != null ? resourcesProvider.hasGradientService() : Theme.hasGradientService()) {
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, paint2);
}
paint1.setAlpha(oldAlpha);
paint2.setAlpha(oldAlpha2);
}
if (drawServiceShaderBackground < 1 && drawOverlayScrim) {
Theme.MessageDrawable messageBackground = parentView.getCurrentBackgroundDrawable(false);
if (drawOverlayScrim && getDrawServiceShaderBackground() < 1 && parentView instanceof ChatMessageCell) {
Theme.MessageDrawable messageBackground = ((ChatMessageCell) parentView).getCurrentBackgroundDrawable(false);
if (messageBackground != null) {
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, messageBackground.getPaint());
}
@ -647,12 +713,12 @@ public class ReactionsLayoutInBubble {
if (imageReceiver != null) {
int size, X;
if (animatedEmojiDrawable != null) {
size = AndroidUtilities.dp(24);
X = AndroidUtilities.dp(6);
imageReceiver.setRoundRadius(AndroidUtilities.dp(6));
size = dp(24);
X = dp(6);
imageReceiver.setRoundRadius(dp(6));
} else {
size = AndroidUtilities.dp(20);
X = AndroidUtilities.dp(8);
size = dp(20);
X = dp(8);
imageReceiver.setRoundRadius(0);
}
int Y = (int) ((height - size) / 2f);
@ -661,16 +727,16 @@ public class ReactionsLayoutInBubble {
drawImage(canvas, alpha);
}
if (counterDrawable != null && (count != 0 || counterDrawable.countChangeProgress != 1f)) {
if (counterDrawable != null && drawCounter()) {
canvas.save();
canvas.translate(x + AndroidUtilities.dp(8) + AndroidUtilities.dp(20) + AndroidUtilities.dp(2), y);
canvas.translate(x + dp(8) + dp(20) + dp(2), y);
counterDrawable.draw(canvas);
canvas.restore();
}
if (avatarsDrawable != null) {
canvas.save();
canvas.translate(x + AndroidUtilities.dp(10) + AndroidUtilities.dp(20) + AndroidUtilities.dp(2), y);
canvas.translate(x + dp(10) + dp(20) + dp(2), y);
avatarsDrawable.setAlpha(alpha);
avatarsDrawable.setTransitionProgress(progress);
avatarsDrawable.onDraw(canvas);
@ -678,9 +744,33 @@ public class ReactionsLayoutInBubble {
}
}
private void updateColors(float progress) {
lastDrawnTextColor = ColorUtils.blendARGB(fromTextColor, ColorUtils.blendARGB(textColor, serviceTextColor, drawServiceShaderBackground), progress);
lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, ColorUtils.blendARGB(backgroundColor, serviceBackgroundColor, drawServiceShaderBackground), progress);
protected void updateColors(float progress) {
lastDrawnTextColor = ColorUtils.blendARGB(fromTextColor, ColorUtils.blendARGB(textColor, serviceTextColor, getDrawServiceShaderBackground()), progress);
lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, ColorUtils.blendARGB(backgroundColor, serviceBackgroundColor, getDrawServiceShaderBackground()), progress);
}
protected boolean isPlaying() {
return false;
}
protected ImageReceiver getImageReceiver() {
return null;
}
protected void removeImageReceiver() {
}
protected boolean supportsImageReceiverCache() {
return false;
}
protected float getDrawServiceShaderBackground() {
return 0;
}
protected boolean drawTagDot() {
return true;
}
private void drawImage(Canvas canvas, float alpha) {
@ -688,8 +778,8 @@ public class ReactionsLayoutInBubble {
if (animatedEmojiDrawable != null && animatedEmojiDrawableColor != lastDrawnTextColor) {
animatedEmojiDrawable.setColorFilter(new PorterDuffColorFilter(animatedEmojiDrawableColor = lastDrawnTextColor, PorterDuff.Mode.SRC_IN));
}
if (drawImage && ((realCount > 1 || !ReactionsEffectOverlay.isPlaying(messageObject.getId(), messageObject.getGroupId(), visibleReaction)) || !isSelected)) {
ImageReceiver imageReceiver2 = animatedReactions.get(visibleReaction);
if (drawImage && (realCount > 1 || !isPlaying() || !isSelected)) {
ImageReceiver imageReceiver2 = getImageReceiver();
boolean drawStaticImage = true;
if (imageReceiver2 != null) {
if (imageReceiver2.getLottieAnimation() != null && imageReceiver2.getLottieAnimation().hasBitmap()) {
@ -699,7 +789,7 @@ public class ReactionsLayoutInBubble {
imageReceiver2.setAlpha(alpha);
if (alpha <= 0) {
imageReceiver2.onDetachedFromWindow();
animatedReactions.remove(visibleReaction);
removeImageReceiver();
}
} else {
if (imageReceiver2.getLottieAnimation() != null && !imageReceiver2.getLottieAnimation().isRunning()) {
@ -707,7 +797,7 @@ public class ReactionsLayoutInBubble {
float alpha1 = imageReceiver2.getAlpha() - 16f / 200;
if (alpha1 <= 0) {
imageReceiver2.onDetachedFromWindow();
animatedReactions.remove(visibleReaction);
removeImageReceiver();
} else {
imageReceiver2.setAlpha(alpha1);
}
@ -736,10 +826,10 @@ public class ReactionsLayoutInBubble {
avatarsDrawable = new AvatarsDrawable(parentView, false);
avatarsDrawable.transitionDuration = ChatListItemAnimator.DEFAULT_DURATION;
avatarsDrawable.transitionInterpolator = ChatListItemAnimator.DEFAULT_INTERPOLATOR;
avatarsDrawable.setSize(AndroidUtilities.dp(20));
avatarsDrawable.width = AndroidUtilities.dp(100);
avatarsDrawable.setSize(dp(20));
avatarsDrawable.width = dp(100);
avatarsDrawable.height = height;
avatarsDrawable.setAvatarsTextSize(AndroidUtilities.dp(22));
avatarsDrawable.setAvatarsTextSize(dp(22));
}
if (attached) {
avatarsDrawable.onAttachedToWindow();
@ -754,7 +844,9 @@ public class ReactionsLayoutInBubble {
}
}
public boolean attached;
public void attach() {
attached = true;
if (imageReceiver != null) {
imageReceiver.onAttachedToWindow();
}
@ -767,6 +859,7 @@ public class ReactionsLayoutInBubble {
}
public void detach() {
attached = false;
if (imageReceiver != null) {
imageReceiver.onDetachedFromWindow();
}
@ -947,6 +1040,17 @@ public class ReactionsLayoutInBubble {
return visibleReaction;
}
public TLRPC.Reaction toTLReaction() {
if (emojicon != null) {
TLRPC.TL_reactionEmoji r = new TLRPC.TL_reactionEmoji();
r.emoticon = emojicon;
return r;
}
TLRPC.TL_reactionCustomEmoji r = new TLRPC.TL_reactionCustomEmoji();
r.document_id = documentId;
return r;
}
public static VisibleReaction fromEmojicon(TLRPC.TL_availableReaction reaction) {
VisibleReaction visibleReaction = new VisibleReaction();
visibleReaction.emojicon = reaction.reaction;
@ -996,6 +1100,11 @@ public class ReactionsLayoutInBubble {
}
public boolean isSame(TLRPC.Reaction reaction) {
if (reaction instanceof TLRPC.TL_reactionEmoji) {
return TextUtils.equals(((TLRPC.TL_reactionEmoji) reaction).emoticon, emojicon);
} else if (reaction instanceof TLRPC.TL_reactionCustomEmoji) {
return ((TLRPC.TL_reactionCustomEmoji) reaction).document_id == documentId;
}
return false;
}
}

View file

@ -94,6 +94,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public final static int TYPE_DEFAULT = 0;
public final static int TYPE_STORY = 1;
public static final int TYPE_STORY_LIKES = 2;
public static final int TYPE_TAGS = 3;
private final static int ALPHA_DURATION = 150;
private final static float SIDE_SCALE = 0.6f;
@ -1053,7 +1054,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
return;
}
}
if (reactionsChat != null) {
if (type == TYPE_TAGS) {
allReactionsAvailable = UserConfig.getInstance(currentAccount).isPremium();
fillRecentReactionsList(visibleReactions);
} else if (reactionsChat != null) {
if (reactionsChat.available_reactions instanceof TLRPC.TL_chatReactionsAll) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(reactionsChat.id);
if (chat != null && !ChatObject.isChannelAndNotMegaGroup(chat)) {
@ -1127,20 +1131,59 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
private void fillRecentReactionsList(List<ReactionsLayoutInBubble.VisibleReaction> visibleReactions) {
if (!allReactionsAvailable) {
//fill default reactions
List<TLRPC.TL_availableReaction> enabledReactions = MediaDataController.getInstance(currentAccount).getEnabledReactionsList();
for (int i = 0; i < enabledReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(enabledReactions.get(i));
visibleReactions.add(visibleReaction);
if (type == TYPE_TAGS) {
ArrayList<TLRPC.Reaction> topReactions = MediaDataController.getInstance(currentAccount).getSavedReactions();
HashSet<ReactionsLayoutInBubble.VisibleReaction> hashSet = new HashSet<>();
int added = 0;
for (int i = 0; i < topReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(topReactions.get(i));
if (!hashSet.contains(visibleReaction)) {
hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction);
added++;
}
if (added == 16) {
break;
}
}
} else {
//fill default reactions
List<TLRPC.TL_availableReaction> enabledReactions = MediaDataController.getInstance(currentAccount).getEnabledReactionsList();
for (int i = 0; i < enabledReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(enabledReactions.get(i));
visibleReactions.add(visibleReaction);
}
}
return;
}
ArrayList<TLRPC.Reaction> topReactions = MediaDataController.getInstance(currentAccount).getTopReactions();
ArrayList<TLRPC.Reaction> topReactions;
if (type == TYPE_TAGS) {
topReactions = MediaDataController.getInstance(currentAccount).getSavedReactions();
} else {
topReactions = MediaDataController.getInstance(currentAccount).getTopReactions();
}
HashSet<ReactionsLayoutInBubble.VisibleReaction> hashSet = new HashSet<>();
int added = 0;
if (type == TYPE_TAGS) {
TLRPC.TL_messages_savedReactionsTags savedTags = MessagesController.getInstance(currentAccount).getSavedReactionTags();
if (savedTags != null) {
for (int i = 0; i < savedTags.tags.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(savedTags.tags.get(i).reaction);
if (!hashSet.contains(visibleReaction)) {
hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction);
added++;
}
if (added == 16) {
break;
}
}
}
}
for (int i = 0; i < topReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(topReactions.get(i));
if (!hashSet.contains(visibleReaction) && (UserConfig.getInstance(currentAccount).isPremium() || visibleReaction.documentId == 0)) {
if (!hashSet.contains(visibleReaction) && (type == TYPE_TAGS || UserConfig.getInstance(currentAccount).isPremium() || visibleReaction.documentId == 0)) {
hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction);
added++;
@ -1150,22 +1193,24 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
}
}
ArrayList<TLRPC.Reaction> recentReactions = MediaDataController.getInstance(currentAccount).getRecentReactions();
for (int i = 0; i < recentReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(recentReactions.get(i));
if (!hashSet.contains(visibleReaction)) {
hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction);
if (type != TYPE_TAGS || UserConfig.getInstance(currentAccount).isPremium()) {
ArrayList<TLRPC.Reaction> recentReactions = MediaDataController.getInstance(currentAccount).getRecentReactions();
for (int i = 0; i < recentReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(recentReactions.get(i));
if (!hashSet.contains(visibleReaction)) {
hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction);
}
}
}
//fill default reactions
List<TLRPC.TL_availableReaction> enabledReactions = MediaDataController.getInstance(currentAccount).getEnabledReactionsList();
for (int i = 0; i < enabledReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(enabledReactions.get(i));
if (!hashSet.contains(visibleReaction)) {
hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction);
//fill default reactions
List<TLRPC.TL_availableReaction> enabledReactions = MediaDataController.getInstance(currentAccount).getEnabledReactionsList();
for (int i = 0; i < enabledReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(enabledReactions.get(i));
if (!hashSet.contains(visibleReaction)) {
hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show more