Update to 8.3.0

This commit is contained in:
xaxtix 2021-12-07 16:02:02 +03:00
parent 23b70a3882
commit 64c32ace43
197 changed files with 9478 additions and 2944 deletions

View file

@ -67,9 +67,7 @@
<uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/>
<uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_READ"/>
<uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_WRITE"/>
<!-- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

View file

@ -38,7 +38,6 @@ import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
@ -48,12 +47,6 @@ import android.provider.CallLog;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.Settings;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import android.telephony.TelephonyManager;
import android.text.Layout;
import android.text.Selection;
@ -72,8 +65,8 @@ import android.util.StateSet;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
@ -95,8 +88,12 @@ import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import com.android.internal.telephony.ITelephony;
import com.google.android.exoplayer2.util.Log;
import com.google.android.gms.auth.api.phone.SmsRetriever;
import com.google.android.gms.auth.api.phone.SmsRetrieverClient;
import com.google.android.gms.tasks.Task;
@ -2254,6 +2251,10 @@ public class AndroidUtilities {
}
public static void appCenterLog(Throwable e) {
}
public static void addToClipboard(CharSequence str) {
try {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);

View file

@ -15,16 +15,22 @@ import android.os.Build;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static boolean DEBUG_PRIVATE_VERSION = false;
public static boolean LOGS_ENABLED = false;
public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 2470;
public static String BUILD_VERSION_STRING = "8.2.7";
public static int BUILD_VERSION = 2493;
public static String BUILD_VERSION_STRING = "8.3.0";
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
public static String APPCENTER_HASH = "a5b5c4f5-51da-dedc-9918-d9766a22ca7c";
// PUBLIC
public static boolean DEBUG_PRIVATE_VERSION = false;
// public static String APPCENTER_HASH_DEBUG = "f9726602-67c9-48d2-b5d0-4761f1c1a8f3";
// PRIVATE
//public static boolean DEBUG_PRIVATE_VERSION = true;
//public static String APPCENTER_HASH_DEBUG = DEBUG_PRIVATE_VERSION ? "29d0a6f1-b92f-493a-9fce-445681d767ec" : "f9726602-67c9-48d2-b5d0-4761f1c1a8f3";
//
public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT");
public static String PLAYSTORE_APP_URL = "https://play.google.com/store/apps/details?id=org.telegram.messenger";

View file

@ -1478,6 +1478,10 @@ public class ChatObject {
return chat == null || chat instanceof TLRPC.TL_chatEmpty || chat instanceof TLRPC.TL_chatForbidden || chat instanceof TLRPC.TL_channelForbidden || chat.left || chat.kicked || chat.deactivated;
}
public static boolean canSendAsPeers(TLRPC.Chat chat) {
return ChatObject.isChannel(chat) && chat.megagroup && (!TextUtils.isEmpty(chat.username) || chat.has_geo || chat.has_link);
}
public static boolean isChannel(TLRPC.Chat chat) {
return chat instanceof TLRPC.TL_channel || chat instanceof TLRPC.TL_channelForbidden;
}
@ -1551,6 +1555,21 @@ public class ChatObject {
return chat != null && chat.admin_rights != null && chat.admin_rights.anonymous;
}
public static long getSendAsPeerId(TLRPC.Chat chat, TLRPC.ChatFull chatFull) {
return getSendAsPeerId(chat, chatFull, false);
}
public static long getSendAsPeerId(TLRPC.Chat chat, TLRPC.ChatFull chatFull, boolean invertChannel) {
if (chat != null && chatFull != null && chatFull.default_send_as != null) {
TLRPC.Peer p = chatFull.default_send_as;
return p.user_id != 0 ? p.user_id : invertChannel ? -p.channel_id : p.channel_id;
}
if (chat != null && chat.admin_rights != null && chat.admin_rights.anonymous) {
return invertChannel ? -chat.id : chat.id;
}
return UserConfig.getInstance(UserConfig.selectedAccount).getClientUserId();
}
public static boolean canAddBotsToChat(TLRPC.Chat chat) {
if (isChannel(chat)) {
if (chat.megagroup && (chat.admin_rights != null && (chat.admin_rights.post_messages || chat.admin_rights.add_admins) || chat.creator)) {

View file

@ -25,7 +25,6 @@ public class ChatThemeController extends BaseController {
private static final long reloadTimeoutMs = 2 * 60 * 60 * 1000;
public static volatile DispatchQueue chatThemeQueue = new DispatchQueue("chatThemeQueue");
//private static final HashMap<Long, Bitmap> themeIdWallpaperMap = new HashMap<>();
private static final HashMap<Long, Bitmap> themeIdWallpaperThumbMap = new HashMap<>();
private static List<EmojiThemes> allChatThemes;
private static volatile long themesHash;

View file

@ -11,6 +11,7 @@ package org.telegram.messenger;
import android.util.Log;
import org.telegram.messenger.time.FastDateFormat;
import org.telegram.messenger.video.MediaCodecVideoConvertor;
import java.io.File;
import java.io.FileOutputStream;
@ -158,9 +159,16 @@ public class FileLog {
}
public static void e(final Throwable e) {
e(e, true);
}
public static void e(final Throwable e, boolean logToAppCenter) {
if (!BuildVars.LOGS_ENABLED) {
return;
}
if (BuildVars.DEBUG_VERSION && needSent(e)) {
AndroidUtilities.appCenterLog(e);
}
ensureInitied();
e.printStackTrace();
if (getInstance().streamWriter != null) {
@ -181,6 +189,13 @@ public class FileLog {
}
}
private static boolean needSent(Throwable e) {
if (e instanceof InterruptedException || e instanceof MediaCodecVideoConvertor.ConversionCanceledException) {
return false;
}
return true;
}
public static void d(final String message) {
if (!BuildVars.LOGS_ENABLED) {
return;

View file

@ -407,7 +407,7 @@ public class ImageLoader {
} else if (e instanceof FileNotFoundException) {
canRetry = false;
}
FileLog.e(e);
FileLog.e(e, false);
} finally {
try {
if (httpConnection != null) {
@ -521,20 +521,25 @@ public class ImageLoader {
fileOutputStream = new RandomAccessFile(cacheImage.tempFilePath, "rws");
}
} catch (Throwable e) {
boolean sentLogs = true;
if (e instanceof SocketTimeoutException) {
if (ApplicationLoader.isNetworkOnline()) {
canRetry = false;
}
sentLogs = false;
} else if (e instanceof UnknownHostException) {
canRetry = false;
sentLogs = false;
} else if (e instanceof SocketException) {
if (e.getMessage() != null && e.getMessage().contains("ECONNRESET")) {
canRetry = false;
}
sentLogs = false;
} else if (e instanceof FileNotFoundException) {
canRetry = false;
sentLogs = false;
}
FileLog.e(e);
FileLog.e(e, sentLogs);
}
}
@ -840,6 +845,7 @@ public class ImageLoader {
int autoRepeat = 1;
int[] colors = null;
String diceEmoji = null;
int fitzModifier = 0;
if (cacheImage.filter != null) {
String[] args = cacheImage.filter.split("_");
if (args.length >= 2) {
@ -871,15 +877,15 @@ public class ImageLoader {
}
if (args.length >= 5) {
if ("c1".equals(args[4])) {
colors = new int[]{0xf77e41, 0xcb7b55, 0xffb139, 0xf6b689, 0xffd140, 0xffcda7, 0xffdf79, 0xffdfc5};
fitzModifier = 12;
} else if ("c2".equals(args[4])) {
colors = new int[]{0xf77e41, 0xa45a38, 0xffb139, 0xdf986b, 0xffd140, 0xedb183, 0xffdf79, 0xf4c3a0};
fitzModifier = 3;
} else if ("c3".equals(args[4])) {
colors = new int[]{0xf77e41, 0x703a17, 0xffb139, 0xab673d, 0xffd140, 0xc37f4e, 0xffdf79, 0xd89667};
fitzModifier = 4;
} else if ("c4".equals(args[4])) {
colors = new int[]{0xf77e41, 0x4a2409, 0xffb139, 0x7d3e0e, 0xffd140, 0x965529, 0xffdf79, 0xa96337};
fitzModifier = 5;
} else if ("c5".equals(args[4])) {
colors = new int[]{0xf77e41, 0x200f0a, 0xffb139, 0x412924, 0xffd140, 0x593d37, 0xffdf79, 0x63453f};
fitzModifier = 6;
}
}
}
@ -918,9 +924,9 @@ public class ImageLoader {
}
}
if (compressed) {
lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, decompressGzip(cacheImage.finalFilePath), w, h, precache, limitFps, colors);
lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, decompressGzip(cacheImage.finalFilePath), w, h, precache, limitFps, null, fitzModifier);
} else {
lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, w, h, precache, limitFps, colors);
lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, w, h, precache, limitFps, null, fitzModifier);
}
}
lottieDrawable.setAutoRepeat(autoRepeat);
@ -1153,7 +1159,11 @@ public class ImageLoader {
}
}
} catch (Throwable e) {
FileLog.e(e);
boolean sentLog = true;
if (e instanceof FileNotFoundException) {
sentLog = false;
}
FileLog.e(e, sentLog);
}
if (cacheImage.type == ImageReceiver.TYPE_THUMB) {

View file

@ -915,7 +915,7 @@ public class LocationController extends BaseController implements NotificationCe
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, fusedLocationListener);
googleApiClient.disconnect();
} catch (Throwable e) {
FileLog.e(e);
FileLog.e(e, false);
}
}
locationManager.removeUpdates(gpsLocationListener);

View file

@ -61,6 +61,7 @@ import android.widget.FrameLayout;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.audioinfo.AudioInfo;
import org.telegram.messenger.video.MediaCodecVideoConvertor;
@ -3923,6 +3924,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
new Thread(() -> {
try {
boolean result = true;
if (Build.VERSION.SDK_INT >= 29) {
try {
@ -3944,10 +3946,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
if (selectedType == 0) {
uriToInsert = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
File dirDest = new File(Environment.DIRECTORY_PICTURES, "Telegram");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, dirDest + File.separator);
}
File dirDest = new File(Environment.DIRECTORY_PICTURES, "Telegram");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, dirDest + File.separator);
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, AndroidUtilities.generateFileName(0, extension));
contentValues.put(MediaStore.Images.Media.MIME_TYPE, mimeType);
} else if (selectedType == 1) {
@ -4823,6 +4823,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
MediaCodecVideoConvertor videoConvertor = new MediaCodecVideoConvertor();
boolean error = videoConvertor.convertVideo(videoPath, cacheFile,
rotationValue, isSecret,
originalWidth, originalHeight,
resultWidth, resultHeight,
framerate, bitrate, originalBitrate,
startTime, endTime, avatarStartTime,

View file

@ -140,6 +140,8 @@ public class MediaDataController extends BaseController {
//igonre
}
}
loadStickersByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME, false, true);
}
public static final int TYPE_IMAGE = 0;

View file

@ -1784,6 +1784,22 @@ public class MessageObject {
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite) {
TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite action = (TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite) event.action;
messageText = replaceWithLink(LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser), "un1", fromUser);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionToggleNoForwards) {
TLRPC.TL_channelAdminLogEventActionToggleNoForwards action = (TLRPC.TL_channelAdminLogEventActionToggleNoForwards) event.action;
boolean isChannel = ChatObject.isChannel(chat) && !chat.megagroup;
if (action.new_value) {
if (isChannel) {
messageText = replaceWithLink(LocaleController.getString("ActionForwardsRestrictedChannel", R.string.ActionForwardsRestrictedChannel), "un1", fromUser);
} else {
messageText = replaceWithLink(LocaleController.getString("ActionForwardsRestrictedGroup", R.string.ActionForwardsRestrictedGroup), "un1", fromUser);
}
} else {
if (isChannel) {
messageText = replaceWithLink(LocaleController.getString("ActionForwardsEnabledChannel", R.string.ActionForwardsEnabledChannel), "un1", fromUser);
} else {
messageText = replaceWithLink(LocaleController.getString("ActionForwardsEnabledGroup", R.string.ActionForwardsEnabledGroup), "un1", fromUser);
}
}
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionExportedInviteDelete) {
TLRPC.TL_channelAdminLogEventActionExportedInviteDelete action = (TLRPC.TL_channelAdminLogEventActionExportedInviteDelete) event.action;
messageText = replaceWithLink(LocaleController.formatString("ActionDeletedInviteLinkClickable", R.string.ActionDeletedInviteLinkClickable), "un1", fromUser);
@ -1841,6 +1857,9 @@ public class MessageObject {
messageText = replaceWithLink(LocaleController.getString("JoinedViaInviteLinkApproved", R.string.JoinedViaInviteLinkApproved), "un1", fromUser);
messageText = replaceWithLink(messageText, "un2", action.invite);
messageText = replaceWithLink(messageText, "un3", MessagesController.getInstance(currentAccount).getUser(action.approved_by));
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionSendMessage) {
message = ((TLRPC.TL_channelAdminLogEventActionSendMessage) event.action).message;
messageText = replaceWithLink(LocaleController.getString("EventLogSendMessages", R.string.EventLogSendMessages), "un1", fromUser);
} else {
messageText = "unsupported " + event.action;
}

View file

@ -21,7 +21,6 @@ import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
@ -29,6 +28,8 @@ import android.util.SparseIntArray;
import androidx.collection.LongSparseArray;
import androidx.core.app.NotificationManagerCompat;
import com.google.android.exoplayer2.util.Log;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.messenger.support.LongSparseIntArray;
import org.telegram.messenger.support.LongSparseLongArray;
@ -41,6 +42,7 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AlertsCreator;
@ -54,6 +56,7 @@ import org.telegram.ui.ProfileActivity;
import org.telegram.ui.Components.SwipeGestureSettingsView;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -174,6 +177,7 @@ public class MessagesController extends BaseController implements NotificationCe
private SparseIntArray migratedChats = new SparseIntArray();
private LongSparseArray<SponsoredMessagesInfo> sponsoredMessages = new LongSparseArray<>();
private LongSparseArray<SendAsPeersInfo> sendAsPeers = new LongSparseArray<>();
private HashMap<String, ArrayList<MessageObject>> reloadingWebpages = new HashMap<>();
private LongSparseArray<ArrayList<MessageObject>> reloadingWebpagesPending = new LongSparseArray<>();
@ -332,6 +336,12 @@ public class MessagesController extends BaseController implements NotificationCe
private boolean loading;
}
private class SendAsPeersInfo {
private TLRPC.TL_channels_sendAsPeers sendAsPeers;
private long loadTime;
private boolean loading;
}
public static class FaqSearchResult {
public String title;
@ -469,16 +479,16 @@ public class MessagesController extends BaseController implements NotificationCe
public TLRPC.SendMessageAction action;
}
public static int DIALOG_FILTER_FLAG_CONTACTS = 0x00000001;
public static int DIALOG_FILTER_FLAG_NON_CONTACTS = 0x00000002;
public static int DIALOG_FILTER_FLAG_GROUPS = 0x00000004;
public static int DIALOG_FILTER_FLAG_CHANNELS = 0x00000008;
public static int DIALOG_FILTER_FLAG_BOTS = 0x00000010;
public static int DIALOG_FILTER_FLAG_EXCLUDE_MUTED = 0x00000020;
public static int DIALOG_FILTER_FLAG_EXCLUDE_READ = 0x00000040;
public static int DIALOG_FILTER_FLAG_EXCLUDE_ARCHIVED = 0x00000080;
public static int DIALOG_FILTER_FLAG_ONLY_ARCHIVED = 0x00000100;
public static int DIALOG_FILTER_FLAG_ALL_CHATS = DIALOG_FILTER_FLAG_CONTACTS | DIALOG_FILTER_FLAG_NON_CONTACTS | DIALOG_FILTER_FLAG_GROUPS | DIALOG_FILTER_FLAG_CHANNELS | DIALOG_FILTER_FLAG_BOTS;
public static int DIALOG_FILTER_FLAG_CONTACTS = 0x00000001;
public static int DIALOG_FILTER_FLAG_NON_CONTACTS = 0x00000002;
public static int DIALOG_FILTER_FLAG_GROUPS = 0x00000004;
public static int DIALOG_FILTER_FLAG_CHANNELS = 0x00000008;
public static int DIALOG_FILTER_FLAG_BOTS = 0x00000010;
public static int DIALOG_FILTER_FLAG_EXCLUDE_MUTED = 0x00000020;
public static int DIALOG_FILTER_FLAG_EXCLUDE_READ = 0x00000040;
public static int DIALOG_FILTER_FLAG_EXCLUDE_ARCHIVED = 0x00000080;
public static int DIALOG_FILTER_FLAG_ONLY_ARCHIVED = 0x00000100;
public static int DIALOG_FILTER_FLAG_ALL_CHATS = DIALOG_FILTER_FLAG_CONTACTS | DIALOG_FILTER_FLAG_NON_CONTACTS | DIALOG_FILTER_FLAG_GROUPS | DIALOG_FILTER_FLAG_CHANNELS | DIALOG_FILTER_FLAG_BOTS;
public static class DialogFilter {
public int id;
@ -658,6 +668,7 @@ public class MessagesController extends BaseController implements NotificationCe
};
private static volatile MessagesController[] Instance = new MessagesController[UserConfig.MAX_ACCOUNT_COUNT];
public static MessagesController getInstance(int num) {
MessagesController localInstance = Instance[num];
if (localInstance == null) {
@ -1284,11 +1295,11 @@ public class MessagesController extends BaseController implements NotificationCe
}
TLRPC.TL_messages_getDialogFilters req = new TLRPC.TL_messages_getDialogFilters();
getConnectionsManager().sendRequest(req, (response, error) -> {
if (response instanceof TLRPC.Vector) {
getMessagesStorage().checkLoadedRemoteFilters((TLRPC.Vector) response);
} else {
AndroidUtilities.runOnUIThread(() -> loadingRemoteFilters = false);
}
if (response instanceof TLRPC.Vector) {
getMessagesStorage().checkLoadedRemoteFilters((TLRPC.Vector) response);
} else {
AndroidUtilities.runOnUIThread(() -> loadingRemoteFilters = false);
}
});
}
@ -1473,7 +1484,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "autologin_domains" : {
case "autologin_domains": {
HashSet<String> newDomains = new HashSet<>();
if (value.value instanceof TLRPC.TL_jsonArray) {
TLRPC.TL_jsonArray array = (TLRPC.TL_jsonArray) value.value;
@ -1492,7 +1503,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "autologin_token" : {
case "autologin_token": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString string = (TLRPC.TL_jsonString) value.value;
if (!string.value.equals(autologinToken)) {
@ -2553,6 +2564,7 @@ public class MessagesController extends BaseController implements NotificationCe
reloadingScheduledWebpages.clear();
reloadingScheduledWebpagesPending.clear();
sponsoredMessages.clear();
sendAsPeers.clear();
dialogs_dict.clear();
dialogs_read_inbox_max.clear();
loadingPinnedDialogs.clear();
@ -2702,6 +2714,20 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
public boolean isChatNoForwards(TLRPC.Chat chat) {
if (chat == null) return false;
if (chat.migrated_to != null) {
TLRPC.Chat migratedTo = getChat(chat.migrated_to.channel_id);
if (migratedTo != null)
return migratedTo.noforwards;
}
return chat.noforwards;
}
public boolean isChatNoForwards(long chatId) {
return isChatNoForwards(getChat(chatId));
}
public TLRPC.User getUser(Long id) {
if (id == 0) {
return UserConfig.getInstance(currentAccount).getCurrentUser();
@ -2940,7 +2966,7 @@ public class MessagesController extends BaseController implements NotificationCe
oldChat.username = chat.username;
oldChat.flags |= 64;
} else {
oldChat.flags = oldChat.flags &~ 64;
oldChat.flags = oldChat.flags & ~64;
oldChat.username = null;
}
if (chat.participants_count != 0) {
@ -2969,19 +2995,19 @@ public class MessagesController extends BaseController implements NotificationCe
int newFlags2 = chat.default_banned_rights != null ? chat.default_banned_rights.flags : 0;
oldChat.default_banned_rights = chat.default_banned_rights;
if (oldChat.default_banned_rights == null) {
oldChat.flags &=~ 262144;
oldChat.flags &= ~262144;
} else {
oldChat.flags |= 262144;
}
oldChat.banned_rights = chat.banned_rights;
if (oldChat.banned_rights == null) {
oldChat.flags &=~ 32768;
oldChat.flags &= ~32768;
} else {
oldChat.flags |= 32768;
}
oldChat.admin_rights = chat.admin_rights;
if (oldChat.admin_rights == null) {
oldChat.flags &=~ 16384;
oldChat.flags &= ~16384;
} else {
oldChat.flags |= 16384;
}
@ -3015,7 +3041,7 @@ public class MessagesController extends BaseController implements NotificationCe
chat.username = oldChat.username;
chat.flags |= 64;
} else {
chat.flags = chat.flags &~ 64;
chat.flags = chat.flags & ~64;
chat.username = null;
}
if (oldChat.participants_count != 0 && chat.participants_count == 0) {
@ -3445,7 +3471,11 @@ public class MessagesController extends BaseController implements NotificationCe
}
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.UserFull userFull = (TLRPC.UserFull) response;
TLRPC.TL_users_userFull res = (TLRPC.TL_users_userFull) response;
TLRPC.UserFull userFull = res.full_user;
putUsers(res.users, false);
putChats(res.chats, false);
res.full_user.user = getUser(res.full_user.id);
getMessagesStorage().updateUserInfo(userFull, false);
AndroidUtilities.runOnUIThread(() -> {
@ -3681,7 +3711,7 @@ public class MessagesController extends BaseController implements NotificationCe
SharedPreferences.Editor editor = notificationsPreferences.edit();
boolean bar_hidden = !settings.report_spam && !settings.add_contact && !settings.block_contact && !settings.share_contact && !settings.report_geo && !settings.invite_members;
if (BuildVars.LOGS_ENABLED) {
FileLog.d("peer settings loaded for " + dialogId + " add = " + settings.add_contact + " block = " + settings.block_contact + " spam = " + settings.report_spam + " share = " + settings.share_contact + " geo = " + settings.report_geo + " hide = " + bar_hidden + " distance = " + settings.geo_distance + " invite = " + settings.invite_members);
FileLog.d("peer settings loaded for " + dialogId + " add = " + settings.add_contact + " block = " + settings.block_contact + " spam = " + settings.report_spam + " share = " + settings.share_contact + " geo = " + settings.report_geo + " hide = " + bar_hidden + " distance = " + settings.geo_distance + " invite = " + settings.invite_members);
}
editor.putInt("dialog_bar_vis3" + dialogId, bar_hidden ? 1 : 2);
editor.putBoolean("dialog_bar_share" + dialogId, settings.share_contact);
@ -3692,6 +3722,9 @@ public class MessagesController extends BaseController implements NotificationCe
editor.putBoolean("dialog_bar_location" + dialogId, settings.report_geo);
editor.putBoolean("dialog_bar_archived" + dialogId, settings.autoarchived);
editor.putBoolean("dialog_bar_invite" + dialogId, settings.invite_members);
editor.putString("dialog_bar_chat_with_admin_title" + dialogId, settings.request_chat_title);
editor.putBoolean("dialog_bar_chat_with_channel" + dialogId, settings.request_chat_broadcast);
editor.putInt("dialog_bar_chat_with_date" + dialogId, settings.request_chat_date);
if (notificationsPreferences.getInt("dialog_bar_distance" + dialogId, -1) != -2) {
if ((settings.flags & 64) != 0) {
editor.putInt("dialog_bar_distance" + dialogId, settings.geo_distance);
@ -3736,7 +3769,12 @@ public class MessagesController extends BaseController implements NotificationCe
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
loadingPeerSettings.remove(dialogId);
if (response != null) {
savePeerSettings(dialogId, (TLRPC.TL_peerSettings) response, false);
TLRPC.TL_messages_peerSettings res = (TLRPC.TL_messages_peerSettings) response;
TLRPC.TL_peerSettings settings = res.settings;
putUsers(res.users, false);
putChats(res.chats, false);
savePeerSettings(dialogId, settings, false);
}
}));
}
@ -4688,9 +4726,9 @@ public class MessagesController extends BaseController implements NotificationCe
if (offset == 0) {
getMessagesStorage().deleteUserChatHistory(-chat.id, user.id);
}
TLRPC.TL_channels_deleteUserHistory req = new TLRPC.TL_channels_deleteUserHistory();
TLRPC.TL_channels_deleteParticipantHistory req = new TLRPC.TL_channels_deleteParticipantHistory();
req.channel = getInputChannel(chat);
req.user_id = getInputUser(user);
req.participant = getInputPeer(user);
getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.TL_messages_affectedHistory res = (TLRPC.TL_messages_affectedHistory) response;
@ -4891,6 +4929,24 @@ public class MessagesController extends BaseController implements NotificationCe
getMessagesStorage().deleteDialog(did, onlyHistory);
return;
}
for (int i = 0; i < sendAsPeers.size(); i++) {
SendAsPeersInfo sendAsInfo = sendAsPeers.valueAt(i);
if (sendAsInfo.sendAsPeers != null) {
for (int j = 0; j < sendAsInfo.sendAsPeers.chats.size(); j++) {
if (sendAsInfo.sendAsPeers.chats.get(j).id == -did) {
sendAsInfo.sendAsPeers.chats.remove(j);
break;
}
}
for (int j = 0; j < sendAsInfo.sendAsPeers.peers.size(); j++) {
if (sendAsInfo.sendAsPeers.peers.get(j).channel_id == -did || sendAsInfo.sendAsPeers.peers.get(j).chat_id == -did) {
sendAsInfo.sendAsPeers.peers.remove(j);
break;
}
}
}
}
sendAsPeers.remove(did);
if (first == 1 && max_id == 0) {
TLRPC.InputPeer peerFinal = peer;
getMessagesStorage().getDialogMaxMessageId(did, (param) -> {
@ -5956,7 +6012,7 @@ public class MessagesController extends BaseController implements NotificationCe
String emoji = ((TLRPC.TL_sendMessageEmojiInteractionSeen) pu.action).emoticon;
String printingString;
if (key < 0 && !isEncryptedChat) {
printingString= LocaleController.formatString("IsEnjoyngAnimations", R.string.IsEnjoyngAnimations, getUserNameForTyping(user), emoji);
printingString = LocaleController.formatString("IsEnjoyngAnimations", R.string.IsEnjoyngAnimations, getUserNameForTyping(user), emoji);
} else {
printingString = LocaleController.formatString("EnjoyngAnimations", R.string.EnjoyngAnimations, emoji);
}
@ -6040,12 +6096,13 @@ public class MessagesController extends BaseController implements NotificationCe
public boolean sendTyping(long dialogId, int threadMsgId, int action, int classGuid) {
return sendTyping(dialogId, threadMsgId, action, null, classGuid);
}
public boolean sendTyping(long dialogId, int threadMsgId, int action, String emojicon, int classGuid) {
if (action < 0 || action >= sendingTypings.length || dialogId == 0) {
return false;
}
if (dialogId < 0) {
if (ChatObject.shouldSendAnonymously(getChat(-dialogId))) {
if (ChatObject.getSendAsPeerId(getChat(-dialogId), getChatFull(-dialogId)) != UserConfig.getInstance(UserConfig.selectedAccount).getClientUserId()) {
return false;
}
} else {
@ -6390,7 +6447,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
public void processLoadedMessages(TLRPC.messages_Messages messagesRes, int resCount, long dialogId, long mergeDialogId, int count, int max_id, int offset_date, boolean isCache, int classGuid,
int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isEnd, int mode, int threadMessageId, int loadIndex, boolean queryFromServer, int mentionsCount, boolean needProcess) {
int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isEnd, int mode, int threadMessageId, int loadIndex, boolean queryFromServer, int mentionsCount, boolean needProcess) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("processLoadedMessages size " + messagesRes.messages.size() + " in chat " + dialogId + " count " + count + " max_id " + max_id + " cache " + isCache + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer);
}
@ -7879,7 +7936,7 @@ public class MessagesController extends BaseController implements NotificationCe
allDialogs.add(dialog);
}
sortDialogs(migrate ? chatsDict : null);
putAllNeededDraftDialogs();
if (loadType != DIALOGS_LOAD_TYPE_CHANNEL && loadType != DIALOGS_LOAD_TYPE_UNKNOWN) {
@ -9090,6 +9147,39 @@ public class MessagesController extends BaseController implements NotificationCe
});
}
public void setDefaultSendAs(long chatId, long newPeer) {
TLRPC.ChatFull cachedFull = getChatFull(-chatId);
if (cachedFull != null) {
cachedFull.default_send_as = getPeer(newPeer);
getMessagesStorage().updateChatInfo(cachedFull, false);
getNotificationCenter().postNotificationName(NotificationCenter.updateDefaultSendAsPeer, chatId, cachedFull.default_send_as);
}
TLRPC.TL_messages_saveDefaultSendAs req = new TLRPC.TL_messages_saveDefaultSendAs();
req.peer = getInputPeer(chatId);
req.send_as = getInputPeer(newPeer);
getConnectionsManager().sendRequest(req, (response, error) -> {
if (response instanceof TLRPC.TL_boolTrue) {
TLRPC.ChatFull full = getChatFull(-chatId);
if (full == null) loadFullChat(-chatId, 0, true);
} else if (error != null && error.code == 400) {
loadFullChat(-chatId, 0, true);
}
}, ConnectionsManager.RequestFlagInvokeAfter);
}
public void toggleChatNoForwards(long chatId, boolean enabled) {
TLRPC.TL_messages_toggleNoForwards req = new TLRPC.TL_messages_toggleNoForwards();
req.peer = getInputPeer(-chatId);
req.enabled = enabled;
getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
processUpdates((TLRPC.Updates) response, false);
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT));
}
}, ConnectionsManager.RequestFlagInvokeAfter);
}
public void toogleChannelSignatures(long chatId, boolean enabled) {
TLRPC.TL_channels_toggleSignatures req = new TLRPC.TL_channels_toggleSignatures();
req.channel = getInputChannel(chatId);
@ -9468,7 +9558,21 @@ public class MessagesController extends BaseController implements NotificationCe
if (type == 1) {
unregistedPush();
TLRPC.TL_auth_logOut req = new TLRPC.TL_auth_logOut();
getConnectionsManager().sendRequest(req, (response, error) -> getConnectionsManager().cleanup(false));
getConnectionsManager().sendRequest(req, (response, error) -> {
getConnectionsManager().cleanup(false);
AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_auth_loggedOut) {
TLRPC.TL_auth_loggedOut res = (TLRPC.TL_auth_loggedOut) response;
if (((TLRPC.TL_auth_loggedOut) response).future_auth_token != null) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
SerializedData data = new SerializedData(response.getObjectSize());
res.serializeToStream(data);
preferences.edit().putString("log_out_token_" + count, Utilities.bytesToHex(data.toByteArray())).putInt("count", count + 1).apply();
}
}
});
});
} else {
getConnectionsManager().cleanup(type == 2);
}
@ -9506,7 +9610,51 @@ public class MessagesController extends BaseController implements NotificationCe
getContactsController().deleteUnknownAppAccounts();
}
public static ArrayList<TLRPC.TL_auth_loggedOut> getSavedLogOutTokens() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
if (count == 0) {
return null;
}
ArrayList<TLRPC.TL_auth_loggedOut> tokens = new ArrayList<>();
for (int i = 0; i < count; i++) {
String value = preferences.getString("log_out_token_" + i, "");
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
// try {
TLRPC.TL_auth_loggedOut token = TLRPC.TL_auth_loggedOut.TLdeserialize(serializedData, serializedData.readInt32(true), true);
if (token != null) {
tokens.add(token);
}
// } catch (Throwable e) {
// FileLog.e(e);
// }
}
return tokens;
}
public static void saveLogOutTokens(ArrayList<TLRPC.TL_auth_loggedOut> tokens) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
ArrayList<TLRPC.TL_auth_loggedOut> activeTokens = new ArrayList<>();
preferences.edit().clear().apply();
int date = (int) (System.currentTimeMillis() / 1000L);
for (int i = 0; i < Math.min(20, tokens.size()); i++) {
activeTokens.add(tokens.get(i));
}
if (activeTokens.size() > 0) {
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("count", activeTokens.size());
for (int i = 0; i < activeTokens.size(); i++) {
SerializedData data = new SerializedData(activeTokens.get(i).getObjectSize());
activeTokens.get(i).serializeToStream(data);
editor.putString("log_out_token_" + i, Utilities.bytesToHex(data.toByteArray()));
}
editor.apply();
}
}
private boolean gettingAppChangelog;
public void generateUpdateMessage() {
if (gettingAppChangelog || BuildVars.DEBUG_VERSION || SharedConfig.lastUpdateVersion == null || SharedConfig.lastUpdateVersion.equals(BuildVars.BUILD_VERSION_STRING)) {
return;
@ -13139,7 +13287,7 @@ public class MessagesController extends BaseController implements NotificationCe
chat.default_banned_rights = update.default_banned_rights;
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.channelRightsUpdated, chat));
}
} else if (baseUpdate instanceof TLRPC.TL_updateBotCommands) {
} else if (baseUpdate instanceof TLRPC.TL_updateBotCommands) {
TLRPC.TL_updateBotCommands update = (TLRPC.TL_updateBotCommands) baseUpdate;
getMediaDataController().updateBotInfo(MessageObject.getPeerId(update.peer), update);
} else if (baseUpdate instanceof TLRPC.TL_updateStickerSets) {
@ -13371,7 +13519,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (userFull != null) {
userFull.ttl_period = updatePeerHistoryTTL.ttl_period;
if (userFull.ttl_period == 0) {
userFull.flags &=~ 16384;
userFull.flags &= ~16384;
} else {
userFull.flags |= 16384;
}
@ -13852,6 +14000,61 @@ public class MessagesController extends BaseController implements NotificationCe
return null;
}
public TLRPC.TL_channels_sendAsPeers getSendAsPeers(long dialogId) {
SendAsPeersInfo info = sendAsPeers.get(dialogId);
if (info != null && (info.loading || Math.abs(SystemClock.elapsedRealtime() - info.loadTime) <= 5 * 60 * 1000)) {
return info.sendAsPeers;
}
TLRPC.Chat chat = getChat(-dialogId);
if (chat == null || !ChatObject.canSendAsPeers(chat)) {
return null;
}
info = new SendAsPeersInfo();
info.loading = true;
sendAsPeers.put(dialogId, info);
SendAsPeersInfo infoFinal = info;
TLRPC.TL_channels_getSendAs req = new TLRPC.TL_channels_getSendAs();
req.peer = getInputPeer(dialogId);
getConnectionsManager().sendRequest(req, (response, error) -> {
TLRPC.TL_channels_sendAsPeers result;
if (response != null) {
TLRPC.TL_channels_sendAsPeers res = (TLRPC.TL_channels_sendAsPeers) response;
if (res.peers.isEmpty()) {
result = null;
} else {
result = res;
AndroidUtilities.runOnUIThread(() -> {
putUsers(res.users, false);
putChats(res.chats, false);
});
final LongSparseArray<TLRPC.User> usersDict = new LongSparseArray<>();
final LongSparseArray<TLRPC.Chat> chatsDict = new LongSparseArray<>();
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User u = res.users.get(a);
usersDict.put(u.id, u);
}
for (int a = 0; a < res.chats.size(); a++) {
TLRPC.Chat c = res.chats.get(a);
chatsDict.put(c.id, c);
}
}
} else {
result = null;
}
AndroidUtilities.runOnUIThread(() -> {
if (result == null) {
sendAsPeers.remove(dialogId);
} else {
infoFinal.loadTime = SystemClock.elapsedRealtime();
infoFinal.sendAsPeers = result;
getNotificationCenter().postNotificationName(NotificationCenter.didLoadSendAsPeers, dialogId, result);
}
});
});
return null;
}
public CharSequence getPrintingString(long dialogId, int threadId, boolean isDialog) {
if (isDialog && DialogObject.isUserDialog(dialogId)) {
TLRPC.User user = getUser(dialogId);
@ -14613,8 +14816,38 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
public void deleteMessagesRange(long dialogId, long channelId, int minDate, int maxDate, boolean forAll, Runnable callback) {
TLRPC.TL_messages_deleteHistory req = new TLRPC.TL_messages_deleteHistory();
req.peer = getInputPeer(dialogId);
req.flags = (1 << 2) | (1 << 3);
req.min_date = minDate;
req.max_date = maxDate;
req.revoke = forAll;
getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.TL_messages_affectedHistory res = (TLRPC.TL_messages_affectedHistory) response;
processNewDifferenceParams(-1, res.pts, -1, res.pts_count);
getMessagesStorage().getStorageQueue().postRunnable(() -> {
ArrayList<Integer> dbMessages = getMessagesStorage().getCachedMessagesInRange(dialogId, minDate, maxDate);
getMessagesStorage().markMessagesAsDeleted(dialogId, dbMessages, false, true, false);
getMessagesStorage().updateDialogsWithDeletedMessages(dialogId, 0, dbMessages, null, false);
AndroidUtilities.runOnUIThread(() -> {
getNotificationCenter().postNotificationName(NotificationCenter.messagesDeleted, dbMessages, channelId, false);
callback.run();
});
});
} else {
AndroidUtilities.runOnUIThread(() -> {
callback.run();
});
}
});
}
public interface MessagesLoadedCallback {
void onMessagesLoaded(boolean fromCache);
void onError();
}
}

View file

@ -50,6 +50,25 @@ import androidx.collection.LongSparseArray;
public class MessagesStorage extends BaseController {
public ArrayList<Integer> getCachedMessagesInRange(long dialogId, int minDate, int maxDate) {
ArrayList<Integer> messageIds = new ArrayList<>();
try {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid FROM messages_v2 WHERE uid = %d AND date >= %d AND date <= %d", dialogId, minDate, maxDate));
try {
while (cursor.next()) {
int mid = cursor.intValue(0);
messageIds.add(mid);
}
} catch (Exception e) {
FileLog.e(e);
}
cursor.dispose();
} catch (Exception e) {
FileLog.e(e);
}
return messageIds;
}
public interface IntCallback {
void run(int param);
}
@ -10571,7 +10590,7 @@ public class MessagesStorage extends BaseController {
try {
database.executeFast(String.format(Locale.US, "UPDATE media_holes_v2 SET end = %d WHERE uid = %d AND type = %d AND start = %d AND end = %d", minId, did, hole.type, hole.start, hole.end)).stepThis().dispose();
} catch (Exception e) {
FileLog.e(e);
FileLog.e(e, false);
}
}
} else if (minId <= hole.start + 1) {
@ -10579,7 +10598,7 @@ public class MessagesStorage extends BaseController {
try {
database.executeFast(String.format(Locale.US, "UPDATE media_holes_v2 SET start = %d WHERE uid = %d AND type = %d AND start = %d AND end = %d", maxId, did, hole.type, hole.start, hole.end)).stepThis().dispose();
} catch (Exception e) {
FileLog.e(e);
FileLog.e(e, false);
}
}
} else {
@ -10633,7 +10652,7 @@ public class MessagesStorage extends BaseController {
try {
database.executeFast(String.format(Locale.US, "UPDATE " + table + " SET end = %d WHERE uid = %d AND start = %d AND end = %d", minId, did, hole.start, hole.end)).stepThis().dispose();
} catch (Exception e) {
FileLog.e(e);
FileLog.e(e, false);
}
}
} else if (minId <= hole.start + 1) {
@ -10641,7 +10660,7 @@ public class MessagesStorage extends BaseController {
try {
database.executeFast(String.format(Locale.US, "UPDATE " + table + " SET start = %d WHERE uid = %d AND start = %d AND end = %d", maxId, did, hole.start, hole.end)).stepThis().dispose();
} catch (Exception e) {
FileLog.e(e);
FileLog.e(e, false);
}
}
} else {

View file

@ -33,6 +33,8 @@ public class NotificationCenter {
public static final int changeRepliesCounter = totalEvents++;
public static final int messagesDidLoad = totalEvents++;
public static final int didLoadSponsoredMessages = totalEvents++;
public static final int didLoadSendAsPeers = totalEvents++;
public static final int updateDefaultSendAsPeer = totalEvents++;
public static final int messagesDidLoadWithoutProcess = totalEvents++;
public static final int loadingMessagesFailed = totalEvents++;
public static final int messageReceivedByAck = totalEvents++;

View file

@ -1221,13 +1221,13 @@ public class NotificationsController extends BaseController {
try {
for (int i = 0, N = MessagesController.getInstance(a).allDialogs.size(); i < N; i++) {
TLRPC.Dialog dialog = MessagesController.getInstance(a).allDialogs.get(i);
if (DialogObject.isChatDialog(dialog.id)) {
if (dialog != null && DialogObject.isChatDialog(dialog.id)) {
TLRPC.Chat chat = getMessagesController().getChat(-dialog.id);
if (ChatObject.isNotInChat(chat)) {
continue;
}
}
if (dialog.unread_count != 0) {
if (dialog != null && dialog.unread_count != 0) {
count += dialog.unread_count;
}
}

View file

@ -1881,16 +1881,20 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
newMsg.from_id = peer_id;
}
newMsg.post = true;
} else if (ChatObject.shouldSendAnonymously(chat)) {
newMsg.from_id = peer_id;
if (rank != null) {
newMsg.post_author = rank;
newMsg.flags |= 65536;
}
} else {
newMsg.from_id = new TLRPC.TL_peerUser();
newMsg.from_id.user_id = myId;
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
long fromPeerId = ChatObject.getSendAsPeerId(chat, getMessagesController().getChatFull(-peer), true);
if (fromPeerId == myId) {
newMsg.from_id = new TLRPC.TL_peerUser();
newMsg.from_id.user_id = myId;
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
} else {
newMsg.from_id = getMessagesController().getPeer(fromPeerId);
if (rank != null) {
newMsg.post_author = rank;
newMsg.flags |= 65536;
}
}
}
if (newMsg.random_id == 0) {
newMsg.random_id = getNextRandomId();
@ -3016,6 +3020,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
request.random_id = random_id != 0 ? random_id : getNextRandomId();
request.message = "";
request.media = game;
long fromId = ChatObject.getSendAsPeerId(getMessagesController().getChat(peer.chat_id), getMessagesController().getChatFull(peer.chat_id));
if (fromId != UserConfig.getInstance(currentAccount).getClientUserId()) {
request.send_as = getMessagesController().getInputPeer(fromId);
}
final long newTaskId;
if (taskId == 0) {
NativeByteBuffer data = null;
@ -3100,7 +3108,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
int type = -1;
boolean isChannel = false;
boolean forceNoSoundVideo = false;
boolean anonymously = false;
TLRPC.Peer fromPeer = null;
String rank = null;
long linkedToGroup = 0;
TLRPC.EncryptedChat encryptedChat = null;
@ -3119,14 +3127,12 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
} else if (sendToPeer instanceof TLRPC.TL_inputPeerChannel) {
TLRPC.Chat chat = getMessagesController().getChat(sendToPeer.channel_id);
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(chat.id);
isChannel = chat != null && !chat.megagroup;
if (isChannel && chat.has_link) {
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(chat.id);
if (chatFull != null) {
linkedToGroup = chatFull.linked_chat_id;
}
if (isChannel && chat.has_link && chatFull != null) {
linkedToGroup = chatFull.linked_chat_id;
}
anonymously = ChatObject.shouldSendAnonymously(chat);
fromPeer = getMessagesController().getPeer(ChatObject.getSendAsPeerId(chat, chatFull, true));
}
try {
@ -3426,8 +3432,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (isChannel && sendToPeer != null) {
newMsg.from_id = new TLRPC.TL_peerChannel();
newMsg.from_id.channel_id = sendToPeer.channel_id;
} else if (anonymously) {
newMsg.from_id = getMessagesController().getPeer(peer);
} else if (fromPeer != null) {
newMsg.from_id = fromPeer;
if (rank != null) {
newMsg.post_author = rank;
newMsg.flags |= 65536;
@ -3637,6 +3643,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
reqSend.silent = newMsg.silent;
reqSend.peer = sendToPeer;
reqSend.random_id = newMsg.random_id;
if (newMsg.from_id != null) {
reqSend.send_as = getMessagesController().getInputPeer(newMsg.from_id);
}
if (newMsg.reply_to != null && newMsg.reply_to.reply_to_msg_id != 0) {
reqSend.flags |= 1;
reqSend.reply_to_msg_id = newMsg.reply_to.reply_to_msg_id;
@ -3996,6 +4005,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
request.reply_to_msg_id = newMsg.reply_to.reply_to_msg_id;
}
request.random_id = newMsg.random_id;
if (newMsg.from_id != null) {
request.send_as = getMessagesController().getInputPeer(newMsg.from_id);
}
request.media = inputMedia;
request.message = caption;
if (entities != null && !entities.isEmpty()) {
@ -4371,6 +4383,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_messages_sendInlineBotResult reqSend = new TLRPC.TL_messages_sendInlineBotResult();
reqSend.peer = sendToPeer;
reqSend.random_id = newMsg.random_id;
if (newMsg.from_id != null) {
reqSend.send_as = getMessagesController().getInputPeer(newMsg.from_id);
}
reqSend.hide_via = !params.containsKey("bot");
if (newMsg.reply_to != null && newMsg.reply_to.reply_to_msg_id != 0) {
reqSend.flags |= 1;

View file

@ -136,6 +136,7 @@ public class SharedConfig {
public static int distanceSystemType;
public static int mediaColumnsCount = 3;
public static int fastScrollHintCount = 3;
public static boolean dontAskManageStorage;
static {
loadConfig();
@ -375,6 +376,7 @@ public class SharedConfig {
dayNightThemeSwitchHintCount = preferences.getInt("dayNightThemeSwitchHintCount", 3);
mediaColumnsCount = preferences.getInt("mediaColumnsCount", 3);
fastScrollHintCount = preferences.getInt("fastScrollHintCount", 3);
dontAskManageStorage = preferences.getBoolean("dontAskManageStorage", false);
preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
showNotificationsForAllAccounts = preferences.getBoolean("AllAccounts", true);
@ -1161,4 +1163,9 @@ public class SharedConfig {
ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().putInt("fastScrollHintCount", fastScrollHintCount).apply();
}
}
public static void setDontAskManageStorage(boolean b) {
dontAskManageStorage = b;
ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().putBoolean("dontAskManageStorage", dontAskManageStorage).apply();
}
}

View file

@ -142,7 +142,6 @@ public class SvgHelper {
height = h;
}
@Override
public void draw(Canvas canvas) {
if (currentColorKey != null) {
@ -287,11 +286,15 @@ public class SvgHelper {
}
public static Bitmap getBitmap(int res, int width, int height, int color) {
return getBitmap(res, width, height, color, 1f);
}
public static Bitmap getBitmap(int res, int width, int height, int color, float scale) {
try (InputStream stream = ApplicationLoader.applicationContext.getResources().openRawResource(res)) {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(width, height, color, false);
SVGHandler handler = new SVGHandler(width, height, color, false, scale);
xr.setContentHandler(handler);
xr.parse(new InputSource(stream));
return handler.getBitmap();
@ -306,7 +309,7 @@ public class SvgHelper {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(width, height, white ? 0xffffffff : null, false);
SVGHandler handler = new SVGHandler(width, height, white ? 0xffffffff : null, false, 1f);
xr.setContentHandler(handler);
xr.parse(new InputSource(stream));
return handler.getBitmap();
@ -321,7 +324,7 @@ public class SvgHelper {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(width, height, white ? 0xffffffff : null, false);
SVGHandler handler = new SVGHandler(width, height, white ? 0xffffffff : null, false, 1f);
xr.setContentHandler(handler);
xr.parse(new InputSource(new StringReader(xml)));
return handler.getBitmap();
@ -336,7 +339,7 @@ public class SvgHelper {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(0, 0, null, true);
SVGHandler handler = new SVGHandler(0, 0, null, true, 1f);
xr.setContentHandler(handler);
xr.parse(new InputSource(new StringReader(xml)));
return handler.getDrawable();
@ -351,7 +354,7 @@ public class SvgHelper {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SVGHandler handler = new SVGHandler(0, 0, color, true);
SVGHandler handler = new SVGHandler(0, 0, color, true, 1f);
xr.setContentHandler(handler);
xr.parse(new InputSource(ApplicationLoader.applicationContext.getResources().openRawResource(resId)));
return handler.getDrawable();
@ -948,12 +951,14 @@ public class SvgHelper {
private RectF rect = new RectF();
private RectF rectTmp = new RectF();
private Integer paintColor;
private float globalScale = 1f;
boolean pushed = false;
private HashMap<String, StyleSet> globalStyles = new HashMap<>();
private SVGHandler(int dw, int dh, Integer color, boolean asDrawable) {
private SVGHandler(int dw, int dh, Integer color, boolean asDrawable, float scale) {
globalScale = scale;
desiredWidth = dw;
desiredHeight = dh;
paintColor = color;
@ -1114,7 +1119,7 @@ public class SvgHelper {
bitmap.eraseColor(0);
canvas = new Canvas(bitmap);
if (scale != 0) {
canvas.scale(scale, scale);
canvas.scale(globalScale * scale, globalScale * scale);
}
} else {
drawable.width = width;

View file

@ -1,11 +1,17 @@
package org.telegram.messenger.video;
import android.annotation.TargetApi;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.opengl.EGL14;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.os.Build;
import android.view.Surface;
import com.google.android.exoplayer2.util.Log;
@ -25,8 +31,16 @@ import org.telegram.ui.LaunchActivity;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
public class MediaCodecVideoConvertor {
private MP4Builder mediaMuxer;
@ -48,6 +62,7 @@ public class MediaCodecVideoConvertor {
public boolean convertVideo(String videoPath, File cacheFile,
int rotationValue, boolean isSecret,
int originalWidth, int originalHeight,
int resultWidth, int resultHeight,
int framerate, int bitrate, int originalBitrate,
long startTime, long endTime, long avatarStartTime,
@ -59,7 +74,7 @@ public class MediaCodecVideoConvertor {
MediaController.CropState cropState,
MediaController.VideoConvertorListener callback) {
this.callback = callback;
return convertVideoInternal(videoPath, cacheFile, rotationValue, isSecret,
return convertVideoInternal(videoPath, cacheFile, rotationValue, isSecret, originalWidth, originalHeight,
resultWidth, resultHeight, framerate, bitrate, originalBitrate, startTime, endTime, avatarStartTime, duration, needCompress, false, savedFilterState, paintPath, mediaEntities, isPhoto, cropState);
}
@ -70,6 +85,7 @@ public class MediaCodecVideoConvertor {
@TargetApi(18)
private boolean convertVideoInternal(String videoPath, File cacheFile,
int rotationValue, boolean isSecret,
int originalWidth, int originalHeight,
int resultWidth, int resultHeight,
int framerate, int bitrate, int originalBitrate,
long startTime, long endTime, long avatarStartTime,
@ -141,8 +157,8 @@ public class MediaCodecVideoConvertor {
MediaFormat outputFormat = MediaFormat.createVideoFormat(MediaController.VIDEO_MIME_TYPE, resultWidth, resultHeight);
outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, framerate);
outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2);
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
encoder = MediaCodec.createEncoderByType(MediaController.VIDEO_MIME_TYPE);
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
@ -150,7 +166,7 @@ public class MediaCodecVideoConvertor {
inputSurface.makeCurrent();
encoder.start();
outputSurface = new OutputSurface(savedFilterState, videoPath, paintPath, mediaEntities, null, resultWidth, resultHeight, rotationValue, framerate, true);
// outputSurface = new OutputSurface(savedFilterState, videoPath, paintPath, mediaEntities, null, resultWidth, resultHeight, rotationValue, framerate, true);
ByteBuffer[] encoderOutputBuffers = null;
ByteBuffer[] encoderInputBuffers = null;
@ -406,6 +422,7 @@ public class MediaCodecVideoConvertor {
decoder = MediaCodec.createDecoderByType(videoFormat.getString(MediaFormat.KEY_MIME));
outputSurface = new OutputSurface(savedFilterState, null, paintPath, mediaEntities, cropState, resultWidth, resultHeight, rotationValue, framerate, false);
outputSurface.changeFragmentShader(createFragmentShader(originalWidth, originalHeight, resultWidth, resultHeight));
decoder.configure(videoFormat, outputSurface.getSurface(), null, 0);
decoder.start();
@ -681,7 +698,7 @@ public class MediaCodecVideoConvertor {
inputDone = false;
decoderDone = false;
doRender = false;
info.flags &=~ MediaCodec.BUFFER_FLAG_END_OF_STREAM;
info.flags &= ~MediaCodec.BUFFER_FLAG_END_OF_STREAM;
decoder.flush();
flushed = true;
}
@ -791,6 +808,7 @@ public class MediaCodecVideoConvertor {
if (repeatWithIncreasedTimeout) {
return convertVideoInternal(videoPath, cacheFile, rotationValue, isSecret,
originalWidth, originalHeight,
resultWidth, resultHeight, framerate, bitrate, originalBitrate, startTime, endTime, avatarStartTime, duration,
needCompress, true, savedFilterState, paintPath, mediaEntities,
isPhoto, cropState);
@ -958,6 +976,52 @@ public class MediaCodecVideoConvertor {
private void checkConversionCanceled() {
if (callback != null && callback.checkConversionCanceled())
throw new RuntimeException("canceled conversion");
throw new ConversionCanceledException();
}
private static String createFragmentShader(
final int srcWidth,
final int srcHeight,
final int dstWidth,
final int dstHeight) {
final float kernelSizeX = Math.max(2f, (float) srcWidth / (float) dstWidth);
final float kernelSizeY = Math.max(2f, (float) srcHeight / (float) dstHeight);
final String shader;
final int kernelRadiusX = (int) Math.ceil(kernelSizeX - .1f) / 2;
final int kernelRadiusY = (int) Math.ceil(kernelSizeY - .1f) / 2;
final float stepX = kernelSizeX / (1 + 2 * kernelRadiusX) * (1f / srcWidth);
final float stepY = kernelSizeY / (1 + 2 * kernelRadiusY) * (1f / srcHeight);
final float sum = (1 + 2 * kernelRadiusX) * (1 + 2 * kernelRadiusY);
final StringBuilder colorLoop = new StringBuilder();
for (int i = -kernelRadiusX; i <= kernelRadiusX; i++) {
for (int j = -kernelRadiusY; j <= kernelRadiusY; j++) {
if (i != 0 || j != 0) {
colorLoop.append(" + texture2D(sTexture, vTextureCoord.xy + vec2(")
.append(i * stepX).append(", ").append(j * stepY).append("))\n");
}
}
}
shader =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" + // highp here doesn't seem to matter
"varying vec2 vTextureCoord;\n" +
"uniform samplerExternalOES sTexture;\n" +
"void main() {\n" +
" gl_FragColor = (texture2D(sTexture, vTextureCoord)\n" +
colorLoop.toString() +
" ) / " + sum + ";\n" +
"}\n";
return shader;
}
public class ConversionCanceledException extends RuntimeException{
public ConversionCanceledException() {
super("canceled conversion");
}
}
}

View file

@ -165,4 +165,8 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener {
throw new RuntimeException("EGL error encountered (see log)");
}
}
public void changeFragmentShader(String fragmentShader) {
mTextureRender.changeFragmentShader(fragmentShader);
}
}

View file

@ -604,7 +604,7 @@ public class TextureRenderer {
if (entity.type == 0) {
if ((entity.subType & 1) != 0) {
entity.metadata = new int[3];
entity.ptr = RLottieDrawable.create(entity.text, null, 512, 512, entity.metadata, false, null, false);
entity.ptr = RLottieDrawable.create(entity.text, null, 512, 512, entity.metadata, false, null, false, 0);
entity.framesPerDraw = entity.metadata[1] / videoFps;
} else {
if (Build.VERSION.SDK_INT >= 19) {
@ -714,4 +714,9 @@ public class TextureRenderer {
}
}
}
public void changeFragmentShader(String fragmentShader) {
GLES20.glDeleteProgram(mProgram[0]);
mProgram[0] = createProgram(VERTEX_SHADER, fragmentShader);
}
}

View file

@ -15,7 +15,7 @@ import java.util.List;
public final class Instance {
public static final List<String> AVAILABLE_VERSIONS = Build.VERSION.SDK_INT >= 18 ? Arrays.asList(/*"3.0.0", */"2.7.7", "2.4.4") : Arrays.asList("2.4.4");
public static final List<String> AVAILABLE_VERSIONS = Build.VERSION.SDK_INT >= 18 ? Arrays.asList("3.0.0", "2.7.7", "2.4.4") : Arrays.asList("2.4.4");
public static final int AUDIO_STATE_MUTED = 0;
public static final int AUDIO_STATE_ACTIVE = 1;

View file

@ -10,6 +10,7 @@ import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Base64;
import com.google.android.exoplayer2.util.Log;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import org.json.JSONArray;
@ -1017,7 +1018,7 @@ public class ConnectionsManager extends BaseController {
buffer.writeBytes(bytes);
return buffer;
} catch (Throwable e) {
FileLog.e(e);
FileLog.e(e, false);
} finally {
try {
if (httpConnectionStream != null) {

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,7 @@ import android.view.ViewOutlineProvider;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.google.android.exoplayer2.util.Log;
@ -191,12 +192,13 @@ public class ActionBarLayout extends FrameLayout {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if ((inPreviewMode || transitionAnimationPreviewMode) && (ev.getActionMasked() == MotionEvent.ACTION_DOWN || ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN)) {
boolean passivePreview = inPreviewMode && previewMenu == null;
if ((passivePreview || transitionAnimationPreviewMode) && (ev.getActionMasked() == MotionEvent.ACTION_DOWN || ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN)) {
return false;
}
//
try {
return (!inPreviewMode || this != containerView) && super.dispatchTouchEvent(ev);
return (!passivePreview || this != containerView) && super.dispatchTouchEvent(ev);
} catch (Throwable e) {
FileLog.e(e);
}
@ -261,7 +263,7 @@ public class ActionBarLayout extends FrameLayout {
private boolean previewOpenAnimationInProgress;
private ColorDrawable previewBackgroundDrawable;
private LayoutContainer containerView;
public LayoutContainer containerView; /* Contest: private -> public temp hack bc I don't know how to blur action bar otherwise */
private LayoutContainer containerViewBack;
private DrawerLayoutContainer drawerLayoutContainer;
private ActionBar currentActionBar;
@ -269,6 +271,9 @@ public class ActionBarLayout extends FrameLayout {
private BaseFragment newFragment;
private BaseFragment oldFragment;
/* Contest */
private View previewMenu;
private AnimatorSet currentAnimation;
private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(1.5f);
private AccelerateDecelerateInterpolator accelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
@ -580,10 +585,12 @@ public class ActionBarLayout extends FrameLayout {
if (view != null) {
previewBackgroundDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
previewBackgroundDrawable.draw(canvas);
int x = (getMeasuredWidth() - AndroidUtilities.dp(24)) / 2;
int y = (int) (view.getTop() + containerView.getTranslationY() - AndroidUtilities.dp(12 + (Build.VERSION.SDK_INT < 21 ? 20 : 0)));
Theme.moveUpDrawable.setBounds(x, y, x + AndroidUtilities.dp(24), y + AndroidUtilities.dp(24));
Theme.moveUpDrawable.draw(canvas);
if (previewMenu == null) {
int x = (getMeasuredWidth() - AndroidUtilities.dp(24)) / 2;
int y = (int) (view.getTop() + containerView.getTranslationY() - AndroidUtilities.dp(12 + (Build.VERSION.SDK_INT < 21 ? 20 : 0)));
Theme.moveUpDrawable.setBounds(x, y, x + AndroidUtilities.dp(24), y + AndroidUtilities.dp(24));
Theme.moveUpDrawable.draw(canvas);
}
}
}
@ -941,15 +948,19 @@ public class ActionBarLayout extends FrameLayout {
}
public boolean presentFragmentAsPreview(BaseFragment fragment) {
return presentFragment(fragment, false, false, true, true);
return presentFragment(fragment, false, false, true, true, null);
}
public boolean presentFragmentAsPreviewWithMenu(BaseFragment fragment, View menu) {
return presentFragment(fragment, false, false, true, true, menu);
}
public boolean presentFragment(BaseFragment fragment) {
return presentFragment(fragment, false, false, true, false);
return presentFragment(fragment, false, false, true, false, null);
}
public boolean presentFragment(BaseFragment fragment, boolean removeLast) {
return presentFragment(fragment, removeLast, false, true, false);
return presentFragment(fragment, removeLast, false, true, false, null);
}
private void startLayoutAnimation(final boolean open, final boolean first, final boolean preview) {
@ -1038,11 +1049,25 @@ public class ActionBarLayout extends FrameLayout {
return inPreviewMode || transitionAnimationPreviewMode;
}
public boolean isInPassivePreviewMode() {
return (inPreviewMode && previewMenu == null) || transitionAnimationPreviewMode;
}
public boolean isInPreviewMenuMode() {
return isInPreviewMode() && previewMenu != null;
}
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation, boolean check, final boolean preview) {
return presentFragment(fragment, removeLast, forceWithoutAnimation, check, preview, null);
}
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation, boolean check, final boolean preview, View menu) {
if (fragment == null || checkTransitionAnimation() || delegate != null && check && !delegate.needPresentFragment(fragment, removeLast, forceWithoutAnimation, this) || !fragment.onFragmentCreate()) {
return false;
}
fragment.setInPreviewMode(preview);
fragment.setInMenuMode(menu != null);
if (parentActivity.getCurrentFocus() != null && fragment.hideKeyboardOnShow() && !preview) {
AndroidUtilities.hideKeyboard(parentActivity.getCurrentFocus());
}
@ -1061,8 +1086,20 @@ public class ActionBarLayout extends FrameLayout {
parent.removeView(fragmentView);
}
}
containerViewBack.addView(fragmentView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) fragmentView.getLayoutParams();
View wrappedView = fragmentView;
containerViewBack.addView(wrappedView);
int menuHeight = 0;
if (menu != null) {
containerViewBack.addView(menu);
menu.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
menuHeight = menu.getMeasuredHeight() + AndroidUtilities.dp(24);
FrameLayout.LayoutParams menuParams = (FrameLayout.LayoutParams) menu.getLayoutParams();
menuParams.width = LayoutHelper.WRAP_CONTENT;
menuParams.height = LayoutHelper.WRAP_CONTENT;
menuParams.topMargin = getMeasuredHeight() - menuHeight - AndroidUtilities.dp(6);
menu.setLayoutParams(menuParams);
}
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) wrappedView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
if (preview) {
@ -1072,14 +1109,17 @@ public class ActionBarLayout extends FrameLayout {
layoutParams.height = height;
layoutParams.topMargin = statusBarHeight + (getMeasuredHeight() - statusBarHeight - height) / 2;
} else {
layoutParams.topMargin = layoutParams.bottomMargin = AndroidUtilities.dp(46);
layoutParams.topMargin = layoutParams.bottomMargin = AndroidUtilities.dp(menu != null ? 0 : 46);
layoutParams.topMargin += AndroidUtilities.statusBarHeight;
}
if (menu != null) {
layoutParams.bottomMargin += menuHeight + AndroidUtilities.dp(8);
}
layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(8);
} else {
layoutParams.topMargin = layoutParams.bottomMargin = layoutParams.rightMargin = layoutParams.leftMargin = 0;
}
fragmentView.setLayoutParams(layoutParams);
wrappedView.setLayoutParams(layoutParams);
if (fragment.actionBar != null && fragment.actionBar.shouldAddToContainer()) {
if (removeActionBarExtraHeight) {
fragment.actionBar.setOccupyStatusBar(false);
@ -1179,6 +1219,7 @@ public class ActionBarLayout extends FrameLayout {
onOpenAnimationEndRunnable = () -> {
if (preview) {
inPreviewMode = true;
previewMenu = menu;
transitionAnimationPreviewMode = false;
containerView.setScaleX(1.0f);
containerView.setScaleY(1.0f);
@ -1346,7 +1387,7 @@ public class ActionBarLayout extends FrameLayout {
}
public void movePreviewFragment(float dy) {
if (!inPreviewMode || transitionAnimationPreviewMode) {
if (!inPreviewMode || transitionAnimationPreviewMode || previewMenu != null) {
return;
}
float currentTranslation = containerView.getTranslationY();
@ -1486,10 +1527,21 @@ public class ActionBarLayout extends FrameLayout {
layoutToIgnore = containerView;
final BaseFragment previousFragmentFinal = previousFragment;
onCloseAnimationEndRunnable = () -> {
if (previewMenu != null) {
ViewGroup parent = (ViewGroup) previewMenu.getParent();
if (parent != null) {
//ViewGroup grandparent = (ViewGroup) parent.getParent();
parent.removeView(previewMenu);
/*if (grandparent != null) {
grandparent.removeView(parent);
}*/
}
}
if (inPreviewMode || transitionAnimationPreviewMode) {
containerViewBack.setScaleX(1.0f);
containerViewBack.setScaleY(1.0f);
inPreviewMode = false;
previewMenu = null;
transitionAnimationPreviewMode = false;
} else {
containerViewBack.setTranslationX(0);
@ -2088,4 +2140,4 @@ public class ActionBarLayout extends FrameLayout {
}
}
}
}
}

View file

@ -1593,6 +1593,23 @@ public class ActionBarMenuItem extends FrameLayout {
}
}
/**
* Hides this menu item if no subitems are available
*/
public void checkHideMenuItem() {
boolean isVisible = false;
for (int i = 0; i < popupLayout.getItemsCount(); i++) {
if (popupLayout.getItemAt(i).getVisibility() == VISIBLE) {
isVisible = true;
break;
}
}
int v = isVisible ? VISIBLE : GONE;
if (v != getVisibility()) {
setVisibility(v);
}
}
public void hideAllSubItems() {
if (popupLayout == null) {
return;

View file

@ -88,6 +88,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
private int topResId;
private View topView;
private int topAnimationId;
private int topAnimationSize;
private int topHeight = 132;
private Drawable topDrawable;
private int topBackgroundColor;
@ -138,6 +139,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
private float aspectRatio;
private boolean dimEnabled = true;
private final Theme.ResourcesProvider resourcesProvider;
private boolean topAnimationAutoRepeat = true;
public static class AlertDialogCell extends FrameLayout {
@ -461,8 +463,8 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
} else if (topResId != 0) {
topImageView.setImageResource(topResId);
} else {
topImageView.setAutoRepeat(true);
topImageView.setAnimation(topAnimationId, 94, 94);
topImageView.setAutoRepeat(topAnimationAutoRepeat);
topImageView.setAnimation(topAnimationId, topAnimationSize, topAnimationSize);
topImageView.playAnimation();
}
topImageView.setScaleType(ImageView.ScaleType.CENTER);
@ -1059,7 +1061,11 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
}
public void setTopAnimation(int resId, int backgroundColor) {
setTopAnimation(resId, 94, backgroundColor);
}
public void setTopAnimation(int resId, int size, int backgroundColor) {
topAnimationId = resId;
topAnimationSize = size;
topBackgroundColor = backgroundColor;
}
@ -1273,11 +1279,16 @@ public class AlertDialog extends Dialog implements Drawable.Callback {
return this;
}
public Builder setTopAnimation(int resId, int backgroundColor) {
public Builder setTopAnimation(int resId, int size, boolean autoRepeat, int backgroundColor) {
alertDialog.topAnimationId = resId;
alertDialog.topAnimationSize = size;
alertDialog.topAnimationAutoRepeat = autoRepeat;
alertDialog.topBackgroundColor = backgroundColor;
return this;
}
public Builder setTopAnimation(int resId, int backgroundColor) {
return setTopAnimation(resId, 94, true, backgroundColor);
}
public Builder setTopImage(Drawable drawable, int backgroundColor) {
alertDialog.topDrawable = drawable;

View file

@ -61,6 +61,7 @@ public abstract class BaseFragment {
protected ActionBarLayout parentLayout;
protected ActionBar actionBar;
protected boolean inPreviewMode;
protected boolean inMenuMode;
protected boolean inBubbleMode;
protected int classGuid;
protected Bundle arguments;
@ -122,6 +123,14 @@ public abstract class BaseFragment {
return inBubbleMode;
}
public boolean getInPreviewMode() {
return inPreviewMode;
}
public boolean getInPassivePreviewMode() {
return parentLayout != null && parentLayout.isInPassivePreviewMode();
}
protected void setInPreviewMode(boolean value) {
inPreviewMode = value;
if (actionBar != null) {
@ -133,6 +142,10 @@ public abstract class BaseFragment {
}
}
protected void setInMenuMode(boolean value) {
inMenuMode = value;
}
protected void onPreviewOpenAnimationEnd() {
}
@ -361,19 +374,23 @@ public abstract class BaseFragment {
}
public boolean presentFragmentAsPreview(BaseFragment fragment) {
return parentLayout != null && parentLayout.presentFragmentAsPreview(fragment);
return allowPresentFragment() && parentLayout != null && parentLayout.presentFragmentAsPreview(fragment);
}
public boolean presentFragmentAsPreviewWithMenu(BaseFragment fragment, View menu) {
return allowPresentFragment() && parentLayout != null && parentLayout.presentFragmentAsPreviewWithMenu(fragment, menu);
}
public boolean presentFragment(BaseFragment fragment) {
return parentLayout != null && parentLayout.presentFragment(fragment);
return allowPresentFragment() && parentLayout != null && parentLayout.presentFragment(fragment);
}
public boolean presentFragment(BaseFragment fragment, boolean removeLast) {
return parentLayout != null && parentLayout.presentFragment(fragment, removeLast);
return allowPresentFragment() && parentLayout != null && parentLayout.presentFragment(fragment, removeLast);
}
public boolean presentFragment(BaseFragment fragment, boolean removeLast, boolean forceWithoutAnimation) {
return parentLayout != null && parentLayout.presentFragment(fragment, removeLast, forceWithoutAnimation, true, false);
return allowPresentFragment() && parentLayout != null && parentLayout.presentFragment(fragment, removeLast, forceWithoutAnimation, true, false, null);
}
public Activity getParentActivity() {
@ -713,4 +730,9 @@ public abstract class BaseFragment {
public Theme.ResourcesProvider getResourceProvider() {
return null;
}
}
protected boolean allowPresentFragment() {
return true;
}
}

View file

@ -165,6 +165,7 @@ public class BottomSheet extends Dialog {
private ValueAnimator keyboardContentAnimator;
protected boolean smoothKeyboardAnimationEnabled;
private boolean openNoDelay;
protected class ContainerView extends FrameLayout implements NestedScrollingParent {
@ -1024,7 +1025,7 @@ public class BottomSheet extends Dialog {
startAnimationRunnable = null;
startOpenAnimation();
}
}, 150);
}, openNoDelay ? 0 : 150);
} else {
startOpenAnimation();
}
@ -1540,4 +1541,8 @@ public class BottomSheet extends Dialog {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
public void setOpenNoDelay(boolean openNoDelay) {
this.openNoDelay = openNoDelay;
}
}

View file

@ -7,8 +7,6 @@ import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.util.Pair;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatThemeController;
@ -21,7 +19,6 @@ import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ResultCallback;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import java.io.File;
import java.io.FileOutputStream;
@ -36,6 +33,17 @@ public class EmojiThemes {
int currentIndex = 0;
ArrayList<ThemeItem> items = new ArrayList<>();
private static final String[] previewColorKeys = new String[]{
Theme.key_chat_inBubble,
Theme.key_chat_outBubble,
Theme.key_featuredStickers_addButton,
Theme.key_chat_wallpaper,
Theme.key_chat_wallpaper_gradient_to1,
Theme.key_chat_wallpaper_gradient_to2,
Theme.key_chat_wallpaper_gradient_to3,
Theme.key_chat_wallpaper_gradient_rotation
};
private EmojiThemes() {
}
@ -98,8 +106,20 @@ public class EmojiThemes {
Theme.ThemeInfo themeInfo = Theme.getTheme(lastDayCustomTheme);
if (themeInfo == null) {
lastDayCustomTheme = "Blue";
dayAccentId = 99;
} else {
dayAccentId = themeInfo.currentAccentId;
}
preferences.edit().putString("lastDayCustomTheme", lastDayCustomTheme).apply();
} else {
if (dayAccentId == -1) {
dayAccentId = Theme.getTheme(lastDayCustomTheme).lastAccentId;
}
}
if (dayAccentId == -1) {
lastDayCustomTheme = "Blue";
dayAccentId = 99;
}
String lastDarkCustomTheme = preferences.getString("lastDarkCustomTheme", null);
@ -109,10 +129,21 @@ public class EmojiThemes {
Theme.ThemeInfo themeInfo = Theme.getTheme(lastDarkCustomTheme);
if (themeInfo == null) {
lastDarkCustomTheme = "Dark Blue";
darkAccentId = 0;
} else {
darkAccentId = themeInfo.currentAccentId;
}
preferences.edit().putString("lastDarkCustomTheme", lastDarkCustomTheme).apply();
} else {
if (darkAccentId == -1) {
darkAccentId = Theme.getTheme(lastDayCustomTheme).lastAccentId;
}
}
if (darkAccentId == -1) {
lastDarkCustomTheme = "Dark Blue";
darkAccentId = 0;
}
ThemeItem lightTheme = new ThemeItem();
lightTheme.themeInfo = Theme.getTheme(lastDayCustomTheme);
@ -156,8 +187,8 @@ public class EmojiThemes {
}
public void initColors() {
getCurrentColors(0, 0);
getCurrentColors(0, 1);
getPreviewColors(0, 0);
getPreviewColors(0, 1);
}
public String getEmoticon() {
@ -184,8 +215,8 @@ public class EmojiThemes {
return items.get(index).settingsIndex;
}
public HashMap<String, Integer> getCurrentColors(int currentAccount, int index) {
HashMap<String, Integer> currentColors = items.get(index).currentColors;
public HashMap<String, Integer> getPreviewColors(int currentAccount, int index) {
HashMap<String, Integer> currentColors = items.get(index).currentPreviewColors;
if (currentColors != null) {
return currentColors;
}
@ -215,9 +246,64 @@ public class EmojiThemes {
items.get(index).wallpaperLink = wallpaperLink[0];
currentColors = new HashMap<>(currentColorsNoAccent);
if (accent != null) {
currentColors = new HashMap<>(currentColorsNoAccent);
accent.fillAccentColors(currentColorsNoAccent, currentColors);
currentColorsNoAccent.clear();
} else {
currentColors = currentColorsNoAccent;
}
HashMap<String, String> fallbackKeys = Theme.getFallbackKeys();
items.get(index).currentPreviewColors = new HashMap<>();
for (int i = 0; i < previewColorKeys.length; i++) {
String key = previewColorKeys[i];
items.get(index).currentPreviewColors.put(key, currentColors.get(key));
if (!items.get(index).currentPreviewColors.containsKey(key)) {
Integer color = currentColors.get(fallbackKeys.get(key));
currentColors.put(key, color);
}
}
currentColors.clear();
return items.get(index).currentPreviewColors;
}
public HashMap<String, Integer> createColors(int currentAccount, int index) {
HashMap<String, Integer> currentColors;
Theme.ThemeInfo themeInfo = getThemeInfo(index);
Theme.ThemeAccent accent = null;
if (themeInfo == null) {
int settingsIndex = getSettingsIndex(index);
TLRPC.TL_theme tlTheme = getTlTheme(index);
Theme.ThemeInfo baseTheme = Theme.getTheme(Theme.getBaseThemeKey(tlTheme.settings.get(settingsIndex)));
themeInfo = new Theme.ThemeInfo(baseTheme);
accent = themeInfo.createNewAccent(tlTheme, currentAccount, true, settingsIndex);
themeInfo.setCurrentAccentId(accent.id);
} else {
if (themeInfo.themeAccentsMap != null) {
accent = themeInfo.themeAccentsMap.get(items.get(index).accentId);
}
}
HashMap<String, Integer> currentColorsNoAccent = new HashMap<>();
String[] wallpaperLink = new String[1];
if (themeInfo.pathToFile != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(new File(themeInfo.pathToFile), null, wallpaperLink));
} else if (themeInfo.assetName != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(null, themeInfo.assetName, wallpaperLink));
}
items.get(index).wallpaperLink = wallpaperLink[0];
if (accent != null) {
currentColors = new HashMap<>(currentColorsNoAccent);
accent.fillAccentColors(currentColorsNoAccent, currentColors);
currentColorsNoAccent.clear();
} else {
currentColors = currentColorsNoAccent;
}
HashMap<String, String> fallbackKeys = Theme.getFallbackKeys();
@ -234,7 +320,6 @@ public class EmojiThemes {
currentColors.put(entry.getKey(), entry.getValue());
}
}
items.get(index).currentColors = currentColors;
return currentColors;
}
@ -313,6 +398,12 @@ public class EmojiThemes {
return;
}
if (wallpaper.document == null) {
if (callback != null) {
callback.onComplete(new Pair<>(themeId, null));
}
return;
}
final TLRPC.PhotoSize thumbSize = FileLoader.getClosestPhotoSizeWithSize(wallpaper.document.thumbs, 120);
ImageLocation imageLocation = ImageLocation.getForDocument(thumbSize, wallpaper.document);
ImageReceiver imageReceiver = new ImageReceiver();
@ -379,7 +470,7 @@ public class EmojiThemes {
}
}
public static HashMap<String, Integer> getCurrentColors(Theme.ThemeInfo themeInfo) {
public static HashMap<String, Integer> getPreviewColors(Theme.ThemeInfo themeInfo) {
HashMap<String, Integer> currentColorsNoAccent = new HashMap<>();
if (themeInfo.pathToFile != null) {
currentColorsNoAccent.putAll(Theme.getThemeFileValues(new File(themeInfo.pathToFile), null, null));
@ -403,7 +494,7 @@ public class EmojiThemes {
if (items.get(i) == null) {
continue;
}
HashMap<String, Integer> colorsMap = getCurrentColors(currentAccount, i);
HashMap<String, Integer> colorsMap = getPreviewColors(currentAccount, i);
Integer color = colorsMap.get(Theme.key_chat_inBubble);
if (color == null) {
color = Theme.getDefaultColor(Theme.key_chat_inBubble);
@ -443,6 +534,12 @@ public class EmojiThemes {
} else {
items.get(i).patternBgGradientColor3 = color;
}
color = colorsMap.get(Theme.key_chat_wallpaper_gradient_rotation);
if (color == null) {
items.get(i).patternBgRotation = 0;
} else {
items.get(i).patternBgRotation = color;
}
if (items.get(i).themeInfo != null && items.get(i).themeInfo.getKey().equals("Blue")) {
int accentId = items.get(i).accentId >= 0 ? items.get(i).accentId : items.get(i).themeInfo.currentAccentId;
if (accentId == 99) {
@ -490,13 +587,14 @@ public class EmojiThemes {
.putInt(accentKey, accentId)
.apply();
}
public static class ThemeItem {
public Theme.ThemeInfo themeInfo;
TLRPC.TL_theme tlTheme;
int settingsIndex;
public int accentId = -1;
public HashMap<String, Integer> currentColors;
public HashMap<String, Integer> currentPreviewColors;
private String wallpaperLink;
public int inBubbleColor;
@ -506,5 +604,6 @@ public class EmojiThemes {
public int patternBgGradientColor1;
public int patternBgGradientColor2;
public int patternBgGradientColor3;
public int patternBgRotation;
}
}

View file

@ -52,6 +52,8 @@ public class MenuDrawable extends Drawable {
public static int TYPE_UDPATE_AVAILABLE = 1;
public static int TYPE_UDPATE_DOWNLOADING = 2;
private int alpha = 255;
public MenuDrawable() {
this(TYPE_DEFAULT);
}
@ -71,6 +73,10 @@ public class MenuDrawable extends Drawable {
rotateToBack = value;
}
public float getCurrentRotation() {
return currentRotation;
}
public void setRotation(float rotation, boolean animated) {
lastFrameTime = 0;
if (currentRotation == 1) {
@ -164,6 +170,7 @@ public class MenuDrawable extends Drawable {
if (rotateToBack) {
canvas.rotate(currentRotation * (reverseAngle ? -180 : 180), AndroidUtilities.dp(9), 0);
paint.setColor(color1);
paint.setAlpha(alpha);
canvas.drawLine(0, 0, AndroidUtilities.dp(18) - AndroidUtilities.dp(3.0f) * currentRotation - diffMiddle, 0, paint);
endYDiff = AndroidUtilities.dp(5) * (1 - Math.abs(currentRotation)) - AndroidUtilities.dp(0.5f) * Math.abs(currentRotation);
endXDiff = AndroidUtilities.dp(18) - AndroidUtilities.dp(2.5f) * Math.abs(currentRotation);
@ -173,6 +180,7 @@ public class MenuDrawable extends Drawable {
canvas.rotate(currentRotation * (reverseAngle ? -225 : 135), AndroidUtilities.dp(9), 0);
if (miniIcon) {
paint.setColor(color1);
paint.setAlpha(alpha);
canvas.drawLine(AndroidUtilities.dpf2(2) * (1 - Math.abs(currentRotation)) + AndroidUtilities.dp(1) * currentRotation, 0, AndroidUtilities.dpf2(16) * (1f - currentRotation) + AndroidUtilities.dp(17) * currentRotation - diffMiddle, 0, paint);
endYDiff = AndroidUtilities.dpf2(5) * (1 - Math.abs(currentRotation)) - AndroidUtilities.dpf2(0.5f) * Math.abs(currentRotation);
endXDiff = AndroidUtilities.dpf2(16) * (1 - Math.abs(currentRotation)) + (AndroidUtilities.dpf2(9)) * Math.abs(currentRotation);
@ -184,6 +192,7 @@ public class MenuDrawable extends Drawable {
int backColor2 = Theme.getColor(Theme.key_actionBarActionModeDefault);
backColor1 = AndroidUtilities.getOffsetColor(backColor1, backColor2, currentRotation, 1.0f);
paint.setColor(AndroidUtilities.getOffsetColor(color1, color2, currentRotation, 1.0f));
paint.setAlpha(alpha);
canvas.drawLine(AndroidUtilities.dp(1) * currentRotation, 0, AndroidUtilities.dp(18) - AndroidUtilities.dp(1) * currentRotation - diffMiddle, 0, paint);
endYDiff = AndroidUtilities.dp(5) * (1 - Math.abs(currentRotation)) - AndroidUtilities.dp(0.5f) * Math.abs(currentRotation);
endXDiff = AndroidUtilities.dp(18) - AndroidUtilities.dp(9) * Math.abs(currentRotation);
@ -207,13 +216,14 @@ public class MenuDrawable extends Drawable {
rad *= (1.0f - typeAnimationProgress);
}
backPaint.setColor(backColor1);
backPaint.setAlpha(alpha);
canvas.drawCircle(cx, cy, rad, paint);
if (type == TYPE_UDPATE_AVAILABLE || previousType == TYPE_UDPATE_AVAILABLE) {
backPaint.setStrokeWidth(AndroidUtilities.density * 1.66f);
if (previousType == TYPE_UDPATE_AVAILABLE) {
backPaint.setAlpha((int) (255 * (1.0f - typeAnimationProgress)));
backPaint.setAlpha((int) (alpha * (1.0f - typeAnimationProgress)));
} else {
backPaint.setAlpha(255);
backPaint.setAlpha(alpha);
}
canvas.drawLine(cx, cy - AndroidUtilities.dp(2), cx, cy, backPaint);
canvas.drawPoint(cx, cy + AndroidUtilities.dp(2.5f), backPaint);
@ -221,9 +231,9 @@ public class MenuDrawable extends Drawable {
if (type == TYPE_UDPATE_DOWNLOADING || previousType == TYPE_UDPATE_DOWNLOADING) {
backPaint.setStrokeWidth(AndroidUtilities.dp(2));
if (previousType == TYPE_UDPATE_DOWNLOADING) {
backPaint.setAlpha((int) (255 * (1.0f - typeAnimationProgress)));
backPaint.setAlpha((int) (alpha * (1.0f - typeAnimationProgress)));
} else {
backPaint.setAlpha(255);
backPaint.setAlpha(alpha);
}
float arcRad = Math.max(4, 360 * animatedDownloadProgress);
rect.set(cx - AndroidUtilities.dp(3), cy - AndroidUtilities.dp(3), cx + AndroidUtilities.dp(3), cy + AndroidUtilities.dp(3));
@ -266,7 +276,12 @@ public class MenuDrawable extends Drawable {
@Override
public void setAlpha(int alpha) {
if (this.alpha != alpha) {
this.alpha = alpha;
paint.setAlpha(alpha);
backPaint.setAlpha(alpha);
invalidateSelf();
}
}
@Override

View file

@ -67,7 +67,6 @@ import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.Bitmaps;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
@ -120,7 +119,6 @@ import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@ -207,6 +205,7 @@ public class Theme {
private Shader crosfadeFromBitmapShader;
PathDrawParams pathDrawCacheParams;
private int overrideRoundRadius;
public MessageDrawable(int type, boolean out, boolean selected) {
this(type, out, selected, null);
@ -658,7 +657,10 @@ public class Theme {
int padding = dp(2);
int rad;
int nearRad;
if (currentType == TYPE_PREVIEW) {
if (overrideRoundRadius != 0) {
rad = overrideRoundRadius;
nearRad = overrideRoundRadius;
} else if (currentType == TYPE_PREVIEW) {
rad = dp(6);
nearRad = dp(6);
} else {
@ -866,6 +868,10 @@ public class Theme {
}
}
public void setRoundRadius(int radius) {
this.overrideRoundRadius = radius;
}
public static class PathDrawParams {
Path path = new Path();
Rect lastRect = new Rect();
@ -1519,7 +1525,7 @@ public class Theme {
if (id < 100) {
return !TextUtils.isEmpty(patternSlug) ? new File(ApplicationLoader.getFilesDirFixed(), String.format(Locale.US, "%s_%d_%s_v5.jpg", parentTheme.getKey(), id, patternSlug)) : null;
} else {
return !TextUtils.isEmpty(patternSlug) ? new File(ApplicationLoader.getFilesDirFixed(), String.format(Locale.US, "%s_%d_%s_v8_dubug.jpg", parentTheme.getKey(), id, patternSlug)) : null;
return !TextUtils.isEmpty(patternSlug) ? new File(ApplicationLoader.getFilesDirFixed(), String.format(Locale.US, "%s_%d_%s_v8_debug.jpg", parentTheme.getKey(), id, patternSlug)) : null;
}
}
@ -2140,6 +2146,9 @@ public class Theme {
for (int a = 0; a < accent.length; a++) {
ThemeAccent themeAccent = new ThemeAccent();
themeAccent.id = ids != null ? ids[a] : a;
if (isHome(themeAccent)) {
themeAccent.isDefault = true;
}
themeAccent.accentColor = accent[a];
themeAccent.parentTheme = this;
if (myMessages != null) {
@ -2356,6 +2365,7 @@ public class Theme {
themeAccent.account = account;
themeAccentsMap.put(id, themeAccent);
themeAccents.add(0, themeAccent);
sortAccents(this);
accentsByThemeId.put(info.id, themeAccent);
return themeAccent;
}
@ -2393,6 +2403,7 @@ public class Theme {
overrideWallpaper = themeAccent.overrideWallpaper;
themeAccentsMap.put(id, themeAccent);
themeAccents.add(0, themeAccent);
sortAccents(this);
return themeAccent;
} else {
return accent;
@ -4839,6 +4850,7 @@ public class Theme {
new int[] { 0, 180, 45, 0, 45, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[] { 0, 52, 46, 57, 45, 64, 52, 35, 36, 41, 50, 50, 35, 38, 37, 30 }
);
sortAccents(themeInfo);
themes.add(currentDayTheme = currentTheme = defaultTheme = themeInfo);
themesDict.put("Blue", themeInfo);
@ -4862,6 +4874,7 @@ public class Theme {
new int[] { 225, 45, 225, 135, 45, 225, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[] { 40, 40, 31, 50, 25, 34, 35, 35, 38, 29, 24, 34, 34, 31, 29, 37, 21, 38 }
);
sortAccents(themeInfo);
themes.add(themeInfo);
themesDict.put("Dark Blue", currentNightTheme = themeInfo);
@ -4885,6 +4898,7 @@ public class Theme {
new int[] { 315, 315, 225, 315, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[] { 50, 50, 58, 47, 46, 50, 49, 46, 51, 50, 49, 34, 54, 50, 40 }
);
sortAccents(themeInfo);
themes.add(themeInfo);
themesDict.put("Arctic Blue", themeInfo);
@ -4908,6 +4922,7 @@ public class Theme {
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
);
sortAccents(themeInfo);
themes.add(themeInfo);
themesDict.put("Day", themeInfo);
@ -4931,15 +4946,21 @@ public class Theme {
new int[] { 45, 135, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new int[] { 34, 47, 52, 48, 54, 50, 37, 56, 48, 49, 40, 64, 38, 48 }
);
sortAccents(themeInfo);
themes.add(themeInfo);
themesDict.put("Night", themeInfo);
String themesString = themeConfig.getString("themes2", null);
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
remoteThemesHash[a] = themeConfig.getLong("2remoteThemesHash" + (a != 0 ? a : ""), 0);
lastLoadingThemesTime[a] = themeConfig.getInt("lastLoadingThemesTime" + (a != 0 ? a : ""), 0);
int remoteVersion = themeConfig.getInt("remote_version", 0);
int appRemoteThemesVersion = 1;
if (remoteVersion == appRemoteThemesVersion) {
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
remoteThemesHash[a] = themeConfig.getLong("2remoteThemesHash" + (a != 0 ? a : ""), 0);
lastLoadingThemesTime[a] = themeConfig.getInt("lastLoadingThemesTime" + (a != 0 ? a : ""), 0);
}
}
themeConfig.edit().putInt("remote_version", appRemoteThemesVersion).apply();
if (!TextUtils.isEmpty(themesString)) {
try {
JSONArray jsonArray = new JSONArray(themesString);
@ -5150,15 +5171,8 @@ public class Theme {
}
}
if (!newAccents.isEmpty()) {
Collections.sort(newAccents, (o1, o2) -> {
if (o1.id > o2.id) {
return -1;
} else if (o1.id < o2.id) {
return 1;
}
return 0;
});
info.themeAccents.addAll(0, newAccents);
sortAccents(info);
}
if (info.themeAccentsMap != null && info.themeAccentsMap.get(info.currentAccentId) == null) {
info.currentAccentId = info.firstAccentIsDefault ? DEFALT_THEME_ACCENT_ID : 0;
@ -5252,7 +5266,10 @@ public class Theme {
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
try {
TLRPC.TL_theme theme = TLRPC.Theme.TLdeserialize(serializedData, serializedData.readInt32(true), true);
previewItems.add(new ChatThemeBottomSheet.ChatThemeItem(EmojiThemes.createPreviewFullTheme(theme)));
EmojiThemes fullTheme = EmojiThemes.createPreviewFullTheme(theme);
if (fullTheme.items.size() >= 4) {
previewItems.add(new ChatThemeBottomSheet.ChatThemeItem(fullTheme));
}
ChatThemeController.chatThemeQueue.postRunnable(new Runnable() {
@Override
@ -5263,7 +5280,6 @@ public class Theme {
AndroidUtilities.runOnUIThread(() -> {
defaultEmojiThemes.clear();
defaultEmojiThemes.addAll(previewItems);
NotificationCenter.getInstance(0).postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
});
}
});
@ -5273,6 +5289,42 @@ public class Theme {
}
}
private static void sortAccents(ThemeInfo info) {
Collections.sort(info.themeAccents, (o1, o2) -> {
if (isHome(o1)) {
return -1;
}
if (isHome(o2)) {
return 1;
}
int i1 = o1.isDefault ? 1 : 0;
int i2 = o2.isDefault ? 1 : 0;
if (i1 == i2) {
if (o1.isDefault) {
if (o1.id > o2.id) {
return 1;
} else if (o1.id < o2.id) {
return -1;
}
} else {
if (o1.id > o2.id) {
return -1;
} else if (o1.id < o2.id) {
return 1;
}
}
} else {
if (i1 > i2) {
return -1;
} else {
return 1;
}
}
return 0;
});
}
private static Method StateListDrawable_getStateDrawableMethod;
private static Field BitmapDrawable_mColorFilter;
@ -7112,7 +7164,7 @@ public class Theme {
}
public static void loadRemoteThemes(final int currentAccount, boolean force) {
if (loadingRemoteThemes[currentAccount]) {
if (loadingRemoteThemes[currentAccount] || !force && Math.abs(System.currentTimeMillis() / 1000 - lastLoadingThemesTime[currentAccount]) < 60 * 60 || !UserConfig.getInstance(currentAccount).isClientActivated()) {
return;
}
loadingRemoteThemes[currentAccount] = true;
@ -7143,15 +7195,13 @@ public class Theme {
boolean loadPatterns = false;
boolean added = false;
for (int a = 0, N = res.themes.size(); a < N; a++) {
TLRPC.Theme t = res.themes.get(a);
TLRPC.TL_theme t = res.themes.get(a);
if (!(t instanceof TLRPC.TL_theme)) {
continue;
}
TLRPC.TL_theme theme = (TLRPC.TL_theme) t;
TLRPC.TL_theme theme = t;
if (theme.isDefault) {
//TODO new emoji themes
continue;
//emojiPreviewThemes.add(theme);
emojiPreviewThemes.add(theme);
}
if (theme.settings != null && theme.settings.size() > 0) {
for (int i = 0; i < theme.settings.size(); i++) {
@ -7183,7 +7233,7 @@ public class Theme {
accent.patternMotion = settings.wallpaper != null && settings.wallpaper.settings != null && settings.wallpaper.settings.motion;
oldServerThemes.remove(accent);
} else {
accent = info.createNewAccent(theme, currentAccount);
accent = info.createNewAccent(theme, currentAccount, false, i);
if (!TextUtils.isEmpty(accent.patternSlug)) {
loadPatterns = true;
}
@ -7262,7 +7312,6 @@ public class Theme {
SerializedData data = new SerializedData(tlChatTheme.getObjectSize());
tlChatTheme.serializeToStream(data);
editor.putString("theme_" + i, Utilities.bytesToHex(data.toByteArray()));
EmojiThemes chatTheme = new EmojiThemes(tlChatTheme, false);
}
editor.apply();
@ -7273,7 +7322,9 @@ public class Theme {
TLRPC.TL_theme theme = emojiPreviewThemes.get(i);
EmojiThemes chatTheme = EmojiThemes.createPreviewFullTheme(theme);
ChatThemeBottomSheet.ChatThemeItem item = new ChatThemeBottomSheet.ChatThemeItem(chatTheme);
previewItems.add(item);
if (chatTheme.items.size() >= 4) {
previewItems.add(item);
}
}
ChatThemeController.chatThemeQueue.postRunnable(new Runnable() {
@Override
@ -7284,13 +7335,13 @@ public class Theme {
AndroidUtilities.runOnUIThread(() -> {
defaultEmojiThemes.clear();
defaultEmojiThemes.addAll(previewItems);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
});
}
});
} else {
defaultEmojiThemes.clear();
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.emojiPreviewThemesChanged);
}
}
@ -9438,6 +9489,7 @@ public class Theme {
Integer gradientToColor2 = currentColors.get(key_chat_wallpaper_gradient_to2);
gradientToColor2 = currentColors.get(key_chat_wallpaper_gradient_to2);
Integer gradientToColor1 = currentColors.get(key_chat_wallpaper_gradient_to1);
if (wallpaperFile != null && wallpaperFile.exists()) {
try {
if (backgroundColor != null && gradientToColor1 != null && gradientToColor2 != null) {
@ -9972,4 +10024,19 @@ public class Theme {
public static boolean isCurrentThemeDay() {
return !getActiveTheme().isDark();
}
public static boolean isHome(ThemeAccent accent) {
if (accent.parentTheme != null) {
if (accent.parentTheme.getKey().equals("Blue") && accent.id == 99) {
return true;
}
if (accent.parentTheme.getKey().equals("Day") && accent.id == 9) {
return true;
}
if ((accent.parentTheme.getKey().equals("Night") || accent.parentTheme.getKey().equals("Dark Blue")) && accent.id == 0) {
return true;
}
}
return false;
}
}

View file

@ -80,6 +80,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
private String currentGroupCreateAddress;
private String currentGroupCreateDisplayAddress;
private Location currentGroupCreateLocation;
private boolean showingAsBottomSheet;
private ActionIntroQRLoginDelegate qrLoginDelegate;
@ -103,23 +104,26 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
@Override
public View createView(Context context) {
actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarWhiteSelector), false);
actionBar.setCastShadows(false);
actionBar.setAddToContainer(false);
if (!AndroidUtilities.isTablet()) {
actionBar.showActionModeTop();
}
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
}
if (actionBar != null) {
actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarWhiteSelector), false);
actionBar.setCastShadows(false);
actionBar.setAddToContainer(false);
if (!AndroidUtilities.isTablet()) {
actionBar.showActionModeTop();
}
});
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
}
}
});
}
fragmentView = new ViewGroup(context) {
@ -128,8 +132,9 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
actionBar.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightMeasureSpec);
if (actionBar != null) {
actionBar.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightMeasureSpec);
}
switch (currentType) {
case ACTION_TYPE_CHANNEL_CREATE: {
if (width > height) {
@ -146,7 +151,13 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
break;
}
case ACTION_TYPE_QR_LOGIN: {
if (width > height) {
if (showingAsBottomSheet) {
imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) (height * 0.32f), MeasureSpec.EXACTLY));
titleTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
descriptionLayout.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
buttonTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY));
height = imageView.getMeasuredHeight() + titleTextView.getMeasuredHeight() + AndroidUtilities.dp(20) + titleTextView.getMeasuredHeight() + descriptionLayout.getMeasuredHeight() + buttonTextView.getMeasuredHeight();
} else if (width > height) {
imageView.measure(MeasureSpec.makeMeasureSpec((int) (width * 0.45f), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) (height * 0.68f), MeasureSpec.EXACTLY));
titleTextView.measure(MeasureSpec.makeMeasureSpec((int) (width * 0.6f), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
descriptionLayout.measure(MeasureSpec.makeMeasureSpec((int) (width * 0.6f), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
@ -214,7 +225,9 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
actionBar.layout(0, 0, r, actionBar.getMeasuredHeight());
if (actionBar != null) {
actionBar.layout(0, 0, r, actionBar.getMeasuredHeight());
}
int width = r - l;
int height = b - t;
@ -247,7 +260,21 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
break;
}
case ACTION_TYPE_QR_LOGIN: {
if (r > b) {
if (showingAsBottomSheet) {
int y;
y = 0;
imageView.layout(0, y, imageView.getMeasuredWidth(), y + imageView.getMeasuredHeight());
y = (int) (height * 0.403f);
titleTextView.layout(0, y, titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
y = (int) (height * 0.631f);
int x = (getMeasuredWidth() - descriptionLayout.getMeasuredWidth()) / 2;
descriptionLayout.layout(x, y, x + descriptionLayout.getMeasuredWidth(), y + descriptionLayout.getMeasuredHeight());
x = (width - buttonTextView.getMeasuredWidth()) / 2;
y = (int) (height * 0.853f);
buttonTextView.layout(x, y, x + buttonTextView.getMeasuredWidth(), y + buttonTextView.getMeasuredHeight());
} else if (r > b) {
int y = (height - imageView.getMeasuredHeight()) / 2;
imageView.layout(0, y, imageView.getMeasuredWidth(), y + imageView.getMeasuredHeight());
int x = (int) (width * 0.4f);
@ -383,7 +410,9 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
ViewGroup viewGroup = (ViewGroup) fragmentView;
viewGroup.setOnTouchListener((v, event) -> true);
viewGroup.addView(actionBar);
if (actionBar != null) {
viewGroup.addView(actionBar);
}
imageView = new RLottieImageView(context);
viewGroup.addView(imageView);
@ -796,7 +825,7 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
}
private void processOpenQrReader() {
CameraScanActivity.showAsSheet(this, false, new CameraScanActivity.CameraScanActivityDelegate() {
CameraScanActivity.showAsSheet(this, false, CameraScanActivity.TYPE_QR, new CameraScanActivity.CameraScanActivityDelegate() {
@Override
public void didFindQr(String text) {
finishFragment(false);
@ -809,6 +838,10 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
return currentType;
}
public void setShowingAsBottomSheet(boolean showingAsBottomSheet) {
this.showingAsBottomSheet = showingAsBottomSheet;
}
@Override
public ArrayList<ThemeDescription> getThemeDescriptions() {
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
@ -817,9 +850,11 @@ public class ActionIntroActivity extends BaseFragment implements LocationControl
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND, null, null, null, delegate, Theme.key_windowBackgroundWhite));
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText2));
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_actionBarWhiteSelector));
if (actionBar != null) {
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText2));
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_actionBarWhiteSelector));
}
themeDescriptions.add(new ThemeDescription(titleTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, delegate, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(subtitleTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));

View file

@ -10,10 +10,13 @@ package org.telegram.ui;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings;
import android.text.TextUtils;
import android.transition.ChangeBounds;
import android.transition.Fade;
@ -22,18 +25,25 @@ import android.transition.TransitionSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.exoplayer2.util.Log;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteDatabase;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildConfig;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
@ -69,7 +79,11 @@ import org.telegram.ui.Components.StroageUsageView;
import org.telegram.ui.Components.UndoView;
import java.io.File;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.stream.Stream;
public class CacheControlActivity extends BaseFragment {
@ -99,10 +113,12 @@ public class CacheControlActivity extends BaseFragment {
private long totalSize = -1;
private long totalDeviceSize = -1;
private long totalDeviceFreeSize = -1;
private long migrateOldFolderRow = -1;
private StorageDiagramView.ClearViewData[] clearViewData = new StorageDiagramView.ClearViewData[7];
private boolean calculating = true;
private volatile boolean canceled = false;
private boolean hasOldFolder;
private View bottomSheetView;
private BottomSheet bottomSheet;
@ -116,18 +132,6 @@ public class CacheControlActivity extends BaseFragment {
public boolean onFragmentCreate() {
super.onFragmentCreate();
rowCount = 0;
keepMediaHeaderRow = rowCount++;
keepMediaChooserRow = rowCount++;
keepMediaInfoRow = rowCount++;
deviseStorageHeaderRow = rowCount++;
storageUsageRow = rowCount++;
cacheInfoRow = rowCount++;
databaseRow = rowCount++;
databaseInfoRow = rowCount++;
databaseSize = MessagesStorage.getInstance(currentAccount).getDatabaseSize();
Utilities.globalQueue.postRunnable(() -> {
@ -209,9 +213,45 @@ public class CacheControlActivity extends BaseFragment {
});
fragmentCreateTime = System.currentTimeMillis();
if (Build.VERSION.SDK_INT >= 30) {
File path = Environment.getExternalStorageDirectory();
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(SharedConfig.storageCacheDir)) {
ArrayList<File> dirs = AndroidUtilities.getRootDirs();
if (dirs != null) {
for (int a = 0, N = dirs.size(); a < N; a++) {
File dir = dirs.get(a);
if (dir.getAbsolutePath().startsWith(SharedConfig.storageCacheDir)) {
path = dir;
break;
}
}
}
}
File oldDirectory = new File(path, "Telegram");
hasOldFolder = oldDirectory.exists();
}
updateRows();
return true;
}
private void updateRows() {
rowCount = 0;
keepMediaHeaderRow = rowCount++;
keepMediaChooserRow = rowCount++;
keepMediaInfoRow = rowCount++;
deviseStorageHeaderRow = rowCount++;
storageUsageRow = rowCount++;
cacheInfoRow = rowCount++;
databaseRow = rowCount++;
databaseInfoRow = rowCount++;
// if (hasOldFolder) {
// migrateOldFolderRow = rowCount++;
// }
}
private void updateStorageUsageRow() {
View view = layoutManager.findViewByPosition(storageUsageRow);
if (view instanceof StroageUsageView) {
@ -406,7 +446,9 @@ public class CacheControlActivity extends BaseFragment {
if (getParentActivity() == null) {
return;
}
if (position == databaseRow) {
if (position == migrateOldFolderRow) {
migrateOldFolder();
} else if (position == databaseRow) {
clearDatabase();
} else if (position == storageUsageRow) {
if (totalSize <= 0 || getParentActivity() == null) {
@ -525,6 +567,115 @@ public class CacheControlActivity extends BaseFragment {
return fragmentView;
}
@RequiresApi(api = Build.VERSION_CODES.R)
private void migrateOldFolder() {
boolean isExternalStorageManager = Environment.isExternalStorageManager();
if (!BuildVars.NO_SCOPED_STORAGE && !isExternalStorageManager) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("MigrateOldFolder", R.string.MigrateOldFolder));
builder.setMessage(LocaleController.getString("ManageAllFilesRational2", R.string.ManageAllFilesRational2));
builder.setPositiveButton(LocaleController.getString("Allow", R.string.Allow), (i1, i2) -> {
Uri uri = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
getParentActivity().startActivity(new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri));
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (i1, i2) -> {
});
builder.show();
return;
}
Thread thread = new Thread() {
int totalFilesCount;
int movedFilesCount;
@Override
public void run() {
super.run();
File path = Environment.getExternalStorageDirectory();
if (Build.VERSION.SDK_INT >= 19 && !TextUtils.isEmpty(SharedConfig.storageCacheDir)) {
ArrayList<File> dirs = AndroidUtilities.getRootDirs();
if (dirs != null) {
for (int a = 0, N = dirs.size(); a < N; a++) {
File dir = dirs.get(a);
if (dir.getAbsolutePath().startsWith(SharedConfig.storageCacheDir)) {
path = dir;
break;
}
}
}
}
File newPath = ApplicationLoader.applicationContext.getExternalFilesDir(null);
File telegramPath = new File(newPath, "Telegram");
File oldPath = new File(path, "Telegram");
totalFilesCount = getFilesCount(oldPath);
long moveStart = System.currentTimeMillis();
moveDirectory(oldPath, telegramPath);
long dt = System.currentTimeMillis() - moveStart;
FileLog.d("move time = " + dt);
}
private int getFilesCount(File source) {
if (!source.exists()) {
return 0;
}
int count = 0;
File[] fileList = source.listFiles();
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isDirectory()) {
count += getFilesCount(fileList[i]);
} else {
count++;
}
}
return count;
}
private void moveDirectory(File source, File target) {
if (!source.exists() || (!target.exists() && !target.mkdir())) {
return;
}
try (Stream<Path> files = Files.list(source.toPath())) {
files.forEach(path -> {
File dest = new File(target, path.getFileName().toString());
if (Files.isDirectory(path)) {
moveDirectory(path.toFile(), dest);
} else {
try {
Files.move(path, dest.toPath());
} catch (Exception e) {
FileLog.e(e);
try {
path.toFile().delete();
} catch (Exception e1) {
FileLog.e(e1);
}
}
movedFilesCount++;
updateProgress();
}
});
} catch (Exception e) {
FileLog.e(e);
}
try {
source.delete();
} catch (Exception e) {
FileLog.e(e);
}
}
private void updateProgress() {
float p = movedFilesCount / (float) totalFilesCount;
}
};
thread.start();
}
private void clearDatabase() {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("LocalDatabaseClearTextTitle", R.string.LocalDatabaseClearTextTitle));
@ -657,7 +808,7 @@ public class CacheControlActivity extends BaseFragment {
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
int position = holder.getAdapterPosition();
return position == databaseRow || (position == storageUsageRow && (totalSize > 0) && !calculating);
return position == migrateOldFolderRow || position == databaseRow || (position == storageUsageRow && (totalSize > 0) && !calculating);
}
@Override
@ -721,6 +872,8 @@ public class CacheControlActivity extends BaseFragment {
TextSettingsCell textCell = (TextSettingsCell) holder.itemView;
if (position == databaseRow) {
textCell.setTextAndValue(LocaleController.getString("ClearLocalDatabase", R.string.ClearLocalDatabase), AndroidUtilities.formatFileSize(databaseSize), false);
} else if (position == migrateOldFolderRow) {
textCell.setTextAndValue(LocaleController.getString("MigrateOldFolder", R.string.MigrateOldFolder), null, false);
}
break;
case 1:

File diff suppressed because it is too large Load diff

View file

@ -13,6 +13,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.Path;
@ -24,6 +25,8 @@ import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.SparseArray;
import android.util.TypedValue;
@ -33,6 +36,8 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
@ -65,6 +70,10 @@ import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.TextPaintWebpageUrlSpan;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanNoUnderline;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@ -97,6 +106,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
public static final int TYPE_MRZ = 0;
public static final int TYPE_QR = 1;
public static final int TYPE_QR_LOGIN = 2;
public interface CameraScanActivityDelegate {
default void didFindMrzInfo(MrzRecognizer.Result result) {
@ -108,7 +118,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
}
}
public static ActionBarLayout[] showAsSheet(BaseFragment parentFragment, boolean gallery, CameraScanActivityDelegate delegate) {
public static ActionBarLayout[] showAsSheet(BaseFragment parentFragment, boolean gallery, int type, CameraScanActivityDelegate delegate) {
if (parentFragment == null || parentFragment.getParentActivity() == null) {
return null;
}
@ -116,7 +126,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
BottomSheet bottomSheet = new BottomSheet(parentFragment.getParentActivity(), false) {
{
actionBarLayout[0].init(new ArrayList<>());
CameraScanActivity fragment = new CameraScanActivity(TYPE_QR) {
CameraScanActivity fragment = new CameraScanActivity(type) {
@Override
public void finishFragment() {
dismiss();
@ -171,7 +181,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
// }
});
currentType = type;
if (currentType == TYPE_QR) {
if (isQr()) {
qrReader = new QRCodeReader();
visionQrReader = new BarcodeDetector.Builder(ApplicationLoader.applicationContext).setBarcodeFormats(Barcode.QR_CODE).build();
}
@ -200,7 +210,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarWhiteSelector), false);
actionBar.setCastShadows(false);
if (!AndroidUtilities.isTablet() && currentType != TYPE_QR) {
if (!AndroidUtilities.isTablet() && !isQr()) {
actionBar.showActionModeTop();
}
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@ -235,7 +245,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
}
flashButton.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY));
}
titleTextView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
titleTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(72), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
descriptionText.measure(MeasureSpec.makeMeasureSpec((int) (width * 0.9f), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
setMeasuredDimension(width, height);
@ -250,15 +260,19 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
if (currentType == TYPE_MRZ) {
cameraView.layout(0, y, cameraView.getMeasuredWidth(), y + cameraView.getMeasuredHeight());
y = (int) (height * 0.65f);
titleTextView.layout(0, y, titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
titleTextView.layout(AndroidUtilities.dp(36), y, AndroidUtilities.dp(36) + titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
recognizedMrzView.setTextSize(TypedValue.COMPLEX_UNIT_PX, cameraView.getMeasuredHeight() / 22);
recognizedMrzView.setPadding(0, 0, 0, cameraView.getMeasuredHeight() / 15);
} else {
actionBar.layout(0, 0, actionBar.getMeasuredWidth(), actionBar.getMeasuredHeight());
cameraView.layout(0, 0, cameraView.getMeasuredWidth(), cameraView.getMeasuredHeight());
int size = (int) (Math.min(cameraView.getWidth(), cameraView.getHeight()) / 1.5f);
y = (cameraView.getMeasuredHeight() - size) / 2 - titleTextView.getMeasuredHeight() - AndroidUtilities.dp(30);
titleTextView.layout(0, y, titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
if (currentType == TYPE_QR) {
y = (cameraView.getMeasuredHeight() - size) / 2 - titleTextView.getMeasuredHeight() - AndroidUtilities.dp(30);
} else {
y = (cameraView.getMeasuredHeight() - size) / 2 - titleTextView.getMeasuredHeight() - AndroidUtilities.dp(64);
}
titleTextView.layout(AndroidUtilities.dp(36), y, AndroidUtilities.dp(36) + titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
recognizedMrzView.layout(0, getMeasuredHeight() - recognizedMrzView.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
int x;
@ -284,7 +298,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
boolean result = super.drawChild(canvas, child, drawingTime);
if (currentType == TYPE_QR && child == cameraView) {
if (isQr() && child == cameraView) {
int size = (int) (Math.min(child.getWidth(), child.getHeight()) / 1.5f);
int x = (child.getWidth() - size) / 2;
int y = (child.getHeight() - size) / 2;
@ -351,9 +365,48 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
viewGroup.addView(actionBar);
}
titleTextView = new TextView(context);
if (currentType == TYPE_QR_LOGIN) {
actionBar.setTitle(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan));
}
Paint selectionPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
selectionPaint.setColor(ColorUtils.setAlphaComponent(Color.WHITE, 100));
titleTextView = new TextView(context) {
LinkPath textPath;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getText() instanceof Spanned) {
Spanned spanned = (Spanned) getText();
URLSpanNoUnderline[] innerSpans = spanned.getSpans(0, spanned.length(), URLSpanNoUnderline.class);
if (innerSpans != null && innerSpans.length > 0) {
textPath = new LinkPath(true);
textPath.setAllowReset(false);
for (int a = 0; a < innerSpans.length; a++) {
int start = spanned.getSpanStart(innerSpans[a]);
int end = spanned.getSpanEnd(innerSpans[a]);
textPath.setCurrentLayout(getLayout(), start, 0);
int shift = getText() != null ? getPaint().baselineShift : 0;
textPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
getLayout().getSelectionPath(start, end, textPath);
}
textPath.setAllowReset(true);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
if (textPath != null) {
canvas.drawPath(textPath, selectionPaint);
}
super.onDraw(canvas);
}
};
titleTextView.setGravity(Gravity.CENTER_HORIZONTAL);
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);
viewGroup.addView(titleTextView);
descriptionText = new TextView(context);
@ -377,7 +430,45 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
if (needGalleryButton) {
//titleTextView.setText(LocaleController.getString("WalletScanCode", R.string.WalletScanCode));
} else {
titleTextView.setText(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan));
if (currentType == TYPE_QR) {
titleTextView.setText(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan));
} else {
String text = LocaleController.getString("AuthAnotherClientInfo5", R.string.AuthAnotherClientInfo5);
SpannableStringBuilder spanned = new SpannableStringBuilder(text);
int index1 = text.indexOf('*');
int index2 = text.indexOf('*', index1 + 1);
if (index1 != -1 && index2 != -1 && index1 != index2) {
titleTextView.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
spanned.replace(index2, index2 + 1, " ");
spanned.replace(index1, index1 + 1, " ");
index1 += 1;
index2 += 1;
spanned.setSpan(new URLSpanNoUnderline(LocaleController.getString("AuthAnotherClientDownloadClientUrl", R.string.AuthAnotherClientDownloadClientUrl)), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
text = spanned.toString();
index1 = text.indexOf('*');
index2 = text.indexOf('*', index1 + 1);
if (index1 != -1 && index2 != -1 && index1 != index2) {
spanned.replace(index2, index2 + 1, " ");
spanned.replace(index1, index1 + 1, " ");
index1 += 1;
index2 += 1;
spanned.setSpan(new URLSpanNoUnderline(LocaleController.getString("AuthAnotherWebClientUrl", R.string.AuthAnotherWebClientUrl)), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
titleTextView.setLinkTextColor(Color.WHITE);
titleTextView.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection));
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
titleTextView.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
titleTextView.setPadding(0, 0, 0, 0);
titleTextView.setText(spanned);
}
}
titleTextView.setTextColor(0xffffffff);
recognizedMrzView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
@ -650,10 +741,15 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa
return null;
}
private boolean isQr() {
return currentType == TYPE_QR || currentType == TYPE_QR_LOGIN;
}
@Override
public ArrayList<ThemeDescription> getThemeDescriptions() {
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
if (currentType == TYPE_QR) {
if (isQr()) {
return themeDescriptions;
}

View file

@ -150,7 +150,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
@Override
public void onItemClick(int id) {
if (id == done_button) {
views[currentViewNum].onNextPressed();
views[currentViewNum].onNextPressed(null);
} else if (id == -1) {
finishFragment();
}
@ -337,7 +337,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (getParentActivity() == null || nextPressed) {
return;
}
@ -392,7 +392,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
@Override
public void onShow() {
super.onShow();
onNextPressed();
onNextPressed(null);
}
}
@ -556,7 +556,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
Intent mailer = new Intent(Intent.ACTION_SENDTO);
mailer.setData(Uri.parse("mailto:"));
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"reports@stel.com"});
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"sms@telegram.org"});
mailer.putExtra(Intent.EXTRA_SUBJECT, "Android cancel account deletion issue " + version + " " + phone);
mailer.putExtra(Intent.EXTRA_TEXT, "Phone: " + phone + "\nApp version: " + version + "\nOS version: SDK " + Build.VERSION.SDK_INT + "\nDevice Name: " + Build.MANUFACTURER + Build.MODEL + "\nLocale: " + Locale.getDefault() + "\nError: " + lastError);
getContext().startActivity(Intent.createChooser(mailer, "Send email..."));
@ -744,7 +744,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
codeField[num + 1].requestFocus();
}
if ((num == length - 1 || num == length - 2 && len >= 2) && getCode().length() == length) {
onNextPressed();
onNextPressed(null);
}
}
}
@ -760,7 +760,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
});
codeField[a].setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -965,11 +965,13 @@ public class CancelAccountDeletionActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (nextPressed) {
return;
}
String code = getCode();
if (code == null) {
code = getCode();
}
if (TextUtils.isEmpty(code)) {
AndroidUtilities.shakeView(codeFieldContainer, 2, 0);
return;
@ -1070,7 +1072,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
}
if (id == NotificationCenter.didReceiveSmsCode) {
codeField[0].setText("" + args[0]);
onNextPressed();
onNextPressed(null);
} else if (id == NotificationCenter.didReceiveCall) {
String num = "" + args[0];
if (!AndroidUtilities.checkPhonePattern(pattern, num)) {
@ -1079,7 +1081,7 @@ public class CancelAccountDeletionActivity extends BaseFragment {
ignoreOnTextChange = true;
codeField[0].setText(num);
ignoreOnTextChange = false;
onNextPressed();
onNextPressed(null);
}
}
}

View file

@ -2369,7 +2369,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private boolean checkTextSelection(MotionEvent event) {
TextSelectionHelper.ChatListTextSelectionHelper textSelectionHelper = delegate.getTextSelectionHelper();
if (textSelectionHelper == null) {
if (textSelectionHelper == null || MessagesController.getInstance(currentAccount).isChatNoForwards(currentMessageObject.getChatId())) {
return false;
}
boolean hasTextBlocks = currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty();
@ -2434,7 +2434,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
private void updateSelectionTextPosition() {
if (getDelegate().getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
int textSelectionType = getDelegate().getTextSelectionHelper().getTextSelectionType(this);
if (textSelectionType == TextSelectionHelper.ChatListTextSelectionHelper.TYPE_DESCRIPTION) {
int linkX;
@ -2969,7 +2969,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
if (getDelegate().getTextSelectionHelper() != null) {
if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null) {
getDelegate().getTextSelectionHelper().onChatMessageCellDetached(this);
}
@ -3053,7 +3053,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
animatingDrawVideoImageButtonProgress = (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) && drawVideoSize ? 1.0f : 0.0f;
}
if (getDelegate().getTextSelectionHelper() != null) {
if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null) {
getDelegate().getTextSelectionHelper().onChatMessageCellAttached(this);
}
@ -3177,9 +3177,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawVideoSize = false;
canStreamVideo = false;
animatingNoSound = 0;
drawSideButton = !isRepliesChat && checkNeedDrawShareButton(messageObject) && (currentPosition == null || currentPosition.last) ? 1 : 0;
if (isPinnedChat || drawSideButton == 1 && messageObject.messageOwner.fwd_from != null && !messageObject.isOutOwner() && messageObject.messageOwner.fwd_from.saved_from_peer != null && messageObject.getDialogId() == UserConfig.getInstance(currentAccount).getClientUserId()) {
drawSideButton = 2;
if (MessagesController.getInstance(currentAccount).isChatNoForwards(messageObject.getChatId())) {
drawSideButton = 0;
} else {
drawSideButton = !isRepliesChat && checkNeedDrawShareButton(messageObject) && (currentPosition == null || currentPosition.last) ? 1 : 0;
if (isPinnedChat || drawSideButton == 1 && messageObject.messageOwner.fwd_from != null && !messageObject.isOutOwner() && messageObject.messageOwner.fwd_from.saved_from_peer != null && messageObject.getDialogId() == UserConfig.getInstance(currentAccount).getClientUserId()) {
drawSideButton = 2;
}
}
replyNameLayout = null;
adminLayout = null;
@ -8118,7 +8122,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.drawPath(urlPath.get(b), Theme.chat_urlPaint);
}
}
if (delegate.getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
if (delegate != null && delegate.getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
delegate.getTextSelectionHelper().drawDescription(currentMessageObject.isOutOwner(), descriptionLayout, canvas);
}
descriptionLayout.draw(canvas);
@ -8146,7 +8150,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
imageDrawn = true;
drawTime = true;
} else {
if (delegate == null || delegate.getPinchToZoomHelper() == null || !delegate.getPinchToZoomHelper().isInOverlayModeFor(this)) {
if (delegate == null || delegate.getPinchToZoomHelper() == null || !delegate.getPinchToZoomHelper().isInOverlayModeFor(this) && drawInstantViewType != 11) {
if (alpha != 1f) {
photoImage.setAlpha(alpha);
imageDrawn = photoImage.draw(canvas);
@ -11105,7 +11109,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.chat_namePaint.setColor(getThemedColor(AvatarDrawable.getNameColorNameForId(currentUser.id)));
}
} else if (currentChat != null) {
if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) {
if (currentMessageObject.isOutOwner() && ChatObject.isChannel(currentChat)) {
if (currentBackgroundDrawable != null && currentBackgroundDrawable.hasGradient()) {
Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_messageTextOut));
} else {
Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_outForwardedNameText));
}
} else if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) {
Theme.chat_namePaint.setColor(Theme.changeColorAccent(getThemedColor(AvatarDrawable.getNameColorNameForId(5))));
} else if (currentMessageObject.isOutOwner()) {
Theme.chat_namePaint.setColor(getThemedColor(Theme.key_chat_outForwardedNameText));
@ -11844,7 +11854,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (!selectionOnly) {
try {
if (getDelegate().getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
if (getDelegate() != null && getDelegate().getTextSelectionHelper() != null && getDelegate().getTextSelectionHelper().isSelected(currentMessageObject)) {
getDelegate().getTextSelectionHelper().drawCaption(currentMessageObject.isOutOwner(), captionLayout, canvas);
}
Emoji.emojiDrawingYOffset = -transitionYOffsetForDrawables;

View file

@ -195,7 +195,7 @@ public class PatternCell extends BackupImageView implements DownloadController.F
if (backgroundGradientColor2 != 0) {
gradientShader = null;
if (backgroundDrawable != null) {
backgroundDrawable.setColors(backgroundColor, backgroundGradientColor1, backgroundGradientColor2, backgroundGradientColor3, false);
backgroundDrawable.setColors(backgroundColor, backgroundGradientColor1, backgroundGradientColor2, backgroundGradientColor3, 0, false);
} else {
backgroundDrawable = new MotionBackgroundDrawable(backgroundColor, backgroundGradientColor1, backgroundGradientColor2, backgroundGradientColor3, true);
backgroundDrawable.setRoundRadius(AndroidUtilities.dp(6));

View file

@ -10,14 +10,22 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
@ -29,6 +37,9 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.DotDividerSpan;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import java.util.Locale;
@ -42,13 +53,16 @@ public class SessionCell extends FrameLayout {
private BackupImageView imageView;
private AvatarDrawable avatarDrawable;
private boolean needDivider;
private boolean showStub;
FlickerLoadingView globalGradient;
LinearLayout linearLayout;
private int currentAccount = UserConfig.selectedAccount;
public SessionCell(Context context, int type) {
super(context);
LinearLayout linearLayout = new LinearLayout(context);
linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setWeightSum(1);
@ -57,14 +71,18 @@ public class SessionCell extends FrameLayout {
avatarDrawable = new AvatarDrawable();
avatarDrawable.setTextSize(AndroidUtilities.dp(10));
imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(10));
addView(imageView, LayoutHelper.createFrame(20, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 21), 13, (LocaleController.isRTL ? 21 : 0), 0));
} else {
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 30, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 15 : 21), 11, (LocaleController.isRTL ? 21 : 15), 0));
imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(10));
addView(imageView, LayoutHelper.createFrame(42, 42, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : 16), 13, (LocaleController.isRTL ? 16 : 0), 0));
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 30, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 15 : 72), 11, (LocaleController.isRTL ? 72 : 15), 0));
}
nameTextView = new TextView(context);
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
@ -95,7 +113,7 @@ public class SessionCell extends FrameLayout {
detailTextView.setSingleLine(true);
detailTextView.setEllipsize(TextUtils.TruncateAt.END);
detailTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 21, 36, 21, 0));
addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, type == 0 ? 72 : 21, 36, 21, 0));
detailExTextView = new TextView(context);
detailExTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
@ -105,7 +123,7 @@ public class SessionCell extends FrameLayout {
detailExTextView.setSingleLine(true);
detailExTextView.setEllipsize(TextUtils.TruncateAt.END);
detailExTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(detailExTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 21, 59, 21, 0));
addView(detailExTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, type == 0 ? 72 : 21, 59, 21, 0));
}
@Override
@ -118,41 +136,17 @@ public class SessionCell extends FrameLayout {
if (object instanceof TLRPC.TL_authorization) {
TLRPC.TL_authorization session = (TLRPC.TL_authorization) object;
nameTextView.setText(String.format(Locale.US, "%s %s", session.app_name, session.app_version));
if ((session.flags & 1) != 0) {
setTag(Theme.key_windowBackgroundWhiteValueText);
onlineTextView.setText(LocaleController.getString("Online", R.string.Online));
onlineTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteValueText));
} else {
setTag(Theme.key_windowBackgroundWhiteGrayText3);
onlineTextView.setText(LocaleController.stringForMessageListDate(session.date_active));
onlineTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
}
imageView.setImageDrawable(createDrawable(session));
// nameTextView.setText(String.format(Locale.US, "%s %s", session.app_name, session.app_version));
StringBuilder stringBuilder = new StringBuilder();
if (session.ip.length() != 0) {
stringBuilder.append(session.ip);
}
if (session.country.length() != 0) {
if (stringBuilder.length() != 0) {
stringBuilder.append(" ");
}
stringBuilder.append("");
stringBuilder.append(session.country);
}
detailExTextView.setText(stringBuilder);
stringBuilder = new StringBuilder();
if (session.device_model.length() != 0) {
if (stringBuilder.length() != 0) {
stringBuilder.append(", ");
}
stringBuilder.append(session.device_model);
}
if (session.system_version.length() != 0 || session.platform.length() != 0) {
if (stringBuilder.length() != 0) {
stringBuilder.append(", ");
}
if (stringBuilder.length() == 0) {
if (session.platform.length() != 0) {
stringBuilder.append(session.platform);
}
@ -163,17 +157,33 @@ public class SessionCell extends FrameLayout {
stringBuilder.append(session.system_version);
}
}
nameTextView.setText(stringBuilder);
if (!session.official_app) {
if (stringBuilder.length() != 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("UnofficialApp", R.string.UnofficialApp));
stringBuilder.append(" (ID: ");
stringBuilder.append(session.api_id);
stringBuilder.append(")");
String timeText;
if ((session.flags & 1) != 0) {
setTag(Theme.key_windowBackgroundWhiteValueText);
timeText = LocaleController.getString("Online", R.string.Online);
} else {
setTag(Theme.key_windowBackgroundWhiteGrayText3);
timeText = LocaleController.stringForMessageListDate(session.date_active);
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
if (session.country.length() != 0) {
spannableStringBuilder.append(session.country);
}
if (spannableStringBuilder.length() != 0) {
DotDividerSpan dotDividerSpan = new DotDividerSpan();
dotDividerSpan.setTopPadding(AndroidUtilities.dp(1.5f));
spannableStringBuilder.append(" . ").setSpan(dotDividerSpan, spannableStringBuilder.length() - 2, spannableStringBuilder.length() - 1, 0);
}
spannableStringBuilder.append(timeText);
detailExTextView.setText(spannableStringBuilder);
stringBuilder = new StringBuilder();
stringBuilder.append(session.app_name);
stringBuilder.append(" ").append(session.app_version);
detailTextView.setText(stringBuilder);
} else if (object instanceof TLRPC.TL_webAuthorization) {
TLRPC.TL_webAuthorization session = (TLRPC.TL_webAuthorization) object;
@ -224,12 +234,111 @@ public class SessionCell extends FrameLayout {
detailTextView.setText(stringBuilder);
}
if (showStub) {
showStub = false;
invalidate();
}
}
public static Drawable createDrawable(TLRPC.TL_authorization session) {
String platform = session.platform.toLowerCase();
if (platform.isEmpty()) {
platform = session.system_version.toLowerCase();
}
String deviceModel = session.device_model.toLowerCase();
int iconId;
String colorKey;
if (deviceModel.contains("safari")) {
iconId = R.drawable.device_web_safari;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("edge")) {
iconId = R.drawable.device_web_edge;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("chrome")) {
iconId = R.drawable.device_web_chrome;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("opera")) {
iconId = R.drawable.device_web_opera;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("firefox")) {
iconId = R.drawable.device_web_firefox;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("vivaldi")) {
iconId = R.drawable.device_web_other;
colorKey = Theme.key_avatar_backgroundPink;
} else if (platform.contains("ios")) {
iconId = deviceModel.contains("ipad") ? R.drawable.device_tablet_ios : R.drawable.device_phone_ios;
colorKey = Theme.key_avatar_backgroundBlue;
} else if (platform.contains("windows")) {
iconId = R.drawable.device_desktop_win;
colorKey = Theme.key_avatar_backgroundCyan;
} else if (platform.contains("macos")) {
iconId = R.drawable.device_desktop_osx;
colorKey = Theme.key_avatar_backgroundCyan;
} else if (platform.contains("android")) {
iconId = deviceModel.contains("tab") ? R.drawable.device_tablet_android : R.drawable.device_phone_android;
colorKey = Theme.key_avatar_backgroundGreen;
} else {
if (session.app_name.toLowerCase().contains("desktop")) {
iconId = R.drawable.device_desktop_other;
colorKey = Theme.key_avatar_backgroundCyan;
} else {
iconId = R.drawable.device_web_other;
colorKey = Theme.key_avatar_backgroundPink;
}
}
Drawable iconDrawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, iconId).mutate();
iconDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_avatar_text), PorterDuff.Mode.SRC_IN));
CombinedDrawable combinedDrawable = new CombinedDrawable(Theme.createCircleDrawable(AndroidUtilities.dp(42), Theme.getColor(colorKey)), iconDrawable);
return combinedDrawable;
}
@Override
protected void onDraw(Canvas canvas) {
if (showStub && globalGradient != null) {
globalGradient.updateColors();
globalGradient.updateGradient();
if (getParent() != null) {
View parent = (View) getParent();
globalGradient.setParentSize(parent.getMeasuredWidth(), parent.getMeasuredHeight(), -getX());
}
float y = linearLayout.getTop() + nameTextView.getTop() + AndroidUtilities.dp(12);
float x = linearLayout.getX();
AndroidUtilities.rectTmp.set(x, y - AndroidUtilities.dp(4), x + getMeasuredWidth() * 0.2f, y + AndroidUtilities.dp(4));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), globalGradient.getPaint());
y = linearLayout.getTop() + detailTextView.getTop() - AndroidUtilities.dp(1);
x = linearLayout.getX();
AndroidUtilities.rectTmp.set(x, y - AndroidUtilities.dp(4), x + getMeasuredWidth() * 0.4f, y + AndroidUtilities.dp(4));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), globalGradient.getPaint());
y = linearLayout.getTop() + detailExTextView.getTop() - AndroidUtilities.dp(1);
x = linearLayout.getX();
AndroidUtilities.rectTmp.set(x, y - AndroidUtilities.dp(4), x + getMeasuredWidth() * 0.3f, y + AndroidUtilities.dp(4));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), globalGradient.getPaint());
invalidate();
}
if (needDivider) {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
}
}
public void showStub(FlickerLoadingView globalGradient) {
this.globalGradient = globalGradient;
showStub = true;
Drawable iconDrawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, AndroidUtilities.isTablet() ? R.drawable.device_tablet_android : R.drawable.device_phone_android).mutate();
iconDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_avatar_text), PorterDuff.Mode.SRC_IN));
CombinedDrawable combinedDrawable = new CombinedDrawable(Theme.createCircleDrawable(AndroidUtilities.dp(42), Theme.getColor(Theme.key_avatar_backgroundGreen)), iconDrawable);
imageView.setImageDrawable(combinedDrawable);
invalidate();
}
public boolean isStub() {
return showStub;
}
}

View file

@ -30,12 +30,17 @@ public class TextCheckBoxCell extends FrameLayout {
private boolean needDivider;
public TextCheckBoxCell(Context context) {
this(context, false);
this(context, false, false);
}
public TextCheckBoxCell(Context context, boolean dialog) {
public TextCheckBoxCell(Context context, boolean dialog, boolean revereLayout) {
super(context);
boolean isRtl = LocaleController.isRTL;
if (revereLayout) {
isRtl = !isRtl;
}
textView = new TextView(context);
textView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
@ -44,14 +49,15 @@ public class TextCheckBoxCell extends FrameLayout {
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 66 : 21, 0, LocaleController.isRTL ? 21 : 66, 0));
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (isRtl ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, isRtl ? 66 : 21, 0, isRtl ? 21 : 66, 0));
checkBox = new CheckBoxSquare(context, dialog);
checkBox.setDuplicateParentStateEnabled(false);
checkBox.setFocusable(false);
checkBox.setFocusableInTouchMode(false);
checkBox.setClickable(false);
addView(checkBox, LayoutHelper.createFrame(18, 18, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 21, 0, 21, 0));
addView(checkBox, LayoutHelper.createFrame(18, 18, (isRtl ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 21, 0, 21, 0));
}
@Override

View file

@ -153,7 +153,7 @@ public class ChangePhoneActivity extends BaseFragment {
@Override
public void onItemClick(int id) {
if (id == done_button) {
views[currentViewNum].onNextPressed();
views[currentViewNum].onNextPressed(null);
} else if (id == -1) {
finishFragment();
}
@ -211,7 +211,7 @@ public class ChangePhoneActivity extends BaseFragment {
if (requestCode == 6) {
checkPermissions = false;
if (currentViewNum == 0) {
views[currentViewNum].onNextPressed();
views[currentViewNum].onNextPressed(null);
}
}
}
@ -594,7 +594,7 @@ public class ChangePhoneActivity extends BaseFragment {
});
phoneField.setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -712,7 +712,7 @@ public class ChangePhoneActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (getParentActivity() == null || nextPressed) {
return;
}
@ -985,7 +985,7 @@ public class ChangePhoneActivity extends BaseFragment {
Intent mailer = new Intent(Intent.ACTION_SENDTO);
mailer.setData(Uri.parse("mailto:"));
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"reports@stel.com"});
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"sms@telegram.org"});
mailer.putExtra(Intent.EXTRA_SUBJECT, "Android registration/login issue " + version + " " + emailPhone);
mailer.putExtra(Intent.EXTRA_TEXT, "Phone: " + requestPhone + "\nApp version: " + version + "\nOS version: SDK " + Build.VERSION.SDK_INT + "\nDevice Name: " + Build.MANUFACTURER + Build.MODEL + "\nLocale: " + Locale.getDefault() + "\nError: " + lastError);
getContext().startActivity(Intent.createChooser(mailer, "Send email..."));
@ -1178,7 +1178,7 @@ public class ChangePhoneActivity extends BaseFragment {
codeField[num + 1].requestFocus();
}
if ((num == length - 1 || num == length - 2 && len >= 2) && getCode().length() == length) {
onNextPressed();
onNextPressed(null);
}
}
}
@ -1194,7 +1194,7 @@ public class ChangePhoneActivity extends BaseFragment {
});
codeField[a].setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -1398,11 +1398,11 @@ public class ChangePhoneActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (nextPressed) {
return;
}
String code = getCode();
code = getCode();
if (TextUtils.isEmpty(code)) {
AndroidUtilities.shakeView(codeFieldContainer, 2, 0);
return;
@ -1550,7 +1550,7 @@ public class ChangePhoneActivity extends BaseFragment {
}
if (id == NotificationCenter.didReceiveSmsCode) {
codeField[0].setText("" + args[0]);
onNextPressed();
onNextPressed(null);
} else if (id == NotificationCenter.didReceiveCall) {
String num = "" + args[0];
if (!AndroidUtilities.checkPhonePattern(pattern, num)) {
@ -1559,7 +1559,7 @@ public class ChangePhoneActivity extends BaseFragment {
ignoreOnTextChange = true;
codeField[0].setText(num);
ignoreOnTextChange = false;
onNextPressed();
onNextPressed(null);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1343,10 +1343,11 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
typeCell.setTextAndValue(LocaleController.getString("TypeLocationGroup", R.string.TypeLocationGroup), link, historyCell != null && historyCell.getVisibility() == View.VISIBLE || linkedCell != null && linkedCell.getVisibility() == View.VISIBLE);
} else {
String type;
boolean isRestricted = currentChat.noforwards;
if (isChannel) {
type = isPrivate ? LocaleController.getString("TypePrivate", R.string.TypePrivate) : LocaleController.getString("TypePublic", R.string.TypePublic);
type = isPrivate ? isRestricted ? LocaleController.getString("TypePrivateRestrictedForwards", R.string.TypePrivateRestrictedForwards) : LocaleController.getString("TypePrivate", R.string.TypePrivate) : LocaleController.getString("TypePublic", R.string.TypePublic);
} else {
type = isPrivate ? LocaleController.getString("TypePrivateGroup", R.string.TypePrivateGroup) : LocaleController.getString("TypePublicGroup", R.string.TypePublicGroup);
type = isPrivate ? isRestricted ? LocaleController.getString("TypePrivateGroupRestrictedForwards", R.string.TypePrivateGroupRestrictedForwards) : LocaleController.getString("TypePrivateGroup", R.string.TypePrivateGroup) : LocaleController.getString("TypePublicGroup", R.string.TypePublicGroup);
}
if (isChannel) {
typeCell.setTextAndValue(LocaleController.getString("ChannelType", R.string.ChannelType), type, historyCell != null && historyCell.getVisibility() == View.VISIBLE || linkedCell != null && linkedCell.getVisibility() == View.VISIBLE);

View file

@ -21,6 +21,7 @@ import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
@ -43,6 +44,7 @@ import org.telegram.ui.Cells.LoadingCell;
import org.telegram.ui.Cells.RadioButtonCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.TextCheckCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Cells.TextSettingsCell;
import org.telegram.ui.Components.EditTextBoldCursor;
@ -81,12 +83,19 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
private TextSettingsCell textCell;
private TextSettingsCell textCell2;
// Saving content restrictions block
private LinearLayout saveContainer;
private HeaderCell saveHeaderCell;
private TextCheckCell saveRestrictCell;
private TextInfoPrivacyCell saveRestrictInfoCell;
private boolean isPrivate;
private TLRPC.Chat currentChat;
private TLRPC.ChatFull info;
private long chatId;
private boolean isChannel;
private boolean isSaveRestricted;
private boolean canCreatePublic = true;
private boolean loadingAdminedChannels;
@ -133,6 +142,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
}
isPrivate = !isForcePublic && TextUtils.isEmpty(currentChat.username);
isChannel = ChatObject.isChannel(currentChat) && !currentChat.megagroup;
isSaveRestricted = isPrivate && currentChat.noforwards;
if (isForcePublic && TextUtils.isEmpty(currentChat.username) || isPrivate && currentChat.creator) {
TLRPC.TL_channels_checkUsername req = new TLRPC.TL_channels_checkUsername();
req.username = "1";
@ -399,6 +409,32 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
manageLinksInfoCell = new TextInfoPrivacyCell(context);
linearLayout.addView(manageLinksInfoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
saveContainer = new LinearLayout(context);
saveContainer.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(saveContainer);
saveHeaderCell = new HeaderCell(context, 23);
saveHeaderCell.setHeight(46);
saveHeaderCell.setText(LocaleController.getString("SavingContentTitle", R.string.SavingContentTitle));
saveHeaderCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
saveContainer.addView(saveHeaderCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
saveRestrictCell = new TextCheckCell(context);
saveRestrictCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
saveRestrictCell.setTextAndCheck(LocaleController.getString("RestrictSavingContent", R.string.RestrictSavingContent), isSaveRestricted, false);
saveRestrictCell.setOnClickListener(v -> {
isSaveRestricted = !isSaveRestricted;
((TextCheckCell) v).setChecked(isSaveRestricted);
});
saveContainer.addView(saveRestrictCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
saveRestrictInfoCell = new TextInfoPrivacyCell(context);
if (isChannel && !ChatObject.isMegagroup(currentChat)) {
saveRestrictInfoCell.setText(LocaleController.getString("RestrictSavingContentInfoChannel", R.string.RestrictSavingContentInfoChannel));
} else {
saveRestrictInfoCell.setText(LocaleController.getString("RestrictSavingContentInfoGroup", R.string.RestrictSavingContentInfoGroup));
}
saveContainer.addView(saveRestrictInfoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (!isPrivate && currentChat.username != null) {
ignoreTextChanges = true;
usernameTextView.setText(currentChat.username);
@ -434,6 +470,9 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
}
private void processDone() {
if (isPrivate && currentChat.noforwards != isSaveRestricted) {
getMessagesController().toggleChatNoForwards(chatId, currentChat.noforwards = isSaveRestricted);
}
if (trySetUsername()) {
finishFragment();
}
@ -577,6 +616,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
}
publicContainer.setVisibility(isPrivate ? View.GONE : View.VISIBLE);
privateContainer.setVisibility(isPrivate ? View.VISIBLE : View.GONE);
saveContainer.setVisibility(isPrivate ? View.VISIBLE : View.GONE);
manageLinksTextView.setVisibility(View.VISIBLE);
manageLinksInfoCell.setVisibility(View.VISIBLE);
linkContainer.setPadding(0, 0, 0, isPrivate ? 0 : AndroidUtilities.dp(7));
@ -769,9 +809,15 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
themeDescriptions.add(new ThemeDescription(linkContainer, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
themeDescriptions.add(new ThemeDescription(headerCell, 0, new Class[]{HeaderCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueHeader));
themeDescriptions.add(new ThemeDescription(headerCell2, 0, new Class[]{HeaderCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueHeader));
themeDescriptions.add(new ThemeDescription(saveHeaderCell, 0, new Class[]{HeaderCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlueHeader));
themeDescriptions.add(new ThemeDescription(editText, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(editText, ThemeDescription.FLAG_HINTTEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteHintText));
themeDescriptions.add(new ThemeDescription(saveRestrictCell, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(saveRestrictCell, 0, new Class[]{TextCheckCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(saveRestrictCell, 0, new Class[]{TextCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrack));
themeDescriptions.add(new ThemeDescription(saveRestrictCell, 0, new Class[]{TextCheckCell.class}, new String[]{"checkBox"}, null, null, null, Theme.key_switchTrackChecked));
themeDescriptions.add(new ThemeDescription(checkTextView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText4));
themeDescriptions.add(new ThemeDescription(checkTextView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText8));
themeDescriptions.add(new ThemeDescription(checkTextView, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGreenText));
@ -784,6 +830,10 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
themeDescriptions.add(new ThemeDescription(manageLinksInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4));
themeDescriptions.add(new ThemeDescription(manageLinksInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText4));
themeDescriptions.add(new ThemeDescription(saveRestrictInfoCell, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow));
themeDescriptions.add(new ThemeDescription(saveRestrictInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayText4));
themeDescriptions.add(new ThemeDescription(saveRestrictInfoCell, ThemeDescription.FLAG_CHECKTAG, new Class[]{TextInfoPrivacyCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteRedText4));
themeDescriptions.add(new ThemeDescription(adminedInfoCell, ThemeDescription.FLAG_BACKGROUNDFILTER, new Class[]{TextInfoPrivacyCell.class}, null, null, null, Theme.key_windowBackgroundGrayShadow));
themeDescriptions.add(new ThemeDescription(adminnedChannelsLayout, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
themeDescriptions.add(new ThemeDescription(loadingAdminedCell, 0, new Class[]{LoadingCell.class}, new String[]{"progressBar"}, null, null, null, Theme.key_progressCircle));

View file

@ -120,7 +120,7 @@ public class ChatLinkActivity extends BaseFragment implements NotificationCenter
}
private void setSticker() {
TLRPC.TL_messages_stickerSet set = MediaDataController.getInstance(currentAccount).getStickerSetByName(stickerSetName);
TLRPC.messages_StickerSet set = MediaDataController.getInstance(currentAccount).getStickerSetByName(stickerSetName);
if (set == null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(stickerSetName);
}

View file

@ -2828,9 +2828,11 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
peerObject = object;
} else if (object instanceof TLRPC.ChannelParticipant) {
long peerId = MessageObject.getPeerId(((TLRPC.ChannelParticipant) object).peer);
if (peerId > 0) {
if (peerId >= 0) {
TLRPC.User user = getMessagesController().getUser(peerId);
un = user.username;
if (user != null) {
un = user.username;
}
peerObject = user;
} else {
TLRPC.Chat chat = getMessagesController().getChat(-peerId);

View file

@ -0,0 +1,287 @@
package org.telegram.ui;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.LinearLayout;
import androidx.core.graphics.ColorUtils;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.LayoutHelper;
public class CodeFieldContainer extends LinearLayout {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
float strokeWidth;
public boolean ignoreOnTextChange;
public CodeNumberField[] codeField;
public CodeFieldContainer(Context context) {
super(context);
paint.setStyle(Paint.Style.STROKE);
setOrientation(HORIZONTAL);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
paint.setStrokeWidth(strokeWidth = AndroidUtilities.dp(1.5f));
}
@Override
protected void dispatchDraw(Canvas canvas) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof CodeNumberField) {
CodeNumberField codeField = (CodeNumberField) child;
if (child.isFocused() && codeField.focusedProgress != 1f) {
codeField.focusedProgress += 16f / 150f;
if (codeField.focusedProgress > 1f) {
codeField.focusedProgress = 1f;
} else {
invalidate();
}
} else if (!child.isFocused() && codeField.focusedProgress != 0) {
codeField.focusedProgress -= 16f / 150f;
if (codeField.focusedProgress < 0f) {
codeField.focusedProgress = 0f;
} else {
invalidate();
}
}
paint.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_windowBackgroundWhiteInputField), Theme.getColor(Theme.key_windowBackgroundWhiteInputFieldActivated), codeField.focusedProgress));
AndroidUtilities.rectTmp.set(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());
AndroidUtilities.rectTmp.inset(strokeWidth, strokeWidth);
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
}
}
super.dispatchDraw(canvas);
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child instanceof CodeNumberField) {
CodeNumberField field = (CodeNumberField) child;
canvas.save();
float progress = ((CodeNumberField) child).enterAnimation;
AndroidUtilities.rectTmp.set(child.getX(), child.getY(), child.getX() + child.getMeasuredWidth(), child.getY() + child.getMeasuredHeight());
AndroidUtilities.rectTmp.inset(strokeWidth, strokeWidth);
canvas.clipRect(AndroidUtilities.rectTmp);
if (field.replaceAnimation) {
float s = progress * 0.5f + 0.5f;
child.setAlpha(progress);
canvas.scale(s, s, field.getX() + field.getMeasuredWidth() / 2f, field.getY() + field.getMeasuredHeight() / 2f);
} else {
child.setAlpha(1f);
canvas.translate(0, child.getMeasuredHeight() * (1f - progress));
}
super.drawChild(canvas, child, drawingTime);
canvas.restore();
float exitProgress = field.exitAnimation;
if (exitProgress < 1f) {
canvas.save();
float s = (1f - exitProgress) * 0.5f + 0.5f;
canvas.scale(s, s, field.getX() + field.getMeasuredWidth() / 2f, field.getY() + field.getMeasuredHeight() / 2f);
bitmapPaint.setAlpha((int) (255 * (1f - exitProgress)));
canvas.drawBitmap(field.exitBitmap, field.getX(), field.getY(), bitmapPaint);
canvas.restore();
}
return true;
}
return super.drawChild(canvas, child, drawingTime);
}
public void setNumbersCount(int length, int currentType) {
if (codeField == null || codeField.length != length) {
codeField = new CodeNumberField[length];
for (int a = 0; a < length; a++) {
final int num = a;
codeField[a] = new CodeNumberField(getContext()) {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
return false;
}
int keyCode = event.getKeyCode();
if (event.getAction() == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_DEL && codeField[num].length() == 1) {
codeField[num].startExitAnimation();
codeField[num].setText("");
return true;
} else if (keyCode == KeyEvent.KEYCODE_DEL && codeField[num].length() == 0 && num > 0) {
codeField[num - 1].setSelection(codeField[num - 1].length());
for (int i = 0; i < num; i++) {
if (i == num - 1) {
codeField[num - 1].requestFocus();
} else {
codeField[i].clearFocus();
}
}
codeField[num - 1].startExitAnimation();
codeField[num - 1].setText("");
return true;
} else {
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
String str = Integer.toString(keyCode - KeyEvent.KEYCODE_0);
if (codeField[num].getText() != null && str.equals(codeField[num].getText().toString())) {
if (num >= length - 1) {
processNextPressed();
} else {
codeField[num + 1].requestFocus();
}
return true;
}
if (codeField[num].length() > 0) {
codeField[num].startExitAnimation();
}
codeField[num].setText(str);
}
return true;
}
} else {
return isFocused();
}
}
};
codeField[a].setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
codeField[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
codeField[a].setMaxLines(1);
codeField[a].setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
codeField[a].setPadding(0, 0, 0, 0);
codeField[a].setGravity(Gravity.CENTER);
if (currentType == 3) {
codeField[a].setEnabled(false);
codeField[a].setInputType(InputType.TYPE_NULL);
codeField[a].setVisibility(GONE);
} else {
codeField[a].setInputType(InputType.TYPE_CLASS_PHONE);
}
int width;
int height;
int gapSize;
if (currentType == LoginActivity.AUTH_TYPE_MISSED_CALL) {
width = 28;
height = 34;
gapSize = 5;
} else {
width = 34;
height = 42;
gapSize = 7;
}
addView(codeField[a], LayoutHelper.createLinear(width, height, Gravity.CENTER_HORIZONTAL, 0, 0, a != length - 1 ? gapSize: 0, 0));
codeField[a].addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (ignoreOnTextChange) {
return;
}
int len = s.length();
if (len >= 1) {
boolean next = false;
int n = num;
if (len > 1) {
String text = s.toString();
ignoreOnTextChange = true;
for (int a = 0; a < Math.min(length - num, len); a++) {
if (a == 0) {
s.replace(0, len, text.substring(a, a + 1));
} else {
n++;
codeField[num + a].setText(text.substring(a, a + 1));
}
}
ignoreOnTextChange = false;
}
if (n != length - 1) {
codeField[n + 1].setSelection(codeField[n + 1].length());
codeField[n + 1].requestFocus();
}
if ((n == length - 1 || n == length - 2 && len >= 2) && getCode().length() == length) {
processNextPressed();
}
}
}
});
codeField[a].setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
processNextPressed();
return true;
}
return false;
});
}
} else {
for (int a = 0; a < codeField.length; a++) {
codeField[a].setText("");
}
}
}
protected void processNextPressed() {
}
public String getCode() {
if (codeField == null) {
return "";
}
StringBuilder codeBuilder = new StringBuilder();
for (int a = 0; a < codeField.length; a++) {
codeBuilder.append(PhoneFormat.stripExceptNumbers(codeField[a].getText().toString()));
}
return codeBuilder.toString();
}
public void setCode(String savedCode) {
codeField[0].setText(savedCode);
}
public void setText(String code) {
setText(code, false);
}
public void setText(String code, boolean fromPaste) {
int startFrom = 0;
if (fromPaste) {
for (int i = 0; i < codeField.length; i++) {
if (codeField[i].isFocused()) {
startFrom = i;
break;
}
}
}
for (int i = startFrom; i < Math.min(codeField.length, startFrom + code.length()); i++) {
codeField[i].setText(Character.toString(code.charAt(i - startFrom)));
}
}
}

View file

@ -0,0 +1,238 @@
package org.telegram.ui;
import android.animation.ValueAnimator;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.Editable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextWatcher;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.OvershootInterpolator;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import org.checkerframework.checker.regex.qual.Regex;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.StaticLayoutEx;
public class CodeNumberField extends EditTextBoldCursor {
float focusedProgress;
float enterAnimation = 1f;
float exitAnimation = 1f;
boolean replaceAnimation;
Bitmap exitBitmap;
Canvas exitCanvas;
ValueAnimator enterAnimator;
ValueAnimator exitAnimator;
ActionMode actionMode;
public CodeNumberField(Context context) {
super(context);
setBackground(null);
setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
setMovementMethod(null);
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
startEnterAnimation(charSequence.length() != 0);
hideActionMode();
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
public void startExitAnimation() {
if (getMeasuredHeight() == 0 || getMeasuredWidth() == 0 || getLayout() == null) {
return;
}
if (exitBitmap == null || exitBitmap.getHeight() != getMeasuredHeight() || exitBitmap.getWidth() != getMeasuredWidth()) {
if (exitBitmap != null) {
exitBitmap.recycle();
}
exitBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
exitCanvas = new Canvas(exitBitmap);
}
exitBitmap.eraseColor(Color.TRANSPARENT);
StaticLayout staticLayout = new StaticLayout(getText(), getLayout().getPaint(), (int) Math.ceil(getLayout().getPaint().measureText(String.valueOf(getText()))), Layout.Alignment.ALIGN_NORMAL, getLineSpacingMultiplier(), getLineSpacingExtra(), getIncludeFontPadding());
exitCanvas.save();
exitCanvas.translate((getMeasuredWidth() - staticLayout.getWidth()) / 2f, (getMeasuredHeight() - staticLayout.getHeight()) / 2f);
staticLayout.draw(exitCanvas);
exitCanvas.restore();
exitAnimation = 0f;
exitAnimator = ValueAnimator.ofFloat(exitAnimation, 1f);
exitAnimator.addUpdateListener(valueAnimator1 -> {
exitAnimation = (float) valueAnimator1.getAnimatedValue();
invalidate();
if (getParent() != null) {
((ViewGroup) getParent()).invalidate();
}
});
exitAnimator.setDuration(220);
exitAnimator.start();
}
public void startEnterAnimation(boolean replace) {
replaceAnimation = replace;
enterAnimation = 0f;
enterAnimator = ValueAnimator.ofFloat(enterAnimation, 1f);
enterAnimator.addUpdateListener(valueAnimator1 -> {
enterAnimation = (float) valueAnimator1.getAnimatedValue();
invalidate();
if (getParent() != null) {
((ViewGroup) getParent()).invalidate();
}
});
if (!replaceAnimation) {
enterAnimator.setInterpolator(new OvershootInterpolator(1.5f));
enterAnimator.setDuration(350);
} else {
enterAnimator.setDuration(220);
}
enterAnimator.start();
}
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
((ViewGroup) getParent()).invalidate();
return super.requestFocus(direction, previouslyFocusedRect);
}
boolean pressed = false;
float startX = 0;
float startY = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressed = true;
startX = event.getX();
startY = event.getY();
}
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
CodeFieldContainer codeFieldContainer = null;
if (getParent() instanceof CodeFieldContainer) {
codeFieldContainer = (CodeFieldContainer) getParent();
}
if (event.getAction() == MotionEvent.ACTION_UP && pressed) {
if (isFocused() && codeFieldContainer != null) {
ClipboardManager clipboard = ContextCompat.getSystemService(getContext(), ClipboardManager.class);
if (clipboard == null) {
return false;
}
clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
int i = -1;
String text = item.getText().toString();
try {
i = Integer.parseInt(text);
} catch (Exception e) {
}
if (i > 0) {
startActionMode(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.add(Menu.NONE, android.R.id.paste, 0, android.R.string.paste);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case android.R.id.paste:
pasteFromClipboard();
hideActionMode();
return true;
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
} else {
requestFocus();
}
setSelection(0);
AndroidUtilities.showKeyboard(this);
}
pressed = false;
}
return pressed;
}
private void pasteFromClipboard() {
CodeFieldContainer codeFieldContainer = null;
if (getParent() instanceof CodeFieldContainer) {
codeFieldContainer = (CodeFieldContainer) getParent();
}
if (codeFieldContainer != null) {
ClipboardManager clipboard = ContextCompat.getSystemService(getContext(), ClipboardManager.class);
if (clipboard == null) {
return;
}
clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
int i = -1;
String text = item.getText().toString();
try {
i = Integer.parseInt(text);
} catch (Exception e) {
}
if (i > 0) {
codeFieldContainer.setText(text, true);
}
}
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (!isFocused()) {
hideActionMode();
}
}
}

View file

@ -1487,6 +1487,80 @@ public class AlertsCreator {
}
}
public static void createClearDaysDialogAlert(BaseFragment fragment, int days, TLRPC.User user, MessagesStorage.BooleanCallback onProcessRunnable, Theme.ResourcesProvider resourcesProvider) {
if (fragment == null || fragment.getParentActivity() == null || user == null) {
return;
}
int account = fragment.getCurrentAccount();
Context context = fragment.getParentActivity();
AlertDialog.Builder builder = new AlertDialog.Builder(context, resourcesProvider);
long selfUserId = UserConfig.getInstance(account).getClientUserId();
CheckBoxCell[] cell = new CheckBoxCell[1];
TextView messageTextView = new TextView(context);
messageTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
FrameLayout frameLayout = new FrameLayout(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (cell[0] != null) {
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() + cell[0].getMeasuredHeight());
}
}
};
builder.setView(frameLayout);
TextView textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setText(LocaleController.formatPluralString("DeleteDays", days));
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 11, 24, 0));
frameLayout.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 48, 24, 18));
messageTextView.setText(LocaleController.getString("DeleteHistoryByDaysMessage", R.string.DeleteHistoryByDaysMessage));
final boolean[] deleteForAll = new boolean[]{false};
if (user.id != selfUserId) {
cell[0] = new CheckBoxCell(context, 1, resourcesProvider);
cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false));
cell[0].setText(LocaleController.formatString("DeleteMessagesOptionAlso", R.string.DeleteMessagesOptionAlso, UserObject.getFirstName(user)), "", false, false);
cell[0].setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0);
frameLayout.addView(cell[0], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 0));
cell[0].setChecked(false, false);
cell[0].setOnClickListener(v -> {
CheckBoxCell cell1 = (CheckBoxCell) v;
deleteForAll[0] = !deleteForAll[0];
cell1.setChecked(deleteForAll[0], true);
});
}
builder.setPositiveButton(LocaleController.getString("Delete", R.string.Delete), (dialogInterface, i) -> {
onProcessRunnable.run(deleteForAll[0]);
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
AlertDialog alertDialog = builder.create();
fragment.showDialog(alertDialog);
TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
}
}
public static void createCallDialogAlert(BaseFragment fragment, TLRPC.User user, boolean videoCall) {
if (fragment == null || fragment.getParentActivity() == null || user == null || UserObject.isDeleted(user) || UserConfig.getInstance(fragment.getCurrentAccount()).getClientUserId() == user.id) {
return;
@ -1831,6 +1905,43 @@ public class AlertsCreator {
}
public static void showChatWithAdmin(BaseFragment fragment, TLRPC.User user, String chatWithAdmin, boolean isChannel, int chatWithAdminDate) {
if (fragment.getParentActivity() == null) {
return;
}
BottomSheet.Builder builder = new BottomSheet.Builder(fragment.getParentActivity());
builder.setTitle(isChannel ? LocaleController.getString("ChatWithAdminChannelTitle", R.string.ChatWithAdminChannelTitle) : LocaleController.getString("ChatWithAdminGroupTitle", R.string.ChatWithAdminGroupTitle), true);
LinearLayout linearLayout = new LinearLayout(fragment.getParentActivity());
linearLayout.setOrientation(LinearLayout.VERTICAL);
TextView messageTextView = new TextView(fragment.getParentActivity());
linearLayout.addView(messageTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 24, 16, 24, 24));
messageTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ChatWithAdminMessage", R.string.ChatWithAdminMessage, chatWithAdmin, LocaleController.formatDateAudio(chatWithAdminDate, false))));
TextView buttonTextView = new TextView(fragment.getParentActivity());
buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0);
buttonTextView.setGravity(Gravity.CENTER);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setText(LocaleController.getString("IUnderstand", R.string.IUnderstand));
buttonTextView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed)));
linearLayout.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, 0, 24, 15, 16, 24));
builder.setCustomView(linearLayout);
BottomSheet bottomSheet = builder.show();
buttonTextView.setOnClickListener((v) -> {
bottomSheet.dismiss();
});
}
public interface BlockDialogCallback {
void run(boolean report, boolean delete);
}

View file

@ -1857,6 +1857,18 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
} else {
optionsButton.setVisibility(View.VISIBLE);
}
if (MessagesController.getInstance(currentAccount).isChatNoForwards(messageObject.getChatId())) {
optionsButton.hideSubItem(1);
optionsButton.hideSubItem(2);
optionsButton.hideSubItem(5);
optionsButton.setAdditionalYOffset(-AndroidUtilities.dp(16));
} else {
optionsButton.showSubItem(1);
optionsButton.showSubItem(2);
optionsButton.showSubItem(5);
optionsButton.setAdditionalYOffset(-AndroidUtilities.dp(157));
}
checkIfMusicDownloaded(messageObject);
updateProgress(messageObject, !sameMessageObject);
updateCover(messageObject, !sameMessageObject);

View file

@ -16,12 +16,14 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@ -34,6 +36,7 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
@ -55,6 +58,7 @@ import android.text.style.ImageSpan;
import android.util.Property;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
@ -63,6 +67,8 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@ -92,6 +98,7 @@ import androidx.core.view.inputmethod.InputContentInfoCompat;
import androidx.customview.widget.ExploreByTouchHelper;
import androidx.recyclerview.widget.ChatListItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
@ -138,6 +145,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
public class ChatActivityEnterView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate, SizeNotifierFrameLayout.SizeNotifierFrameLayoutDelegate, StickersAlert.StickersAlertDelegate {
@ -211,6 +219,28 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
default boolean hasForwardingMessages() {
return false;
}
/**
* @return Height of the content view
*/
default int getContentViewHeight() {
return 0;
}
/**
* @return Measured keyboard height
*/
default int measureKeyboardHeight() {
return 0;
}
/**
* @return A list of available peers to send messages as
*/
@Nullable
default TLRPC.TL_channels_sendAsPeers getSendAsPeers() {
return null;
}
}
private final static int RECORD_STATE_ENTER = 0;
@ -244,6 +274,13 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
public BotCommandsMenuContainer botCommandsMenuContainer;
private BotCommandsMenuView.BotCommandsAdapter botCommandsAdapter;
// Send as... stuff
private SenderSelectView senderSelectView;
private ActionBarPopupWindow senderSelectPopupWindow;
private Runnable onEmojiSearchClosed;
private int popupX, popupY;
private Runnable onKeyboardClosed;
private ValueAnimator searchAnimator;
private float searchToOpenProgress;
@ -325,10 +362,6 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
private ActionBarPopupWindow.ActionBarPopupWindowLayout sendPopupLayout;
private ImageView cancelBotButton;
private ImageView[] emojiButton = new ImageView[2];
@SuppressWarnings("FieldCanBeLocal")
private ImageView emojiButton1;
@SuppressWarnings("FieldCanBeLocal")
private ImageView emojiButton2;
private ImageView expandStickersButton;
private EmojiView emojiView;
private AnimatorSet panelAnimation;
@ -1777,9 +1810,6 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
emojiButton[a].setAlpha(0.0f);
emojiButton[a].setScaleX(0.1f);
emojiButton[a].setScaleY(0.1f);
emojiButton2 = emojiButton[a];
} else {
emojiButton1 = emojiButton[a];
}
}
setEmojiButtonImage(false, false);
@ -2412,6 +2442,527 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
attachButton.setContentDescription(LocaleController.getString("AccDescrAttachButton", R.string.AccDescrAttachButton));
}
senderSelectView = new SenderSelectView(getContext());
senderSelectView.setOnClickListener(v -> {
if (getTranslationY() != 0) {
onEmojiSearchClosed = () -> senderSelectView.callOnClick();
hidePopup(true, true);
return;
}
if (delegate.measureKeyboardHeight() > AndroidUtilities.dp(20)) {
int totalHeight = delegate.getContentViewHeight();
int keyboard = delegate.measureKeyboardHeight();
if (keyboard <= AndroidUtilities.dp(20)) {
totalHeight += keyboard;
}
if (emojiViewVisible) {
totalHeight -= getEmojiPadding();
}
if (totalHeight < AndroidUtilities.dp(200)) {
onKeyboardClosed = () -> senderSelectView.callOnClick();
closeKeyboard();
return;
}
}
if (delegate.getSendAsPeers() != null) {
if (senderSelectPopupWindow != null) {
senderSelectPopupWindow.setPauseNotifications(false);
senderSelectPopupWindow.dismiss();
return;
}
MessagesController controller = MessagesController.getInstance(currentAccount);
TLRPC.ChatFull chatFull = controller.getChatFull(-dialog_id);
if (chatFull == null) {
return;
}
List<TLRPC.Peer> peers = delegate.getSendAsPeers().peers;
ViewGroup fl = parentFragment.getParentLayout();
FrameLayout scrimPopupContainerLayout = new FrameLayout(getContext()) {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && senderSelectPopupWindow != null && senderSelectPopupWindow.isShowing()) {
senderSelectPopupWindow.dismiss();
}
return super.dispatchKeyEvent(event);
}
};
scrimPopupContainerLayout.setLayoutParams(LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
Drawable shadowDrawable2 = ContextCompat.getDrawable(getContext(), R.drawable.popup_fixed_alert).mutate();
shadowDrawable2.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground), PorterDuff.Mode.MULTIPLY));
scrimPopupContainerLayout.setBackground(shadowDrawable2);
View dim = new View(getContext());
dim.setBackgroundColor(0x33000000);
int maxHeight = AndroidUtilities.dp(450);
LinearLayout rc = new LinearLayout(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Math.min(MeasureSpec.getSize(heightMeasureSpec), maxHeight), MeasureSpec.getMode(heightMeasureSpec)));
}
};
rc.setOrientation(LinearLayout.VERTICAL);
TextView headerText = new TextView(parent.getContext());
headerText.setTextColor(Theme.getColor(Theme.key_dialogTextBlue));
headerText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
headerText.setText(LocaleController.getString("SendMessageAsTitle", R.string.SendMessageAsTitle));
headerText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), Typeface.BOLD);
int dp = AndroidUtilities.dp(18);
headerText.setPadding(dp, AndroidUtilities.dp(13), dp, AndroidUtilities.dp(13));
rc.addView(headerText);
View shadow = new View(getContext());
shadow.setAlpha(0);
FrameLayout rfl = new FrameLayout(getContext());
RecyclerListView rv = new RecyclerListView(getContext());
LinearLayoutManager llm = new LinearLayoutManager(getContext());
AtomicReference<ValueAnimator.AnimatorUpdateListener> animatorUpdateListenerRef = new AtomicReference<>();
AtomicReference<Animator.AnimatorListener> animatorListenerRef = new AtomicReference<>();
AtomicReference<Animator> animatorForSetRef = new AtomicReference<>();
rv.setLayoutManager(llm);
rv.setAdapter(new RecyclerListView.SelectionAdapter() {
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
return true;
}
final Object avatar = new Object(), title = new Object(), subtitle = new Object();
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
FrameLayout fl = new FrameLayout(parent.getContext());
LinearLayout ll = new LinearLayout(parent.getContext());
ll.setLayoutParams(LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setGravity(Gravity.CENTER_VERTICAL);
int dp = AndroidUtilities.dp(14);
ll.setPadding(dp, dp / 2, dp, dp / 2);
SimpleAvatarView avatar = new SimpleAvatarView(parent.getContext());
avatar.setTag(this.avatar);
ll.addView(avatar, LayoutHelper.createLinear(44, 44));
LinearLayout ll2 = new LinearLayout(ll.getContext());
ll2.setOrientation(LinearLayout.VERTICAL);
TextView title = new TextView(parent.getContext());
title.setTextColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem));
title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
title.setTag(this.title);
title.setMaxLines(1);
title.setEllipsize(TextUtils.TruncateAt.END);
ll2.addView(title);
TextView subtitle = new TextView(parent.getContext());
subtitle.setTextColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem), 0x66));
subtitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
subtitle.setTag(this.subtitle);
subtitle.setMaxLines(1);
subtitle.setEllipsize(TextUtils.TruncateAt.END);
ll2.addView(subtitle);
ll.addView(ll2, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1f, 12, 0, 0, 0));
View v = new View(parent.getContext());
fl.addView(ll);
fl.addView(v);
return new RecyclerListView.Holder(fl);
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
TLRPC.Peer peer = peers.get(position);
long peerId = 0;
if (peer.channel_id != 0) {
peerId = -peer.channel_id;
}
if (peerId == 0 && peer.user_id != 0) {
peerId = peer.user_id;
}
SimpleAvatarView avatar = holder.itemView.findViewWithTag(this.avatar);
TextView title = holder.itemView.findViewWithTag(this.title);
TextView subtitle = holder.itemView.findViewWithTag(this.subtitle);
if (peerId < 0) {
TLRPC.Chat chat = controller.getChat(-peerId);
if (chat != null) {
title.setText(chat.title);
subtitle.setText(LocaleController.formatPluralString(ChatObject.isChannel(chat) && !chat.megagroup ? "Subscribers" : "Members", chat.participants_count));
avatar.setAvatar(chat);
}
avatar.setSelected(chatFull.default_send_as != null && chatFull.default_send_as.channel_id == peer.channel_id, false);
} else {
TLRPC.User user = controller.getUser(peerId);
if (user != null) {
title.setText(user.first_name + (user.last_name != null ? " " + user.last_name : ""));
subtitle.setText(LocaleController.getString("VoipGroupPersonalAccount", R.string.VoipGroupPersonalAccount));
avatar.setAvatar(user);
}
avatar.setSelected(chatFull.default_send_as != null && chatFull.default_send_as.user_id == peer.user_id, false);
}
}
@Override
public int getItemCount() {
return peers.size();
}
});
rv.setOnItemClickListener((view, position) -> {
if (senderSelectPopupWindow == null)
return;
TLRPC.Peer peer = peers.get(position);
if (chatFull != null) {
chatFull.default_send_as = peer;
updateSendAsButton();
}
parentFragment.getMessagesController().setDefaultSendAs(dialog_id, peer.user_id != 0 ? peer.user_id : -peer.channel_id);
int[] loc = new int[2];
SimpleAvatarView sAvatar = (SimpleAvatarView) ((ViewGroup)((ViewGroup) view).getChildAt(0)).getChildAt(0);
boolean wasSelected = sAvatar.isSelected();
sAvatar.getLocationInWindow(loc);
sAvatar.setSelected(true, true);
SimpleAvatarView avatar = new SimpleAvatarView(getContext());
if (peer.channel_id != 0) {
TLRPC.Chat chat = controller.getChat(peer.channel_id);
if (chat != null) {
avatar.setAvatar(chat);
}
} else if (peer.user_id != 0) {
TLRPC.User user = controller.getUser(peer.user_id);
if (user != null) {
avatar.setAvatar(user);
}
}
for (int i = 0; i < rv.getChildCount(); i++) {
View ch = rv.getChildAt(i);
if (i != position) {
((SimpleAvatarView) ((ViewGroup)((ViewGroup) ch).getChildAt(0)).getChildAt(0)).setSelected(false, true);
}
}
Dialog d = new Dialog(getContext(), R.style.TransparentDialogNoAnimation);
FrameLayout aFrame = new FrameLayout(getContext());
aFrame.addView(avatar, LayoutHelper.createFrame(44, 44, Gravity.LEFT));
d.setContentView(aFrame);
d.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
d.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
d.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
d.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
d.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
d.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
d.getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
d.getWindow().getAttributes().windowAnimations = 0;
d.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
d.getWindow().setStatusBarColor(0);
d.getWindow().setNavigationBarColor(0);
int color = Theme.getColor(Theme.key_actionBarDefault, null, true);
AndroidUtilities.setLightStatusBar(d.getWindow(), color == Color.WHITE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int color2 = Theme.getColor(Theme.key_windowBackgroundGray, null, true);
float brightness = AndroidUtilities.computePerceivedBrightness(color2);
AndroidUtilities.setLightNavigationBar(d.getWindow(), brightness >= 0.721f);
}
}
float offX = 0, offY = 0;
if (AndroidUtilities.isTablet()) {
parentFragment.getFragmentView().getLocationInWindow(location);
popupX += location[0];
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
WindowInsets wi = getRootWindowInsets();
popupX += wi.getSystemWindowInsetLeft();
}
senderSelectView.getLocationInWindow(location);
float eX = location[0], eY = location[1];
float off = wasSelected ? AndroidUtilities.dp(5) : 0;
float sX = loc[0] + popupX + off + AndroidUtilities.dp(4) + offX, sY = loc[1] + popupY + off + offY;
avatar.setTranslationX(sX);
avatar.setTranslationY(sY);
float sSc = wasSelected ? 34f / 44f : 1, eSc = senderSelectView.getLayoutParams().width / (float)AndroidUtilities.dp(44);
avatar.setPivotX(0);
avatar.setPivotY(0);
avatar.setScaleX(sSc);
avatar.setScaleY(sSc);
animatorListenerRef.set(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
avatar.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
@Override
public void onDraw() {
avatar.post(()->{
avatar.getViewTreeObserver().removeOnDrawListener(this);
sAvatar.setHideAvatar(true);
});
}
});
d.show();
}
@Override
public void onAnimationEnd(Animator animation) {
senderSelectView.setProgress(0, false);
senderSelectView.setScaleX(1);
senderSelectView.setScaleY(1);
senderSelectView.setAlpha(1);
senderSelectView.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
@Override
public void onDraw() {
senderSelectView.post(()->{
senderSelectView.getViewTreeObserver().removeOnDrawListener(this);
d.dismiss();
});
}
});
}
@Override
public void onAnimationCancel(Animator animation) {
onAnimationEnd(animation);
}
});
animatorUpdateListenerRef.set(animation -> {
float f = (float) animation.getAnimatedValue();
float selSc = 0.5f + f * 0.5f;
senderSelectView.setScaleX(selSc);
senderSelectView.setScaleY(selSc);
senderSelectView.setAlpha(f);
});
ValueAnimator anim = ValueAnimator.ofFloat(0, 1).setDuration(350);
float pos = (rv.getY() + rv.getMeasuredHeight() - loc[1]) / (float)AndroidUtilities.dp(58);
float mAmplitude = 0.18f - pos * 0.009f,
mFrequency = 5.7f - pos * 0.325f;
anim.setInterpolator(time -> (float) (-1 * Math.pow(Math.E, -time / mAmplitude) *
Math.cos(mFrequency * time) + 1));
anim.addUpdateListener(animation -> {
float val = (float) animation.getAnimatedValue();
avatar.setTranslationX(sX + (eX - sX) * val);
avatar.setTranslationY(sY + (eY - sY) * val);
float sc = sSc + (eSc - sSc) * val;
avatar.setScaleX(sc);
avatar.setScaleY(sc);
});
animatorForSetRef.set(anim);
senderSelectPopupWindow.dismiss();
});
int shadowDuration = 150;
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
Boolean isVisible;
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
boolean v = llm.findFirstCompletelyVisibleItemPosition() == 0;
if (isVisible == null || v != isVisible) {
shadow.animate().cancel();
if (v) {
shadow.animate().alpha(0).setDuration(shadowDuration).start();
} else {
shadow.animate().alpha(1).setDuration(shadowDuration).start();
}
isVisible = v;
}
}
});
rv.setOverScrollMode(OVER_SCROLL_NEVER);
rfl.addView(rv);
Drawable d = Theme.getThemedDrawable(getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow);
shadow.setBackground(d);
rfl.addView(shadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 4));
rc.addView(rfl, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
scrimPopupContainerLayout.addView(rc);
senderSelectPopupWindow = new ActionBarPopupWindow(scrimPopupContainerLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT) {
private void dismissSuper() {
super.dismiss();
}
@Override
public void dismiss() {
if (senderSelectPopupWindow != this) {
fl.removeView(dim);
super.dismiss();
return;
}
float scStart = 0.25f;
scrimPopupContainerLayout.setPivotX(AndroidUtilities.dp(8));
scrimPopupContainerLayout.setPivotY(scrimPopupContainerLayout.getMeasuredHeight() - AndroidUtilities.dp(8));
rc.setPivotX(0);
rc.setPivotY(0);
scrimPopupContainerLayout.setScaleX(1);
scrimPopupContainerLayout.setScaleY(1);
rc.setAlpha(1);
dim.setAlpha(1);
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator anim = ValueAnimator.ofFloat(1, 0).setDuration(220);
anim.setInterpolator(CubicBezierInterpolator.EASE_OUT);
anim.addUpdateListener(animation -> {
float val = (float) animation.getAnimatedValue();
float sc = scStart + (1f - scStart) * val;
scrimPopupContainerLayout.setScaleX(sc);
scrimPopupContainerLayout.setScaleY(sc);
scrimPopupContainerLayout.setAlpha(val);
rc.setScaleX(1f / sc);
rc.setScaleY(1f / sc);
rc.setAlpha(sc);
dim.setAlpha(val);
});
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
fl.removeView(dim);
dismissSuper();
}
});
ValueAnimator anim2 = ValueAnimator.ofFloat(1, 0).setDuration(350);
anim2.setInterpolator(Easings.easeOutSine);
ValueAnimator.AnimatorUpdateListener l = animatorUpdateListenerRef.get();
if (l != null) {
anim2.addUpdateListener(l);
}
Animator.AnimatorListener l2 = animatorListenerRef.get();
if (l2 != null) {
anim2.addListener(l2);
}
animatorSet.playTogether(anim, anim2);
senderSelectPopupWindow = null;
if (l == null && l2 == null) senderSelectView.setProgress(0);
Animator secAnim = animatorForSetRef.get();
if (secAnim != null) {
animatorSet.playTogether(secAnim);
}
animatorSet.start();
}
};
senderSelectPopupWindow.setPauseNotifications(true);
senderSelectPopupWindow.setDismissAnimationDuration(220);
senderSelectPopupWindow.setOutsideTouchable(true);
senderSelectPopupWindow.setClippingEnabled(true);
senderSelectPopupWindow.setFocusable(true);
scrimPopupContainerLayout.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST));
senderSelectPopupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
senderSelectPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
senderSelectPopupWindow.getContentView().setFocusableInTouchMode(true);
senderSelectPopupWindow.setAnimationEnabled(false);
TLRPC.Peer defPeer = chatFull.default_send_as != null ? chatFull.default_send_as : null;
if (defPeer != null) {
int itemHeight = AndroidUtilities.dp(14 + 44);
int totalRecyclerHeight = peers.size() * itemHeight;
for (int i = 0; i < peers.size(); i++) {
TLRPC.Peer p = peers.get(i);
if (p.channel_id != 0 && p.channel_id == defPeer.channel_id || p.user_id != 0 && p.user_id == defPeer.user_id ||
p.chat_id != 0 && p.chat_id == defPeer.chat_id) {
int off = 0;
if (i != peers.size() - 1 && rv.getMeasuredHeight() < totalRecyclerHeight) {
off = rv.getMeasuredHeight() % itemHeight;
}
llm.scrollToPositionWithOffset(i, off + AndroidUtilities.dp(7) + (totalRecyclerHeight - (peers.size() - 2) * itemHeight));
if (rv.computeVerticalScrollOffset() > 0) {
shadow.animate().cancel();
shadow.animate().alpha(1).setDuration(shadowDuration).start();
}
break;
}
}
}
int pad = -AndroidUtilities.dp(4);
int[] location = new int[2];
int popupX = pad;
if (AndroidUtilities.isTablet()) {
parentFragment.getFragmentView().getLocationInWindow(location);
popupX += location[0];
}
int totalHeight = delegate.getContentViewHeight();
int height = scrimPopupContainerLayout.getMeasuredHeight();
int keyboard = delegate.measureKeyboardHeight();
if (keyboard <= AndroidUtilities.dp(20)) {
totalHeight += keyboard;
}
if (emojiViewVisible) {
totalHeight -= getEmojiPadding();
}
int shadowPad = AndroidUtilities.dp(1);
int popupY;
if (height < totalHeight + pad * 2 - (parentFragment.isInBubbleMode() ? 0 : AndroidUtilities.statusBarHeight) - headerText.getMeasuredHeight()) {
ChatActivityEnterView.this.getLocationInWindow(location);
popupY = location[1] - height - pad - AndroidUtilities.dp(2);
fl.addView(dim, new FrameLayout.LayoutParams(LayoutHelper.MATCH_PARENT, popupY + pad + height + shadowPad + AndroidUtilities.dp(2)));
} else {
popupY = parentFragment.isInBubbleMode() ? 0 : AndroidUtilities.statusBarHeight;
int off = AndroidUtilities.dp(14);
rc.getLayoutParams().height = totalHeight - popupY - off - getHeightWithTopView();
fl.addView(dim, new FrameLayout.LayoutParams(LayoutHelper.MATCH_PARENT, off + popupY + rc.getLayoutParams().height + shadowPad));
}
float scStart = 0.25f;
scrimPopupContainerLayout.setPivotX(AndroidUtilities.dp(8));
scrimPopupContainerLayout.setPivotY(scrimPopupContainerLayout.getMeasuredHeight() - AndroidUtilities.dp(8));
rc.setPivotX(0);
rc.setPivotY(0);
scrimPopupContainerLayout.setScaleX(scStart);
scrimPopupContainerLayout.setScaleY(scStart);
rc.setAlpha(scStart);
dim.setAlpha(0);
ValueAnimator anim = ValueAnimator.ofFloat(0, 1).setDuration(220);
anim.setInterpolator(CubicBezierInterpolator.EASE_OUT);
anim.addUpdateListener(animation -> {
float val = (float) animation.getAnimatedValue();
float sc = scStart + (1f - scStart) * val;
scrimPopupContainerLayout.setScaleX(sc);
scrimPopupContainerLayout.setScaleY(sc);
rc.setScaleX(1f / sc);
rc.setScaleY(1f / sc);
rc.setAlpha(sc);
dim.setAlpha(val);
});
anim.start();
senderSelectPopupWindow.showAtLocation(v, Gravity.LEFT | Gravity.TOP, this.popupX = popupX, this.popupY = popupY);
senderSelectView.setProgress(1);
}
});
senderSelectView.setVisibility(GONE);
frameLayout.addView(senderSelectView, LayoutHelper.createFrame(32, 32, Gravity.BOTTOM | Gravity.LEFT, 10, 8, 10, 8));
recordedAudioPanel = new FrameLayout(context);
recordedAudioPanel.setVisibility(audioToSend == null ? GONE : VISIBLE);
recordedAudioPanel.setFocusable(true);
@ -3585,6 +4136,13 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
return topView != null && topView.getVisibility() == VISIBLE;
}
public void onAdjustPanTransitionEnd() {
if (onKeyboardClosed != null) {
onKeyboardClosed.run();
onKeyboardClosed = null;
}
}
public void onAdjustPanTransitionStart(boolean keyboardVisible) {
if (keyboardVisible && showTopViewRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(showTopViewRunnable);
@ -3682,6 +4240,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
if (sizeNotifierLayout != null) {
sizeNotifierLayout.setDelegate(null);
}
if (senderSelectPopupWindow != null) {
senderSelectPopupWindow.setPauseNotifications(false);
senderSelectPopupWindow.dismiss();
}
}
public void checkChannelRights() {
@ -3704,10 +4266,23 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (senderSelectPopupWindow != null){
senderSelectPopupWindow.setPauseNotifications(false);
senderSelectPopupWindow.dismiss();
}
}
private Runnable hideKeyboardRunnable;
public void onPause() {
isPaused = true;
if (senderSelectPopupWindow != null) {
senderSelectPopupWindow.setPauseNotifications(false);
senderSelectPopupWindow.dismiss();
}
if (keyboardVisible) {
showKeyboardOnResume = true;
}
@ -3781,6 +4356,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
updateScheduleButton(false);
checkRoundVideo();
updateFieldHint(false);
updateSendAsButton();
}
public void setChatInfo(TLRPC.ChatFull chatInfo) {
@ -3832,7 +4408,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
return hasRecordVideo;
}
private void updateFieldHint(boolean animated) {
public void updateFieldHint(boolean animated) {
if (replyingMessageObject != null && replyingMessageObject.messageOwner.reply_markup != null && !TextUtils.isEmpty(replyingMessageObject.messageOwner.reply_markup.placeholder)) {
messageEditText.setHintText(replyingMessageObject.messageOwner.reply_markup.placeholder, animated);
} else if (editingMessageObject != null) {
@ -3844,8 +4420,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
boolean anonymously = false;
if (DialogObject.isChatDialog(dialog_id)) {
TLRPC.Chat chat = accountInstance.getMessagesController().getChat(-dialog_id);
TLRPC.ChatFull chatFull = accountInstance.getMessagesController().getChatFull(-dialog_id);
isChannel = ChatObject.isChannel(chat) && !chat.megagroup;
anonymously = ChatObject.shouldSendAnonymously(chat);
anonymously = ChatObject.getSendAsPeerId(chat, chatFull) == chat.id;
}
if (anonymously) {
messageEditText.setHintText(LocaleController.getString("SendAnonymously", R.string.SendAnonymously));
@ -4082,6 +4659,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
messageEditText.setAlpha(1f);
messageEditText.setTranslationX(0);
messageEditText.requestFocus();
updateSendAsButton();
}
});
@ -5678,6 +6256,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
slideText.setCancelToProgress(0f);
delegate.onAudioVideoInterfaceUpdated();
updateSendAsButton();
}
}
});
@ -5685,6 +6264,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
recordTimerView.stop();
}
delegate.onAudioVideoInterfaceUpdated();
updateSendAsButton();
}
@Override
@ -5926,6 +6506,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
updateFieldRight(1);
}
updateFieldHint(false);
updateSendAsButton();
}
public ImageView getAttachButton() {
@ -5949,9 +6530,6 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
public void updateColors() {
if (emojiView != null) {
emojiView.updateColors();
}
if (sendPopupLayout != null) {
for (int a = 0, count = sendPopupLayout.getChildCount(); a < count; a++) {
final View view = sendPopupLayout.getChildAt(a);
@ -5992,7 +6570,11 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
for (int i = 0; i < 2; ++i) {
emojiButton[i].setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_chat_messagePanelIcons), PorterDuff.Mode.MULTIPLY));
if (Build.VERSION.SDK_INT >= 21) {
emojiButton[i].setBackgroundDrawable(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector)));
}
}
}
private void updateRecordedDeleteIconColors() {
@ -6215,6 +6797,108 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
}
public void updateSendAsButton() {
if (parentFragment == null) {
return;
}
TLRPC.ChatFull full = parentFragment.getMessagesController().getChatFull(-dialog_id);
TLRPC.Peer defPeer = full != null ? full.default_send_as : null;
if (defPeer == null && delegate.getSendAsPeers() != null && !delegate.getSendAsPeers().peers.isEmpty()) {
defPeer = delegate.getSendAsPeers().peers.get(0);
}
if (defPeer != null) {
if (defPeer.channel_id != 0) {
TLRPC.Chat ch = MessagesController.getInstance(currentAccount).getChat(defPeer.channel_id);
if (ch != null) senderSelectView.setAvatar(ch);
} else {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(defPeer.user_id);
if (user != null) senderSelectView.setAvatar(user);
}
}
boolean wasVisible = senderSelectView.getVisibility() == View.VISIBLE;
boolean isVisible = delegate.getSendAsPeers() != null && defPeer != null && delegate.getSendAsPeers().peers.size() > 1 && !isEditingMessage() && !isRecordingAudioVideo() && (recordedAudioPanel == null || recordedAudioPanel.getVisibility() == View.GONE);
int pad = AndroidUtilities.dp(2);
MarginLayoutParams params = (MarginLayoutParams) senderSelectView.getLayoutParams();
float sA = isVisible ? 0 : 1;
float sX = isVisible ? -senderSelectView.getLayoutParams().width - params.leftMargin - pad : 0;
float eA = isVisible ? 1 : 0;
float eX = isVisible ? 0 : -senderSelectView.getLayoutParams().width - params.leftMargin - pad;
if (wasVisible != isVisible) {
ValueAnimator a = (ValueAnimator) senderSelectView.getTag();
if (a != null) {
a.cancel();
senderSelectView.setTag(null);
}
if (parentFragment.getOtherSameChatsDiff() == 0 && parentFragment.fragmentOpened) {
ValueAnimator anim = ValueAnimator.ofFloat(0, 1).setDuration(220);
anim.setInterpolator(CubicBezierInterpolator.DEFAULT);
anim.addUpdateListener(animation -> {
float val = (float) animation.getAnimatedValue();
senderSelectView.setAlpha(sA + (eA - sA) * val);
senderSelectView.setTranslationX(sX + (eX - sX) * val);
for (ImageView emoji : emojiButton)
emoji.setTranslationX(senderSelectView.getTranslationX());
messageEditText.setTranslationX(senderSelectView.getTranslationX());
});
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
if (isVisible)
senderSelectView.setVisibility(VISIBLE);
senderSelectView.setAlpha(sA);
senderSelectView.setTranslationX(sX);
for (ImageView emoji : emojiButton)
emoji.setTranslationX(senderSelectView.getTranslationX());
messageEditText.setTranslationX(senderSelectView.getTranslationX());
if (botCommandsMenuButton.getTag() == null) {
animationParamsX.clear();
}
}
@Override
public void onAnimationEnd(Animator animation) {
if (!isVisible) {
senderSelectView.setVisibility(GONE);
for (ImageView emoji : emojiButton)
emoji.setTranslationX(0);
messageEditText.setTranslationX(0);
}
}
@Override
public void onAnimationCancel(Animator animation) {
if (isVisible) {
senderSelectView.setVisibility(VISIBLE);
} else {
senderSelectView.setVisibility(GONE);
}
senderSelectView.setAlpha(eA);
senderSelectView.setTranslationX(eX);
for (ImageView emoji : emojiButton)
emoji.setTranslationX(senderSelectView.getTranslationX());
messageEditText.setTranslationX(senderSelectView.getTranslationX());
requestLayout();
}
});
anim.start();
senderSelectView.setTag(anim);
} else {
senderSelectView.setVisibility(isVisible ? VISIBLE : GONE);
senderSelectView.setTranslationX(eX);
for (ImageView emoji : emojiButton)
emoji.setTranslationX(eX);
messageEditText.setTranslationX(eX);
senderSelectView.setAlpha(eA);
senderSelectView.setTag(null);
}
}
}
private void updateBotButton(boolean animated) {
if (botButton == null) {
return;
@ -7160,12 +7844,16 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
public void hidePopup(boolean byBackButton) {
hidePopup(byBackButton, false);
}
public void hidePopup(boolean byBackButton, boolean forceAnimate) {
if (isPopupShowing()) {
if (currentPopupContentType == 1 && byBackButton && botButtonsMessageObject != null) {
SharedPreferences preferences = MessagesController.getMainSettings(currentAccount);
preferences.edit().putInt("hidekeyboard_" + dialog_id, botButtonsMessageObject.getId()).commit();
}
if (byBackButton && searchingType != 0) {
if (byBackButton && searchingType != 0 || forceAnimate) {
setSearchingTypeInternal(0, true);
if (emojiView != null) {
emojiView.closeSearch(true);
@ -7804,6 +8492,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
if (keyboardVisible && isPopupShowing()) {
showPopup(0, currentPopupContentType);
}
if (onEmojiSearchClosed != null) {
onEmojiSearchClosed.run();
onEmojiSearchClosed = null;
}
NotificationCenter.getInstance(currentAccount).onAnimationFinish(notificationsIndex);
}
});
@ -8406,6 +9098,12 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
((MarginLayoutParams) emojiButton[i].getLayoutParams()).leftMargin = AndroidUtilities.dp(10) + botCommandsMenuButton.getMeasuredWidth();
}
((MarginLayoutParams) messageEditText.getLayoutParams()).leftMargin = AndroidUtilities.dp(57) + botCommandsMenuButton.getMeasuredWidth();
} else if (senderSelectView != null && senderSelectView.getVisibility() == View.VISIBLE) {
senderSelectView.measure(widthMeasureSpec, heightMeasureSpec);
for (int i = 0; i < emojiButton.length; i++) {
((MarginLayoutParams) emojiButton[i].getLayoutParams()).leftMargin = AndroidUtilities.dp(16) + senderSelectView.getLayoutParams().width;
}
((MarginLayoutParams) messageEditText.getLayoutParams()).leftMargin = AndroidUtilities.dp(63) + senderSelectView.getLayoutParams().width;
} else {
for (int i = 0; i < emojiButton.length; i++) {
((MarginLayoutParams) emojiButton[i].getLayoutParams()).leftMargin = AndroidUtilities.dp(3);

View file

@ -13,14 +13,20 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Application;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.Gravity;
@ -29,10 +35,12 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildConfig;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
@ -57,6 +65,7 @@ import org.telegram.ui.Cells.GraySectionCell;
import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.SharedDocumentCell;
import org.telegram.ui.Cells.TextCheckBoxCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.FilteredSearchView;
import org.telegram.ui.PhotoPickerActivity;
@ -327,10 +336,40 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
ListItem item = (ListItem) object;
File file = item.file;
boolean isExternalStorageManager = false;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
isExternalStorageManager = Environment.isExternalStorageManager();
}
if (file == null) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// isExternalStorageManager = Environment.isExternalStorageManager();
// }
if (!BuildVars.NO_SCOPED_STORAGE && (item.icon == R.drawable.files_storage || item.icon == R.drawable.files_internal)) {
//if (SharedConfig.dontAskManageStorage) {
delegate.startDocumentSelectActivity();
/*} else {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTopImage(R.drawable.doc_big, Theme.getColor(Theme.key_dialogTopBackground));
builder.setMessage(AndroidUtilities.replaceTags(LocaleController.getString("ManageAllFilesRational", R.string.ManageAllFilesRational)));
TextCheckBoxCell textCheckBoxCell = new TextCheckBoxCell(context, true, true);
textCheckBoxCell.setTextAndCheck(LocaleController.getString("DontAskAgain", R.string.DontAskAgain), false, false);
textCheckBoxCell.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
textCheckBoxCell.setChecked(!textCheckBoxCell.isChecked());
}
});
builder.setView(textCheckBoxCell);
builder.setPositiveButton(LocaleController.getString("Allow", R.string.Allow), (i1, i2) -> {
Uri uri = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
context.startActivity(new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri));
});
builder.setNegativeButton(LocaleController.getString("UseFileManger", R.string.UseFileManger), (i1, i2) -> {
if (textCheckBoxCell.isChecked()) {
SharedConfig.setDontAskManageStorage(true);
}
delegate.startDocumentSelectActivity();
});
builder.show();
}*/
} else if (file == null) {
if (item.icon == R.drawable.files_gallery) {
HashMap<Object, Object> selectedPhotos = new HashMap<>();
ArrayList<Object> selectedPhotosOrder = new ArrayList<>();
@ -373,8 +412,6 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
if (delegate != null) {
delegate.startMusicSelectActivity();
}
} else if (!BuildVars.NO_SCOPED_STORAGE && item.icon == R.drawable.files_storage && !isExternalStorageManager) {
delegate.startDocumentSelectActivity();
} else {
int top = getTopForScroll();
HistoryEntry he = history.remove(history.size() - 1);
@ -950,13 +987,13 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
isExternalStorageManager = Environment.isExternalStorageManager();
}
if (!BuildVars.NO_SCOPED_STORAGE && !isExternalStorageManager) {
ListItem ext = new ListItem();
ext.title = LocaleController.getString("InternalStorage", R.string.InternalStorage);
ext.icon = R.drawable.files_storage;
ext.subtitle = LocaleController.getString("InternalFolderInfo", R.string.InternalFolderInfo);
items.add(ext);
} else {
// if (!BuildVars.NO_SCOPED_STORAGE && !isExternalStorageManager) {
// ListItem ext = new ListItem();
// ext.title = LocaleController.getString("InternalStorage", R.string.InternalStorage);
// ext.icon = R.drawable.files_storage;
// ext.subtitle = LocaleController.getString("InternalFolderInfo", R.string.InternalFolderInfo);
// items.add(ext);
// } else {
String defaultPath = Environment.getExternalStorageDirectory().getPath();
String defaultPathState = Environment.getExternalStorageState();
if (defaultPathState.equals(Environment.MEDIA_MOUNTED) || defaultPathState.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
@ -1031,7 +1068,7 @@ public class ChatAttachAlertDocumentLayout extends ChatAttachAlert.AttachAlertLa
}
}
}
}
//}
ListItem fs;
try {

View file

@ -4,27 +4,17 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
@ -44,11 +34,8 @@ import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.NotificationCenter;
@ -63,6 +50,7 @@ import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.DrawerProfileCell;
import org.telegram.ui.Cells.ThemesHorizontalListCell;
import org.telegram.ui.ChatActivity;
@ -107,7 +95,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
this.themeDelegate = themeDelegate;
this.originalTheme = themeDelegate.getCurrentTheme();
this.originalIsDark = Theme.getActiveTheme().isDark();
adapter = new Adapter(currentAccount, themeDelegate, Adapter.TYPE_DEFAULT);
adapter = new Adapter(currentAccount, themeDelegate, ThemeSmallPreviewView.TYPE_DEFAULT);
setDimBehind(false);
setCanDismissWithSwipe(false);
setApplyBottomPadding(false);
@ -196,13 +184,13 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
}, 100);
for (int i = 0; i < recyclerView.getChildCount(); i++) {
Adapter.ChatThemeView child = (Adapter.ChatThemeView) recyclerView.getChildAt(i);
ThemeSmallPreviewView child = (ThemeSmallPreviewView) recyclerView.getChildAt(i);
if (child != view) {
child.cancelAnimation();
}
}
if (!adapter.items.get(position).chatTheme.showAsDefaultStub) {
((Adapter.ChatThemeView) view).playEmojiAnimation();
((ThemeSmallPreviewView) view).playEmojiAnimation();
}
});
@ -363,7 +351,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
themeDescriptions.add(new ThemeDescription(null, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, new Drawable[]{shadowDrawable}, descriptionDelegate, Theme.key_dialogBackground));
themeDescriptions.add(new ThemeDescription(titleView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_dialogTextBlack));
themeDescriptions.add(new ThemeDescription(recyclerView, ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{Adapter.ChatThemeView.class}, null, null, null, Theme.key_dialogBackgroundGray));
themeDescriptions.add(new ThemeDescription(recyclerView, ThemeDescription.FLAG_CELLBACKGROUNDCOLOR, new Class[]{ThemeSmallPreviewView.class}, null, null, null, Theme.key_dialogBackgroundGray));
themeDescriptions.add(new ThemeDescription(applyButton, ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_featuredStickers_addButton));
themeDescriptions.add(new ThemeDescription(applyButton, ThemeDescription.FLAG_BACKGROUNDFILTER | ThemeDescription.FLAG_DRAWABLESELECTEDSTATE, null, null, null, null, Theme.key_featuredStickers_addButtonPressed));
for (ThemeDescription description : themeDescriptions) {
@ -657,21 +645,19 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
@SuppressLint("NotifyDataSetChanged")
public static class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public final static int TYPE_DEFAULT = 0;
public final static int TYPE_GRID = 1;
private final Theme.ResourcesProvider resourcesProvider;
public List<ChatThemeItem> items;
private WeakReference<ChatThemeView> selectedViewRef;
private WeakReference<ThemeSmallPreviewView> selectedViewRef;
private int selectedItemPosition = -1;
private final int currentAccount;
private final int currentType;
private final int currentViewType;
private HashMap<String, Theme.ThemeInfo> loadingThemes = new HashMap<>();
private HashMap<Theme.ThemeInfo, String> loadingWallpapers = new HashMap<>();
public Adapter(int currentAccount, Theme.ResourcesProvider resourcesProvider, int type) {
this.currentType = type;
this.currentViewType = type;
this.resourcesProvider = resourcesProvider;
this.currentAccount = currentAccount;
}
@ -679,12 +665,12 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new RecyclerListView.Holder(new ChatThemeView(parent.getContext(), currentAccount, resourcesProvider, currentType));
return new RecyclerListView.Holder(new ThemeSmallPreviewView(parent.getContext(), currentAccount, resourcesProvider, currentViewType));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ChatThemeView view = (ChatThemeView) holder.itemView;
ThemeSmallPreviewView view = (ThemeSmallPreviewView) holder.itemView;
Theme.ThemeInfo themeInfo = items.get(position).chatTheme.getThemeInfo(items.get(position).themeIndex);
if (themeInfo != null && themeInfo.pathToFile != null && !themeInfo.previewParsed) {
File file = new File(themeInfo.pathToFile);
@ -693,9 +679,14 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
parseTheme(themeInfo);
}
}
boolean animated = true;
ChatThemeItem newItem = items.get(position);
if (view.chatThemeItem == null || !view.chatThemeItem.chatTheme.getEmoticon().equals(newItem.chatTheme.getEmoticon()) || DrawerProfileCell.switchingTheme || view.lastThemeIndex != newItem.themeIndex) {
animated = false;
}
view.setItem(items.get(position));
view.setSelected(position == selectedItemPosition);
view.setItem(newItem, animated);
view.setSelected(position == selectedItemPosition, animated);
if (position == selectedItemPosition) {
selectedViewRef = new WeakReference<>(view);
}
@ -874,7 +865,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
if (selectedItemPosition >= 0) {
notifyItemChanged(selectedItemPosition);
ChatThemeView view = selectedViewRef == null ? null : selectedViewRef.get();
ThemeSmallPreviewView view = selectedViewRef == null ? null : selectedViewRef.get();
if (view != null) {
view.setSelected(false);
}
@ -883,437 +874,6 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
notifyItemChanged(selectedItemPosition);
}
public static class ChatThemeView extends FrameLayout implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener {
private final float STROKE_RADIUS = AndroidUtilities.dp(8);
private final float INNER_RADIUS = AndroidUtilities.dp(6);
private final float INNER_RECT_SPACE = AndroidUtilities.dp(4);
private final float BUBBLE_HEIGHT = AndroidUtilities.dp(21);
private final float BUBBLE_WIDTH = AndroidUtilities.dp(41);
private final Paint backgroundFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint outBubblePaintFirst = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint outBubblePaintSecond = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint inBubblePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RectF rectF = new RectF();
private final Path clipPath = new Path();
private final Theme.ResourcesProvider resourcesProvider;
private ValueAnimator strokeAlphaAnimator;
private TextPaint noThemeTextPaint;
private StaticLayout textLayout;
private ChatThemeItem chatThemeItem;
private BackupImageView backupImageView;
private boolean hasAnimatedEmoji;
private final int currentAccount;
Runnable animationCancelRunnable;
private int currentType;
int patternColor;
public ChatThemeView(Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider, int currentType) {
super(context);
this.currentType = currentType;
this.currentAccount = currentAccount;
this.resourcesProvider = resourcesProvider;
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(AndroidUtilities.dp(2));
setBackgroundColor(getThemedColor(Theme.key_dialogBackgroundGray));
backupImageView = new BackupImageView(context);
backupImageView.getImageReceiver().setCrossfadeWithOldImage(true);
backupImageView.getImageReceiver().setAllowStartLottieAnimation(false);
backupImageView.getImageReceiver().setAutoRepeat(0);
if (currentType == TYPE_DEFAULT) {
addView(backupImageView, LayoutHelper.createFrame(28, 28, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 12));
} else {
addView(backupImageView, LayoutHelper.createFrame(36, 36, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 12));
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (currentType == TYPE_GRID) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int) (width * 1.2f);
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
} else {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = AndroidUtilities.dp(77);
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
backupImageView.setPivotY(backupImageView.getMeasuredHeight());
backupImageView.setPivotX(backupImageView.getMeasuredWidth() / 2f);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (w == oldw && h == oldh) {
return;
}
rectF.set(INNER_RECT_SPACE, INNER_RECT_SPACE, w - INNER_RECT_SPACE, h - INNER_RECT_SPACE);
clipPath.reset();
clipPath.addRoundRect(rectF, INNER_RADIUS, INNER_RADIUS, Path.Direction.CW);
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (chatThemeItem == null) {
super.dispatchDraw(canvas);
return;
}
if (chatThemeItem.isSelected || strokeAlphaAnimator != null) {
float rectSpace = strokePaint.getStrokeWidth() * 0.5f;
rectF.set(rectSpace, rectSpace, getWidth() - rectSpace, getHeight() - rectSpace);
canvas.drawRoundRect(rectF, STROKE_RADIUS, STROKE_RADIUS, strokePaint);
}
rectF.set(INNER_RECT_SPACE, INNER_RECT_SPACE, getWidth() - INNER_RECT_SPACE, getHeight() - INNER_RECT_SPACE);
if (chatThemeItem.chatTheme == null || chatThemeItem.chatTheme.showAsDefaultStub) {
canvas.drawRoundRect(rectF, INNER_RADIUS, INNER_RADIUS, backgroundFillPaint);
canvas.save();
StaticLayout textLayout = getNoThemeStaticLayout();
canvas.translate((getWidth() - textLayout.getWidth()) * 0.5f, AndroidUtilities.dp(18));
textLayout.draw(canvas);
canvas.restore();
} else {
if (chatThemeItem.previewDrawable != null) {
canvas.save();
canvas.clipPath(clipPath);
if (chatThemeItem.previewDrawable instanceof BitmapDrawable) {
int drawableW = chatThemeItem.previewDrawable.getIntrinsicWidth();
int drawableH = chatThemeItem.previewDrawable.getIntrinsicHeight();
if (drawableW / (float) drawableH > getWidth() / (float) getHeight()) {
int w = (int) (getWidth() * (float) drawableH / drawableW);
int padding = (w - getWidth()) / 2;
chatThemeItem.previewDrawable.setBounds(padding, 0, padding + w , getHeight());
} else {
int h = (int) (getHeight() * (float) drawableH / drawableW);
int padding = (getHeight() - h) / 2;
chatThemeItem.previewDrawable.setBounds(0, padding, getWidth(), padding + h);
}
} else {
chatThemeItem.previewDrawable.setBounds(0, 0, getWidth(), getHeight());
}
chatThemeItem.previewDrawable.draw(canvas);
canvas.restore();
} else {
canvas.drawRoundRect(rectF, INNER_RADIUS, INNER_RADIUS, backgroundFillPaint);
}
float bubbleTop = INNER_RECT_SPACE + AndroidUtilities.dp(8);
float bubbleLeft = INNER_RECT_SPACE + AndroidUtilities.dp(22);
if (currentType == TYPE_DEFAULT) {
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
} else {
bubbleTop = getMeasuredHeight() * 0.12f;
bubbleLeft = getMeasuredWidth() - getMeasuredWidth() * 0.6f;
float bubbleRight = getMeasuredWidth() - getMeasuredWidth() * 0.1f;
float bubbleBottom = getMeasuredHeight() * 0.32f;
rectF.set(bubbleLeft, bubbleTop, bubbleRight, bubbleBottom);
}
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, outBubblePaintFirst);
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, outBubblePaintSecond);
if (currentType == TYPE_DEFAULT) {
bubbleLeft = INNER_RECT_SPACE + AndroidUtilities.dp(5);
bubbleTop += BUBBLE_HEIGHT + AndroidUtilities.dp(4);
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
} else {
bubbleTop = getMeasuredHeight() * 0.35f;
bubbleLeft = getMeasuredWidth() * 0.1f;
float bubbleRight = getMeasuredWidth() * 0.6f;
float bubbleBottom = getMeasuredHeight() * 0.55f;
rectF.set(bubbleLeft, bubbleTop, bubbleRight, bubbleBottom);
}
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, inBubblePaint);
}
super.dispatchDraw(canvas);
}
int lastThemeIndex;
public void setItem(ChatThemeItem item) {
boolean itemChanged = chatThemeItem != item;
boolean darkModeChanged = lastThemeIndex != item.themeIndex;
lastThemeIndex = item.themeIndex;
this.chatThemeItem = item;
hasAnimatedEmoji = false;
TLRPC.Document document = null;
if (item.chatTheme.getEmoticon() != null) {
document = MediaDataController.getInstance(currentAccount).getEmojiAnimatedSticker(item.chatTheme.getEmoticon());
}
if (itemChanged) {
if (animationCancelRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(animationCancelRunnable);
animationCancelRunnable = null;
}
backupImageView.animate().cancel();
backupImageView.setScaleX(1f);
backupImageView.setScaleY(1f);
}
if (itemChanged) {
Drawable thumb = null;
if (document != null) {
thumb = DocumentObject.getSvgThumb(document, Theme.key_emptyListPlaceholder, 0.2f);
}
if (thumb == null) {
thumb = Emoji.getEmojiDrawable(item.chatTheme.getEmoticon());
}
backupImageView.setImage(ImageLocation.getForDocument(document), "50_50", thumb, null);
}
if (itemChanged || darkModeChanged) {
updatePreviewBackground();
TLRPC.TL_theme theme = item.chatTheme.getTlTheme(lastThemeIndex);
if (theme != null) {
final long themeId = theme.id;
TLRPC.WallPaper wallPaper = item.chatTheme.getWallpaper(lastThemeIndex);
if (wallPaper != null) {
final int intensity = wallPaper.settings.intensity;
int index = item.chatTheme.getSettingsIndex(lastThemeIndex);
item.chatTheme.loadWallpaperThumb(lastThemeIndex, result -> {
if (result != null && result.first == themeId) {
if (item.previewDrawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) item.previewDrawable;
motionBackgroundDrawable.setPatternBitmap(intensity >= 0 ? 100 : -100, result.second);
motionBackgroundDrawable.setPatternColorFilter(patternColor);
}
invalidate();
}
});
}
}
}
}
@Override
public void setSelected(boolean selected) {
super.setSelected(selected);
if (chatThemeItem.isSelected != selected) {
if (strokeAlphaAnimator != null) {
strokeAlphaAnimator.cancel();
}
if (selected) {
strokePaint.setAlpha(0);
}
strokeAlphaAnimator = ValueAnimator.ofInt(selected ? 0 : 255, selected ? 255 : 0);
strokeAlphaAnimator.addUpdateListener(this);
strokeAlphaAnimator.addListener(this);
strokeAlphaAnimator.setDuration(350);
strokeAlphaAnimator.start();
}
chatThemeItem.isSelected = selected;
}
@Override
public void setBackgroundColor(int color) {
backgroundFillPaint.setColor(getThemedColor(Theme.key_dialogBackgroundGray));
if (noThemeTextPaint != null) {
noThemeTextPaint.setColor(getThemedColor(Theme.key_chat_emojiPanelTrendingDescription));
}
invalidate();
}
private void fillOutBubblePaint(Paint paint, List<Integer> messageColors) {
if (messageColors.size() > 1) {
int[] colors = new int[messageColors.size()];
for (int i = 0; i != messageColors.size(); ++i) {
colors[i] = messageColors.get(i);
}
float top = INNER_RECT_SPACE + AndroidUtilities.dp(8);
paint.setShader(new LinearGradient(0f, top, 0f, top + BUBBLE_HEIGHT, colors, null, Shader.TileMode.CLAMP));
} else {
paint.setShader(null);
}
}
public void updatePreviewBackground() {
if (chatThemeItem == null || chatThemeItem.chatTheme == null) {
return;
}
EmojiThemes.ThemeItem themeItem = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
int color = themeItem.inBubbleColor;
inBubblePaint.setColor(color);
color = themeItem.outBubbleColor;
outBubblePaintSecond.setColor(color);
int strokeColor = chatThemeItem.chatTheme.showAsDefaultStub
? getThemedColor(Theme.key_featuredStickers_addButton)
: themeItem.outLineColor;
int strokeAlpha = strokePaint.getAlpha();
strokePaint.setColor(strokeColor);
strokePaint.setAlpha(strokeAlpha);
TLRPC.TL_theme tlTheme = chatThemeItem.chatTheme.getTlTheme(chatThemeItem.themeIndex);
if (tlTheme != null) {
int index = chatThemeItem.chatTheme.getSettingsIndex(chatThemeItem.themeIndex);
TLRPC.ThemeSettings themeSettings = tlTheme.settings.get(index);
fillOutBubblePaint(outBubblePaintSecond, themeSettings.message_colors);
outBubblePaintSecond.setAlpha(255);
getPreviewDrawable(tlTheme, index);
} else {
EmojiThemes.ThemeItem item = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
getPreviewDrawable(item);
}
invalidate();
}
private Drawable getPreviewDrawable(TLRPC.TL_theme theme, int settingsIndex) {
if (chatThemeItem == null) {
return null;
}
int color1 = 0;
int color2 = 0;
int color3 = 0;
int color4 = 0;
Drawable drawable;
if (settingsIndex >= 0) {
TLRPC.ThemeSettings themeSettings = theme.settings.get(settingsIndex);
TLRPC.WallPaperSettings wallPaperSettings = themeSettings.wallpaper.settings;
color1 = wallPaperSettings.background_color;
color2 = wallPaperSettings.second_background_color;
color3 = wallPaperSettings.third_background_color;
color4 = wallPaperSettings.fourth_background_color;
}
if (color2 != 0) {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(color1, color2, color3, color4, true);
patternColor = motionBackgroundDrawable.getPatternColor();
drawable = motionBackgroundDrawable;
} else {
drawable = new MotionBackgroundDrawable(color1, color1, color1, color1, true);
patternColor = Color.BLACK;
}
chatThemeItem.previewDrawable = drawable;
return drawable;
}
private Drawable getPreviewDrawable(EmojiThemes.ThemeItem item) {
if (chatThemeItem == null) {
return null;
}
Drawable drawable = null;
int color1 = item.patternBgColor;
int color2 = item.patternBgGradientColor1;
int color3 = item.patternBgGradientColor2;
int color4 = item.patternBgGradientColor3;
if (item.themeInfo.getAccent(false) != null) {
if (color2 != 0) {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(color1, color2, color3, color4, true);
patternColor = motionBackgroundDrawable.getPatternColor();
drawable = motionBackgroundDrawable;
} else {
drawable = new MotionBackgroundDrawable(color1, color1, color1, color1, true);
patternColor = Color.BLACK;
}
} else {
if (color1 != 0 && color2 != 0) {
drawable = new MotionBackgroundDrawable(color1, color2, color3, color4, true);
} else if (color1 != 0) {
drawable = new ColorDrawable(color1);
} else if (item.themeInfo != null && (item.themeInfo.previewWallpaperOffset > 0 || item.themeInfo.pathToWallpaper != null)) {
Bitmap wallpaper = getScaledBitmap(AndroidUtilities.dp(76), AndroidUtilities.dp(97), item.themeInfo.pathToWallpaper, item.themeInfo.pathToFile, item.themeInfo.previewWallpaperOffset);
if (wallpaper != null) {
drawable = new BitmapDrawable(wallpaper);
}
} else {
drawable = new MotionBackgroundDrawable(0xffdbddbb, 0xff6ba587, 0xffd5d88d, 0xff88b884, true);
}
}
chatThemeItem.previewDrawable = drawable;
return drawable;
}
private StaticLayout getNoThemeStaticLayout() {
if (textLayout != null) {
return textLayout;
}
noThemeTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG + TextPaint.SUBPIXEL_TEXT_FLAG);
noThemeTextPaint.setColor(getThemedColor(Theme.key_chat_emojiPanelTrendingDescription));
noThemeTextPaint.setTextSize(AndroidUtilities.dp(14));
noThemeTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textLayout = StaticLayoutEx.createStaticLayout2(
LocaleController.getString("ChatNoTheme", R.string.ChatNoTheme),
noThemeTextPaint,
AndroidUtilities.dp(52),
Layout.Alignment.ALIGN_CENTER,
1f, 0f, true,
TextUtils.TruncateAt.END, AndroidUtilities.dp(52), 3
);
return textLayout;
}
private int getThemedColor(String key) {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
EmojiThemes.ThemeItem themeItem = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
int strokeColor = chatThemeItem.chatTheme.showAsDefaultStub
? getThemedColor(Theme.key_featuredStickers_addButton)
: themeItem.outLineColor;
strokePaint.setColor(strokeColor);
strokePaint.setAlpha((int) valueAnimator.getAnimatedValue());
invalidate();
}
@Override
public void onAnimationEnd(Animator animator) {
strokeAlphaAnimator = null;
invalidate();
}
@Override
public void onAnimationCancel(Animator animator) {
strokeAlphaAnimator = null;
invalidate();
}
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
public void playEmojiAnimation() {
if (backupImageView.getImageReceiver().getLottieAnimation() != null) {
AndroidUtilities.cancelRunOnUIThread(animationCancelRunnable);
backupImageView.setVisibility(View.VISIBLE);
backupImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false);
backupImageView.getImageReceiver().getLottieAnimation().start();
backupImageView.animate().scaleX(2f).scaleY(2f).setDuration(300).setInterpolator(AndroidUtilities.overshootInterpolator).start();
AndroidUtilities.runOnUIThread(animationCancelRunnable = () -> {
animationCancelRunnable = null;
backupImageView.animate().scaleX(1f).scaleY(1f).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}, 2500);
}
}
public void cancelAnimation() {
if (animationCancelRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(animationCancelRunnable);
animationCancelRunnable.run();
}
}
}
}
public static class ChatThemeItem {
@ -1334,54 +894,4 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
super.show();
resetTextView.setText(themeDelegate.getCurrentTheme() == null ? LocaleController.getString("DoNoSetTheme", R.string.DoNoSetTheme) : LocaleController.getString("ChatResetTheme", R.string.ChatResetTheme));
}
public static Bitmap getScaledBitmap(float w, float h, String path, String streamPath, int streamOffset) {
FileInputStream stream = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
if (path != null) {
BitmapFactory.decodeFile(path, options);
} else {
stream = new FileInputStream(streamPath);
stream.getChannel().position(streamOffset);
BitmapFactory.decodeStream(stream, null, options);
}
if (options.outWidth > 0 && options.outHeight > 0) {
if (w > h && options.outWidth < options.outHeight) {
float temp = w;
w = h;
h = temp;
}
float scale = Math.min(options.outWidth / w, options.outHeight / h);
options.inSampleSize = 1;
if (scale > 1.0f) {
do {
options.inSampleSize *= 2;
} while (options.inSampleSize < scale);
}
options.inJustDecodeBounds = false;
Bitmap wallpaper;
if (path != null) {
wallpaper = BitmapFactory.decodeFile(path, options);
} else {
stream.getChannel().position(streamOffset);
wallpaper = BitmapFactory.decodeStream(stream, null, options);
}
return wallpaper;
}
} catch (Throwable e) {
FileLog.e(e);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (Exception e2) {
FileLog.e(e2);
}
}
return null;
}
}

View file

@ -119,7 +119,7 @@ public class EditTextBoldCursor extends EditText {
private ViewTreeObserver.OnPreDrawListener listenerFixer;
private FloatingToolbar floatingToolbar;
private FloatingActionMode floatingActionMode;
public FloatingActionMode floatingActionMode;
private ViewTreeObserver.OnPreDrawListener floatingToolbarPreDrawListener;
private View windowView;
private View attachedToWindow;

View file

@ -531,7 +531,9 @@ public class FlickerLoadingView extends View {
}
matrix.setTranslate(parentXOffset, totalTranslation);
}
gradient.setLocalMatrix(matrix);
if (gradient != null) {
gradient.setLocalMatrix(matrix);
}
}
public void updateColors() {

View file

@ -30,6 +30,7 @@ import org.telegram.ui.Cells.ChatMessageCell;
public class HintView extends FrameLayout {
public static final int TYPE_SEARCH_AS_LIST = 3;
public static final int TYPE_COMMON = 4;
public static final int TYPE_POLL_VOTE = 5;
private TextView textView;

View file

@ -2609,7 +2609,9 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (zoom > 0f) {
finishZoomTransition = ValueAnimator.ofFloat(zoom, 0);
finishZoomTransition.addUpdateListener(valueAnimator -> {
cameraSession.setZoom((float) valueAnimator.getAnimatedValue());
if (cameraSession != null) {
cameraSession.setZoom((float) valueAnimator.getAnimatedValue());
}
});
finishZoomTransition.addListener(new AnimatorListenerAdapter() {
@Override

View file

@ -11,13 +11,14 @@ package org.telegram.ui.Components;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import org.telegram.messenger.AndroidUtilities;
public class LinkPath extends Path {
private StaticLayout currentLayout;
private Layout currentLayout;
private int currentLine;
private float lastTop = -1;
private float heightOffset;
@ -36,7 +37,7 @@ public class LinkPath extends Path {
useRoundRect = roundRect;
}
public void setCurrentLayout(StaticLayout layout, int start, float yOffset) {
public void setCurrentLayout(Layout layout, int start, float yOffset) {
currentLayout = layout;
currentLine = layout.getLineForOffset(start);
lastTop = -1;

View file

@ -213,7 +213,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
}
};
sharedMediaLayout.setPinnedToTop(true);
sharedMediaLayout.getSearchItem().setTranslationY(0);
sharedMediaLayout.photoVideoOptionsItem.setTranslationY(0);

View file

@ -18,6 +18,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.os.SystemClock;
import android.view.View;
@ -83,6 +84,7 @@ public class MotionBackgroundDrawable extends Drawable {
private Bitmap legacyBitmap;
private Canvas legacyCanvas2;
private Bitmap legacyBitmap2;
private GradientDrawable gradientDrawable = new GradientDrawable();
private boolean invalidateLegacy;
private boolean rotationBack;
@ -107,12 +109,13 @@ public class MotionBackgroundDrawable extends Drawable {
}
public MotionBackgroundDrawable(int c1, int c2, int c3, int c4, boolean preview) {
this(c1, c2, c3 ,c4, 0, preview);
}
public MotionBackgroundDrawable(int c1, int c2, int c3, int c4, int rotation, boolean preview) {
super();
colors[0] = c1;
colors[1] = c2;
colors[2] = c3;
colors[3] = c4;
isPreview = preview;
setColors(c1, c2, c3, c4, rotation, false);
init();
}
@ -298,7 +301,7 @@ public class MotionBackgroundDrawable extends Drawable {
}
public void setColors(int c1, int c2, int c3, int c4) {
setColors(c1, c2, c3, c4, true);
setColors(c1, c2, c3, c4, 0, true);
}
public void setColors(int c1, int c2, int c3, int c4, Bitmap bitmap) {
@ -309,14 +312,21 @@ public class MotionBackgroundDrawable extends Drawable {
Utilities.generateGradient(bitmap, true, phase, interpolator.getInterpolation(posAnimationProgress), currentBitmap.getWidth(), currentBitmap.getHeight(), currentBitmap.getRowBytes(), colors);
}
public void setColors(int c1, int c2, int c3, int c4, boolean invalidate) {
public void setColors(int c1, int c2, int c3, int c4, int rotation, boolean invalidate) {
if (isPreview && c3 == 0 && c4 == 0) {
gradientDrawable = new GradientDrawable(BackgroundGradientDrawable.getGradientOrientation(rotation), new int[]{c1, c2});
} else {
gradientDrawable = null;
}
colors[0] = c1;
colors[1] = c2;
colors[2] = c3;
colors[3] = c4;
Utilities.generateGradient(currentBitmap, true, phase, interpolator.getInterpolation(posAnimationProgress), currentBitmap.getWidth(), currentBitmap.getHeight(), currentBitmap.getRowBytes(), colors);
if (invalidate) {
invalidateParent();
if (currentBitmap != null) {
Utilities.generateGradient(currentBitmap, true, phase, interpolator.getInterpolation(posAnimationProgress), currentBitmap.getWidth(), currentBitmap.getHeight(), currentBitmap.getRowBytes(), colors);
if (invalidate) {
invalidateParent();
}
}
}
@ -573,8 +583,13 @@ public class MotionBackgroundDrawable extends Drawable {
canvas.drawRoundRect(rect, roundRadius, roundRadius, paint);
} else {
canvas.translate(0, tr);
rect.set(x, y, x + width, y + height);
canvas.drawBitmap(currentBitmap, null, rect, paint);
if (gradientDrawable != null) {
gradientDrawable.setBounds((int) x, (int) y, (int) (x + width), (int) (y + height));
gradientDrawable.draw(canvas);
} else {
rect.set(x, y, x + width, y + height);
canvas.drawBitmap(currentBitmap, null, rect, paint);
}
}
if (patternBitmap != null) {
@ -723,4 +738,8 @@ public class MotionBackgroundDrawable extends Drawable {
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
public boolean isOneColor() {
return colors[0] == colors[1] && colors[0] == colors[2] && colors[0] == colors[3];
}
}

View file

@ -40,16 +40,25 @@ public class NumberTextView extends View {
private float textWidth;
private float oldTextWidth;
private OnTextWidthProgressChangedListener onTextWidthProgressChangedListener;
public NumberTextView(Context context) {
super(context);
}
public void setOnTextWidthProgressChangedListener(OnTextWidthProgressChangedListener onTextWidthProgressChangedListener) {
this.onTextWidthProgressChangedListener = onTextWidthProgressChangedListener;
}
@Keep
public void setProgress(float value) {
if (progress == value) {
return;
}
progress = value;
if (onTextWidthProgressChangedListener != null) {
onTextWidthProgressChangedListener.onTextWidthProgress(oldTextWidth, textWidth, progress);
}
invalidate();
}
@ -86,9 +95,9 @@ public class NumberTextView extends View {
forwardAnimation = number > currentNumber;
}
boolean replace = false;
textWidth = textPaint.measureText(text);
oldTextWidth = textPaint.measureText(oldText);
if (center) {
textWidth = textPaint.measureText(text);
oldTextWidth = textPaint.measureText(oldText);
if (textWidth != oldTextWidth) {
replace = true;
}
@ -121,6 +130,8 @@ public class NumberTextView extends View {
}
});
animator.start();
} else if (onTextWidthProgressChangedListener != null) {
onTextWidthProgressChangedListener.onTextWidthProgress(oldTextWidth, textWidth, progress);
}
invalidate();
}
@ -213,4 +224,22 @@ public class NumberTextView extends View {
}
canvas.restore();
}
public float getOldTextWidth() {
return oldTextWidth;
}
public float getTextWidth() {
return textWidth;
}
public interface OnTextWidthProgressChangedListener {
/**
* Notifies layout that text width has changed
* @param fromWidth Old text width value
* @param toWidth New text width value
* @param progress Progress for the animation
*/
void onTextWidthProgress(float fromWidth, float toWidth, float progress);
}
}

View file

@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit;
public class RLottieDrawable extends BitmapDrawable implements Animatable {
public static native long create(String src, String json, int w, int h, int[] params, boolean precache, int[] colorReplacement, boolean limitFps);
public static native long create(String src, String json, int w, int h, int[] params, boolean precache, int[] colorReplacement, boolean limitFps, int fitzModifier);
protected static native long createWithJson(String json, String name, int[] params, int[] colorReplacement);
public static native void destroy(long ptr);
private static native void setLayerColor(long ptr, String layer, int color);
@ -355,16 +355,16 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable {
};
public RLottieDrawable(File file, int w, int h, boolean precache, boolean limitFps) {
this(file, w, h, precache, limitFps, null);
this(file, w, h, precache, limitFps, null, 0);
}
public RLottieDrawable(File file, int w, int h, boolean precache, boolean limitFps, int[] colorReplacement) {
public RLottieDrawable(File file, int w, int h, boolean precache, boolean limitFps, int[] colorReplacement, int fitzModifier) {
width = w;
height = h;
shouldLimitFps = limitFps;
getPaint().setFlags(Paint.FILTER_BITMAP_FLAG);
nativePtr = create(file.getAbsolutePath(), null, w, h, metaData, precache, colorReplacement, shouldLimitFps);
nativePtr = create(file.getAbsolutePath(), null, w, h, metaData, precache, colorReplacement, shouldLimitFps, fitzModifier);
if (precache && lottieCacheGenerateQueue == null) {
lottieCacheGenerateQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
}
@ -377,13 +377,13 @@ public class RLottieDrawable extends BitmapDrawable implements Animatable {
timeBetweenFrames = Math.max(shouldLimitFps ? 33 : 16, (int) (1000.0f / metaData[1]));
}
public RLottieDrawable(File file, String json, int w, int h, boolean precache, boolean limitFps, int[] colorReplacement) {
public RLottieDrawable(File file, String json, int w, int h, boolean precache, boolean limitFps, int[] colorReplacement, int fitzModifier) {
width = w;
height = h;
shouldLimitFps = limitFps;
getPaint().setFlags(Paint.FILTER_BITMAP_FLAG);
nativePtr = create(file.getAbsolutePath(), json, w, h, metaData, precache, colorReplacement, shouldLimitFps);
nativePtr = create(file.getAbsolutePath(), json, w, h, metaData, precache, colorReplacement, shouldLimitFps, fitzModifier);
if (precache && lottieCacheGenerateQueue == null) {
lottieCacheGenerateQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
}

View file

@ -21,6 +21,7 @@ public class RecyclerItemsEnterAnimator {
HashSet<View> ignoreView = new HashSet<>();
boolean invalidateAlpha;
boolean alwaysCheckItemsAlpha;
public boolean animateAlphaProgressView = true;
ArrayList<AnimatorSet> currentAnimations = new ArrayList<>();
ArrayList<ViewTreeObserver.OnPreDrawListener> preDrawListeners = new ArrayList<>();
@ -28,6 +29,7 @@ public class RecyclerItemsEnterAnimator {
public RecyclerItemsEnterAnimator(RecyclerListView listView, boolean alwaysCheckItemsAlpha) {
this.listView = listView;
this.alwaysCheckItemsAlpha = alwaysCheckItemsAlpha;
listView.setItemsEnterAnimator(this);
}
public void dispatchDraw() {
@ -49,22 +51,19 @@ public class RecyclerItemsEnterAnimator {
}
public void showItemsAnimated(int from) {
int n = listView.getChildCount();
View progressView = null;
for (int i = 0; i < n; i++) {
View child = listView.getChildAt(i);
if (listView.getChildAdapterPosition(child) >= 0 && child instanceof FlickerLoadingView) {
progressView = child;
}
}
final View finalProgressView = progressView;
final View finalProgressView = getProgressView();
RecyclerView.LayoutManager layoutManager = listView.getLayoutManager();
if (progressView != null && layoutManager != null) {
listView.removeView(progressView);
if (finalProgressView != null && layoutManager != null) {
listView.removeView(finalProgressView);
ignoreView.add(finalProgressView);
listView.addView(finalProgressView);
layoutManager.ignoreView(finalProgressView);
Animator animator = ObjectAnimator.ofFloat(finalProgressView, View.ALPHA, finalProgressView.getAlpha(), 0);
Animator animator;
if (animateAlphaProgressView) {
animator = ObjectAnimator.ofFloat(finalProgressView, View.ALPHA, finalProgressView.getAlpha(), 0f);
} else {
animator = ValueAnimator.ofFloat(0f, 1f);
}
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@ -135,6 +134,18 @@ public class RecyclerItemsEnterAnimator {
listView.getViewTreeObserver().addOnPreDrawListener(preDrawListener);
}
public View getProgressView() {
View progressView = null;
int n = listView.getChildCount();
for (int i = 0; i < n; i++) {
View child = listView.getChildAt(i);
if (listView.getChildAdapterPosition(child) >= 0 && child instanceof FlickerLoadingView) {
progressView = child;
}
}
return progressView;
}
public void onDetached() {
cancel();
}

View file

@ -144,6 +144,7 @@ public class RecyclerListView extends RecyclerView {
float lastY = Float.MAX_VALUE;
int[] listPaddings;
HashSet<Integer> selectedPositions;
RecyclerItemsEnterAnimator itemsEnterAnimator;
protected final Theme.ResourcesProvider resourcesProvider;
@ -367,6 +368,7 @@ public class RecyclerListView extends RecyclerView {
private TextPaint letterPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private String currentLetter;
private Path path = new Path();
private Path arrowPath = new Path();
private float[] radii = new float[8];
private float textX;
private float textY;
@ -381,7 +383,7 @@ public class RecyclerListView extends RecyclerView {
private int[] positionWithOffset = new int[2];
boolean isVisible;
float touchSlop;
Drawable fastScrollShadowDrawable;
Drawable fastScrollBackgroundDrawable;
Runnable hideFloatingDateRunnable = new Runnable() {
@ -407,7 +409,7 @@ public class RecyclerListView extends RecyclerView {
letterPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
paint2.setColor(Theme.getColor(Theme.key_windowBackgroundWhite));
fastScrollBackgroundDrawable = ContextCompat.getDrawable(context, R.drawable.calendar_date).mutate();
fastScrollBackgroundDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhite), PorterDuff.Mode.MULTIPLY));
fastScrollBackgroundDrawable.setColorFilter(new PorterDuffColorFilter(ColorUtils.blendARGB(Theme.getColor(Theme.key_windowBackgroundWhite), Color.WHITE, 0.1f), PorterDuff.Mode.MULTIPLY));
}
for (int a = 0; a < 8; a++) {
radii[a] = AndroidUtilities.dp(44);
@ -418,6 +420,7 @@ public class RecyclerListView extends RecyclerView {
setFocusableInTouchMode(true);
ViewConfiguration vc = ViewConfiguration.get(context);
touchSlop = vc.getScaledTouchSlop();
fastScrollShadowDrawable = ContextCompat.getDrawable(context, R.drawable.fast_scroll_shadow);
}
private void updateColors() {
@ -436,6 +439,8 @@ public class RecyclerListView extends RecyclerView {
float startY;
boolean isMoving;
long startTime;
float visibilityAlpha;
float viewAlpha;
@Override
public boolean onTouchEvent(MotionEvent event) {
@ -451,6 +456,11 @@ public class RecyclerListView extends RecyclerView {
if (LocaleController.isRTL && x > AndroidUtilities.dp(25) || !LocaleController.isRTL && x < AndroidUtilities.dp(107) || lastY < currentY || lastY > currentY + AndroidUtilities.dp(30)) {
return false;
}
if (type == DATE_TYPE && !floatingDateVisible) {
if (LocaleController.isRTL && x > AndroidUtilities.dp(25) || !LocaleController.isRTL && x < (getMeasuredWidth() - AndroidUtilities.dp(25)) || lastY < currentY || lastY > currentY + AndroidUtilities.dp(30)) {
return false;
}
}
startDy = lastY - currentY;
startTime = System.currentTimeMillis();
pressed = true;
@ -558,14 +568,42 @@ public class RecyclerListView extends RecyclerView {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(AndroidUtilities.dp(type == LETTER_TYPE ? 132 : 240), MeasureSpec.getSize(heightMeasureSpec));
arrowPath.reset();
arrowPath.setLastPoint(0, 0);
arrowPath.lineTo(AndroidUtilities.dp(4), -AndroidUtilities.dp(4));
arrowPath.lineTo(-AndroidUtilities.dp(4), -AndroidUtilities.dp(4));
arrowPath.close();
}
@Override
protected void onDraw(Canvas canvas) {
paint.setColor(ColorUtils.blendARGB(inactiveColor, activeColor, bubbleProgress));
int y = (int) Math.ceil((getMeasuredHeight() - AndroidUtilities.dp(24 + 30)) * progress);
rect.set(scrollX, AndroidUtilities.dp(12) + y, scrollX + AndroidUtilities.dp(5), AndroidUtilities.dp(12 + 30) + y);
canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), paint);
if (type == LETTER_TYPE) {
paint.setColor(ColorUtils.blendARGB(inactiveColor, activeColor, bubbleProgress));
canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), paint);
} else {
paint.setColor(ColorUtils.blendARGB(Theme.getColor(Theme.key_windowBackgroundWhite), Color.WHITE, 0.1f));
float cy = y + AndroidUtilities.dp(12 + 15);
fastScrollShadowDrawable.setBounds(getMeasuredWidth() - fastScrollShadowDrawable.getIntrinsicWidth(), (int) (cy - fastScrollShadowDrawable.getIntrinsicHeight() / 2), getMeasuredWidth(), (int) (cy + fastScrollShadowDrawable.getIntrinsicHeight() / 2));
fastScrollShadowDrawable.draw(canvas);
canvas.drawCircle(scrollX + AndroidUtilities.dp(8), y + AndroidUtilities.dp(12 + 15), AndroidUtilities.dp(24), paint);
paint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
canvas.save();
canvas.translate(scrollX + AndroidUtilities.dp(4), y + AndroidUtilities.dp(12 + 15 + 2 + 5) + AndroidUtilities.dp(2) * bubbleProgress);
canvas.drawPath(arrowPath, paint);
canvas.restore();
canvas.save();
canvas.translate(scrollX + AndroidUtilities.dp(4), y + AndroidUtilities.dp(12 + 15 + 2 - 5) - AndroidUtilities.dp(2) * bubbleProgress);
canvas.rotate(180, 0, -AndroidUtilities.dp(2));
canvas.drawPath(arrowPath, paint);
canvas.restore();
}
if (type == LETTER_TYPE) {
if ((isMoving || bubbleProgress != 0)) {
paint.setAlpha((int) (255 * bubbleProgress));
@ -617,7 +655,7 @@ public class RecyclerListView extends RecyclerView {
canvas.scale(s, s, rect.right - AndroidUtilities.dp(12), rect.centerY());
float cy = rect.centerY();
float x = rect.left - AndroidUtilities.dp(30) * bubbleProgress;
float x = rect.left - AndroidUtilities.dp(30) * bubbleProgress - AndroidUtilities.dp(8);
float r = letterLayout.getHeight() / 2f + AndroidUtilities.dp(6);
rect.set(x - letterLayout.getWidth() - AndroidUtilities.dp(36), cy - letterLayout.getHeight() / 2f - AndroidUtilities.dp(8), x - AndroidUtilities.dp(12), cy + letterLayout.getHeight() / 2f + AndroidUtilities.dp(8));
@ -626,6 +664,7 @@ public class RecyclerListView extends RecyclerView {
paint2.setAlpha((int) (oldAlpha1 * floatingDateProgress));
letterPaint.setAlpha((int) (oldAlpha2 * floatingDateProgress));
fastScrollBackgroundDrawable.setBounds((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
fastScrollBackgroundDrawable.setAlpha((int) (255 * floatingDateProgress));
fastScrollBackgroundDrawable.draw(canvas);
canvas.save();
canvas.translate(x - letterLayout.getWidth() - AndroidUtilities.dp(24), cy - letterLayout.getHeight() / 2f);
@ -702,12 +741,35 @@ public class RecyclerListView extends RecyclerView {
invalidate();
}
AndroidUtilities.cancelRunOnUIThread(hideFloatingDateRunnable);
AndroidUtilities.runOnUIThread(hideFloatingDateRunnable, 4000);
AndroidUtilities.runOnUIThread(hideFloatingDateRunnable, 2000);
}
public void setIsVisible(boolean visible) {
this.isVisible = visible;
setAlpha(visible ? 1f : 0f);
if (isVisible != visible) {
this.isVisible = visible;
visibilityAlpha = visible ? 1f : 0f;
super.setAlpha(viewAlpha * visibilityAlpha);
}
}
public void setVisibilityAlpha(float v) {
if (visibilityAlpha != v) {
visibilityAlpha = v;
super.setAlpha(viewAlpha * visibilityAlpha);
}
}
@Override
public void setAlpha(float alpha) {
if (viewAlpha != alpha) {
viewAlpha = alpha;
super.setAlpha(viewAlpha * visibilityAlpha);
}
}
@Override
public float getAlpha() {
return viewAlpha;
}
public int getScrollBarY() {
@ -717,6 +779,7 @@ public class RecyclerListView extends RecyclerView {
public float getProgress() {
return progress;
}
}
private class RecyclerListViewItemClickListener implements OnItemTouchListener {
@ -1963,6 +2026,10 @@ public class RecyclerListView extends RecyclerView {
@Override
protected void dispatchDraw(Canvas canvas) {
if (itemsEnterAnimator != null) {
itemsEnterAnimator.dispatchDraw();
}
if (drawSelectorBehind && !selectorRect.isEmpty()) {
selectorDrawable.setBounds(selectorRect);
selectorDrawable.draw(canvas);
@ -2026,6 +2093,9 @@ public class RecyclerListView extends RecyclerView {
super.onDetachedFromWindow();
selectorPosition = NO_POSITION;
selectorRect.setEmpty();
if (itemsEnterAnimator != null) {
itemsEnterAnimator.onDetached();
}
}
public void addOverlayView(View view, FrameLayout.LayoutParams layoutParams) {
@ -2308,4 +2378,8 @@ public class RecyclerListView extends RecyclerView {
void getPaddings(int paddings[]);
void scrollBy(int dy);
}
public void setItemsEnterAnimator(RecyclerItemsEnterAnimator itemsEnterAnimator) {
this.itemsEnterAnimator = itemsEnterAnimator;
}
}

View file

@ -104,19 +104,7 @@ public class SearchViewPager extends ViewPagerFixed implements FilteredSearchVie
}
};
searchListView = new RecyclerListView(context) {
@Override
protected void dispatchDraw(Canvas canvas) {
itemsEnterAnimator.dispatchDraw();
super.dispatchDraw(canvas);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
itemsEnterAnimator.onDetached();
}
};
searchListView = new RecyclerListView(context);
searchListView.setPivotY(0);
searchListView.setAdapter(dialogsSearchAdapter);
searchListView.setVerticalScrollBarEnabled(true);

View file

@ -0,0 +1,161 @@
package org.telegram.ui.Components;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ImageReceiver;
import org.telegram.tgnet.TLObject;
import org.telegram.ui.ActionBar.MenuDrawable;
import org.telegram.ui.ActionBar.Theme;
public class SenderSelectView extends View {
private ImageReceiver avatarImage = new ImageReceiver(this);
private AvatarDrawable avatarDrawable = new AvatarDrawable();
private MenuDrawable menuDrawable = new MenuDrawable() {
@Override
public void invalidateSelf() {
super.invalidateSelf();
invalidate();
}
};
private Drawable selectorDrawable;
private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private RectF mTempRect = new RectF();
public SenderSelectView(Context context) {
super(context);
}
public SenderSelectView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SenderSelectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
avatarImage.setRoundRadius(AndroidUtilities.dp(28));
menuDrawable.setMiniIcon(true);
menuDrawable.setRotateToBack(false);
menuDrawable.setRotation(0f, false);
menuDrawable.setRoundCap();
menuDrawable.setCallback(this);
updateColors();
}
/**
* Updates theme colors
*/
private void updateColors() {
backgroundPaint.setColor(Theme.getColor(Theme.key_chat_messagePanelVoiceBackground));
int textColor = Theme.getColor(Theme.key_chat_messagePanelVoicePressed);
menuDrawable.setBackColor(textColor);
menuDrawable.setIconColor(textColor);
selectorDrawable = Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(16), Color.TRANSPARENT, Theme.getColor(Theme.key_windowBackgroundWhite));
selectorDrawable.setCallback(this);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
avatarImage.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
avatarImage.onDetachedFromWindow();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
avatarImage.setImageCoords(0, 0, getWidth(), getHeight());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
avatarImage.draw(canvas);
int alpha = (int) (menuDrawable.getCurrentRotation() * 0xFF);
backgroundPaint.setAlpha(alpha);
mTempRect.set(0, 0, getWidth(), getHeight());
canvas.drawRoundRect(mTempRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), backgroundPaint);
canvas.save();
canvas.translate(AndroidUtilities.dp(4), AndroidUtilities.dp(4));
menuDrawable.setAlpha(alpha);
menuDrawable.setBounds(0, 0, getWidth(), getHeight());
menuDrawable.draw(canvas);
canvas.restore();
selectorDrawable.setBounds(0, 0, getWidth(), getHeight());
selectorDrawable.draw(canvas);
}
/**
* Sets new User or Chat to be bound as the avatar
* @param obj User or chat
*/
public void setAvatar(TLObject obj) {
avatarDrawable.setInfo(obj);
avatarImage.setForUserOrChat(obj, avatarDrawable);
}
/**
* Sets new animation progress
* @param progress New progress
*/
public void setProgress(float progress) {
setProgress(progress, true);
}
/**
* Sets new animation progress
* @param progress New progress
* @param animate If we should animate
*/
public void setProgress(float progress, boolean animate) {
menuDrawable.setRotation(progress, animate);
}
/**
* @return Current animation progress
*/
public float getProgress() {
return menuDrawable.getCurrentRotation();
}
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return super.verifyDrawable(who) || selectorDrawable == who;
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
selectorDrawable.setState(getDrawableState());
}
@Override
public void jumpDrawablesToCurrentState() {
super.jumpDrawablesToCurrentState();
selectorDrawable.jumpToCurrentState();
}
}

View file

@ -962,18 +962,6 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
searchGridView = new RecyclerListView(context, resourcesProvider) {
@Override
protected void dispatchDraw(Canvas canvas) {
recyclerItemsEnterAnimator.dispatchDraw();
super.dispatchDraw(canvas);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
recyclerItemsEnterAnimator.onDetached();
}
@Override
protected boolean allowSelectChildAtPosition(float x, float y) {
return y >= AndroidUtilities.dp(darkTheme && linkToCopy[1] != null ? 111 : 58) + (Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0);

View file

@ -1,7 +1,6 @@
package org.telegram.ui.Components;
import static org.telegram.messenger.MediaDataController.MEDIA_PHOTOVIDEO;
import static org.telegram.messenger.MediaDataController.getMediaType;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@ -73,6 +72,7 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser;
@ -107,7 +107,7 @@ import org.telegram.ui.Cells.SharedPhotoVideoCell2;
import org.telegram.ui.Cells.UserCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.MediaCalendarActivity;
import org.telegram.ui.CalendarActivity;
import org.telegram.ui.PhotoViewer;
import org.telegram.ui.ProfileActivity;
@ -146,6 +146,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
boolean isInPinchToZoomTouchMode;
boolean maybePinchToZoomTouchMode;
boolean maybePinchToZoomTouchMode2;
boolean isPinnedToTop;
private int pointerId1, pointerId2;
@ -310,8 +311,23 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
return sharedMediaData[0].filterType;
}
public boolean isPinnedToTop() {
return isPinnedToTop;
}
public void setPinnedToTop(boolean pinnedToTop) {
if (isPinnedToTop != pinnedToTop) {
isPinnedToTop = pinnedToTop;
for (int i = 0; i < mediaPages.length; i++) {
updateFastScrollVisibility(mediaPages[i], true);
}
}
}
private static class MediaPage extends FrameLayout {
public long lastCheckScrollTime;
public boolean fastScrollEnabled;
public ObjectAnimator fastScrollAnimator;
private RecyclerListView listView;
private RecyclerListView animationSupportingListView;
private GridLayoutManager animationSupportingLayoutManager;
@ -363,6 +379,43 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
}
}
}
public void updateFastScrollVisibility(MediaPage mediaPage, boolean animated) {
boolean show = mediaPage.fastScrollEnabled && isPinnedToTop;
View view = mediaPage.listView.getFastScroll();
if (mediaPage.fastScrollAnimator != null) {
mediaPage.fastScrollAnimator.removeAllListeners();
mediaPage.fastScrollAnimator.cancel();
}
if (!animated) {
view.animate().setListener(null).cancel();
view.setVisibility(show ? View.VISIBLE : View.GONE);
view.setTag(show ? 1 : null);
view.setAlpha(1f);
view.setScaleX(1f);
view.setScaleY(1f);
} else if (show && view.getTag() == null) {
view.animate().setListener(null).cancel();
if (view.getVisibility() != View.VISIBLE) {
view.setVisibility(View.VISIBLE);
view.setAlpha(0f);
}
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 1f);
mediaPage.fastScrollAnimator = objectAnimator;
objectAnimator.setDuration(150).start();
view.setTag(1);
} else if (!show && view.getTag() != null) {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 0f);
objectAnimator.addListener(new HideViewAfterAnimation(view));
mediaPage.fastScrollAnimator = objectAnimator;
objectAnimator.setDuration(150).start();
view.animate().setListener(null).cancel();
view.setTag(null);
}
}
private ActionBar actionBar;
@ -1068,6 +1121,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
private boolean isActionModeShowed;
final Delegate delegate;
private HintView fwdRestrictedHint;
public SharedMediaLayout(Context context, long did, SharedMediaPreloader preloader, int commonGroupsCount, ArrayList<Integer> sortedUsers, TLRPC.ChatFull chatInfo, boolean membersFirst, BaseFragment parent, Delegate delegate, int viewType) {
super(context);
@ -1423,7 +1477,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
gotoItem.setDuplicateParentStateEnabled(false);
actionModeLayout.addView(gotoItem, new LinearLayout.LayoutParams(AndroidUtilities.dp(54), ViewGroup.LayoutParams.MATCH_PARENT));
actionModeViews.add(gotoItem);
gotoItem.setOnClickListener(v -> onActionBarItemClick(gotochat));
gotoItem.setOnClickListener(v -> onActionBarItemClick(v, gotochat));
forwardItem = new ActionBarMenuItem(context, null, Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
forwardItem.setIcon(R.drawable.msg_forward);
@ -1431,7 +1485,15 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
forwardItem.setDuplicateParentStateEnabled(false);
actionModeLayout.addView(forwardItem, new LinearLayout.LayoutParams(AndroidUtilities.dp(54), ViewGroup.LayoutParams.MATCH_PARENT));
actionModeViews.add(forwardItem);
forwardItem.setOnClickListener(v -> onActionBarItemClick(forward));
forwardItem.setOnClickListener(v -> onActionBarItemClick(v, forward));
boolean noforwards = profileActivity.getMessagesController().isChatNoForwards(-dialog_id);
forwardItem.setAlpha(noforwards ? 0.5f : 1f);
if (noforwards) {
if (forwardItem.getBackground() != null) forwardItem.setBackground(null);
} else if (forwardItem.getBackground() == null) {
forwardItem.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), 5));
}
}
deleteItem = new ActionBarMenuItem(context, null, Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
deleteItem.setIcon(R.drawable.msg_delete);
@ -1439,7 +1501,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
deleteItem.setDuplicateParentStateEnabled(false);
actionModeLayout.addView(deleteItem, new LinearLayout.LayoutParams(AndroidUtilities.dp(54), ViewGroup.LayoutParams.MATCH_PARENT));
actionModeViews.add(deleteItem);
deleteItem.setOnClickListener(v -> onActionBarItemClick(delete));
deleteItem.setOnClickListener(v -> onActionBarItemClick(v, delete));
photoVideoAdapter = new SharedPhotoVideoAdapter(context) {
@Override
@ -1668,13 +1730,13 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
drawingViews.addAll(animationSupportingSortedCells);
FastScroll fastScroll = getFastScroll();
if (fastScroll != null) {
if (fastScroll != null && fastScroll.getTag() != null) {
float p1 = photoVideoAdapter.getScrollProgress(mediaPage.listView);
float p2 = animationSupportingPhotoVideoAdapter.getScrollProgress(mediaPage.animationSupportingListView);
float a1 = photoVideoAdapter.fastScrollIsVisible(mediaPage.listView) ? 1f : 0f;
float a2 = animationSupportingPhotoVideoAdapter.fastScrollIsVisible(mediaPage.animationSupportingListView) ? 1f : 0f;
fastScroll.setProgress(p1 * (1f - photoVideoChangeColumnsProgress) + p2 * photoVideoChangeColumnsProgress);
fastScroll.setAlpha(a1 * (1f - photoVideoChangeColumnsProgress) + a2 * photoVideoChangeColumnsProgress);
fastScroll.setVisibilityAlpha(a1 * (1f - photoVideoChangeColumnsProgress) + a2 * photoVideoChangeColumnsProgress);
}
}
@ -1913,6 +1975,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
mediaPages[a].addView(mediaPages[a].animationSupportingListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
mediaPages[a].animationSupportingListView.setVisibility(View.GONE);
mediaPages[a].listView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(android.graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
@ -2143,6 +2206,10 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
}
public void setForwardRestrictedHint(HintView hintView) {
fwdRestrictedHint = hintView;
}
private int getMessageId(View child) {
if (child instanceof SharedPhotoVideoCell2) {
return ((SharedPhotoVideoCell2) child).getMessageId();
@ -2262,8 +2329,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
}
}
MediaCalendarActivity calendarActivity = new MediaCalendarActivity(bundle, sharedMediaData[0].filterType, date);
calendarActivity.setCallback(new MediaCalendarActivity.Callback() {
bundle.putInt("type", CalendarActivity.TYPE_MEDIA_CALENDAR);
CalendarActivity calendarActivity = new CalendarActivity(bundle, sharedMediaData[0].filterType, date);
calendarActivity.setCallback(new CalendarActivity.Callback() {
@Override
public void onDateSelected(int messageId, int startOffset) {
int index = -1;
@ -2346,7 +2414,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (photoVideoAdapter.getItemCount() == oldItemCount) {
AndroidUtilities.updateVisibleRows(mediaPage.listView);
} else {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
if (pinchCenterPosition >= 0) {
@ -2396,7 +2464,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (photoVideoAdapter.getItemCount() == oldItemCount) {
AndroidUtilities.updateVisibleRows(finalMediaPage.listView);
} else {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
}
finalMediaPage.animationSupportingListView.setVisibility(View.GONE);
@ -2465,7 +2533,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (photoVideoAdapter.getItemCount() == oldItemCount) {
AndroidUtilities.updateVisibleRows(finalMediaPage.listView);
} else {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
finalMediaPage.animationSupportingListView.setVisibility(View.GONE);
saveScrollPosition();
@ -2932,40 +3000,17 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (!sharedMediaData[type].fastScrollPeriods.isEmpty()) {
for (int i = 0; i < mediaPages.length; i++) {
if (mediaPages[i].selectedType == type) {
mediaPages[i].listView.setFastScrollVisible(true);
mediaPages[i].listView.getFastScroll().setAlpha(0);
mediaPages[i].listView.getFastScroll().animate().alpha(1f).setDuration(100).start();
mediaPages[i].listView.checkSection(true);
mediaPages[i].fastScrollEnabled = true;
updateFastScrollVisibility(mediaPages[i], true);
}
}
}
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}));
ConnectionsManager.getInstance(profileActivity.getCurrentAccount()).bindRequestToGuid(reqId, profileActivity.getClassGuid());
}
}
private void updatePhotosAdapter() {
// MediaPage mediaPage = getMediaPage(0);
// if (mediaPage != null) {
// for (int i = 0; i < mediaPage.listView.getChildCount(); i++) {
// View child = mediaPage.listView.getChildAt(i);
// if (child instanceof SharedPhotoVideoCell2) {
// ((SharedPhotoVideoCell2) child).moveImageToFront();
// }
// }
// if (mediaPage.animationSupportingListView.getVisibility() == View.VISIBLE) {
// for (int i = 0; i < mediaPage.animationSupportingListView.getChildCount(); i++) {
// View child = mediaPage.animationSupportingListView.getChildAt(i);
// if (child instanceof SharedPhotoVideoCell2) {
// ((SharedPhotoVideoCell2) child).moveImageToFront();
// }
// }
// }
// }
photoVideoAdapter.notifyDataSetChanged();
}
private static void showFastScrollHint(MediaPage mediaPage, SharedMediaData[] sharedMediaData, boolean show) {
if (show) {
@ -3012,7 +3057,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
checkCurrentTabValid();
}
public void onActionBarItemClick(int id) {
public void onActionBarItemClick(View v, int id) {
if (id == delete) {
TLRPC.Chat currentChat = null;
TLRPC.User currentUser = null;
@ -3030,6 +3075,18 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
cantDeleteMessagesCount = 0;
}, null);
} else if (id == forward) {
if (info != null) {
TLRPC.Chat chat = profileActivity.getMessagesController().getChat(info.id);
if (profileActivity.getMessagesController().isChatNoForwards(chat)) {
if (fwdRestrictedHint != null) {
fwdRestrictedHint.setText(ChatObject.isChannel(chat) && !chat.megagroup ? LocaleController.getString("ForwardsRestrictedInfoChannel", R.string.ForwardsRestrictedInfoChannel) :
LocaleController.getString("ForwardsRestrictedInfoGroup", R.string.ForwardsRestrictedInfoGroup));
fwdRestrictedHint.showForView(v, true);
}
return;
}
}
Bundle args = new Bundle();
args.putBoolean("onlySelect", true);
args.putInt("dialogsType", 3);
@ -3242,6 +3299,10 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
velocityTracker = VelocityTracker.obtain();
}
velocityTracker.addMovement(ev);
if (fwdRestrictedHint != null) {
fwdRestrictedHint.hide();
}
}
if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN && !startedTracking && !maybeStartTracking && ev.getY() >= AndroidUtilities.dp(48)) {
startedTrackingPointerId = ev.getPointerId(0);
@ -3581,7 +3642,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (photoVideoAdapter.getItemCount() == oldItemCount) {
AndroidUtilities.updateVisibleRows(listView);
} else {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
} else {
adapter.notifyDataSetChanged();
@ -3679,7 +3740,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
if (updated) {
scrolling = true;
if (photoVideoAdapter != null) {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
if (documentsAdapter != null) {
documentsAdapter.notifyDataSetChanged();
@ -3745,7 +3806,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
if (adapter != null) {
int count = adapter.getItemCount();
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
documentsAdapter.notifyDataSetChanged();
voiceAdapter.notifyDataSetChanged();
linksAdapter.notifyDataSetChanged();
@ -3830,6 +3891,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
if (messageId != 0) {
int index = -1;
if (mediaPages[k].selectedType < 0 || mediaPages[k].selectedType >= sharedMediaData.length) {
continue;
}
for (int i = 0; i < sharedMediaData[mediaPages[k].selectedType].messages.size(); i++) {
if (messageId == sharedMediaData[mediaPages[k].selectedType].messages.get(i).getId()) {
index = i;
@ -3941,7 +4005,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
public void onResume() {
scrolling = true;
if (photoVideoAdapter != null) {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
if (documentsAdapter != null) {
documentsAdapter.notifyDataSetChanged();
@ -3996,7 +4060,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
public void updateAdapters() {
if (photoVideoAdapter != null) {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
if (documentsAdapter != null) {
documentsAdapter.notifyDataSetChanged();
@ -4396,7 +4460,8 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
mediaPages[a].listView.setVisibility(View.VISIBLE);
}
mediaPages[a].listView.setFastScrollVisible(fastScrollVisible);
mediaPages[a].fastScrollEnabled = fastScrollVisible;
updateFastScrollVisibility(mediaPages[a], false);
mediaPages[a].layoutManager.setSpanCount(spanCount);
mediaPages[a].listView.setRecycledViewPool(viewPool);
mediaPages[a].animationSupportingListView.setRecycledViewPool(viewPool);
@ -4607,7 +4672,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
}
if (num == 0) {
updatePhotosAdapter();
photoVideoAdapter.notifyDataSetChanged();
}
}

View file

@ -0,0 +1,127 @@
package org.telegram.ui.Components;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ImageReceiver;
import org.telegram.tgnet.TLObject;
import org.telegram.ui.ActionBar.Theme;
public class SimpleAvatarView extends View {
private ImageReceiver avatarImage = new ImageReceiver(this);
private AvatarDrawable avatarDrawable = new AvatarDrawable();
private Paint selectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float selectProgress;
private boolean isAvatarHidden;
private ValueAnimator animator;
public SimpleAvatarView(Context context) {
super(context);
}
public SimpleAvatarView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SimpleAvatarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
{
avatarImage.setRoundRadius(AndroidUtilities.dp(28));
selectPaint.setStrokeWidth(AndroidUtilities.dp(2));
selectPaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
avatarImage.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
avatarImage.onDetachedFromWindow();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
selectPaint.setColor(Theme.getColor(Theme.key_dialogTextBlue));
canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, Math.min(getWidth(), getHeight()) / 2f - selectPaint.getStrokeWidth(), selectPaint);
if (!isAvatarHidden) {
float pad = selectPaint.getStrokeWidth() * 2.5f * selectProgress;
avatarImage.setImageCoords(pad, pad, getWidth() - pad * 2, getHeight() - pad * 2);
avatarImage.draw(canvas);
}
}
/**
* Sets new User or Chat to be bound as the avatar
* @param obj User or chat
*/
public void setAvatar(TLObject obj) {
avatarDrawable.setInfo(obj);
avatarImage.setForUserOrChat(obj, avatarDrawable);
}
/**
* @return If avatar is currently selected
*/
public boolean isSelected() {
return selectProgress == 1;
}
/**
* Sets avatar selected value
* @param s If avatar is selected
* @param animate If we should animate status change
*/
public void setSelected(boolean s, boolean animate) {
if (animate) {
if (animator != null)
animator.cancel();
float to = s ? 1 : 0;
ValueAnimator anim = ValueAnimator.ofFloat(selectProgress, to).setDuration((long) (350 * Math.abs(to - selectProgress)));
anim.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
anim.addUpdateListener(animation -> {
selectProgress = (float) animation.getAnimatedValue();
invalidate();
});
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (animator == animation)
animator = null;
}
});
anim.start();
animator = anim;
} else {
selectProgress = s ? 1 : 0;
invalidate();
}
}
/**
* Sets avatar hidden
* @param h If we should hide avatar from view
*/
public void setHideAvatar(boolean h) {
isAvatarHidden = h;
invalidate();
}
}

View file

@ -38,7 +38,7 @@ public class SlideView extends LinearLayout {
}
public void onNextPressed() {
public void onNextPressed(String code) {
}

View file

@ -0,0 +1,678 @@
package org.telegram.ui.Components;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SvgHelper;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import java.io.FileInputStream;
import java.util.List;
public class ThemeSmallPreviewView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
public final static int TYPE_DEFAULT = 0;
public final static int TYPE_GRID = 1;
private final float STROKE_RADIUS = AndroidUtilities.dp(8);
private final float INNER_RADIUS = AndroidUtilities.dp(6);
private final float INNER_RECT_SPACE = AndroidUtilities.dp(4);
private final float BUBBLE_HEIGHT = AndroidUtilities.dp(21);
private final float BUBBLE_WIDTH = AndroidUtilities.dp(41);
ThemeDrawable themeDrawable = new ThemeDrawable();
ThemeDrawable animateOutThemeDrawable;
private float changeThemeProgress = 1f;
Paint outlineBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint backgroundFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RectF rectF = new RectF();
private final Path clipPath = new Path();
private final Theme.ResourcesProvider resourcesProvider;
private ValueAnimator strokeAlphaAnimator;
private TextPaint noThemeTextPaint;
private StaticLayout textLayout;
public ChatThemeBottomSheet.ChatThemeItem chatThemeItem;
private BackupImageView backupImageView;
private boolean hasAnimatedEmoji;
private final int currentAccount;
Runnable animationCancelRunnable;
private int currentType;
int patternColor;
private float selectionProgress;
public ThemeSmallPreviewView(Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider, int currentType) {
super(context);
this.currentType = currentType;
this.currentAccount = currentAccount;
this.resourcesProvider = resourcesProvider;
setBackgroundColor(getThemedColor(Theme.key_dialogBackgroundGray));
backupImageView = new BackupImageView(context);
backupImageView.getImageReceiver().setCrossfadeWithOldImage(true);
backupImageView.getImageReceiver().setAllowStartLottieAnimation(false);
backupImageView.getImageReceiver().setAutoRepeat(0);
if (currentType == TYPE_DEFAULT) {
addView(backupImageView, LayoutHelper.createFrame(28, 28, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 12));
} else {
addView(backupImageView, LayoutHelper.createFrame(36, 36, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 12));
}
outlineBackgroundPaint.setStrokeWidth(AndroidUtilities.dp(2));
outlineBackgroundPaint.setStyle(Paint.Style.STROKE);
outlineBackgroundPaint.setColor(0xFFE3E3E3);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (currentType == TYPE_GRID) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int) (width * 1.2f);
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
} else {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = AndroidUtilities.dp(77);
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
backupImageView.setPivotY(backupImageView.getMeasuredHeight());
backupImageView.setPivotX(backupImageView.getMeasuredWidth() / 2f);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (w == oldw && h == oldh) {
return;
}
rectF.set(INNER_RECT_SPACE, INNER_RECT_SPACE, w - INNER_RECT_SPACE, h - INNER_RECT_SPACE);
clipPath.reset();
clipPath.addRoundRect(rectF, INNER_RADIUS, INNER_RADIUS, Path.Direction.CW);
}
Theme.MessageDrawable messageDrawableOut = new Theme.MessageDrawable(Theme.MessageDrawable.TYPE_TEXT, true, false);
Theme.MessageDrawable messageDrawableIn = new Theme.MessageDrawable(Theme.MessageDrawable.TYPE_TEXT, false, false);
@Override
protected void dispatchDraw(Canvas canvas) {
if (chatThemeItem == null) {
super.dispatchDraw(canvas);
return;
}
if (changeThemeProgress != 1 && animateOutThemeDrawable != null) {
animateOutThemeDrawable.drawBackground(canvas, 1f);
}
if (changeThemeProgress != 0) {
themeDrawable.drawBackground(canvas, changeThemeProgress);
}
if (changeThemeProgress != 1 && animateOutThemeDrawable != null) {
animateOutThemeDrawable.draw(canvas, 1f);
}
if (changeThemeProgress != 0) {
themeDrawable.draw(canvas, changeThemeProgress);
}
if (changeThemeProgress != 1f) {
changeThemeProgress += 16 / 150f;
if (changeThemeProgress >= 1f) {
changeThemeProgress = 1f;
}
invalidate();
}
super.dispatchDraw(canvas);
}
public int lastThemeIndex;
public void setItem(ChatThemeBottomSheet.ChatThemeItem item, boolean animated) {
boolean itemChanged = chatThemeItem != item;
boolean darkModeChanged = lastThemeIndex != item.themeIndex;
lastThemeIndex = item.themeIndex;
this.chatThemeItem = item;
hasAnimatedEmoji = false;
TLRPC.Document document = null;
if (item.chatTheme.getEmoticon() != null) {
document = MediaDataController.getInstance(currentAccount).getEmojiAnimatedSticker(item.chatTheme.getEmoticon());
}
if (itemChanged) {
if (animationCancelRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(animationCancelRunnable);
animationCancelRunnable = null;
}
backupImageView.animate().cancel();
backupImageView.setScaleX(1f);
backupImageView.setScaleY(1f);
}
if (itemChanged) {
Drawable thumb = null;
if (document != null) {
thumb = DocumentObject.getSvgThumb(document, Theme.key_emptyListPlaceholder, 0.2f);
}
if (thumb == null) {
Emoji.preloadEmoji(item.chatTheme.getEmoticon());
thumb = Emoji.getEmojiDrawable(item.chatTheme.getEmoticon());
}
backupImageView.setImage(ImageLocation.getForDocument(document), "50_50", thumb, null);
}
if (itemChanged || darkModeChanged) {
if (animated) {
changeThemeProgress = 0f;
animateOutThemeDrawable = themeDrawable;
themeDrawable = new ThemeDrawable();
invalidate();
} else {
changeThemeProgress = 1f;
}
updatePreviewBackground(themeDrawable);
TLRPC.TL_theme theme = item.chatTheme.getTlTheme(lastThemeIndex);
if (theme != null) {
final long themeId = theme.id;
TLRPC.WallPaper wallPaper = item.chatTheme.getWallpaper(lastThemeIndex);
if (wallPaper != null) {
final int intensity = wallPaper.settings.intensity;
item.chatTheme.loadWallpaperThumb(lastThemeIndex, result -> {
if (result != null && result.first == themeId) {
if (item.previewDrawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) item.previewDrawable;
motionBackgroundDrawable.setPatternBitmap(intensity >= 0 ? 100 : -100, result.second);
motionBackgroundDrawable.setPatternColorFilter(patternColor);
}
invalidate();
}
});
}
} else {
Theme.ThemeInfo themeInfo = item.chatTheme.getThemeInfo(lastThemeIndex);
Theme.ThemeAccent accent = null;
if (themeInfo.themeAccentsMap != null) {
accent = themeInfo.themeAccentsMap.get(item.chatTheme.getAccentId(lastThemeIndex));
}
if (accent != null && accent.info != null && accent.info.settings.size() > 0) {
TLRPC.WallPaper wallPaper = accent.info.settings.get(0).wallpaper;
if (wallPaper != null && wallPaper.document != null) {
TLRPC.Document wallpaperDocument = wallPaper.document;
final TLRPC.PhotoSize thumbSize = FileLoader.getClosestPhotoSizeWithSize(wallpaperDocument.thumbs, 120);
ImageLocation imageLocation = ImageLocation.getForDocument(thumbSize, wallpaperDocument);
ImageReceiver imageReceiver = new ImageReceiver();
imageReceiver.setImage(imageLocation, "120_80", null, null, null, 1);
imageReceiver.setDelegate((receiver, set, thumb, memCache) -> {
ImageReceiver.BitmapHolder holder = receiver.getBitmapSafe();
if (!set || holder == null) {
return;
}
Bitmap resultBitmap = holder.bitmap;
if (resultBitmap != null) {
if (item.previewDrawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) item.previewDrawable;
motionBackgroundDrawable.setPatternBitmap(wallPaper.settings == null || wallPaper.settings.intensity >= 0 ? 100 : -100, resultBitmap);
motionBackgroundDrawable.setPatternColorFilter(patternColor);
invalidate();
}
}
});
ImageLoader.getInstance().loadImageForImageReceiver(imageReceiver);
}
} else if (accent != null && accent.info == null) {
ChatThemeController.chatThemeQueue.postRunnable(() -> {
Bitmap bitmap = SvgHelper.getBitmap(R.raw.default_pattern, AndroidUtilities.dp(80), AndroidUtilities.dp(120), Color.BLACK, 3f);
AndroidUtilities.runOnUIThread(() -> {
if (item.previewDrawable instanceof MotionBackgroundDrawable) {
MotionBackgroundDrawable motionBackgroundDrawable = (MotionBackgroundDrawable) item.previewDrawable;
motionBackgroundDrawable.setPatternBitmap(100, bitmap);
motionBackgroundDrawable.setPatternColorFilter(patternColor);
invalidate();
}
});
});
}
}
}
if (!animated) {
backupImageView.animate().cancel();;
backupImageView.setScaleX(1f);
backupImageView.setScaleY(1f);
AndroidUtilities.cancelRunOnUIThread(animationCancelRunnable);
if (backupImageView.getImageReceiver().getLottieAnimation() != null) {
backupImageView.getImageReceiver().getLottieAnimation().stop();
backupImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false);
}
}
}
boolean isSelected;
public void setSelected(boolean selected, boolean animated) {
if (!animated) {
if (strokeAlphaAnimator != null) {
strokeAlphaAnimator.cancel();
}
isSelected = selected;
selectionProgress = selected ? 1f : 0;
invalidate();
return;
}
if (isSelected != selected) {
float currentProgress = selectionProgress;
if (strokeAlphaAnimator != null) {
strokeAlphaAnimator.cancel();
}
strokeAlphaAnimator = ValueAnimator.ofFloat(currentProgress, selected ? 1f : 0);
strokeAlphaAnimator.addUpdateListener(valueAnimator -> {
selectionProgress = (float) valueAnimator.getAnimatedValue();
invalidate();
});
strokeAlphaAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
selectionProgress = selected ? 1f : 0;
invalidate();
}
});
strokeAlphaAnimator.setDuration(250);
strokeAlphaAnimator.start();
}
isSelected = selected;
}
@Override
public void setBackgroundColor(int color) {
backgroundFillPaint.setColor(getThemedColor(Theme.key_dialogBackgroundGray));
if (noThemeTextPaint != null) {
noThemeTextPaint.setColor(getThemedColor(Theme.key_chat_emojiPanelTrendingDescription));
}
invalidate();
}
private void fillOutBubblePaint(Paint paint, List<Integer> messageColors) {
if (messageColors.size() > 1) {
int[] colors = new int[messageColors.size()];
for (int i = 0; i != messageColors.size(); ++i) {
colors[i] = messageColors.get(i);
}
float top = INNER_RECT_SPACE + AndroidUtilities.dp(8);
paint.setShader(new LinearGradient(0f, top, 0f, top + BUBBLE_HEIGHT, colors, null, Shader.TileMode.CLAMP));
} else {
paint.setShader(null);
}
}
public void updatePreviewBackground(ThemeDrawable themeDrawable) {
if (chatThemeItem == null || chatThemeItem.chatTheme == null) {
return;
}
EmojiThemes.ThemeItem themeItem = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
int color = themeItem.inBubbleColor;
themeDrawable.inBubblePaint.setColor(color);
color = themeItem.outBubbleColor;
themeDrawable.outBubblePaintSecond.setColor(color);
int strokeColor = chatThemeItem.chatTheme.showAsDefaultStub
? getThemedColor(Theme.key_featuredStickers_addButton)
: themeItem.outLineColor;
int strokeAlpha = themeDrawable.strokePaint.getAlpha();
themeDrawable.strokePaint.setColor(strokeColor);
themeDrawable.strokePaint.setAlpha(strokeAlpha);
TLRPC.TL_theme tlTheme = chatThemeItem.chatTheme.getTlTheme(chatThemeItem.themeIndex);
if (tlTheme != null) {
int index = chatThemeItem.chatTheme.getSettingsIndex(chatThemeItem.themeIndex);
TLRPC.ThemeSettings themeSettings = tlTheme.settings.get(index);
fillOutBubblePaint(themeDrawable.outBubblePaintSecond, themeSettings.message_colors);
themeDrawable.outBubblePaintSecond.setAlpha(255);
getPreviewDrawable(tlTheme, index);
} else {
EmojiThemes.ThemeItem item = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
getPreviewDrawable(item);
}
themeDrawable.previewDrawable = chatThemeItem.previewDrawable;
invalidate();
}
private Drawable getPreviewDrawable(TLRPC.TL_theme theme, int settingsIndex) {
if (chatThemeItem == null) {
return null;
}
int color1 = 0;
int color2 = 0;
int color3 = 0;
int color4 = 0;
Drawable drawable;
if (settingsIndex >= 0) {
TLRPC.ThemeSettings themeSettings = theme.settings.get(settingsIndex);
TLRPC.WallPaperSettings wallPaperSettings = themeSettings.wallpaper.settings;
color1 = wallPaperSettings.background_color;
color2 = wallPaperSettings.second_background_color;
color3 = wallPaperSettings.third_background_color;
color4 = wallPaperSettings.fourth_background_color;
}
if (color2 != 0) {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(color1, color2, color3, color4, true);
patternColor = motionBackgroundDrawable.getPatternColor();
drawable = motionBackgroundDrawable;
} else {
drawable = new MotionBackgroundDrawable(color1, color1, color1, color1, true);
patternColor = Color.BLACK;
}
chatThemeItem.previewDrawable = drawable;
return drawable;
}
private Drawable getPreviewDrawable(EmojiThemes.ThemeItem item) {
if (chatThemeItem == null) {
return null;
}
Drawable drawable = null;
int color1 = item.patternBgColor;
int color2 = item.patternBgGradientColor1;
int color3 = item.patternBgGradientColor2;
int color4 = item.patternBgGradientColor3;
int rotation = item.patternBgRotation;
if (item.themeInfo.getAccent(false) != null) {
if (color2 != 0) {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(color1, color2, color3, color4, rotation, true);
patternColor = motionBackgroundDrawable.getPatternColor();
drawable = motionBackgroundDrawable;
} else {
drawable = new MotionBackgroundDrawable(color1, color1, color1, color1, rotation, true);
patternColor = Color.BLACK;
}
} else {
if (color1 != 0 && color2 != 0) {
drawable = new MotionBackgroundDrawable(color1, color2, color3, color4, rotation, true);
} else if (color1 != 0) {
drawable = new ColorDrawable(color1);
} else if (item.themeInfo != null && (item.themeInfo.previewWallpaperOffset > 0 || item.themeInfo.pathToWallpaper != null)) {
Bitmap wallpaper = getScaledBitmap(AndroidUtilities.dp(76), AndroidUtilities.dp(97), item.themeInfo.pathToWallpaper, item.themeInfo.pathToFile, item.themeInfo.previewWallpaperOffset);
if (wallpaper != null) {
drawable = new BitmapDrawable(wallpaper);
}
} else {
drawable = new MotionBackgroundDrawable(0xffdbddbb, 0xff6ba587, 0xffd5d88d, 0xff88b884, true);
}
}
chatThemeItem.previewDrawable = drawable;
return drawable;
}
private StaticLayout getNoThemeStaticLayout() {
if (textLayout != null) {
return textLayout;
}
noThemeTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG + TextPaint.SUBPIXEL_TEXT_FLAG);
noThemeTextPaint.setColor(getThemedColor(Theme.key_chat_emojiPanelTrendingDescription));
noThemeTextPaint.setTextSize(AndroidUtilities.dp(14));
noThemeTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textLayout = StaticLayoutEx.createStaticLayout2(
LocaleController.getString("ChatNoTheme", R.string.ChatNoTheme),
noThemeTextPaint,
AndroidUtilities.dp(52),
Layout.Alignment.ALIGN_CENTER,
1f, 0f, true,
TextUtils.TruncateAt.END, AndroidUtilities.dp(52), 3
);
return textLayout;
}
private int getThemedColor(String key) {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
public void playEmojiAnimation() {
if (backupImageView.getImageReceiver().getLottieAnimation() != null) {
AndroidUtilities.cancelRunOnUIThread(animationCancelRunnable);
backupImageView.setVisibility(View.VISIBLE);
backupImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false);
backupImageView.getImageReceiver().getLottieAnimation().start();
backupImageView.animate().scaleX(2f).scaleY(2f).setDuration(300).setInterpolator(AndroidUtilities.overshootInterpolator).start();
AndroidUtilities.runOnUIThread(animationCancelRunnable = () -> {
animationCancelRunnable = null;
backupImageView.animate().scaleX(1f).scaleY(1f).setDuration(150).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}, 2500);
}
}
public void cancelAnimation() {
if (animationCancelRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(animationCancelRunnable);
animationCancelRunnable.run();
}
}
public static Bitmap getScaledBitmap(float w, float h, String path, String streamPath, int streamOffset) {
FileInputStream stream = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
if (path != null) {
BitmapFactory.decodeFile(path, options);
} else {
stream = new FileInputStream(streamPath);
stream.getChannel().position(streamOffset);
BitmapFactory.decodeStream(stream, null, options);
}
if (options.outWidth > 0 && options.outHeight > 0) {
if (w > h && options.outWidth < options.outHeight) {
float temp = w;
w = h;
h = temp;
}
float scale = Math.min(options.outWidth / w, options.outHeight / h);
options.inSampleSize = 1;
if (scale > 1.0f) {
do {
options.inSampleSize *= 2;
} while (options.inSampleSize < scale);
}
options.inJustDecodeBounds = false;
Bitmap wallpaper;
if (path != null) {
wallpaper = BitmapFactory.decodeFile(path, options);
} else {
stream.getChannel().position(streamOffset);
wallpaper = BitmapFactory.decodeStream(stream, null, options);
}
return wallpaper;
}
} catch (Throwable e) {
FileLog.e(e);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (Exception e2) {
FileLog.e(e2);
}
}
return null;
}
private class ThemeDrawable {
private final Paint strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint outBubblePaintSecond = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint inBubblePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Drawable previewDrawable;
ThemeDrawable() {
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(AndroidUtilities.dp(2));
}
public void drawBackground(Canvas canvas, float alpha) {
if (previewDrawable != null) {
canvas.save();
canvas.clipPath(clipPath);
if (previewDrawable instanceof BitmapDrawable) {
int drawableW = previewDrawable.getIntrinsicWidth();
int drawableH = previewDrawable.getIntrinsicHeight();
if (drawableW / (float) drawableH > getWidth() / (float) getHeight()) {
int w = (int) (getWidth() * (float) drawableH / drawableW);
int padding = (w - getWidth()) / 2;
previewDrawable.setBounds(padding, 0, padding + w , getHeight());
} else {
int h = (int) (getHeight() * (float) drawableH / drawableW);
int padding = (getHeight() - h) / 2;
previewDrawable.setBounds(0, padding, getWidth(), padding + h);
}
} else {
previewDrawable.setBounds(0, 0, getWidth(), getHeight());
}
previewDrawable.setAlpha((int) (255 * alpha));
previewDrawable.draw(canvas);
if (previewDrawable instanceof ColorDrawable || (previewDrawable instanceof MotionBackgroundDrawable && ((MotionBackgroundDrawable) previewDrawable).isOneColor())) {
outlineBackgroundPaint.setAlpha((int) (255 * alpha));
float padding = INNER_RECT_SPACE;
AndroidUtilities.rectTmp.set(padding, padding, getWidth() - padding, getHeight() - padding);
canvas.drawRoundRect(AndroidUtilities.rectTmp, INNER_RADIUS, INNER_RADIUS, outlineBackgroundPaint);
}
canvas.restore();
} else {
canvas.drawRoundRect(rectF, INNER_RADIUS, INNER_RADIUS, backgroundFillPaint);
}
}
public void draw(Canvas canvas, float alpha) {
if (chatThemeItem.isSelected || strokeAlphaAnimator != null) {
EmojiThemes.ThemeItem themeItem = chatThemeItem.chatTheme.getThemeItem(chatThemeItem.themeIndex);
int strokeColor = chatThemeItem.chatTheme.showAsDefaultStub
? getThemedColor(Theme.key_featuredStickers_addButton)
: themeItem.outLineColor;
strokePaint.setColor(strokeColor);
strokePaint.setAlpha((int) (selectionProgress * alpha * 255));
float rectSpace = strokePaint.getStrokeWidth() * 0.5f + AndroidUtilities.dp(4) * (1f - selectionProgress);
rectF.set(rectSpace, rectSpace, getWidth() - rectSpace, getHeight() - rectSpace);
canvas.drawRoundRect(rectF, STROKE_RADIUS, STROKE_RADIUS, strokePaint);
}
outBubblePaintSecond.setAlpha((int) (255 * alpha));
inBubblePaint.setAlpha((int) (255 * alpha));
rectF.set(INNER_RECT_SPACE, INNER_RECT_SPACE, getWidth() - INNER_RECT_SPACE, getHeight() - INNER_RECT_SPACE);
if (chatThemeItem.chatTheme == null || chatThemeItem.chatTheme.showAsDefaultStub) {
canvas.drawRoundRect(rectF, INNER_RADIUS, INNER_RADIUS, backgroundFillPaint);
canvas.save();
StaticLayout textLayout = getNoThemeStaticLayout();
canvas.translate((getWidth() - textLayout.getWidth()) * 0.5f, AndroidUtilities.dp(18));
textLayout.draw(canvas);
canvas.restore();
} else {
float bubbleTop = INNER_RECT_SPACE + AndroidUtilities.dp(8);
float bubbleLeft = INNER_RECT_SPACE + AndroidUtilities.dp(22);
if (currentType == TYPE_DEFAULT) {
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
} else {
bubbleTop = getMeasuredHeight() * 0.12f;
bubbleLeft = getMeasuredWidth() - getMeasuredWidth() * 0.65f;
float bubbleRight = getMeasuredWidth() - getMeasuredWidth() * 0.1f;
float bubbleBottom = getMeasuredHeight() * 0.32f;
rectF.set(bubbleLeft, bubbleTop, bubbleRight, bubbleBottom);
}
Paint paint = outBubblePaintSecond;
if (currentType == TYPE_DEFAULT) {
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, paint);
} else {
messageDrawableOut.setBounds((int) rectF.left, (int) rectF.top - AndroidUtilities.dp(2), (int) rectF.right + AndroidUtilities.dp(4), (int) rectF.bottom + AndroidUtilities.dp(2));
messageDrawableOut.setRoundRadius((int) (rectF.height() * 0.5f));
messageDrawableOut.draw(canvas, paint);
}
if (currentType == TYPE_DEFAULT) {
bubbleLeft = INNER_RECT_SPACE + AndroidUtilities.dp(5);
bubbleTop += BUBBLE_HEIGHT + AndroidUtilities.dp(4);
rectF.set(bubbleLeft, bubbleTop, bubbleLeft + BUBBLE_WIDTH, bubbleTop + BUBBLE_HEIGHT);
} else {
bubbleTop = getMeasuredHeight() * 0.35f;
bubbleLeft = getMeasuredWidth() * 0.1f;
float bubbleRight = getMeasuredWidth() * 0.65f;
float bubbleBottom = getMeasuredHeight() * 0.55f;
rectF.set(bubbleLeft, bubbleTop, bubbleRight, bubbleBottom);
}
if (currentType == TYPE_DEFAULT) {
canvas.drawRoundRect(rectF, rectF.height() * 0.5f, rectF.height() * 0.5f, inBubblePaint);
} else {
messageDrawableIn.setBounds((int) rectF.left - AndroidUtilities.dp(4), (int) rectF.top - AndroidUtilities.dp(2), (int) rectF.right, (int) rectF.bottom + AndroidUtilities.dp(2));
messageDrawableIn.setRoundRadius((int) (rectF.height() * 0.5f));
messageDrawableIn.draw(canvas, inBubblePaint);
}
}
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.emojiLoaded) {
invalidate();
}
}
}

View file

@ -29,6 +29,7 @@ public class Tooltip extends TextView {
animator.start();
};
public Tooltip(Context context, ViewGroup parentView, int backgroundColor, int textColor) {
super(context);

View file

@ -171,6 +171,7 @@ public class UndoView extends FrameLayout {
public final static int ACTION_PIN_DIALOGS = 78;
public final static int ACTION_UNPIN_DIALOGS = 79;
public final static int ACTION_EMAIL_COPIED = 80;
public final static int ACTION_CLEAR_DATES = 81;
private CharSequence infoText;
private int hideAnimationType = 1;
@ -1312,7 +1313,7 @@ public class UndoView extends FrameLayout {
subinfoTextView.setVisibility(GONE);
leftImageView.setVisibility(GONE);
if (currentAction == ACTION_CLEAR || currentAction == ACTION_CLEAR_FEW) {
if (currentAction == ACTION_CLEAR_DATES || currentAction == ACTION_CLEAR || currentAction == ACTION_CLEAR_FEW) {
infoTextView.setText(LocaleController.getString("HistoryClearedUndo", R.string.HistoryClearedUndo));
} else if (currentAction == ACTION_DELETE_FEW) {
infoTextView.setText(LocaleController.getString("ChatsDeletedUndo", R.string.ChatsDeletedUndo));
@ -1328,8 +1329,10 @@ public class UndoView extends FrameLayout {
infoTextView.setText(LocaleController.getString("ChatDeletedUndo", R.string.ChatDeletedUndo));
}
}
for (int a = 0; a < dialogIds.size(); a++) {
MessagesController.getInstance(currentAccount).addDialogAction(dialogIds.get(a), currentAction == ACTION_CLEAR || currentAction == ACTION_CLEAR_FEW);
if (currentAction != ACTION_CLEAR_DATES) {
for (int a = 0; a < dialogIds.size(); a++) {
MessagesController.getInstance(currentAccount).addDialogAction(dialogIds.get(a), currentAction == ACTION_CLEAR || currentAction == ACTION_CLEAR_FEW);
}
}
}
@ -1423,7 +1426,7 @@ public class UndoView extends FrameLayout {
backgroundDrawable.draw(canvas);
}
if (currentAction == ACTION_DELETE || currentAction == ACTION_CLEAR || currentAction == ACTION_DELETE_FEW || currentAction == ACTION_CLEAR_FEW) {
if (currentAction == ACTION_DELETE || currentAction == ACTION_CLEAR || currentAction == ACTION_DELETE_FEW || currentAction == ACTION_CLEAR_FEW || currentAction == ACTION_CLEAR_DATES) {
int newSeconds = timeLeft > 0 ? (int) Math.ceil(timeLeft / 1000.0f) : 0;
if (prevSeconds != newSeconds) {
prevSeconds = newSeconds;

View file

@ -316,7 +316,7 @@ public class DataAutoDownloadActivity extends BaseFragment {
TextCheckBoxCell[] cells = new TextCheckBoxCell[4];
for (int a = 0; a < 4; a++) {
TextCheckBoxCell checkBoxCell = cells[a] = new TextCheckBoxCell(getParentActivity(), true);
TextCheckBoxCell checkBoxCell = cells[a] = new TextCheckBoxCell(getParentActivity(), true, false);
if (a == 0) {
cells[a].setTextAndCheck(LocaleController.getString("AutodownloadContacts", R.string.AutodownloadContacts), (currentPreset.mask[DownloadController.PRESET_NUM_CONTACT] & type) != 0, true);
} else if (a == 1) {

View file

@ -1,16 +1,21 @@
package org.telegram.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -23,8 +28,10 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.DrawerProfileCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.ThemeSmallPreviewView;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable;
@ -57,7 +64,7 @@ public class DefaultThemesPreviewCell extends LinearLayout {
addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
adapter = new ChatThemeBottomSheet.Adapter(parentFragment.getCurrentAccount(), null, currentType == ThemeActivity.THEME_TYPE_BASIC ? ChatThemeBottomSheet.Adapter.TYPE_DEFAULT : ChatThemeBottomSheet.Adapter.TYPE_GRID);
adapter = new ChatThemeBottomSheet.Adapter(parentFragment.getCurrentAccount(), null, currentType == ThemeActivity.THEME_TYPE_BASIC ? ThemeSmallPreviewView.TYPE_DEFAULT : ThemeSmallPreviewView.TYPE_GRID);
recyclerView = new RecyclerListView(getContext());
recyclerView.setAdapter(adapter);
recyclerView.setClipChildren(false);
@ -79,12 +86,13 @@ public class DefaultThemesPreviewCell extends LinearLayout {
recyclerView.setLayoutManager(layoutManager = gridLayoutManager);
}
recyclerView.setFocusable(false);
recyclerView.setPadding(AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12), 0);
recyclerView.setOnItemClickListener((view, position) -> {
ChatThemeBottomSheet.ChatThemeItem chatTheme = adapter.items.get(position);
Theme.ThemeInfo info = chatTheme.chatTheme.getThemeInfo(themeIndex);
int accentId = -1;
if (chatTheme.chatTheme.getEmoticon().equals("\uD83C\uDFE0")) {
if (chatTheme.chatTheme.getEmoticon().equals("\uD83C\uDFE0") || chatTheme.chatTheme.getEmoticon().equals("\uD83C\uDFA8")) {
accentId = chatTheme.chatTheme.getAccentId(themeIndex);
}
if (info == null) {
@ -104,18 +112,28 @@ public class DefaultThemesPreviewCell extends LinearLayout {
}
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, info, false, null, accentId);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, info, true, null, accentId);
selectedPosition = position;
for (int i = 0; i < adapter.items.size(); i++) {
adapter.items.get(i).isSelected = i == selectedPosition;
}
adapter.setSelectedItem(selectedPosition);
for (int i = 0; i < recyclerView.getChildCount(); i++) {
ChatThemeBottomSheet.Adapter.ChatThemeView child = (ChatThemeBottomSheet.Adapter.ChatThemeView) recyclerView.getChildAt(i);
ThemeSmallPreviewView child = (ThemeSmallPreviewView) recyclerView.getChildAt(i);
if (child != view) {
child.cancelAnimation();
}
}
((ChatThemeBottomSheet.Adapter.ChatThemeView) view).playEmojiAnimation();
((ThemeSmallPreviewView) view).playEmojiAnimation();
if (info != null) {
SharedPreferences.Editor editor = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE).edit();
editor.putString(currentType == ThemeActivity.THEME_TYPE_NIGHT || info.isDark() ? "lastDarkTheme" : "lastDayTheme", info.getKey());
editor.commit();
}
});
progressView = new FlickerLoadingView(getContext(), null);
@ -141,7 +159,6 @@ public class DefaultThemesPreviewCell extends LinearLayout {
darkThemeDrawable.commitApplyLayerColors();
dayNightCell = new TextCell(context);
dayNightCell.setTextAndIcon(LocaleController.getString("SettingsSwitchToNightMode", R.string.SettingsSwitchToNightMode), darkThemeDrawable, true);
dayNightCell.imageLeft = 21;
addView(dayNightCell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
@ -154,6 +171,11 @@ public class DefaultThemesPreviewCell extends LinearLayout {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onClick(View view) {
if (DrawerProfileCell.switchingTheme) {
return;
}
int iconOldColor = Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4);
DrawerProfileCell.switchingTheme = true;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("themeconfig", Activity.MODE_PRIVATE);
String dayThemeName = preferences.getString("lastDayTheme", "Blue");
if (Theme.getTheme(dayThemeName) == null || Theme.getTheme(dayThemeName).isDark()) {
@ -190,6 +212,32 @@ public class DefaultThemesPreviewCell extends LinearLayout {
updateDayNightMode();
updateSelectedPosition();
int iconNewColor = Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4);
darkThemeDrawable.setColorFilter(new PorterDuffColorFilter(iconNewColor, PorterDuff.Mode.SRC_IN));
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int color = ColorUtils.blendARGB(iconOldColor, iconNewColor, (Float) valueAnimator.getAnimatedValue());
darkThemeDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
}
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
darkThemeDrawable.setColorFilter(new PorterDuffColorFilter(iconNewColor, PorterDuff.Mode.SRC_IN));
super.onAnimationEnd(animation);
}
});
valueAnimator.setDuration(350);
valueAnimator.start();
if (Theme.isCurrentThemeDay()) {
dayNightCell.setTextAndIcon(LocaleController.getString("SettingsSwitchToNightMode", R.string.SettingsSwitchToNightMode), darkThemeDrawable, true);
} else {
dayNightCell.setTextAndIcon(LocaleController.getString("SettingsSwitchToDayMode", R.string.SettingsSwitchToDayMode), darkThemeDrawable, true);
}
}
});
@ -200,12 +248,14 @@ public class DefaultThemesPreviewCell extends LinearLayout {
if (!Theme.isCurrentThemeDay()) {
darkThemeDrawable.setCurrentFrame(darkThemeDrawable.getFramesCount() - 1);
dayNightCell.setTextAndIcon(LocaleController.getString("SettingsSwitchToDaytMode", R.string.SettingsSwitchToDayMode), darkThemeDrawable, true);
} else {
dayNightCell.setTextAndIcon(LocaleController.getString("SettingsSwitchToNightMode", R.string.SettingsSwitchToNightMode), darkThemeDrawable, true);
}
}
if (!Theme.defaultEmojiThemes.isEmpty()) {
ArrayList<ChatThemeBottomSheet.ChatThemeItem> themes = new ArrayList<>();
themes.addAll(Theme.defaultEmojiThemes);
ArrayList<ChatThemeBottomSheet.ChatThemeItem> themes = new ArrayList<>(Theme.defaultEmojiThemes);
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
EmojiThemes chatTheme = EmojiThemes.createPreviewCustom();
@ -263,20 +313,36 @@ public class DefaultThemesPreviewCell extends LinearLayout {
selectedPosition = -1;
for (int i = 0; i < adapter.items.size(); i++) {
TLRPC.TL_theme theme = adapter.items.get(i).chatTheme.getTlTheme(themeIndex);
Theme.ThemeInfo themeInfo = adapter.items.get(i).chatTheme.getThemeInfo(themeIndex);
if (theme != null) {
int settingsIndex = adapter.items.get(i).chatTheme.getSettingsIndex(themeIndex);
String key = Theme.getBaseThemeKey(theme.settings.get(settingsIndex));
if (Theme.getCurrentTheme().name.equals(key)) {
Theme.ThemeAccent accent = Theme.getCurrentTheme().accentsByThemeId.get(theme.id);
if (accent != null && accent.id == Theme.getCurrentTheme().currentAccentId) {
if (Theme.getActiveTheme().name.equals(key)) {
if (Theme.getActiveTheme().accentsByThemeId == null) {
selectedPosition = i;
break;
} else {
Theme.ThemeAccent accent = Theme.getActiveTheme().accentsByThemeId.get(theme.id);
if (accent != null && accent.id == Theme.getActiveTheme().currentAccentId) {
selectedPosition = i;
break;
}
}
}
} else if (themeInfo != null) {
String key = themeInfo.getKey();
if (Theme.getActiveTheme().name.equals(key) && adapter.items.get(i).chatTheme.getAccentId(themeIndex) == Theme.getActiveTheme().currentAccentId) {
selectedPosition = i;
break;
}
}
}
if (selectedPosition == -1) {
if (selectedPosition == -1 && currentType != ThemeActivity.THEME_TYPE_THEMES_BROWSER) {
selectedPosition = adapter.items.size() - 1;
}
for (int i = 0; i < adapter.items.size(); i++) {
adapter.items.get(i).isSelected = i == selectedPosition;
}
adapter.setSelectedItem(selectedPosition);
}
@ -300,7 +366,7 @@ public class DefaultThemesPreviewCell extends LinearLayout {
}
Theme.setCurrentNightTheme(themeInfo);
} else {
if (themeInfo == Theme.getCurrentTheme()) {
if (themeInfo == Theme.getActiveTheme()) {
return;
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.needSetDayNightTheme, themeInfo, false, null, -1);
@ -318,10 +384,7 @@ public class DefaultThemesPreviewCell extends LinearLayout {
public void updateColors() {
if (currentType == ThemeActivity.THEME_TYPE_BASIC) {
darkThemeDrawable.setLayerColor("Sunny.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
darkThemeDrawable.setLayerColor("Path.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
darkThemeDrawable.setLayerColor("Path 10.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
darkThemeDrawable.setLayerColor("Path 11.**", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
darkThemeDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4), PorterDuff.Mode.SRC_IN));
dayNightCell.setBackground(Theme.createSelectorWithBackgroundDrawable(Theme.getColor(Theme.key_windowBackgroundWhite), Theme.getColor(Theme.key_listSelector)));
browseThemesCell.setBackground(Theme.createSelectorWithBackgroundDrawable(Theme.getColor(Theme.key_windowBackgroundWhite), Theme.getColor(Theme.key_listSelector)));

View file

@ -337,6 +337,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
private boolean allowSwitchAccount;
private boolean checkCanWrite;
private boolean afterSignup;
private boolean showSetPasswordConfirm;
private int otherwiseReloginDays;
private FrameLayout updateLayout;
private AnimatorSet updateLayoutAnimator;
@ -1191,7 +1193,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
@Override
protected void dispatchDraw(Canvas canvas) {
parentPage.recyclerItemsEnterAnimator.dispatchDraw();
super.dispatchDraw(canvas);
if (drawMovingViewsOverlayed()) {
paint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite));
@ -1233,9 +1234,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (parentPage != null && parentPage.recyclerItemsEnterAnimator != null) {
parentPage.recyclerItemsEnterAnimator.onDetached();
}
}
@Override
@ -1784,6 +1782,8 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
messagesCount = arguments.getInt("messagesCount", 0);
hasPoll = arguments.getInt("hasPoll", 0);
hasInvoice = arguments.getBoolean("hasInvoice", false);
showSetPasswordConfirm = arguments.getBoolean("showSetPasswordConfirm", showSetPasswordConfirm);
otherwiseReloginDays = arguments.getInt("otherwiseRelogin");
}
if (initialDialogsType == 0) {
@ -4155,6 +4155,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
AndroidUtilities.requestAdjustResize(getParentActivity(), classGuid);
}
updateVisibleRows(0, false);
}
@Override

View file

@ -23,6 +23,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
@ -66,6 +67,8 @@ import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.exoplayer2.util.Log;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
@ -113,6 +116,7 @@ import org.telegram.ui.Components.VerticalPositionAutoAnimator;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -126,8 +130,13 @@ import java.util.TimerTask;
@SuppressLint("HardwareIds")
public class LoginActivity extends BaseFragment {
public final static int AUTH_TYPE_SMS = 2;
public final static int AUTH_TYPE_FLASH_CALL = 3;
public final static int AUTH_TYPE_CALL = 4;
public final static int AUTH_TYPE_MISSED_CALL = 11;
private int currentViewNum;
private SlideView[] views = new SlideView[11];
private SlideView[] views = new SlideView[12];
private boolean restoringState;
@ -331,6 +340,7 @@ public class LoginActivity extends BaseFragment {
views[8] = new LoginActivityResetWaitView(context);
views[9] = new LoginActivityNewPasswordView(context, 0);
views[10] = new LoginActivityNewPasswordView(context, 1);
views[11] = new LoginActivitySmsView(context, 11);
for (int a = 0; a < views.length; a++) {
views[a].setVisibility(a == 0 ? View.VISIBLE : View.GONE);
@ -486,7 +496,7 @@ public class LoginActivity extends BaseFragment {
if (requestCode == 6) {
checkPermissions = false;
if (currentViewNum == 0) {
views[currentViewNum].onNextPressed();
views[currentViewNum].onNextPressed(null);
}
} else if (requestCode == 7) {
checkShowPermissions = false;
@ -599,7 +609,7 @@ public class LoginActivity extends BaseFragment {
} else if (currentViewNum == 7 || currentViewNum == 8) {
views[currentViewNum].onBackPressed(true);
setPage(6, true, null, true);
} else if (currentViewNum >= 1 && currentViewNum <= 4) {
} else if ((currentViewNum >= 1 && currentViewNum <= 4) || currentViewNum == AUTH_TYPE_MISSED_CALL) {
if (views[currentViewNum].onBackPressed(false)) {
setPage(0, true, null, true);
}
@ -608,7 +618,7 @@ public class LoginActivity extends BaseFragment {
} else if (currentViewNum == 9) {
views[currentViewNum].onBackPressed(true);
setPage(7, true, null, true);
} else if (currentViewNum == 10 || currentViewNum == 11) {
} else if (currentViewNum == 10) {
views[currentViewNum].onBackPressed(true);
setPage(9, true, null, true);
}
@ -664,7 +674,7 @@ public class LoginActivity extends BaseFragment {
Intent mailer = new Intent(Intent.ACTION_SENDTO);
mailer.setData(Uri.parse("mailto:"));
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"login@stel.com"});
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{banned ? "recover@telegram.org" : "login@stel.com"});
if (banned) {
mailer.putExtra(Intent.EXTRA_SUBJECT, "Banned phone number: " + phoneNumber);
mailer.putExtra(Intent.EXTRA_TEXT, "I'm trying to use my mobile phone number: " + phoneNumber + "\nBut Telegram says it's banned. Please help.\n\nApp version: " + version + "\nOS version: SDK " + Build.VERSION.SDK_INT + "\nDevice Name: " + Build.MANUFACTURER + Build.MODEL + "\nLocale: " + Locale.getDefault());
@ -798,10 +808,10 @@ public class LoginActivity extends BaseFragment {
});
showDialog(builder.create());
} else {
views[currentViewNum].onNextPressed();
views[currentViewNum].onNextPressed(null);
}
}
private void showEditDoneProgress(final boolean show, boolean animated) {
if (doneItemAnimation != null) {
doneItemAnimation.cancel();
@ -1039,7 +1049,7 @@ public class LoginActivity extends BaseFragment {
}
}
private void needFinishActivity(boolean afterSignup) {
private void needFinishActivity(boolean afterSignup, boolean showSetPasswordConfirm, int otherwiseRelogin) {
clearCurrentState();
if (getParentActivity() instanceof LaunchActivity) {
if (newAccount) {
@ -1047,9 +1057,18 @@ public class LoginActivity extends BaseFragment {
((LaunchActivity) getParentActivity()).switchToAccount(currentAccount, false);
finishFragment();
} else {
final Bundle args = new Bundle();
args.putBoolean("afterSignup", afterSignup);
presentFragment(new DialogsActivity(args), true);
if (afterSignup && showSetPasswordConfirm) {
TwoStepVerificationSetupActivity twoStepVerification = new TwoStepVerificationSetupActivity(TwoStepVerificationSetupActivity.TYPE_INTRO, null);
twoStepVerification.setBlockingAlert(otherwiseRelogin);
presentFragment(twoStepVerification, true);
} else {
final Bundle args = new Bundle();
args.putBoolean("afterSignup", afterSignup);
DialogsActivity dialogsActivity = new DialogsActivity(args);
presentFragment(dialogsActivity, true);
}
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.mainUserInfoChanged);
}
} else if (getParentActivity() instanceof ExternalActionActivity) {
@ -1076,17 +1095,19 @@ public class LoginActivity extends BaseFragment {
ContactsController.getInstance(currentAccount).checkAppAccount();
MessagesController.getInstance(currentAccount).checkPromoInfo(true);
ConnectionsManager.getInstance(currentAccount).updateDcSettings();
needFinishActivity(afterSignup);
needFinishActivity(afterSignup, res.setup_password_required, res.otherwise_relogin_days);
}
private void fillNextCodeParams(Bundle params, TLRPC.TL_auth_sentCode res) {
params.putString("phoneHash", res.phone_code_hash);
if (res.next_type instanceof TLRPC.TL_auth_codeTypeCall) {
params.putInt("nextType", 4);
params.putInt("nextType", AUTH_TYPE_CALL);
} else if (res.next_type instanceof TLRPC.TL_auth_codeTypeFlashCall) {
params.putInt("nextType", 3);
params.putInt("nextType", AUTH_TYPE_FLASH_CALL);
} else if (res.next_type instanceof TLRPC.TL_auth_codeTypeSms) {
params.putInt("nextType", 2);
params.putInt("nextType", AUTH_TYPE_SMS);
} else if (res.next_type instanceof TLRPC.TL_auth_codeTypeMissedCall) {
params.putInt("nextType", AUTH_TYPE_MISSED_CALL);
}
if (res.type instanceof TLRPC.TL_auth_sentCodeTypeApp) {
params.putInt("type", 1);
@ -1109,6 +1130,11 @@ public class LoginActivity extends BaseFragment {
params.putInt("type", 2);
params.putInt("length", res.type.length);
setPage(2, true, params, false);
} else if (res.type instanceof TLRPC.TL_auth_sentCodeTypeMissedCall) {
params.putInt("type", AUTH_TYPE_MISSED_CALL);
params.putInt("length", res.type.length);
params.putString("prefix", res.type.prefix);
setPage(AUTH_TYPE_MISSED_CALL, true, params, false);
}
}
}
@ -1271,6 +1297,18 @@ public class LoginActivity extends BaseFragment {
});
phoneField = new HintEditText(context) {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL && phoneField.length() == 0) {
codeField.requestFocus();
codeField.setSelection(codeField.length());
codeField.dispatchKeyEvent(event);
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
@ -1371,16 +1409,7 @@ public class LoginActivity extends BaseFragment {
});
phoneField.setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
return true;
}
return false;
});
phoneField.setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_DEL && phoneField.length() == 0) {
codeField.requestFocus();
codeField.setSelection(codeField.length());
codeField.dispatchKeyEvent(event);
onNextPressed(null);
return true;
}
return false;
@ -1582,7 +1611,7 @@ public class LoginActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (getParentActivity() == null || nextPressed) {
return;
}
@ -1623,15 +1652,20 @@ public class LoginActivity extends BaseFragment {
if (preferences.getBoolean("firstlogin", true) || getParentActivity().shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE) || getParentActivity().shouldShowRequestPermissionRationale(Manifest.permission.READ_CALL_LOG)) {
preferences.edit().putBoolean("firstlogin", false).commit();
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.setPositiveButton(LocaleController.getString("Contin", R.string.Continue), null);
int resId;
if (!allowCall && (!allowCancelCall || !allowReadCallLog)) {
builder.setMessage(LocaleController.getString("AllowReadCallAndLog", R.string.AllowReadCallAndLog));
resId = R.raw.calls_log;
} else if (!allowCancelCall || !allowReadCallLog) {
builder.setMessage(LocaleController.getString("AllowReadCallLog", R.string.AllowReadCallLog));
resId = R.raw.calls_log;
} else {
builder.setMessage(LocaleController.getString("AllowReadCall", R.string.AllowReadCall));
resId = R.raw.incoming_calls;
}
builder.setTopAnimation(resId, 46, false, Theme.getColor(Theme.key_dialogTopBackground));
permissionsDialog = showDialog(builder.create());
} else {
try {
@ -1700,7 +1734,21 @@ public class LoginActivity extends BaseFragment {
req.phone_number = phone;
req.settings = new TLRPC.TL_codeSettings();
req.settings.allow_flashcall = simcardAvailable && allowCall && allowCancelCall && allowReadCallLog;
req.settings.allow_missed_call = simcardAvailable && allowCall;
req.settings.allow_app_hash = ApplicationLoader.hasPlayServices;
ArrayList<TLRPC.TL_auth_loggedOut> tokens = MessagesController.getSavedLogOutTokens();
if (tokens != null) {
for (int i = 0; i < tokens.size(); i++) {
if (req.settings.logout_tokens == null) {
req.settings.logout_tokens = new ArrayList<>();
}
req.settings.logout_tokens.add(tokens.get(i).future_auth_token);
}
MessagesController.saveLogOutTokens(tokens);
}
if (req.settings.logout_tokens != null) {
req.settings.flags |= 64;
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
if (req.settings.allow_app_hash) {
preferences.edit().putString("sms_hash", BuildVars.SMS_HASH).commit();
@ -1743,7 +1791,27 @@ public class LoginActivity extends BaseFragment {
fillNextCodeParams(params, (TLRPC.TL_auth_sentCode) response);
} else {
if (error.text != null) {
if (error.text.contains("PHONE_NUMBER_INVALID")) {
if (error.text.contains("SESSION_PASSWORD_NEEDED")) {
TLRPC.TL_account_getPassword req2 = new TLRPC.TL_account_getPassword();
ConnectionsManager.getInstance(currentAccount).sendRequest(req2, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> {
nextPressed = false;
showDoneButton(false, true);
if (error1 == null) {
TLRPC.TL_account_password password = (TLRPC.TL_account_password) response1;
if (!TwoStepVerificationActivity.canHandleCurrentPassword(password, true)) {
AlertsCreator.showUpdateAppAlert(getParentActivity(), LocaleController.getString("UpdateAppAlert", R.string.UpdateAppAlert), true);
return;
}
Bundle bundle = new Bundle();
SerializedData data = new SerializedData(password.getObjectSize());
password.serializeToStream(data);
bundle.putString("password", Utilities.bytesToHex(data.toByteArray()));
setPage(6, true, bundle, false);
} else {
needShowAlert(LocaleController.getString("AppName", R.string.AppName), error1.text);
}
}), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin);
} else if (error.text.contains("PHONE_NUMBER_INVALID")) {
needShowInvalidAlert(LoginActivity.this, req.phone_number, false);
} else if (error.text.contains("PHONE_PASSWORD_FLOOD")) {
needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("FloodWait", R.string.FloodWait));
@ -1776,20 +1844,28 @@ public class LoginActivity extends BaseFragment {
TelephonyManager tm = (TelephonyManager) ApplicationLoader.applicationContext.getSystemService(Context.TELEPHONY_SERVICE);
if (tm.getSimState() != TelephonyManager.SIM_STATE_ABSENT && tm.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE) {
boolean allowCall = true;
boolean allowReadPhoneNumbers = true;
if (Build.VERSION.SDK_INT >= 23) {
allowCall = getParentActivity().checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
if (checkShowPermissions && !allowCall) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
allowReadPhoneNumbers = getParentActivity().checkSelfPermission(Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED;
}
if (checkShowPermissions && (!allowCall || !allowReadPhoneNumbers)) {
permissionsShowItems.clear();
if (!allowCall) {
permissionsShowItems.add(Manifest.permission.READ_PHONE_STATE);
}
if (!allowReadPhoneNumbers) {
permissionsShowItems.add(Manifest.permission.READ_PHONE_NUMBERS);
}
if (!permissionsShowItems.isEmpty()) {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
if (preferences.getBoolean("firstloginshow", true) || getParentActivity().shouldShowRequestPermissionRationale(Manifest.permission.READ_PHONE_STATE)) {
preferences.edit().putBoolean("firstloginshow", false).commit();
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.setTopAnimation(R.raw.incoming_calls, 46, false, Theme.getColor(Theme.key_dialogTopBackground));
builder.setPositiveButton(LocaleController.getString("Continue", R.string.Continue), null);
builder.setMessage(LocaleController.getString("AllowFillNumber", R.string.AllowFillNumber));
permissionsShowDialog = showDialog(builder.create());
needRequestPermissions = true;
@ -1801,7 +1877,7 @@ public class LoginActivity extends BaseFragment {
}
}
numberFilled = true;
if (!newAccount && allowCall) {
if (!newAccount && allowCall && allowReadPhoneNumbers) {
String number = PhoneFormat.stripExceptNumbers(tm.getLine1Number());
String textToSet = null;
boolean ok = false;
@ -1897,8 +1973,7 @@ public class LoginActivity extends BaseFragment {
private String phoneHash;
private String requestPhone;
private String emailPhone;
private LinearLayout codeFieldContainer;
private EditTextBoldCursor[] codeField;
private CodeFieldContainer codeFieldContainer;
private TextView confirmTextView;
private TextView titleTextView;
private ImageView blackImageView;
@ -1907,6 +1982,7 @@ public class LoginActivity extends BaseFragment {
private TextView problemText;
private Bundle currentParams;
private ProgressView progressView;
private TextView prefixTextView;
RLottieDrawable hintDrawable;
@ -1925,6 +2001,7 @@ public class LoginActivity extends BaseFragment {
private int currentType;
private int nextType;
private String pattern = "*";
private String prefix = "";
private String catchedPhone;
private int length;
@ -1947,7 +2024,65 @@ public class LoginActivity extends BaseFragment {
titleTextView.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
titleTextView.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
if (currentType == 3) {
if (currentType == AUTH_TYPE_MISSED_CALL) {
titleTextView.setText(LocaleController.getString("MissedCallDescriptionTitle", R.string.MissedCallDescriptionTitle));
FrameLayout frameLayout = new FrameLayout(context);
ImageView iconView1 = new ImageView(context);
ImageView iconView2 = new ImageView(context);
frameLayout.addView(iconView1);
frameLayout.addView(iconView2);
iconView1.setImageResource(R.drawable.login_arrow1);
iconView1.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteInputFieldActivated), PorterDuff.Mode.SRC_IN));
iconView2.setImageResource(R.drawable.login_phone1);
iconView2.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText), PorterDuff.Mode.SRC_IN));
addView(frameLayout, LayoutHelper.createLinear(64, 64, Gravity.CENTER_HORIZONTAL, 0, 0, 0, 0));
addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 8, 0, 0));
TextView subtitleTextView2 = new TextView(context);
subtitleTextView2.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
subtitleTextView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
subtitleTextView2.setGravity(Gravity.CENTER_HORIZONTAL);
subtitleTextView2.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
subtitleTextView2.setText(AndroidUtilities.replaceTags(LocaleController.getString("MissedCallDescriptionSubtitle", R.string.MissedCallDescriptionSubtitle)));
addView(subtitleTextView2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 36, 16, 36, 0));
codeFieldContainer = new CodeFieldContainer(context) {
@Override
protected void processNextPressed() {
onNextPressed(null);
}
};
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
prefixTextView = new TextView(context);
prefixTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
prefixTextView.setMaxLines(1);
prefixTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
prefixTextView.setPadding(0, 0, 0, 0);
prefixTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
prefixTextView.setGravity(Gravity.CENTER_VERTICAL);
linearLayout.addView(prefixTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER_VERTICAL, 0, 0, 4, 0));
linearLayout.addView(codeFieldContainer, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 34, Gravity.CENTER_HORIZONTAL, 0, 28, 0, 0));
subtitleTextView2 = new TextView(context);
subtitleTextView2.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
subtitleTextView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
subtitleTextView2.setGravity(Gravity.CENTER_HORIZONTAL);
subtitleTextView2.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
subtitleTextView2.setText(AndroidUtilities.replaceTags(LocaleController.getString("MissedCallDescriptionSubtitle2", R.string.MissedCallDescriptionSubtitle2)));
addView(subtitleTextView2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 36, 28, 36, 12));
} else if (currentType == 3) {
confirmTextView.setGravity(Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT));
FrameLayout frameLayout = new FrameLayout(context);
addView(frameLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT));
@ -1991,10 +2126,16 @@ public class LoginActivity extends BaseFragment {
addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 18, 0, 0));
addView(confirmTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 17, 0, 0));
}
if (currentType != AUTH_TYPE_MISSED_CALL) {
codeFieldContainer = new CodeFieldContainer(context) {
@Override
protected void processNextPressed() {
onNextPressed(null);
}
};
codeFieldContainer = new LinearLayout(context);
codeFieldContainer.setOrientation(HORIZONTAL);
addView(codeFieldContainer, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 36, Gravity.CENTER_HORIZONTAL));
addView(codeFieldContainer, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 42, Gravity.CENTER_HORIZONTAL));
}
if (currentType == 3) {
codeFieldContainer.setVisibility(GONE);
}
@ -2033,7 +2174,11 @@ public class LoginActivity extends BaseFragment {
problemText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
problemText.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
if (currentType == 1) {
problemText.setText(LocaleController.getString("DidNotGetTheCodeSms", R.string.DidNotGetTheCodeSms));
if (nextType == AUTH_TYPE_FLASH_CALL || nextType == AUTH_TYPE_CALL || nextType == AUTH_TYPE_MISSED_CALL) {
problemText.setText(LocaleController.getString("DidNotGetTheCodPhone", R.string.DidNotGetTheCodePhone));
} else {
problemText.setText(LocaleController.getString("DidNotGetTheCodeSms", R.string.DidNotGetTheCodeSms));
}
} else {
problemText.setText(LocaleController.getString("DidNotGetTheCode", R.string.DidNotGetTheCode));
}
@ -2055,7 +2200,7 @@ public class LoginActivity extends BaseFragment {
Intent mailer = new Intent(Intent.ACTION_SENDTO);
mailer.setData(Uri.parse("mailto:"));
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"reports@stel.com"});
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"sms@telegram.org"});
mailer.putExtra(Intent.EXTRA_SUBJECT, "Android registration/login issue " + version + " " + emailPhone);
mailer.putExtra(Intent.EXTRA_TEXT, "Phone: " + requestPhone + "\nApp version: " + version + "\nOS version: SDK " + Build.VERSION.SDK_INT + "\nDevice Name: " + Build.MANUFACTURER + Build.MODEL + "\nLocale: " + Locale.getDefault() + "\nError: " + lastError);
getContext().startActivity(Intent.createChooser(mailer, "Send email..."));
@ -2147,12 +2292,12 @@ public class LoginActivity extends BaseFragment {
}
needHideProgress(false);
}), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin);
needShowProgress(0);
needShowProgress(reqId);
}
@Override
public String getHeaderName() {
if (currentType == 1) {
if (currentType == 1 || currentType == AUTH_TYPE_MISSED_CALL) {
return phone;
} else {
return LocaleController.getString("YourCode", R.string.YourCode);
@ -2187,103 +2332,13 @@ public class LoginActivity extends BaseFragment {
openTime = (int) (System.currentTimeMillis() / 1000);
nextType = params.getInt("nextType");
pattern = params.getString("pattern");
prefix = params.getString("prefix");
length = params.getInt("length");
if (length == 0) {
length = 5;
}
if (codeField == null || codeField.length != length) {
codeField = new EditTextBoldCursor[length];
for (int a = 0; a < length; a++) {
final int num = a;
codeField[a] = new EditTextBoldCursor(getContext());
codeField[a].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
codeField[a].setCursorColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
codeField[a].setCursorSize(AndroidUtilities.dp(20));
codeField[a].setCursorWidth(1.5f);
Drawable pressedDrawable = getResources().getDrawable(R.drawable.search_dark_activated).mutate();
pressedDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteInputFieldActivated), PorterDuff.Mode.MULTIPLY));
codeField[a].setBackgroundDrawable(pressedDrawable);
codeField[a].setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
codeField[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
codeField[a].setMaxLines(1);
codeField[a].setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
codeField[a].setPadding(0, 0, 0, 0);
codeField[a].setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
if (currentType == 3) {
codeField[a].setEnabled(false);
codeField[a].setInputType(InputType.TYPE_NULL);
codeField[a].setVisibility(GONE);
} else {
codeField[a].setInputType(InputType.TYPE_CLASS_PHONE);
}
codeFieldContainer.addView(codeField[a], LayoutHelper.createLinear(34, 36, Gravity.CENTER_HORIZONTAL, 0, 0, a != length - 1 ? 7 : 0, 0));
codeField[a].addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (ignoreOnTextChange) {
return;
}
int len = s.length();
if (len >= 1) {
if (len > 1) {
String text = s.toString();
ignoreOnTextChange = true;
for (int a = 0; a < Math.min(length - num, len); a++) {
if (a == 0) {
s.replace(0, len, text.substring(a, a + 1));
} else {
codeField[num + a].setText(text.substring(a, a + 1));
}
}
ignoreOnTextChange = false;
}
if (num != length - 1) {
codeField[num + 1].setSelection(codeField[num + 1].length());
codeField[num + 1].requestFocus();
}
if ((num == length - 1 || num == length - 2 && len >= 2) && getCode().length() == length) {
onNextPressed();
}
}
}
});
codeField[a].setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_DEL && codeField[num].length() == 0 && num > 0) {
codeField[num - 1].setSelection(codeField[num - 1].length());
codeField[num - 1].requestFocus();
codeField[num - 1].dispatchKeyEvent(event);
return true;
}
return false;
});
codeField[a].setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
return true;
}
return false;
});
}
} else {
for (int a = 0; a < codeField.length; a++) {
codeField[a].setText("");
}
}
codeFieldContainer.setNumbersCount(length, currentType);
if (progressView != null) {
progressView.setVisibility(nextType != 0 ? VISIBLE : GONE);
@ -2307,10 +2362,10 @@ public class LoginActivity extends BaseFragment {
confirmTextView.setText(str);
if (currentType != 3) {
AndroidUtilities.showKeyboard(codeField[0]);
codeField[0].requestFocus();
AndroidUtilities.showKeyboard(codeFieldContainer.codeField[0]);
codeFieldContainer.codeField[0].requestFocus();
} else {
AndroidUtilities.hideKeyboard(codeField[0]);
AndroidUtilities.hideKeyboard(codeFieldContainer.codeField[0]);
}
destroyTimer();
@ -2330,15 +2385,9 @@ public class LoginActivity extends BaseFragment {
}
String callLogNumber = restore ? AndroidUtilities.obtainLoginPhoneCall(pattern) : null;
if (callLogNumber != null) {
ignoreOnTextChange = true;
codeField[0].setText(callLogNumber);
ignoreOnTextChange = false;
onNextPressed();
onNextPressed(callLogNumber);
} else if (catchedPhone != null) {
ignoreOnTextChange = true;
codeField[0].setText(catchedPhone);
ignoreOnTextChange = false;
onNextPressed();
onNextPressed(catchedPhone);
} else {
createTimer();
}
@ -2359,8 +2408,8 @@ public class LoginActivity extends BaseFragment {
}
}
if (savedCode != null) {
codeField[0].setText(savedCode);
onNextPressed();
codeFieldContainer.setCode(savedCode);
onNextPressed(null);
} else {
createTimer();
}
@ -2374,6 +2423,23 @@ public class LoginActivity extends BaseFragment {
problemText.setVisibility(GONE);
createCodeTimer();
}
if (currentType == AUTH_TYPE_MISSED_CALL) {
String pref = prefix;
for (int i = 0; i < length; i++) {
pref += "0";
}
pref = PhoneFormat.getInstance().format("+" + pref);
for (int i = 0; i < length; i++) {
int index = pref.lastIndexOf("0");
if (index >= 0) {
pref = pref.substring(0, index);
}
}
pref = pref.replaceAll("\\)", "");
pref = pref.replaceAll("\\(", "");
prefixTextView.setText(pref);
}
}
private void createCodeTimer() {
@ -2495,24 +2561,22 @@ public class LoginActivity extends BaseFragment {
}
}
private String getCode() {
if (codeField == null) {
return "";
}
StringBuilder codeBuilder = new StringBuilder();
for (int a = 0; a < codeField.length; a++) {
codeBuilder.append(PhoneFormat.stripExceptNumbers(codeField[a].getText().toString()));
}
return codeBuilder.toString();
}
@Override
public void onNextPressed() {
if (nextPressed || currentViewNum < 1 || currentViewNum > 4) {
return;
public void onNextPressed(String code) {
if (currentViewNum == AUTH_TYPE_MISSED_CALL) {
if (nextPressed) {
return;
}
} else {
if (nextPressed || currentViewNum < 1 || currentViewNum > 4) {
return;
}
}
String code = getCode();
if (code == null) {
code = codeFieldContainer.getCode();
}
if (TextUtils.isEmpty(code)) {
onFieldError(codeFieldContainer);
return;
@ -2533,6 +2597,7 @@ public class LoginActivity extends BaseFragment {
destroyTimer();
int reqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
boolean ok = false;
if (error == null) {
nextPressed = false;
ok = true;
@ -2599,10 +2664,10 @@ public class LoginActivity extends BaseFragment {
needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidPhoneNumber", R.string.InvalidPhoneNumber));
} else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) {
needShowAlert(LocaleController.getString("AppName", R.string.AppName), LocaleController.getString("InvalidCode", R.string.InvalidCode));
for (int a = 0; a < codeField.length; a++) {
codeField[a].setText("");
for (int a = 0; a < codeFieldContainer.codeField.length; a++) {
codeFieldContainer.codeField[a].setText("");
}
codeField[0].requestFocus();
codeFieldContainer.codeField[0].requestFocus();
} else if (error.text.contains("PHONE_CODE_EXPIRED")) {
onBackPressed(true);
setPage(0, true, null, true);
@ -2687,12 +2752,12 @@ public class LoginActivity extends BaseFragment {
hintDrawable.setCurrentFrame(0);
}
AndroidUtilities.runOnUIThread(() -> {
if (codeField != null) {
for (int a = codeField.length - 1; a >= 0; a--) {
if (a == 0 || codeField[a].length() != 0) {
codeField[a].requestFocus();
codeField[a].setSelection(codeField[a].length());
AndroidUtilities.showKeyboard(codeField[a]);
if (codeFieldContainer.codeField != null) {
for (int a = codeFieldContainer.codeField.length - 1; a >= 0; a--) {
if (a == 0 || codeFieldContainer.codeField[a].length() != 0) {
codeFieldContainer.codeField[a].requestFocus();
codeFieldContainer.codeField[a].setSelection(codeFieldContainer.codeField[a].length());
AndroidUtilities.showKeyboard(codeFieldContainer.codeField[a]);
break;
}
}
@ -2705,12 +2770,12 @@ public class LoginActivity extends BaseFragment {
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (!waitingForEvent || codeField == null) {
if (!waitingForEvent || codeFieldContainer.codeField == null) {
return;
}
if (id == NotificationCenter.didReceiveSmsCode) {
codeField[0].setText("" + args[0]);
onNextPressed();
codeFieldContainer.setText("" + args[0]);
onNextPressed(null);
} else if (id == NotificationCenter.didReceiveCall) {
String num = "" + args[0];
if (!AndroidUtilities.checkPhonePattern(pattern, num)) {
@ -2720,16 +2785,13 @@ public class LoginActivity extends BaseFragment {
catchedPhone = num;
AndroidUtilities.endIncomingCall();
}
ignoreOnTextChange = true;
codeField[0].setText(num);
ignoreOnTextChange = false;
onNextPressed();
onNextPressed(num);
}
}
@Override
public void saveStateParams(Bundle bundle) {
String code = getCode();
String code = codeFieldContainer.getCode();
if (code.length() != 0) {
bundle.putString("smsview_code_" + currentType, code);
}
@ -2758,8 +2820,8 @@ public class LoginActivity extends BaseFragment {
catchedPhone = catched;
}
String code = bundle.getString("smsview_code_" + currentType);
if (code != null && codeField != null) {
codeField[0].setText(code);
if (code != null && codeFieldContainer.codeField != null) {
codeFieldContainer.setText(code);
}
int t = bundle.getInt("time");
if (t != 0) {
@ -2820,7 +2882,7 @@ public class LoginActivity extends BaseFragment {
addView(codeField, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, Gravity.CENTER_HORIZONTAL, 0, 20, 0, 0));
codeField.setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -2995,7 +3057,7 @@ public class LoginActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (nextPressed) {
return;
}
@ -3030,7 +3092,7 @@ public class LoginActivity extends BaseFragment {
ConnectionsManager.getInstance(currentAccount).sendRequest(getPasswordReq, (response2, error2) -> AndroidUtilities.runOnUIThread(() -> {
if (error2 == null) {
currentPassword = (TLRPC.TL_account_password) response2;
onNextPressed();
onNextPressed(null);
}
}), ConnectionsManager.RequestFlagWithoutLogin);
return;
@ -3333,7 +3395,7 @@ public class LoginActivity extends BaseFragment {
addView(codeField, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, Gravity.CENTER_HORIZONTAL, 0, 20, 0, 0));
codeField.setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -3404,12 +3466,12 @@ public class LoginActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (nextPressed) {
return;
}
String code = codeField.getText().toString();
code = codeField.getText().toString();
if (code.length() == 0) {
onPasscodeError(false);
return;
@ -3418,12 +3480,13 @@ public class LoginActivity extends BaseFragment {
needShowProgress(0);
TLRPC.TL_auth_checkRecoveryPassword req = new TLRPC.TL_auth_checkRecoveryPassword();
req.code = code;
String finalCode = code;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
needHideProgress(false);
nextPressed = false;
if (response instanceof TLRPC.TL_boolTrue) {
Bundle params = new Bundle();
params.putString("emailCode", code);
params.putString("emailCode", finalCode);
params.putString("password", passwordString);
setPage(9, true, params, false);
} else {
@ -3542,7 +3605,7 @@ public class LoginActivity extends BaseFragment {
codeField[1].requestFocus();
return true;
} else if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -3631,12 +3694,12 @@ public class LoginActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (nextPressed) {
return;
}
String code = codeField[0].getText().toString();
code = codeField[0].getText().toString();
if (code.length() == 0) {
onPasscodeError(false, 0);
return;
@ -3824,7 +3887,7 @@ public class LoginActivity extends BaseFragment {
if (needAccept) {
builder.setPositiveButton(LocaleController.getString("Accept", R.string.Accept), (dialog, which) -> {
currentTermsOfService.popup = false;
onNextPressed();
onNextPressed(null);
});
builder.setNegativeButton(LocaleController.getString("Decline", R.string.Decline), (dialog, which) -> {
AlertDialog.Builder builder1 = new AlertDialog.Builder(getParentActivity());
@ -3832,7 +3895,7 @@ public class LoginActivity extends BaseFragment {
builder1.setMessage(LocaleController.getString("TosDecline", R.string.TosDecline));
builder1.setPositiveButton(LocaleController.getString("SignUp", R.string.SignUp), (dialog1, which1) -> {
currentTermsOfService.popup = false;
onNextPressed();
onNextPressed(null);
});
builder1.setNegativeButton(LocaleController.getString("Decline", R.string.Decline), (dialog12, which12) -> {
onBackPressed(true);
@ -4003,7 +4066,7 @@ public class LoginActivity extends BaseFragment {
editTextContainer.addView(lastNameField, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 36, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 85, 51, LocaleController.isRTL ? 85 : 0, 0));
lastNameField.setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_DONE || i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -4189,7 +4252,7 @@ public class LoginActivity extends BaseFragment {
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (nextPressed) {
return;
}
@ -4393,10 +4456,10 @@ public class LoginActivity extends BaseFragment {
arrayList.add(new ThemeDescription(smsView1.confirmTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));
arrayList.add(new ThemeDescription(smsView1.titleTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
if (smsView1.codeField != null) {
for (int a = 0; a < smsView1.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView1.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView1.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
if (smsView1.codeFieldContainer.codeField != null) {
for (int a = 0; a < smsView1.codeFieldContainer.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView1.codeFieldContainer.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView1.codeFieldContainer.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
}
}
arrayList.add(new ThemeDescription(smsView1.timeText, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));
@ -4408,10 +4471,10 @@ public class LoginActivity extends BaseFragment {
arrayList.add(new ThemeDescription(smsView2.confirmTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));
arrayList.add(new ThemeDescription(smsView2.titleTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
if (smsView2.codeField != null) {
for (int a = 0; a < smsView2.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView2.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView2.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
if (smsView2.codeFieldContainer.codeField != null) {
for (int a = 0; a < smsView2.codeFieldContainer.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView2.codeFieldContainer.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView2.codeFieldContainer.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
}
}
arrayList.add(new ThemeDescription(smsView2.timeText, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));
@ -4423,10 +4486,10 @@ public class LoginActivity extends BaseFragment {
arrayList.add(new ThemeDescription(smsView3.confirmTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));
arrayList.add(new ThemeDescription(smsView3.titleTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
if (smsView3.codeField != null) {
for (int a = 0; a < smsView3.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView3.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView3.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
if (smsView3.codeFieldContainer.codeField != null) {
for (int a = 0; a < smsView3.codeFieldContainer.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView3.codeFieldContainer.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView3.codeFieldContainer.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
}
}
arrayList.add(new ThemeDescription(smsView3.timeText, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));
@ -4438,10 +4501,10 @@ public class LoginActivity extends BaseFragment {
arrayList.add(new ThemeDescription(smsView4.confirmTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));
arrayList.add(new ThemeDescription(smsView4.titleTextView, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
if (smsView4.codeField != null) {
for (int a = 0; a < smsView4.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView4.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView4.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
if (smsView4.codeFieldContainer.codeField != null) {
for (int a = 0; a < smsView4.codeFieldContainer.codeField.length; a++) {
arrayList.add(new ThemeDescription(smsView4.codeFieldContainer.codeField[a], ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
arrayList.add(new ThemeDescription(smsView4.codeFieldContainer.codeField[a], ThemeDescription.FLAG_BACKGROUNDFILTER, null, null, null, null, Theme.key_windowBackgroundWhiteInputFieldActivated));
}
}
arrayList.add(new ThemeDescription(smsView4.timeText, ThemeDescription.FLAG_TEXTCOLOR, null, null, null, null, Theme.key_windowBackgroundWhiteGrayText6));

View file

@ -547,19 +547,7 @@ public class ManageLinksActivity extends BaseFragment {
FrameLayout frameLayout = (FrameLayout) fragmentView;
listView = new RecyclerListView(context) {
@Override
protected void dispatchDraw(Canvas canvas) {
recyclerItemsEnterAnimator.dispatchDraw();
super.dispatchDraw(canvas);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
recyclerItemsEnterAnimator.onDetached();
}
};
listView = new RecyclerListView(context);
LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) {
@Override
public boolean supportsPredictiveItemAnimations() {

View file

@ -1,642 +0,0 @@
package org.telegram.ui;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextPaint;
import android.util.Log;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DownloadController;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.SharedMediaLayout;
import java.time.DayOfWeek;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Random;
public class MediaCalendarActivity extends BaseFragment {
FrameLayout contentView;
RecyclerListView listView;
LinearLayoutManager layoutManager;
TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
TextPaint activeTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
TextPaint textPaint2 = new TextPaint(Paint.ANTI_ALIAS_FLAG);
Paint blackoutPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private long dialogId;
private boolean loading;
private boolean checkEnterItems;
int startFromYear;
int startFromMonth;
int monthCount;
CalendarAdapter adapter;
Callback callback;
SparseArray<SparseArray<PeriodDay>> messagesByYearMounth = new SparseArray<>();
boolean endReached;
int startOffset = 0;
int lastId;
int minMontYear;
private int photosVideosTypeFilter;
private boolean isOpened;
int selectedYear;
int selectedMonth;
public MediaCalendarActivity(Bundle args, int photosVideosTypeFilter, int selectedDate) {
super(args);
this.photosVideosTypeFilter = photosVideosTypeFilter;
if (selectedDate != 0) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(selectedDate * 1000L);
selectedYear = calendar.get(Calendar.YEAR);
selectedMonth = calendar.get(Calendar.MONTH);
}
}
@Override
public boolean onFragmentCreate() {
dialogId = getArguments().getLong("dialog_id");
return super.onFragmentCreate();
}
@Override
public View createView(Context context) {
textPaint.setTextSize(AndroidUtilities.dp(16));
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint2.setTextSize(AndroidUtilities.dp(11));
textPaint2.setTextAlign(Paint.Align.CENTER);
textPaint2.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
activeTextPaint.setTextSize(AndroidUtilities.dp(16));
activeTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
activeTextPaint.setTextAlign(Paint.Align.CENTER);
contentView = new FrameLayout(context);
createActionBar(context);
contentView.addView(actionBar);
actionBar.setTitle(LocaleController.getString("Calendar", R.string.Calendar));
actionBar.setCastShadows(false);
listView = new RecyclerListView(context) {
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
checkEnterItems = false;
}
};
listView.setLayoutManager(layoutManager = new LinearLayoutManager(context));
layoutManager.setReverseLayout(true);
listView.setAdapter(adapter = new CalendarAdapter());
listView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
checkLoadNext();
}
});
contentView.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 0, 36, 0, 0));
final String[] daysOfWeek = new String[]{
LocaleController.getString("CalendarWeekNameShortMonday", R.string.CalendarWeekNameShortMonday),
LocaleController.getString("CalendarWeekNameShortTuesday", R.string.CalendarWeekNameShortTuesday),
LocaleController.getString("CalendarWeekNameShortWednesday", R.string.CalendarWeekNameShortWednesday),
LocaleController.getString("CalendarWeekNameShortThursday", R.string.CalendarWeekNameShortThursday),
LocaleController.getString("CalendarWeekNameShortFriday", R.string.CalendarWeekNameShortFriday),
LocaleController.getString("CalendarWeekNameShortSaturday", R.string.CalendarWeekNameShortSaturday),
LocaleController.getString("CalendarWeekNameShortSunday", R.string.CalendarWeekNameShortSunday),
};
Drawable headerShadowDrawable = ContextCompat.getDrawable(context, R.drawable.header_shadow).mutate();
View calendarSignatureView = new View(context) {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float xStep = getMeasuredWidth() / 7f;
for (int i = 0; i < 7; i++) {
float cx = xStep * i + xStep / 2f;
float cy = (getMeasuredHeight() - AndroidUtilities.dp(2)) / 2f;
canvas.drawText(daysOfWeek[i], cx, cy + AndroidUtilities.dp(5), textPaint2);
}
headerShadowDrawable.setBounds(0, getMeasuredHeight() - AndroidUtilities.dp(3), getMeasuredWidth(), getMeasuredHeight());
headerShadowDrawable.draw(canvas);
}
};
contentView.addView(calendarSignatureView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, 0, 0, 0, 0, 0));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
}
}
});
fragmentView = contentView;
Calendar calendar = Calendar.getInstance();
startFromYear = calendar.get(Calendar.YEAR);
startFromMonth = calendar.get(Calendar.MONTH);
if (selectedYear != 0) {
monthCount = (startFromYear - selectedYear) * 12 + startFromMonth - selectedMonth + 1;
layoutManager.scrollToPositionWithOffset(monthCount - 1, AndroidUtilities.dp(120));
}
if (monthCount < 3) {
monthCount = 3;
}
loadNext();
updateColors();
activeTextPaint.setColor(Color.WHITE);
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
return fragmentView;
}
private void updateColors() {
actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
activeTextPaint.setColor(Color.WHITE);
textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
textPaint2.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
actionBar.setTitleColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText), false);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_listSelector), false);
}
private void loadNext() {
if (loading || endReached) {
return;
}
loading = true;
TLRPC.TL_messages_getSearchResultsCalendar req = new TLRPC.TL_messages_getSearchResultsCalendar();
if (photosVideosTypeFilter == SharedMediaLayout.FILTER_PHOTOS_ONLY) {
req.filter = new TLRPC.TL_inputMessagesFilterPhotos();
} else if (photosVideosTypeFilter == SharedMediaLayout.FILTER_VIDEOS_ONLY) {
req.filter = new TLRPC.TL_inputMessagesFilterVideo();
} else {
req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo();
}
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
req.offset_id = lastId;
Calendar calendar = Calendar.getInstance();
listView.setItemAnimator(null);
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (error == null) {
TLRPC.TL_messages_searchResultsCalendar res = (TLRPC.TL_messages_searchResultsCalendar) response;
for (int i = 0; i < res.periods.size(); i++) {
TLRPC.TL_searchResultsCalendarPeriod period = res.periods.get(i);
calendar.setTimeInMillis(period.date * 1000L);
int month = calendar.get(Calendar.YEAR) * 100 + calendar.get(Calendar.MONTH);
SparseArray<PeriodDay> messagesByDays = messagesByYearMounth.get(month);
if (messagesByDays == null) {
messagesByDays = new SparseArray<>();
messagesByYearMounth.put(month, messagesByDays);
}
PeriodDay periodDay = new PeriodDay();
MessageObject messageObject = new MessageObject(currentAccount, res.messages.get(i), false, false);
periodDay.messageObject = messageObject;
startOffset += res.periods.get(i).count;
periodDay.startOffset = startOffset;
int index = calendar.get(Calendar.DAY_OF_MONTH) - 1;
if (messagesByDays.get(index, null) == null) {
messagesByDays.put(index, periodDay);
}
if (month < minMontYear || minMontYear == 0) {
minMontYear = month;
}
}
loading = false;
if (!res.messages.isEmpty()) {
lastId = res.messages.get(res.messages.size() - 1).id;
endReached = false;
checkLoadNext();
} else {
endReached = true;
}
if (isOpened) {
checkEnterItems = true;
}
listView.invalidate();
int newMonthCount = (int) (((calendar.getTimeInMillis() / 1000) - res.min_date) / 2629800) + 1;
adapter.notifyItemRangeChanged(0, monthCount);
if (newMonthCount > monthCount) {
adapter.notifyItemRangeInserted(monthCount + 1, newMonthCount);
monthCount = newMonthCount;
}
if (endReached) {
resumeDelayedFragmentAnimation();
}
}
}));
}
private void checkLoadNext() {
if (loading || endReached) {
return;
}
int listMinMonth = Integer.MAX_VALUE;
for (int i = 0; i < listView.getChildCount(); i++) {
View child = listView.getChildAt(i);
if (child instanceof MonthView) {
int currentMonth = ((MonthView) child).currentYear * 100 + ((MonthView) child).currentMonthInYear;
if (currentMonth < listMinMonth) {
listMinMonth = currentMonth;
}
}
};
int min1 = (minMontYear / 100 * 12) + minMontYear % 100;
int min2 = (listMinMonth / 100 * 12) + listMinMonth % 100;
if (min1 + 3 >= min2) {
loadNext();
}
}
private class CalendarAdapter extends RecyclerView.Adapter {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new RecyclerListView.Holder(new MonthView(parent.getContext()));
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
MonthView monthView = (MonthView) holder.itemView;
int year = startFromYear - position / 12;
int month = startFromMonth - position % 12;
if (month < 0) {
month += 12;
year--;
}
boolean animated = monthView.currentYear == year && monthView.currentMonthInYear == month;
monthView.setDate(year, month, messagesByYearMounth.get(year * 100 + month), animated);
}
@Override
public long getItemId(int position) {
int year = startFromYear - position / 12;
int month = startFromMonth - position % 12;
return year * 100L + month;
}
@Override
public int getItemCount() {
return monthCount;
}
}
private class MonthView extends FrameLayout {
SimpleTextView titleView;
int currentYear;
int currentMonthInYear;
int daysInMonth;
int startDayOfWeek;
int cellCount;
int startMonthTime;
SparseArray<PeriodDay> messagesByDays = new SparseArray<>();
SparseArray<ImageReceiver> imagesByDays = new SparseArray<>();
SparseArray<PeriodDay> animatedFromMessagesByDays = new SparseArray<>();
SparseArray<ImageReceiver> animatedFromImagesByDays = new SparseArray<>();
boolean attached;
float animationProgress = 1f;
public MonthView(Context context) {
super(context);
setWillNotDraw(false);
titleView = new SimpleTextView(context);
titleView.setTextSize(15);
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleView.setGravity(Gravity.CENTER);
titleView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 28, 0, 0, 12, 0, 4));
}
public void setDate(int year, int monthInYear, SparseArray<PeriodDay> messagesByDays, boolean animated) {
boolean dateChanged = year != currentYear && monthInYear != currentMonthInYear;
currentYear = year;
currentMonthInYear = monthInYear;
this.messagesByDays = messagesByDays;
if (dateChanged) {
if (imagesByDays != null) {
for (int i = 0; i < imagesByDays.size(); i++) {
imagesByDays.valueAt(i).onDetachedFromWindow();
imagesByDays.valueAt(i).setParentView(null);
}
imagesByDays = null;
}
}
if (messagesByDays != null) {
if (imagesByDays == null) {
imagesByDays = new SparseArray<>();
}
for (int i = 0; i < messagesByDays.size(); i++) {
int key = messagesByDays.keyAt(i);
if (imagesByDays.get(key, null) != null) {
continue;
}
ImageReceiver receiver = new ImageReceiver();
receiver.setParentView(this);
PeriodDay periodDay = messagesByDays.get(key);
MessageObject messageObject = periodDay.messageObject;
if (messageObject != null) {
if (messageObject.isVideo()) {
TLRPC.Document document = messageObject.getDocument();
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 50);
TLRPC.PhotoSize qualityThumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 320);
if (thumb == qualityThumb) {
qualityThumb = null;
}
if (thumb != null) {
if (messageObject.strippedThumb != null) {
receiver.setImage(ImageLocation.getForDocument(qualityThumb, document), "44_44", messageObject.strippedThumb, null, messageObject, 0);
} else {
receiver.setImage(ImageLocation.getForDocument(qualityThumb, document), "44_44", ImageLocation.getForDocument(thumb, document), "b", (String) null, messageObject, 0);
}
}
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageObject.messageOwner.media.photo != null && !messageObject.photoThumbs.isEmpty()) {
TLRPC.PhotoSize currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 50);
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 320, false, currentPhotoObjectThumb, false);
if (messageObject.mediaExists || DownloadController.getInstance(currentAccount).canDownloadMedia(messageObject)) {
if (currentPhotoObject == currentPhotoObjectThumb) {
currentPhotoObjectThumb = null;
}
if (messageObject.strippedThumb != null) {
receiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), "44_44", null, null, messageObject.strippedThumb, currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
} else {
receiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), "44_44", ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), "b", currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
}
} else {
if (messageObject.strippedThumb != null) {
receiver.setImage(null, null, messageObject.strippedThumb, null, messageObject, 0);
} else {
receiver.setImage(null, null, ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), "b", (String) null, messageObject, 0);
}
}
}
receiver.setRoundRadius(AndroidUtilities.dp(22));
imagesByDays.put(key, receiver);
}
}
}
YearMonth yearMonthObject = YearMonth.of(year, monthInYear + 1);
daysInMonth = yearMonthObject.lengthOfMonth();
Calendar calendar = Calendar.getInstance();
calendar.set(year, monthInYear, 0);
startDayOfWeek = (calendar.get(Calendar.DAY_OF_WEEK) + 6) % 7;
startMonthTime= (int) (calendar.getTimeInMillis() / 1000L);
int totalColumns = daysInMonth + startDayOfWeek;
cellCount = (int) (totalColumns / 7f) + (totalColumns % 7 == 0 ? 0 : 1);
calendar.set(year, monthInYear + 1, 0);
titleView.setText(LocaleController.formatYearMont(calendar.getTimeInMillis() / 1000, true));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(cellCount * (44 + 8) + 44), MeasureSpec.EXACTLY));
}
boolean pressed;
float pressedX;
float pressedY;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressed = true;
pressedX = event.getX();
pressedY = event.getY();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (pressed) {
for (int i = 0; i < imagesByDays.size(); i++) {
if (imagesByDays.valueAt(i).getDrawRegion().contains(pressedX, pressedY)) {
if (callback != null) {
PeriodDay periodDay = messagesByDays.valueAt(i);
callback.onDateSelected(periodDay.messageObject.getId(), periodDay.startOffset);
finishFragment();
break;
}
}
}
}
pressed = false;
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
pressed = false;
}
return pressed;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int currentCell = 0;
int currentColumn = startDayOfWeek;
float xStep = getMeasuredWidth() / 7f;
float yStep = AndroidUtilities.dp(44 + 8);
for (int i = 0; i < daysInMonth; i++) {
float cx = xStep * currentColumn + xStep / 2f;
float cy = yStep * currentCell + yStep / 2f + AndroidUtilities.dp(44);
int nowTime = (int) (System.currentTimeMillis() / 1000L);
if (nowTime < startMonthTime + (i + 1) * 86400) {
int oldAlpha = textPaint.getAlpha();
textPaint.setAlpha((int) (oldAlpha * 0.3f));
canvas.drawText(Integer.toString(i + 1), cx, cy + AndroidUtilities.dp(5), textPaint);
textPaint.setAlpha(oldAlpha);
} else if (messagesByDays != null && messagesByDays.get(i, null) != null) {
float alpha = 1f;
if (imagesByDays.get(i) != null) {
if (checkEnterItems && !messagesByDays.get(i).wasDrawn) {
messagesByDays.get(i).enterAlpha = 0f;
messagesByDays.get(i).startEnterDelay = (cy + getY()) / listView.getMeasuredHeight() * 150;
}
if (messagesByDays.get(i).startEnterDelay > 0) {
messagesByDays.get(i).startEnterDelay -= 16;
if (messagesByDays.get(i).startEnterDelay < 0) {
messagesByDays.get(i).startEnterDelay = 0;
} else {
invalidate();
}
}
if (messagesByDays.get(i).startEnterDelay == 0 && messagesByDays.get(i).enterAlpha != 1f) {
messagesByDays.get(i).enterAlpha += 16 / 220f;
if (messagesByDays.get(i).enterAlpha > 1f) {
messagesByDays.get(i).enterAlpha = 1f;
} else {
invalidate();
}
}
alpha = messagesByDays.get(i).enterAlpha;
if (alpha != 1f) {
canvas.save();
float s = 0.8f + 0.2f * alpha;
canvas.scale(s, s,cx, cy);
}
imagesByDays.get(i).setAlpha(messagesByDays.get(i).enterAlpha);
imagesByDays.get(i).setImageCoords(cx - AndroidUtilities.dp(44) / 2f, cy - AndroidUtilities.dp(44) / 2f, AndroidUtilities.dp(44), AndroidUtilities.dp(44));
imagesByDays.get(i).draw(canvas);
blackoutPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (messagesByDays.get(i).enterAlpha * 80)));
canvas.drawCircle(cx, cy, AndroidUtilities.dp(44) / 2f, blackoutPaint);
messagesByDays.get(i).wasDrawn = true;
if (alpha != 1f) {
canvas.restore();
}
}
if (alpha != 1f) {
int oldAlpha = textPaint.getAlpha();
textPaint.setAlpha((int) (oldAlpha * (1f - alpha)));
canvas.drawText(Integer.toString(i + 1), cx, cy + AndroidUtilities.dp(5), textPaint);
textPaint.setAlpha(oldAlpha);
oldAlpha = textPaint.getAlpha();
activeTextPaint.setAlpha((int) (oldAlpha * alpha));
canvas.drawText(Integer.toString(i + 1), cx, cy + AndroidUtilities.dp(5), activeTextPaint);
activeTextPaint.setAlpha(oldAlpha);
} else {
canvas.drawText(Integer.toString(i + 1), cx, cy + AndroidUtilities.dp(5), activeTextPaint);
}
} else {
canvas.drawText(Integer.toString(i + 1), cx, cy + AndroidUtilities.dp(5), textPaint);
}
currentColumn++;
if (currentColumn >= 7) {
currentColumn = 0;
currentCell++;
}
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
attached = true;
if (imagesByDays != null) {
for (int i = 0; i < imagesByDays.size(); i++) {
imagesByDays.valueAt(i).onAttachedToWindow();
}
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
attached = false;
if (imagesByDays != null) {
for (int i = 0; i < imagesByDays.size(); i++) {
imagesByDays.valueAt(i).onDetachedFromWindow();
}
}
}
}
public void setCallback(Callback callback) {
this.callback = callback;
}
public interface Callback {
void onDateSelected(int messageId, int startOffset);
}
private class PeriodDay {
MessageObject messageObject;
int startOffset;
float enterAlpha = 1f;
float startEnterDelay = 1f;
boolean wasDrawn;
}
@Override
public ArrayList<ThemeDescription> getThemeDescriptions() {
ThemeDescription.ThemeDescriptionDelegate descriptionDelegate = new ThemeDescription.ThemeDescriptionDelegate() {
@Override
public void didSetColor() {
updateColors();
}
};
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
new ThemeDescription(null, 0, null, null, null, descriptionDelegate, Theme.key_windowBackgroundWhite);
new ThemeDescription(null, 0, null, null, null, descriptionDelegate, Theme.key_windowBackgroundWhiteBlackText);
new ThemeDescription(null, 0, null, null, null, descriptionDelegate, Theme.key_listSelector);
return super.getThemeDescriptions();
}
@Override
public boolean needDelayOpenAnimation() {
return true;
}
@Override
protected void onTransitionAnimationStart(boolean isOpen, boolean backward) {
super.onTransitionAnimationStart(isOpen, backward);
isOpened = true;
}
}

View file

@ -1145,7 +1145,7 @@ public class PassportActivity extends BaseFragment implements NotificationCenter
return;
}
if (currentActivityType == TYPE_PHONE_VERIFICATION) {
views[currentViewNum].onNextPressed();
views[currentViewNum].onNextPressed(null);
} else {
final Runnable finishRunnable = () -> finishFragment();
final ErrorRunnable errorRunnable = new ErrorRunnable() {
@ -7385,7 +7385,7 @@ public class PassportActivity extends BaseFragment implements NotificationCenter
Intent mailer = new Intent(Intent.ACTION_SENDTO);
mailer.setData(Uri.parse("mailto:"));
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"reports@stel.com"});
mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"sms@telegram.org"});
mailer.putExtra(Intent.EXTRA_SUBJECT, "Android registration/login issue " + version + " " + phone);
mailer.putExtra(Intent.EXTRA_TEXT, "Phone: " + phone + "\nApp version: " + version + "\nOS version: SDK " + Build.VERSION.SDK_INT + "\nDevice Name: " + Build.MANUFACTURER + Build.MODEL + "\nLocale: " + Locale.getDefault() + "\nError: " + lastError);
getContext().startActivity(Intent.createChooser(mailer, "Send email..."));
@ -7565,7 +7565,7 @@ public class PassportActivity extends BaseFragment implements NotificationCenter
codeField[num + 1].requestFocus();
}
if ((num == length - 1 || num == length - 2 && len >= 2) && getCode().length() == length) {
onNextPressed();
onNextPressed(null);
}
}
}
@ -7581,7 +7581,7 @@ public class PassportActivity extends BaseFragment implements NotificationCenter
});
codeField[a].setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_NEXT) {
onNextPressed();
onNextPressed(null);
return true;
}
return false;
@ -7780,11 +7780,13 @@ public class PassportActivity extends BaseFragment implements NotificationCenter
}
@Override
public void onNextPressed() {
public void onNextPressed(String code) {
if (nextPressed) {
return;
}
String code = getCode();
if (code == null) {
code = getCode();
}
if (TextUtils.isEmpty(code)) {
AndroidUtilities.shakeView(codeFieldContainer, 2, 0);
return;
@ -7915,7 +7917,7 @@ public class PassportActivity extends BaseFragment implements NotificationCenter
}
if (id == NotificationCenter.didReceiveSmsCode) {
codeField[0].setText("" + args[0]);
onNextPressed();
onNextPressed(null);
} else if (id == NotificationCenter.didReceiveCall) {
String num = "" + args[0];
if (!AndroidUtilities.checkPhonePattern(pattern, num)) {
@ -7924,7 +7926,7 @@ public class PassportActivity extends BaseFragment implements NotificationCenter
ignoreOnTextChange = true;
codeField[0].setText(num);
ignoreOnTextChange = false;
onNextPressed();
onNextPressed(null);
}
}
}

View file

@ -9802,12 +9802,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
bottomLayout.setVisibility(View.GONE);
}
if (slideshowMessageId == 0) {
boolean noforwards = MessagesController.getInstance(UserConfig.selectedAccount).isChatNoForwards(messageObject.getChatId());
imagesArr.add(messageObject);
if (messageObject.eventId != 0) {
needSearchImageInArr = false;
} else if (currentAnimation != null) {
needSearchImageInArr = false;
if (messageObject.canForwardMessage()) {
if (messageObject.canForwardMessage() && !noforwards) {
setItemVisible(sendItem, true, false);
}
} else if (!messageObject.scheduled && !(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaInvoice) && !(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) && (messageObject.messageOwner.action == null || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionEmpty)) {
@ -9817,7 +9818,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
menuItem.showSubItem(gallery_menu_showinchat);
menuItem.showSubItem(gallery_menu_showall);
}
setItemVisible(sendItem, true, false);
setItemVisible(sendItem, !noforwards, false);
} else if (isEmbedVideo && messageObject.eventId == 0) {
setItemVisible(sendItem, true, false);
}
@ -9869,7 +9870,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
startOffset = object.starOffset;
}
menuItem.showSubItem(gallery_menu_showinchat);
if (openingObject.canForwardMessage()) {
if (openingObject.canForwardMessage() && !MessagesController.getInstance(UserConfig.selectedAccount).isChatNoForwards(openingObject.getChatId())) {
setItemVisible(sendItem, true, false);
}
if (openingObject.canPreviewDocument()) {
@ -10061,7 +10062,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
nameTextView.setText("");
dateTextView.setText("");
} else {
if (newMessageObject.isNewGif()) {
if (newMessageObject.isNewGif() && allowShare) {
menuItem.showSubItem(gallery_menu_savegif);
}
if (newMessageObject.canDeleteMessage(parentChatActivity != null && parentChatActivity.isInScheduleMode(), null) && slideshowMessageId == 0) {
@ -10069,11 +10070,17 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
} else {
menuItem.hideSubItem(gallery_menu_delete);
}
boolean noforwards = MessagesController.getInstance(UserConfig.selectedAccount).isChatNoForwards(newMessageObject.getChatId());
if (isEmbedVideo) {
menuItem.showSubItem(gallery_menu_openin);
setItemVisible(pipItem, true, false);
} else if (isVideo) {
menuItem.showSubItem(gallery_menu_openin);
if (!noforwards || (slideshowMessageId == 0 ? newMessageObject.messageOwner.media.webpage != null && newMessageObject.messageOwner.media.webpage.url != null :
imagesArr.get(0).messageOwner.media.webpage != null && imagesArr.get(0).messageOwner.media.webpage.url != null)) {
menuItem.showSubItem(gallery_menu_openin);
} else {
menuItem.hideSubItem(gallery_menu_openin);
}
final boolean masksItemVisible = masksItem.getVisibility() == View.VISIBLE;
if (masksItemVisible) {
setItemVisible(masksItem, false, false);
@ -10090,6 +10097,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
menuItem.hideSubItem(gallery_menu_masks2);
}
} else {
speedGap.setVisibility(View.GONE);
menuItem.hideSubItem(gallery_menu_openin);
final boolean pipItemVisible = pipItem.getVisibility() == View.VISIBLE;
final boolean shouldMasksItemBeVisible = newMessageObject.hasAttachedStickers() && !DialogObject.isEncryptedDialog(newMessageObject.getDialogId());
@ -10114,7 +10122,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
nameTextView.setText("", animatedLocal);
}
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(newMessageObject.getChatId());
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-newMessageObject.getSenderId());
if (ChatObject.isChannel(chat) && chat.megagroup && newMessageObject.isForwardedChannelPost()) {
chat = MessagesController.getInstance(currentAccount).getChat(newMessageObject.messageOwner.fwd_from.from_id.channel_id);
}
@ -10155,9 +10163,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
if (!newMessageObject.canDeleteMessage(parentChatActivity != null && parentChatActivity.isInScheduleMode(), null)) {
menuItem.hideSubItem(gallery_menu_delete);
}
allowShare = true;
allowShare = !MessagesController.getInstance(UserConfig.selectedAccount).isChatNoForwards(-currentDialogId);
bottomButtonsLayout.setVisibility(View.VISIBLE);
paintButton.setVisibility(View.GONE);
shareItem.setVisibility(allowShare ? View.VISIBLE : View.GONE);
shareButton.setVisibility(allowShare ? View.VISIBLE : View.GONE);
actionBar.setTitle(LocaleController.getString("AttachGif", R.string.AttachGif));
} else {
if (totalImagesCount + totalImagesCountMerge != 0 && !needSearchImageInArr) {
@ -10228,10 +10238,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
} else if (newMessageObject.getDocument() != null) {
actionBar.setTitle(LocaleController.getString("AttachDocument", R.string.AttachDocument));
}
if (DialogObject.isEncryptedDialog(currentDialogId) && !isEmbedVideo) {
if (DialogObject.isEncryptedDialog(currentDialogId) && !isEmbedVideo ||
MessagesController.getInstance(currentAccount).isChatNoForwards(newMessageObject.getChatId())) {
setItemVisible(sendItem, false, false);
}
if (isEmbedVideo || newMessageObject.messageOwner.ttl != 0 && newMessageObject.messageOwner.ttl < 60 * 60) {
if (isEmbedVideo || newMessageObject.messageOwner.ttl != 0 && newMessageObject.messageOwner.ttl < 60 * 60 || MessagesController.getInstance(UserConfig.selectedAccount).isChatNoForwards(newMessageObject.getChatId())) {
allowShare = false;
menuItem.hideSubItem(gallery_menu_save);
bottomButtonsLayout.setVisibility(View.GONE);
@ -10293,8 +10304,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
} else {
actionBar.setTitle(LocaleController.formatString("Of", R.string.Of, switchingToIndex + 1, imagesArrLocations.size()));
}
menuItem.showSubItem(gallery_menu_save);
allowShare = true;
boolean noforwards = avatarsDialogId != 0 && MessagesController.getInstance(currentAccount).isChatNoForwards(-avatarsDialogId);
if (noforwards)
menuItem.hideSubItem(gallery_menu_save);
else menuItem.showSubItem(gallery_menu_save);
allowShare = !noforwards;
shareButton.setVisibility(allowShare ? View.VISIBLE : View.GONE);
bottomButtonsLayout.setVisibility(!videoPlayerControlVisible ? View.VISIBLE : View.GONE);
if (bottomButtonsLayout.getVisibility() == View.VISIBLE) {
menuItem.hideSubItem(gallery_menu_share);
@ -10506,7 +10522,10 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
caption = pageBlocksAdapter.getCaption(switchingToIndex);
isVideo = pageBlocksAdapter.isVideo(switchingToIndex);
if (isVideo) {
menuItem.showSubItem(gallery_menu_openin);
if (!MessagesController.getInstance(UserConfig.selectedAccount).isChatNoForwards(-currentDialogId))
menuItem.showSubItem(gallery_menu_openin);
else menuItem.hideSubItem(gallery_menu_openin);
if (!pipAvailable) {
pipItem.setEnabled(false);
setItemVisible(pipItem, true, true, 0.5f);
@ -10522,13 +10541,16 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
}
bottomLayout.setTag(null);
allowShare = true;
shareItem.setVisibility(View.VISIBLE);
allowShare = !MessagesController.getInstance(UserConfig.selectedAccount).isChatNoForwards(-currentDialogId);
shareItem.setVisibility(allowShare ? View.VISIBLE : View.GONE);
if (currentAnimation != null) {
menuItem.setVisibility(View.VISIBLE);
menuItem.hideSubItem(gallery_menu_save);
menuItem.showSubItem(gallery_menu_savegif);
if (allowShare) {
menuItem.showSubItem(gallery_menu_savegif);
} else {
menuItem.hideSubItem(gallery_menu_savegif);
}
actionBar.setTitle(LocaleController.getString("AttachGif", R.string.AttachGif));
} else {
menuItem.setVisibility(View.VISIBLE);
@ -10642,7 +10664,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
isVideo = newMessageObject.isVideo();
if (sharedMediaType == MediaDataController.MEDIA_FILE) {
if (canZoom = newMessageObject.canPreviewDocument()) {
menuItem.showSubItem(gallery_menu_save);
if (allowShare) {
menuItem.showSubItem(gallery_menu_save);
} else {
menuItem.hideSubItem(gallery_menu_save);
}
setDoubleTapEnabled(true);
} else {
menuItem.hideSubItem(gallery_menu_save);
@ -10650,10 +10676,12 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
}
}
if (isVideo || isEmbedVideo) {
menuItem.showSubItem(gallery_menu_speed);
speedGap.setVisibility(View.VISIBLE);
menuItem.showSubItem(gallery_menu_speed);
} else {
menuItem.hideSubItem(gallery_menu_speed);
speedGap.setVisibility(View.GONE);
menuItem.checkHideMenuItem();
}
} else if (!secureDocuments.isEmpty()) {
if (index < 0 || index >= secureDocuments.size()) {
@ -11994,7 +12022,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
} else {
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
}
if (chatActivity != null && chatActivity.getCurrentEncryptedChat() != null) {
if (chatActivity != null && chatActivity.getCurrentEncryptedChat() != null ||
avatarsDialogId != 0 && MessagesController.getInstance(currentAccount).isChatNoForwards(-avatarsDialogId) ||
messageObject != null && MessagesController.getInstance(currentAccount).isChatNoForwards(messageObject.getChatId())) {
windowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_SECURE;
} else {
windowLayoutParams.flags &=~ WindowManager.LayoutParams.FLAG_SECURE;

View file

@ -148,6 +148,7 @@ import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.CrossfadeDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.FragmentContextView;
import org.telegram.ui.Components.HintView;
import org.telegram.ui.Components.IdenticonDrawable;
import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.LayoutHelper;
@ -207,6 +208,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
private RLottieDrawable cameraDrawable;
private HintView fwdRestrictedHint;
private FrameLayout avatarContainer;
private FrameLayout avatarContainer2;
private AvatarImageView avatarImage;
@ -1999,7 +2001,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (pinchToZoomHelper.isInOverlayMode()) {
return pinchToZoomHelper.onTouchEvent(ev);
}
if (sharedMediaLayout != null && sharedMediaLayout.isInFastScroll() && sharedMediaLayout.getY() == 0) {
if (sharedMediaLayout != null && sharedMediaLayout.isInFastScroll() && sharedMediaLayout.isPinnedToTop()) {
return sharedMediaLayout.dispatchFastScrollEvent(ev);
}
if (sharedMediaLayout != null && sharedMediaLayout.checkPinchToZoom(ev)) {
@ -2087,7 +2089,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
allowPullingDown = true;
isPulledDown = true;
if (otherItem != null) {
otherItem.showSubItem(gallery_menu_save);
if (!getMessagesController().isChatNoForwards(currentChat)) {
otherItem.showSubItem(gallery_menu_save);
} else {
otherItem.hideSubItem(gallery_menu_save);
}
if (imageUpdater != null) {
otherItem.showSubItem(edit_avatar);
otherItem.showSubItem(delete_avatar);
@ -3190,10 +3196,14 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (fwdRestrictedHint != null) {
fwdRestrictedHint.hide();
}
checkListViewScroll();
if (participantsMap != null && !usersEndReached && layoutManager.findLastVisibleItemPosition() > membersEndRow - 8) {
getChannelParticipants(false);
}
sharedMediaLayout.setPinnedToTop(sharedMediaLayout.getY() == 0);
}
});
@ -3297,6 +3307,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
updateSelectedMediaTabText();
fwdRestrictedHint = new HintView(getParentActivity(), 9);
fwdRestrictedHint.setAlpha(0);
frameLayout.addView(fwdRestrictedHint, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 12, 0, 12, 0));
sharedMediaLayout.setForwardRestrictedHint(fwdRestrictedHint);
ViewGroup decorView;
if (Build.VERSION.SDK_INT >= 21) {
@ -4269,7 +4283,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
if (allowPullingDown && (openingAvatar || expandProgress >= 0.33f)) {
if (!isPulledDown) {
if (otherItem != null) {
otherItem.showSubItem(gallery_menu_save);
if (!getMessagesController().isChatNoForwards(currentChat)) {
otherItem.showSubItem(gallery_menu_save);
} else {
otherItem.hideSubItem(gallery_menu_save);
}
if (imageUpdater != null) {
otherItem.showSubItem(add_photo);
otherItem.showSubItem(edit_avatar);
@ -6137,6 +6155,10 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
} else {
otherItem.addSubItem(gallery_menu_save, R.drawable.msg_gallery, LocaleController.getString("SaveToGallery", R.string.SaveToGallery));
}
if (getMessagesController().isChatNoForwards(currentChat)) {
otherItem.hideSubItem(gallery_menu_save);
}
if (selfUser) {
otherItem.addSubItem(logout, R.drawable.msg_leave, LocaleController.getString("LogOut", R.string.LogOut));
}

View file

@ -0,0 +1,419 @@
package org.telegram.ui;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
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.ScrollView;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextCheckCell2;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.Switch;
public class SessionBottomSheet extends BottomSheet {
TLRPC.TL_authorization session;
BaseFragment parentFragment;
RLottieImageView imageView;
public SessionBottomSheet(BaseFragment fragment, TLRPC.TL_authorization session, boolean isCurrentSession, Callback callback) {
super(fragment.getParentActivity(), false);
setOpenNoDelay(true);
Context context = fragment.getParentActivity();
this.session = session;
this.parentFragment = fragment;
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
imageView = new RLottieImageView(context);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!imageView.isPlaying() && imageView.getAnimatedDrawable() != null) {
imageView.getAnimatedDrawable().setCurrentFrame(40);
imageView.playAnimation();
}
}
});
imageView.setScaleType(ImageView.ScaleType.CENTER);
linearLayout.addView(imageView, LayoutHelper.createLinear(70, 70, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 0));
TextView nameView = new TextView(context);
nameView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
nameView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameView.setGravity(Gravity.CENTER);
linearLayout.addView(nameView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 21, 12, 21, 0));
TextView timeView = new TextView(context);
timeView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
timeView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
timeView.setGravity(Gravity.CENTER);
linearLayout.addView(timeView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL, 21, 4, 21, 21));
String timeText;
if ((session.flags & 1) != 0) {
timeText = LocaleController.getString("Online", R.string.Online);
} else {
timeText = LocaleController.stringForMessageListDate(session.date_active);
}
timeView.setText(timeText);
StringBuilder stringBuilder = new StringBuilder();
if (session.device_model.length() != 0) {
stringBuilder.append(session.device_model);
}
if (stringBuilder.length() == 0) {
if (session.platform.length() != 0) {
stringBuilder.append(session.platform);
}
if (session.system_version.length() != 0) {
if (session.platform.length() != 0) {
stringBuilder.append(" ");
}
stringBuilder.append(session.system_version);
}
}
nameView.setText(stringBuilder);
setAnimation(session, imageView);
ItemView applicationItemView = new ItemView(context, false);
stringBuilder = new StringBuilder();
stringBuilder.append(session.app_name);
stringBuilder.append(" ").append(session.app_version);
applicationItemView.valueText.setText(stringBuilder);
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.menu_devices).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.SRC_IN));
applicationItemView.iconView.setImageDrawable(drawable);
applicationItemView.descriptionText.setText(LocaleController.getString("Application", R.string.Application));
linearLayout.addView(applicationItemView);
ItemView prevItem = applicationItemView;
if (session.country.length() != 0) {
ItemView locationItemView = new ItemView(context, false);
locationItemView.valueText.setText(session.country);
drawable = ContextCompat.getDrawable(context, R.drawable.menu_location).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.SRC_IN));
locationItemView.iconView.setImageDrawable(drawable);
locationItemView.descriptionText.setText(LocaleController.getString("Location", R.string.Location));
locationItemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
copyText(session.country);
}
});
locationItemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
copyText(session.country);
return true;
}
});
locationItemView.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 2));
linearLayout.addView(locationItemView);
if (prevItem != null) {
prevItem.needDivider = true;
}
prevItem = locationItemView;
}
if (session.ip.length() != 0) {
ItemView locationItemView = new ItemView(context, false);
locationItemView.valueText.setText(session.ip);
drawable = ContextCompat.getDrawable(context, R.drawable.menu_language).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.SRC_IN));
locationItemView.iconView.setImageDrawable(drawable);
locationItemView.descriptionText.setText(LocaleController.getString("IpAddress", R.string.IpAddress));
locationItemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
copyText(session.ip);
}
});
locationItemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
copyText(session.country);
return true;
}
});
locationItemView.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 2));
linearLayout.addView(locationItemView);
if (prevItem != null) {
prevItem.needDivider = true;
}
prevItem = locationItemView;
}
if (secretChatsEnabled(session)) {
ItemView acceptSecretChats = new ItemView(context, true);
acceptSecretChats.valueText.setText(LocaleController.getString("AcceptSecretChats", R.string.AcceptSecretChats));
drawable = ContextCompat.getDrawable(context, R.drawable.menu_secret).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.SRC_IN));
acceptSecretChats.iconView.setImageDrawable(drawable);
acceptSecretChats.switchView.setChecked(!session.encrypted_requests_disabled, false);
acceptSecretChats.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 7));
acceptSecretChats.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
acceptSecretChats.switchView.setChecked(!acceptSecretChats.switchView.isChecked(), true);
session.encrypted_requests_disabled = !acceptSecretChats.switchView.isChecked();
uploadSessionSettings();
}
});
if (prevItem != null) {
prevItem.needDivider = true;
}
acceptSecretChats.descriptionText.setText(LocaleController.getString("AcceptSecretChatsDescription", R.string.AcceptSecretChatsDescription));
linearLayout.addView(acceptSecretChats);
prevItem = acceptSecretChats;
}
ItemView acceptCalls = new ItemView(context, true);
acceptCalls.valueText.setText(LocaleController.getString("AcceptCalls", R.string.AcceptCalls));
drawable = ContextCompat.getDrawable(context, R.drawable.menu_calls).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.SRC_IN));
acceptCalls.iconView.setImageDrawable(drawable);
acceptCalls.switchView.setChecked(!session.call_requests_disabled, false);
acceptCalls.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 7));
acceptCalls.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
acceptCalls.switchView.setChecked(!acceptCalls.switchView.isChecked(), true);
session.call_requests_disabled = !acceptCalls.switchView.isChecked();
uploadSessionSettings();
}
});
if (prevItem != null) {
prevItem.needDivider = true;
}
acceptCalls.descriptionText.setText(LocaleController.getString("AcceptCallsChatsDescription", R.string.AcceptCallsChatsDescription));
linearLayout.addView(acceptCalls);
if (!isCurrentSession) {
TextView buttonTextView = new TextView(context);
buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0);
buttonTextView.setGravity(Gravity.CENTER);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setText(LocaleController.getString("TerminateSession", R.string.TerminateSession));
buttonTextView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Theme.getColor(Theme.key_chat_attachAudioBackground), ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_windowBackgroundWhite), 120)));
linearLayout.addView(buttonTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, 0, 16, 15, 16, 16));
buttonTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(parentFragment.getParentActivity());
final boolean[] param = new boolean[1];
String buttonText;
builder.setMessage(LocaleController.getString("TerminateSessionText", R.string.TerminateSessionText));
builder.setTitle(LocaleController.getString("AreYouSureSessionTitle", R.string.AreYouSureSessionTitle));
buttonText = LocaleController.getString("Terminate", R.string.Terminate);
builder.setPositiveButton(buttonText, (dialogInterface, option) -> {
callback.onSessionTerminated(session);
dismiss();
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
AlertDialog alertDialog = builder.create();
fragment.showDialog(alertDialog);
TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
}
}
});
}
ScrollView scrollView = new ScrollView(context);
scrollView.addView(linearLayout);
setCustomView(scrollView);
}
private boolean secretChatsEnabled(TLRPC.TL_authorization session) {
if (session.api_id == 2040 || session.api_id == 2496) {
return false;
}
return true;
}
private void uploadSessionSettings() {
TLRPC.TL_account_changeAuthorizationSettings req = new TLRPC.TL_account_changeAuthorizationSettings();
req.encrypted_requests_disabled = session.encrypted_requests_disabled;
req.call_requests_disabled = session.call_requests_disabled;
req.flags = 1 | 2;
req.hash = session.hash;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
});
}
private void copyText(String text) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setItems(new CharSequence[]{LocaleController.getString("Copy", R.string.Copy)}, (dialogInterface, i) -> {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("label", text);
clipboard.setPrimaryClip(clip);
BulletinFactory.of(getContainer(), null).createCopyBulletin(LocaleController.getString("TextCopied", R.string.TextCopied)).show();
});
builder.show();
}
private void setAnimation(TLRPC.TL_authorization session, RLottieImageView imageView) {
String platform = session.platform.toLowerCase();
if (platform.isEmpty()) {
platform = session.system_version.toLowerCase();
}
String deviceModel = session.device_model.toLowerCase();
int iconId;
String colorKey;
boolean animation = true;
if (deviceModel.contains("safari")) {
iconId = R.raw.safari_30;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("edge")) {
iconId = R.raw.edge_30;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("chrome")) {
iconId = R.raw.chrome_30;
colorKey = Theme.key_avatar_backgroundPink;
} else if (deviceModel.contains("opera") || deviceModel.contains("firefox") || deviceModel.contains("vivaldi")) {
animation = false;
if (deviceModel.contains("opera")) {
iconId = R.drawable.device_web_opera;
} else if (deviceModel.contains("firefox")) {
iconId = R.drawable.device_web_firefox;
} else {
iconId = R.drawable.device_web_other;
}
colorKey = Theme.key_avatar_backgroundPink;
} else if (platform.contains("ubuntu")) {
iconId = R.raw.ubuntu_30;
colorKey = Theme.key_avatar_backgroundBlue;
} else if (platform.contains("ios")) {
iconId = deviceModel.contains("ipad") ? R.raw.ipad_30 : R.raw.iphone_30;
colorKey = Theme.key_avatar_backgroundBlue;
} else if (platform.contains("windows")) {
iconId = R.raw.windows_30;
colorKey = Theme.key_avatar_backgroundCyan;
} else if (platform.contains("macos")) {
iconId = R.raw.mac_30;
colorKey = Theme.key_avatar_backgroundCyan;
} else if (platform.contains("android")) {
iconId = R.raw.android_30;
colorKey = Theme.key_avatar_backgroundGreen;
} else {
if (session.app_name.toLowerCase().contains("desktop")) {
iconId = R.raw.windows_30;
colorKey = Theme.key_avatar_backgroundCyan;
} else {
iconId = R.raw.chrome_30;
colorKey = Theme.key_avatar_backgroundPink;
}
}
imageView.setBackground(Theme.createCircleDrawable(AndroidUtilities.dp(42), Theme.getColor(colorKey)));
if (animation) {
int[] colors = new int[]{0x000000, Theme.getColor(colorKey)};
imageView.setAnimation(iconId, 50, 50, colors);
} else {
imageView.setImageDrawable(ContextCompat.getDrawable(getContext(), iconId));
}
}
private static class ItemView extends FrameLayout {
ImageView iconView;
TextView valueText;
TextView descriptionText;
Switch switchView;
boolean needDivider = false;
public ItemView(Context context, boolean needSwitch) {
super(context);
iconView = new ImageView(context);
addView(iconView, LayoutHelper.createFrame(28, 28, 0, 16, 8, 0, 0));
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 64, 4, 0, 4));
valueText = new TextView(context);
valueText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
valueText.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
linearLayout.addView(valueText, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 0, 0));
descriptionText = new TextView(context);
descriptionText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
descriptionText.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
linearLayout.addView(descriptionText, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 4, 0, 0));
setPadding(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4));
if (needSwitch) {
switchView = new Switch(context);
switchView.setDrawIconType(1);
addView(switchView, LayoutHelper.createFrame(37, 40, Gravity.RIGHT | Gravity.CENTER_VERTICAL, 21, 0, 21, 0));
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (needDivider) {
canvas.drawRect(AndroidUtilities.dp(64), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight(), Theme.dividerPaint);
}
}
}
public interface Callback {
void onSessionTerminated(TLRPC.TL_authorization session);
}
@Override
public void show() {
super.show();
imageView.playAnimation();
}
}

View file

@ -8,11 +8,19 @@
package org.telegram.ui;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.net.Uri;
import android.os.Build;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.util.Base64;
import android.util.TypedValue;
import android.view.Gravity;
@ -26,12 +34,17 @@ import android.widget.TextView;
import android.widget.Toast;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
@ -44,17 +57,29 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.RadioColorCell;
import org.telegram.ui.Cells.SessionCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Cells.TextSettingsCell;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.ColoredImageSpan;
import org.telegram.ui.Components.EmptyTextProgressView;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RecyclerItemsEnterAnimator;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ReplaceableIconDrawable;
import org.telegram.ui.Components.SlideChooseView;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.UndoView;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -66,14 +91,16 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
private TextView textView1;
private TextView textView2;
private EmptyTextProgressView emptyView;
private FlickerLoadingView globalFlickerLoadingView;
private ArrayList<TLObject> sessions = new ArrayList<>();
private ArrayList<TLObject> passwordSessions = new ArrayList<>();
private TLRPC.TL_authorization currentSession;
private boolean loading;
private LinearLayout emptyLayout;
private UndoView undoView;
private RecyclerItemsEnterAnimator itemsEnterAnimator;
private int ttlDays;
private int currentType;
@ -91,7 +118,11 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
private int otherSessionsTerminateDetail;
private int noOtherSessionsRow;
private int qrCodeRow;
private int qrCodeDividerRow;
private int rowCount;
private int ttlHeaderRow;
private int ttlRow;
private int ttlDivideRow;
public SessionsActivity(int type) {
currentType = type;
@ -113,7 +144,10 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
}
@Override
public View createView(Context context) {
public View createView(Context context) {
globalFlickerLoadingView = new FlickerLoadingView(context);
globalFlickerLoadingView.setIsSingleCell(true);
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setAllowOverlayTitle(true);
if (currentType == 0) {
@ -183,44 +217,71 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
listView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
listView.setVerticalScrollBarEnabled(false);
listView.setEmptyView(emptyView);
listView.setAnimateEmptyView(true, 0);
frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
listView.setAdapter(listAdapter);
listView.setOnItemClickListener((view, position) -> {
if (position == qrCodeRow) {
ActionIntroActivity fragment = new ActionIntroActivity(ActionIntroActivity.ACTION_TYPE_QR_LOGIN);
fragment.setQrLoginDelegate(code -> {
AlertDialog progressDialog = new AlertDialog(getParentActivity(), 3);
progressDialog.setCanCacnel(false);
progressDialog.show();
byte[] token = Base64.decode(code.substring("tg://login?token=".length()), Base64.URL_SAFE);
TLRPC.TL_auth_acceptLoginToken req = new TLRPC.TL_auth_acceptLoginToken();
req.token = token;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog.dismiss();
} catch (Exception ignore) {
if (position == ttlRow) {
if (getParentActivity() == null) {
return;
}
int selected;
if (ttlDays <= 7) {
selected = 0;
} else if (ttlDays <= 93) {
selected = 1;
} else if (ttlDays <= 183) {
selected = 2;
} else {
selected = 3;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("SessionsSelfDestruct", R.string.SessionsSelfDestruct));
String[] items = new String[]{
LocaleController.formatPluralString("Weeks", 1),
LocaleController.formatPluralString("Months", 3),
LocaleController.formatPluralString("Months", 6),
LocaleController.formatPluralString("Years", 1)
};
final LinearLayout linearLayout = new LinearLayout(getParentActivity());
linearLayout.setOrientation(LinearLayout.VERTICAL);
builder.setView(linearLayout);
for (int a = 0; a < items.length; a++) {
RadioColorCell cell = new RadioColorCell(getParentActivity());
cell.setPadding(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), 0);
cell.setTag(a);
cell.setCheckColor(Theme.getColor(Theme.key_radioBackground), Theme.getColor(Theme.key_dialogRadioBackgroundChecked));
cell.setTextAndValue(items[a], selected == a);
linearLayout.addView(cell);
cell.setOnClickListener(v -> {
builder.getDismissRunnable().run();
Integer which = (Integer) v.getTag();
int value = 0;
if (which == 0) {
value = 7;
} else if (which == 1) {
value = 90;
} else if (which == 2) {
value = 183;
} else if (which == 3) {
value = 365;
}
if (response instanceof TLRPC.TL_authorization) {
TLRPC.TL_authorization authorization = (TLRPC.TL_authorization) response;
sessions.add(0, authorization);
updateRows();
final TLRPC.TL_account_setAuthorizationTTL req = new TLRPC.TL_account_setAuthorizationTTL();
req.authorization_ttl_days = value;
ttlDays = value;
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
undoView.showWithAction(0, UndoView.ACTION_QR_SESSION_ACCEPTED, response);
} else {
AndroidUtilities.runOnUIThread(() -> {
final String text;
if (error.text.equals("AUTH_TOKEN_EXCEPTION")) {
text = LocaleController.getString("AccountAlreadyLoggedIn", R.string.AccountAlreadyLoggedIn);
} else {
text = LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred) + "\n" + error.text;
}
AlertsCreator.showSimpleAlert(SessionsActivity.this, LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient), text);
});
}
}));
});
presentFragment(fragment);
getConnectionsManager().sendRequest(req, (response, error) -> {
});
});
}
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
showDialog(builder.create());
} else if (position == terminateAllSessionsRow) {
if (getParentActivity() == null) {
return;
@ -286,10 +347,24 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
}
} else if (position >= otherSessionsStartRow && position < otherSessionsEndRow || position >= passwordSessionsStartRow && position < passwordSessionsEndRow) {
} else if (position >= otherSessionsStartRow && position < otherSessionsEndRow || position >= passwordSessionsStartRow && position < passwordSessionsEndRow || position == currentSessionRow) {
if (getParentActivity() == null) {
return;
}
if (currentType == 0) {
final TLRPC.TL_authorization authorization;
boolean isCurrentSession = false;
if (position == currentSessionRow) {
authorization = currentSession;
isCurrentSession = true;
} else if (position >= otherSessionsStartRow && position < otherSessionsEndRow) {
authorization = (TLRPC.TL_authorization) sessions.get(position - otherSessionsStartRow);
} else {
authorization = (TLRPC.TL_authorization) passwordSessions.get(position - passwordSessionsStartRow);
}
showSessionBottomSheet(authorization, isCurrentSession);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
final boolean[] param = new boolean[1];
String buttonText;
@ -421,9 +496,50 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
frameLayout.addView(undoView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8));
}
itemsEnterAnimator = new RecyclerItemsEnterAnimator(listView, true) {
@Override
public View getProgressView() {
View progressView = null;
for (int i = 0; i < listView.getChildCount(); i++) {
View child = listView.getChildAt(i);
if (listView.getChildAdapterPosition(child) >= 0 && child instanceof SessionCell && ((SessionCell) child).isStub()) {
progressView = child;
}
}
return progressView;
}
};
itemsEnterAnimator.animateAlphaProgressView = false;
updateRows();
return fragmentView;
}
private void showSessionBottomSheet(TLRPC.TL_authorization authorization, boolean isCurrentSession) {
if (authorization == null) {
return;
}
SessionBottomSheet bottomSheet = new SessionBottomSheet(this, authorization, isCurrentSession, new SessionBottomSheet.Callback() {
@Override
public void onSessionTerminated(TLRPC.TL_authorization authorization) {
sessions.remove(authorization);
passwordSessions.remove(authorization);
updateRows();
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
TLRPC.TL_account_resetAuthorization req = new TLRPC.TL_account_resetAuthorization();
req.hash = authorization.hash;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
}));
}
});
bottomSheet.show();
}
@Override
public void onPause() {
super.onPause();
@ -465,6 +581,7 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
TLRPC.TL_account_getAuthorizations req = new TLRPC.TL_account_getAuthorizations();
int reqId = ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
loading = false;
int oldItemsCount = listAdapter.getItemCount();
if (error == null) {
sessions.clear();
passwordSessions.clear();
@ -479,8 +596,10 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
sessions.add(authorization);
}
}
ttlDays = res.authorization_ttl_days;
updateRows();
}
itemsEnterAnimator.showItemsAnimated(oldItemsCount + 1);
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
@ -497,6 +616,7 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
sessions.addAll(res.authorizations);
updateRows();
}
itemsEnterAnimator.showItemsAnimated(0);
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
@ -507,15 +627,43 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
private void updateRows() {
rowCount = 0;
currentSessionSectionRow = -1;
currentSessionRow = -1;
terminateAllSessionsRow = -1;
terminateAllSessionsDetailRow = -1;
passwordSessionsSectionRow = -1;
passwordSessionsStartRow = -1;
passwordSessionsEndRow = -1;
passwordSessionsDetailRow = -1;
otherSessionsSectionRow = -1;
otherSessionsStartRow = -1;
otherSessionsEndRow = -1;
otherSessionsTerminateDetail = -1;
noOtherSessionsRow = -1;
qrCodeRow = -1;
qrCodeDividerRow = -1;
ttlHeaderRow = -1;
ttlRow = -1;
ttlDivideRow = -1;
boolean hasQr = currentType == 0 && getMessagesController().qrLoginCamera;
if (hasQr) {
qrCodeRow = rowCount++;
qrCodeDividerRow = rowCount++;
}
if (loading) {
if (currentType == 0) {
currentSessionSectionRow = rowCount++;
currentSessionRow = rowCount++;
}
return;
}
if (currentSession != null) {
currentSessionSectionRow = rowCount++;
currentSessionRow = rowCount++;
} else {
currentSessionRow = -1;
currentSessionSectionRow = -1;
}
boolean hasQr = currentType == 0 && getMessagesController().qrLoginCamera;
if (!passwordSessions.isEmpty() || !sessions.isEmpty()) {
terminateAllSessionsRow = rowCount++;
terminateAllSessionsDetailRow = rowCount++;
@ -523,42 +671,32 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
} else {
terminateAllSessionsRow = -1;
terminateAllSessionsDetailRow = -1;
if (hasQr) {
qrCodeRow = rowCount++;
}
if (currentType == 1 || currentSession != null) {
noOtherSessionsRow = rowCount++;
} else {
noOtherSessionsRow = -1;
}
}
if (passwordSessions.isEmpty()) {
passwordSessionsDetailRow = -1;
passwordSessionsEndRow = -1;
passwordSessionsStartRow = -1;
passwordSessionsSectionRow = -1;
} else {
if (!passwordSessions.isEmpty()) {
passwordSessionsSectionRow = rowCount++;
passwordSessionsStartRow = rowCount;
rowCount += passwordSessions.size();
passwordSessionsEndRow = rowCount;
passwordSessionsDetailRow = rowCount++;
}
if (sessions.isEmpty()) {
otherSessionsSectionRow = -1;
otherSessionsStartRow = -1;
otherSessionsEndRow = -1;
otherSessionsTerminateDetail = -1;
} else {
if (!sessions.isEmpty()) {
otherSessionsSectionRow = rowCount++;
if (hasQr) {
qrCodeRow = rowCount++;
}
otherSessionsStartRow = rowCount;
otherSessionsEndRow = rowCount + sessions.size();
rowCount += sessions.size();
otherSessionsTerminateDetail = rowCount++;
}
if (ttlDays > 0) {
ttlHeaderRow = rowCount++;
ttlRow = rowCount++;
ttlDivideRow = rowCount++;
}
}
private class ListAdapter extends RecyclerListView.SelectionAdapter {
@ -572,12 +710,12 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
int position = holder.getAdapterPosition();
return position == terminateAllSessionsRow || position == qrCodeRow || position >= otherSessionsStartRow && position < otherSessionsEndRow || position >= passwordSessionsStartRow && position < passwordSessionsEndRow;
return position == terminateAllSessionsRow || position >= otherSessionsStartRow && position < otherSessionsEndRow || position >= passwordSessionsStartRow && position < passwordSessionsEndRow || position == currentSessionRow || position == ttlRow;
}
@Override
public int getItemCount() {
return loading ? 0 : rowCount;
return rowCount;
}
@Override
@ -585,7 +723,7 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
View view;
switch (viewType) {
case 0:
view = new TextSettingsCell(mContext);
view = new TextCell(mContext);
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
break;
case 1:
@ -598,6 +736,13 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
case 3:
view = emptyLayout;
break;
case 5:
view = new ScanQRCodeView(mContext);
break;
case 6:
view = new TextSettingsCell(mContext);
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
break;
default:
view = new SessionCell(mContext, currentType);
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
@ -610,23 +755,24 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
TextSettingsCell textCell = (TextSettingsCell) holder.itemView;
TextCell textCell = (TextCell) holder.itemView;
if (position == terminateAllSessionsRow) {
textCell.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText2));
textCell.setColors(Theme.key_windowBackgroundWhiteRedText2, Theme.key_windowBackgroundWhiteRedText2);
textCell.setTag(Theme.key_windowBackgroundWhiteRedText2);
if (currentType == 0) {
textCell.setText(LocaleController.getString("TerminateAllSessions", R.string.TerminateAllSessions), false);
textCell.setTextAndIcon(LocaleController.getString("TerminateAllSessions", R.string.TerminateAllSessions), R.drawable.msg_block2, false);
} else {
textCell.setText(LocaleController.getString("TerminateAllWebSessions", R.string.TerminateAllWebSessions), false);
textCell.setTextAndIcon(LocaleController.getString("TerminateAllWebSessions", R.string.TerminateAllWebSessions), R.drawable.msg_block2, false);
}
} else if (position == qrCodeRow) {
textCell.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4));
textCell.setColors(Theme.key_windowBackgroundWhiteBlueText4, Theme.key_windowBackgroundWhiteBlueText4);
textCell.setTag(Theme.key_windowBackgroundWhiteBlueText4);
textCell.setText(LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient), !sessions.isEmpty());
textCell.setTextAndIcon(LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient), R.drawable.msg_qrcode, !sessions.isEmpty());
}
break;
case 1:
TextInfoPrivacyCell privacyCell = (TextInfoPrivacyCell) holder.itemView;
privacyCell.setFixedSize(0);
if (position == terminateAllSessionsDetailRow) {
if (currentType == 0) {
privacyCell.setText(LocaleController.getString("ClearOtherSessionsHelp", R.string.ClearOtherSessionsHelp));
@ -639,7 +785,7 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
if (sessions.isEmpty()) {
privacyCell.setText("");
} else {
privacyCell.setText(LocaleController.getString("TerminateSessionInfo", R.string.TerminateSessionInfo));
privacyCell.setText(LocaleController.getString("SessionsListInfo", R.string.SessionsListInfo));
}
} else {
privacyCell.setText(LocaleController.getString("TerminateWebSessionInfo", R.string.TerminateWebSessionInfo));
@ -652,6 +798,10 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
} else {
privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
}
} else if (position == qrCodeDividerRow || position == ttlDivideRow || position == noOtherSessionsRow) {
privacyCell.setBackgroundDrawable(Theme.getThemedDrawable(mContext, R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow));
privacyCell.setText("");
privacyCell.setFixedSize(12);
}
break;
case 2:
@ -666,6 +816,8 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
}
} else if (position == passwordSessionsSectionRow) {
headerCell.setText(LocaleController.getString("LoginAttempts", R.string.LoginAttempts));
} else if (position == ttlHeaderRow) {
headerCell.setText(LocaleController.getString("TerminateOldSessionHeader", R.string.TerminateOldSessionHeader));
}
break;
case 3:
@ -675,10 +827,28 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
emptyLayout.setLayoutParams(layoutParams);
}
break;
case 5:
break;
case 6:
TextSettingsCell textSettingsCell = (TextSettingsCell) holder.itemView;
String value;
if (ttlDays > 30 && ttlDays <= 183) {
value = LocaleController.formatPluralString("Months", ttlDays / 30);
} else if (ttlDays == 365) {
value = LocaleController.formatPluralString("Years", ttlDays / 365);
} else {
value = LocaleController.formatPluralString("Weeks", ttlDays / 7);
}
textSettingsCell.setTextAndValue(LocaleController.getString("IfInactiveFor", R.string.IfInactiveFor), value, false);
break;
default:
SessionCell sessionCell = (SessionCell) holder.itemView;
if (position == currentSessionRow) {
sessionCell.setSession(currentSession, !sessions.isEmpty() || !passwordSessions.isEmpty() || qrCodeRow != -1);
if (currentSession == null) {
sessionCell.showStub(globalFlickerLoadingView);
} else {
sessionCell.setSession(currentSession, !sessions.isEmpty() || !passwordSessions.isEmpty() || qrCodeRow != -1);
}
} else if (position >= otherSessionsStartRow && position < otherSessionsEndRow) {
sessionCell.setSession(sessions.get(position - otherSessionsStartRow), position != otherSessionsEndRow - 1);
} else if (position >= passwordSessionsStartRow && position < passwordSessionsEndRow) {
@ -690,21 +860,221 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
@Override
public int getItemViewType(int position) {
if (position == terminateAllSessionsRow || position == qrCodeRow) {
if (position == terminateAllSessionsRow) {
return 0;
} else if (position == terminateAllSessionsDetailRow || position == otherSessionsTerminateDetail || position == passwordSessionsDetailRow) {
} else if (position == terminateAllSessionsDetailRow || position == otherSessionsTerminateDetail || position == passwordSessionsDetailRow || position == qrCodeDividerRow || position == ttlDivideRow || position == noOtherSessionsRow) {
return 1;
} else if (position == currentSessionSectionRow || position == otherSessionsSectionRow || position == passwordSessionsSectionRow) {
} else if (position == currentSessionSectionRow || position == otherSessionsSectionRow || position == passwordSessionsSectionRow || position == ttlHeaderRow) {
return 2;
} else if (position == noOtherSessionsRow) {
return 3;
} else if (position == currentSessionRow || position >= otherSessionsStartRow && position < otherSessionsEndRow || position >= passwordSessionsStartRow && position < passwordSessionsEndRow) {
return 4;
} else if (position == qrCodeRow) {
return 5;
} else if (position == ttlRow) {
return 6;
}
return 0;
}
}
private class ScanQRCodeView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
BackupImageView imageView;
TextView textView;
public ScanQRCodeView(@NonNull Context context) {
super(context);
imageView = new BackupImageView(context);
addView(imageView, LayoutHelper.createFrame(120, 120, Gravity.CENTER_HORIZONTAL, 0, 16, 0, 0));
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (imageView.getImageReceiver().getLottieAnimation() != null && !imageView.getImageReceiver().getLottieAnimation().isRunning()) {
imageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false);
imageView.getImageReceiver().getLottieAnimation().restart();
}
}
});
int[] colors = new int[8];
colors[0] = 0x333333;
colors[1] = Theme.getColor(Theme.key_windowBackgroundWhiteBlackText);
colors[2] = 0xffffff;
colors[3] = Theme.getColor(Theme.key_windowBackgroundWhite);
colors[4] = 0x50a7ea;
colors[5] = Theme.getColor(Theme.key_featuredStickers_addButton);
colors[6] = 0x212020;
colors[7] = Theme.getColor(Theme.key_windowBackgroundWhite);
// imageView.replaceColors(colors);
// imageView.setAnimation(R.raw.qr_login, 230, 230, colors);
// imageView.setScaleType(ImageView.ScaleType.CENTER);
// imageView.playAnimation();
textView = new TextView(context);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 36, 152, 36, 0));
textView.setGravity(Gravity.CENTER_HORIZONTAL);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setLinkTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkText));
textView.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection));
setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
String text = LocaleController.getString("AuthAnotherClientInfo4", R.string.AuthAnotherClientInfo4);
SpannableStringBuilder spanned = new SpannableStringBuilder(text);
int index1 = text.indexOf('*');
int index2 = text.indexOf('*', index1 + 1);
if (index1 != -1 && index2 != -1 && index1 != index2) {
textView.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
spanned.replace(index2, index2 + 1, "");
spanned.replace(index1, index1 + 1, "");
spanned.setSpan(new URLSpanNoUnderline(LocaleController.getString("AuthAnotherClientDownloadClientUrl", R.string.AuthAnotherClientDownloadClientUrl)), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
text = spanned.toString();
index1 = text.indexOf('*');
index2 = text.indexOf('*', index1 + 1);
if (index1 != -1 && index2 != -1 && index1 != index2) {
textView.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
spanned.replace(index2, index2 + 1, "");
spanned.replace(index1, index1 + 1, "");
spanned.setSpan(new URLSpanNoUnderline(LocaleController.getString("AuthAnotherWebClientUrl", R.string.AuthAnotherWebClientUrl)), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
textView.setText(spanned);
TextView buttonTextView = new TextView(context);
buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0);
buttonTextView.setGravity(Gravity.CENTER);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(". ").append(LocaleController.getString("LinkDesktopDevice", R.string.LinkDesktopDevice));
spannableStringBuilder.setSpan(new ColoredImageSpan(ContextCompat.getDrawable(getContext(), R.drawable.msg_mini_qr)), 0, 1, 0);
buttonTextView.setText(spannableStringBuilder);
buttonTextView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed)));
buttonTextView.setOnClickListener(view -> {
if (getParentActivity() == null) {
return;
}
if (Build.VERSION.SDK_INT >= 23 && getParentActivity().checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
getParentActivity().requestPermissions(new String[]{Manifest.permission.CAMERA}, ActionIntroActivity.CAMERA_PERMISSION_REQUEST_CODE);
return;
}
CameraScanActivity.showAsSheet(SessionsActivity.this, false, CameraScanActivity.TYPE_QR_LOGIN, new CameraScanActivity.CameraScanActivityDelegate() {
@Override
public void didFindQr(String text) {
proccessQrCode(text);
}
});
});
addView(buttonTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM, 16, 15, 16, 16));
setSticker();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(276), MeasureSpec.EXACTLY));
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setSticker();
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.diceStickersDidLoad);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.diceStickersDidLoad);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.diceStickersDidLoad) {
String name = (String) args[0];
if (AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME.equals(name)) {
setSticker();
}
}
}
private void setSticker() {
String imageFilter = null;
TLRPC.Document document = null;
TLRPC.TL_messages_stickerSet set = null;
set = MediaDataController.getInstance(currentAccount).getStickerSetByName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
if (set == null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
}
if (set != null && set.documents.size() > 6) {
document = set.documents.get(6);
}
imageFilter = "130_130";
SvgHelper.SvgDrawable svgThumb = null;
if (document != null) {
svgThumb = DocumentObject.getSvgThumb(document.thumbs, Theme.key_emptyListPlaceholder, 0.2f);
}
if (svgThumb != null) {
svgThumb.overrideWidthAndHeight(512, 512);
}
if (document != null) {
ImageLocation imageLocation = ImageLocation.getForDocument(document);
imageView.setImage(imageLocation, imageFilter, "tgs", svgThumb, set);
imageView.getImageReceiver().setAutoRepeat(2);
} else {
MediaDataController.getInstance(currentAccount).loadStickersByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME, false, set == null);
}
}
}
private void proccessQrCode(String code) {
AlertDialog progressDialog = new AlertDialog(getParentActivity(), 3);
progressDialog.setCanCacnel(false);
progressDialog.show();
byte[] token = Base64.decode(code.substring("tg://login?token=".length()), Base64.URL_SAFE);
TLRPC.TL_auth_acceptLoginToken req = new TLRPC.TL_auth_acceptLoginToken();
req.token = token;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog.dismiss();
} catch (Exception ignore) {
}
if (response instanceof TLRPC.TL_authorization) {
TLRPC.TL_authorization authorization = (TLRPC.TL_authorization) response;
sessions.add(0, authorization);
updateRows();
listAdapter.notifyDataSetChanged();
undoView.showWithAction(0, UndoView.ACTION_QR_SESSION_ACCEPTED, response);
} else {
AndroidUtilities.runOnUIThread(() -> {
final String text;
if (error.text.equals("AUTH_TOKEN_EXCEPTION")) {
text = LocaleController.getString("AccountAlreadyLoggedIn", R.string.AccountAlreadyLoggedIn);
} else {
text = LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred) + "\n" + error.text;
}
AlertsCreator.showSimpleAlert(SessionsActivity.this, LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient), text);
});
}
}));
}
@Override
public ArrayList<ThemeDescription> getThemeDescriptions() {
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
@ -751,4 +1121,21 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter
return themeDescriptions;
}
@Override
public void onRequestPermissionsResultFragment(int requestCode, String[] permissions, int[] grantResults) {
if (getParentActivity() == null) {
return;
}
if (requestCode == ActionIntroActivity.CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
CameraScanActivity.showAsSheet(SessionsActivity.this, false, CameraScanActivity.TYPE_QR_LOGIN, new CameraScanActivity.CameraScanActivityDelegate() {
@Override
public void didFindQr(String text) {
proccessQrCode(text);
}
});
}
}
}
}

View file

@ -111,7 +111,7 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
public TextMessageEnterTransition(ChatMessageCell messageView, ChatActivity chatActivity, RecyclerListView listView, MessageEnterTransitionContainer container, Theme.ResourcesProvider resourcesProvider) {
this.resourcesProvider = resourcesProvider;
currentAccount = UserConfig.selectedAccount;
if (messageView.getMessageObject().textLayoutBlocks.size() > 1 || messageView.getMessageObject().textLayoutBlocks.get(0).textLayout.getLineCount() > 10) {
if (messageView.getMessageObject().textLayoutBlocks.size() > 1 || messageView.getMessageObject().textLayoutBlocks.isEmpty() || messageView.getMessageObject().textLayoutBlocks.get(0).textLayout.getLineCount() > 10) {
return;
}
this.messageView = messageView;

View file

@ -563,16 +563,17 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No
backgroundRow = rowCount++;
newThemeInfoRow = rowCount++;
themeHeaderRow = rowCount++;
// TODO
//themeListRow2 = rowCount++;
themeListRow = rowCount++;
hasThemeAccents = Theme.getCurrentTheme().hasAccentColors();
if (themesHorizontalListCell != null) {
themesHorizontalListCell.setDrawDivider(hasThemeAccents);
}
if (hasThemeAccents) {
themeAccentListRow = rowCount++;
}
themeListRow2 = rowCount++;
//
// themeListRow = rowCount++;
// hasThemeAccents = Theme.getCurrentTheme().hasAccentColors();
// if (themesHorizontalListCell != null) {
// themesHorizontalListCell.setDrawDivider(hasThemeAccents);
// }
// if (hasThemeAccents) {
// themeAccentListRow = rowCount++;
// }
//
themeInfoRow = rowCount++;
@ -729,6 +730,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiLoaded);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.needShareTheme);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.needSetDayNightTheme);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.emojiPreviewThemesChanged);
getNotificationCenter().addObserver(this, NotificationCenter.themeUploadedToServer);
getNotificationCenter().addObserver(this, NotificationCenter.themeUploadError);
if (currentType == THEME_TYPE_BASIC) {
@ -749,6 +751,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.needShareTheme);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.needSetDayNightTheme);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiPreviewThemesChanged);
getNotificationCenter().removeObserver(this, NotificationCenter.themeUploadedToServer);
getNotificationCenter().removeObserver(this, NotificationCenter.themeUploadError);
Theme.saveAutoNightThemeConfig();
@ -801,6 +804,10 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No
} else if (id == NotificationCenter.needSetDayNightTheme) {
updateMenuItem();
checkCurrentDayNight();
} else if (id == NotificationCenter.emojiPreviewThemesChanged) {
if (themeListRow2 >= 0) {
listAdapter.notifyItemChanged(themeListRow2);
}
}
}
@ -1902,7 +1909,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No
return false;
}
Theme.ThemeAccent accent = accentsAdapter.themeAccents.get(position);
if (accent.id >= 100) {
if (accent.id >= 100 && !accent.isDefault) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
CharSequence[] items = new CharSequence[]{
LocaleController.getString("OpenInEditor", R.string.OpenInEditor),
@ -1988,6 +1995,7 @@ public class ThemeActivity extends BaseFragment implements NotificationCenter.No
case 17:
DefaultThemesPreviewCell cell = new DefaultThemesPreviewCell(mContext, ThemeActivity.this, currentType);
view = cell;
cell.setFocusable(false);
view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
break;
}

View file

@ -2349,10 +2349,26 @@ public class ThemePreviewActivity extends BaseFragment implements DownloadContro
Drawable background = backgroundImage.getBackground();
Bitmap bitmap = backgroundImage.getImageReceiver().getBitmap();
if (background instanceof MotionBackgroundDrawable) {
FileOutputStream stream = new FileOutputStream(toFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 87, stream);
stream.close();
} else {
Bitmap dst = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(dst);
background.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
background.draw(canvas);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setColorFilter(new PorterDuffColorFilter(patternColor, blendMode));
paint.setAlpha((int) (255 * currentIntensity));
canvas.drawBitmap(bitmap, 0, 0, paint);
FileOutputStream stream = new FileOutputStream(toFile);
dst.compress(Bitmap.CompressFormat.JPEG, 87, stream);
stream.close();
}
FileOutputStream stream = new FileOutputStream(toFile);
bitmap.compress(background instanceof MotionBackgroundDrawable ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG, 87, stream);
stream.close();
} catch (Throwable e) {
FileLog.e(e);
}

View file

@ -11,6 +11,7 @@ package org.telegram.ui;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.InputType;
import android.text.TextUtils;
@ -101,6 +102,7 @@ public class TwoStepVerificationActivity extends BaseFragment implements Notific
private int rowCount;
private boolean forgotPasswordOnShow;
int otherwiseReloginDays = -1;
private TwoStepVerificationActivityDelegate delegate;
@ -169,7 +171,11 @@ public class TwoStepVerificationActivity extends BaseFragment implements Notific
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
if (otherwiseReloginDays >= 0) {
showSetForcePasswordAlert();
} else {
finishFragment();
}
} else if (id == done_button) {
processDone();
}
@ -1103,4 +1109,43 @@ public class TwoStepVerificationActivity extends BaseFragment implements Notific
return themeDescriptions;
}
@Override
public boolean onBackPressed() {
if (otherwiseReloginDays >= 0) {
showSetForcePasswordAlert();
return false;
}
return super.onBackPressed();
}
private void showSetForcePasswordAlert() {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("Warning", R.string.Warning));
builder.setMessage(LocaleController.formatPluralString("ForceSetPasswordAlertMessage", otherwiseReloginDays));
builder.setPositiveButton(LocaleController.getString("ForceSetPasswordContinue", R.string.ForceSetPasswordContinue), (a1, a2) -> {
});
builder.setNegativeButton(LocaleController.getString("ForceSetPasswordCancel", R.string.ForceSetPasswordCancel), (a1, a2) -> {
finishFragment();
});
AlertDialog alertDialog = builder.show();
((TextView)alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE)).setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
}
public void setBlockingAlert(int otherwiseRelogin) {
otherwiseReloginDays = otherwiseRelogin;
}
@Override
public void finishFragment() {
if (otherwiseReloginDays >= 0) {
final Bundle args = new Bundle();
args.putBoolean("afterSignup", true);
presentFragment(new DialogsActivity(args), true);
} else {
super.finishFragment();
}
}
}

View file

@ -22,6 +22,7 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.text.Editable;
import android.text.InputType;
@ -33,6 +34,7 @@ import android.view.ActionMode;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
@ -44,6 +46,8 @@ import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
@ -84,7 +88,8 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
private ScrollView scrollView;
private View actionBarBackground;
private ImageView showPasswordButton;
private int otherwiseReloginDays = -1;
private AnimatorSet buttonAnimation;
private ArrayList<BaseFragment> fragmentsToClose = new ArrayList<>();
@ -221,7 +226,11 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
if (otherwiseReloginDays >= 0 && parentLayout.fragmentsStack.size() == 1) {
showSetForcePasswordAlert();
} else {
finishFragment();
}
} else if (id == item_resend) {
TLRPC.TL_account_resendPasswordEmail req = new TLRPC.TL_account_resendPasswordEmail();
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
@ -357,6 +366,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
TwoStepVerificationActivity fragment = new TwoStepVerificationActivity();
fragment.setForgotPasswordOnShow();
fragment.setPassword(currentPassword);
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
}
});
@ -382,6 +392,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
}
TwoStepVerificationSetupActivity fragment = new TwoStepVerificationSetupActivity(currentAccount, TYPE_ENTER_FIRST, currentPassword);
fragment.closeAfterSet = closeAfterSet;
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
break;
}
@ -391,6 +402,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
} else {
TwoStepVerificationActivity fragment = new TwoStepVerificationActivity();
fragment.setCurrentPasswordParams(currentPassword, currentPasswordHash, currentSecretId, currentSecret);
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
}
break;
@ -429,7 +441,9 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
needHideProgress();
currentPasswordHash = x_bytes;
getMessagesController().removeSuggestion(0, "VALIDATE_PASSWORD");
presentFragment(new TwoStepVerificationSetupActivity(TYPE_VERIFY_OK, currentPassword), true);
TwoStepVerificationSetupActivity fragment = new TwoStepVerificationSetupActivity(TYPE_VERIFY_OK, currentPassword);
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
});
} else {
AndroidUtilities.runOnUIThread(() -> {
@ -497,6 +511,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
fragment.fragmentsToClose.addAll(fragmentsToClose);
fragment.fragmentsToClose.add(this);
fragment.closeAfterSet = closeAfterSet;
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment);
break;
}
@ -517,6 +532,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
fragment.fragmentsToClose.addAll(fragmentsToClose);
fragment.fragmentsToClose.add(this);
fragment.closeAfterSet = closeAfterSet;
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment);
break;
}
@ -557,6 +573,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
fragment.fragmentsToClose.addAll(fragmentsToClose);
fragment.addFragmentToClose(TwoStepVerificationSetupActivity.this);
fragment.setCurrentEmailCode(code);
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
} else {
if (error == null || error.text.startsWith("CODE_INVALID")) {
@ -602,6 +619,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
currentPassword.has_recovery = true;
currentPassword.email_unconfirmed_pattern = "";
fragment.setCurrentPasswordParams(currentPassword, currentPasswordHash, currentSecretId, currentSecret);
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.didSetOrRemoveTwoStepPassword, currentPassword);
});
@ -627,6 +645,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
fragment.setCurrentPasswordParams(currentPasswordHash, currentSecretId, currentSecret, emailOnly);
fragment.fragmentsToClose.addAll(fragmentsToClose);
fragment.closeAfterSet = closeAfterSet;
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.twoStepPasswordChanged, currentPasswordHash, currentPassword.new_algo, currentPassword.new_secure_algo, currentPassword.secure_random, email, hint, null, firstPassword);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.didSetOrRemoveTwoStepPassword, currentPassword);
@ -1303,6 +1322,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
fragment.fragmentsToClose.addAll(fragmentsToClose);
fragment.fragmentsToClose.add(this);
fragment.closeAfterSet = closeAfterSet;
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment);
} else {
email = "";
@ -1486,6 +1506,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
currentPassword.has_recovery = false;
currentPassword.email_unconfirmed_pattern = "";
fragment.setCurrentPasswordParams(currentPassword, currentPasswordHash, currentSecretId, currentSecret);
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.didRemoveTwoStepPassword);
}
@ -1605,6 +1626,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
currentPassword.has_recovery = !TextUtils.isEmpty(currentPassword.email_unconfirmed_pattern);
}
fragment.setCurrentPasswordParams(currentPassword, newPasswordHash != null ? newPasswordHash : currentPasswordHash, currentSecretId, currentSecret);
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.didSetOrRemoveTwoStepPassword, currentPassword);
});
@ -1633,6 +1655,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
TwoStepVerificationSetupActivity fragment = new TwoStepVerificationSetupActivity(TYPE_PASSWORD_SET, currentPassword);
fragment.setCurrentPasswordParams(newPasswordHash != null ? newPasswordHash : currentPasswordHash, currentSecretId, currentSecret, emailOnly);
fragment.closeAfterSet = closeAfterSet;
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.didSetOrRemoveTwoStepPassword, currentPassword);
}
@ -1648,6 +1671,7 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
TwoStepVerificationSetupActivity fragment = new TwoStepVerificationSetupActivity(TwoStepVerificationSetupActivity.TYPE_EMAIL_CONFIRM, currentPassword);
fragment.setCurrentPasswordParams(newPasswordHash != null ? newPasswordHash : currentPasswordHash, currentSecretId, currentSecret, emailOnly);
fragment.closeAfterSet = closeAfterSet;
fragment.setBlockingAlert(otherwiseReloginDays);
presentFragment(fragment, true);
} else {
if ("EMAIL_INVALID".equals(error.text)) {
@ -1759,4 +1783,51 @@ public class TwoStepVerificationSetupActivity extends BaseFragment {
return themeDescriptions;
}
@Override
public boolean isSwipeBackEnabled(MotionEvent event) {
if (otherwiseReloginDays >= 0 && parentLayout.fragmentsStack.size() == 1) {
return false;
}
return super.isSwipeBackEnabled(event);
}
@Override
public boolean onBackPressed() {
if (otherwiseReloginDays >= 0 && parentLayout.fragmentsStack.size() == 1) {
showSetForcePasswordAlert();
return false;
}
return super.onBackPressed();
}
private void showSetForcePasswordAlert() {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("Warning", R.string.Warning));
builder.setMessage(LocaleController.formatPluralString("ForceSetPasswordAlertMessage", otherwiseReloginDays));
builder.setPositiveButton(LocaleController.getString("ForceSetPasswordContinue", R.string.ForceSetPasswordContinue), (a1, a2) -> {
});
builder.setNegativeButton(LocaleController.getString("ForceSetPasswordCancel", R.string.ForceSetPasswordCancel), (a1, a2) -> {
finishFragment();
});
AlertDialog alertDialog = builder.show();
((TextView)alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE)).setTextColor(Theme.getColor(Theme.key_dialogTextRed2));
}
public void setBlockingAlert(int otherwiseRelogin) {
otherwiseReloginDays = otherwiseRelogin;
}
@Override
public void finishFragment() {
if (otherwiseReloginDays >= 0 && parentLayout.fragmentsStack.size() == 1) {
final Bundle args = new Bundle();
args.putBoolean("afterSignup", true);
presentFragment(new DialogsActivity(args), true);
} else {
super.finishFragment();
}
}
}

View file

@ -1706,6 +1706,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
byte[] sha256 = Utilities.computeSHA256(auth_key, 0, auth_key.length);
String[] emoji = EncryptionKeyEmojifier.emojifyForCall(sha256);
for (int i = 0; i < 4; i++) {
Emoji.preloadEmoji(emoji[i]);
Emoji.EmojiDrawable drawable = Emoji.getEmojiDrawable(emoji[i]);
if (drawable != null) {
drawable.setBounds(0, 0, AndroidUtilities.dp(22), AndroidUtilities.dp(22));

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

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