update to 9.6.6 (33562)

This commit is contained in:
xaxtix 2023-05-27 16:04:37 +04:00
parent 7c62a5da96
commit dfd74f809e
33 changed files with 584 additions and 256 deletions

View file

@ -673,6 +673,9 @@ void ConnectionsManager::cleanUp(bool resetKeys, int32_t datacenterId) {
}
void ConnectionsManager::onConnectionClosed(Connection *connection, int reason) {
if (reason == 1) {
lastProtocolUsefullData = false;
}
Datacenter *datacenter = connection->getDatacenter();
if ((connection->getConnectionType() == ConnectionTypeGeneric || connection->getConnectionType() == ConnectionTypeGenericMedia) && datacenter->isHandshakingAny()) {
datacenter->onHandshakeConnectionClosed(connection);
@ -3543,6 +3546,7 @@ void ConnectionsManager::setNetworkAvailable(bool value, int32_t type, bool slow
void ConnectionsManager::setIpStrategy(uint8_t value) {
scheduleTask([&, value] {
lastProtocolUsefullData = false;
ipStrategy = value;
});
}

View file

@ -24,8 +24,8 @@ public class BuildVars {
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 = 3356;
public static String BUILD_VERSION_STRING = "9.6.5";
public static int BUILD_VERSION = 3362;
public static String BUILD_VERSION_STRING = "9.6.6";
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View file

@ -318,6 +318,10 @@ public class FileLoader extends BaseController {
}
public void checkUploadNewDataAvailable(final String location, final boolean encrypted, final long newAvailableSize, final long finalSize) {
checkUploadNewDataAvailable(location, encrypted, newAvailableSize, finalSize, null);
}
public void checkUploadNewDataAvailable(final String location, final boolean encrypted, final long newAvailableSize, final long finalSize, final Float progress) {
fileLoaderQueue.postRunnable(() -> {
FileUploadOperation operation;
if (encrypted) {
@ -326,7 +330,7 @@ public class FileLoader extends BaseController {
operation = uploadOperationPaths.get(location);
}
if (operation != null) {
operation.checkNewDataAvailable(newAvailableSize, finalSize);
operation.checkNewDataAvailable(newAvailableSize, finalSize, progress);
} else if (finalSize != 0) {
uploadSizes.put(location, finalSize);
}

View file

@ -79,6 +79,7 @@ public class FileUploadOperation {
private long availableSize;
private boolean uploadFirstPartLater;
private SparseArray<UploadCachedResult> cachedResults = new SparseArray<>();
private boolean[] recalculatedEstimatedSize = {false, false};
protected long lastProgressUpdateTime;
public interface FileUploadOperationDelegate {
@ -197,8 +198,23 @@ public class FileUploadOperation {
AutoDeleteMediaTask.unlockFile(uploadingFilePath);
}
protected void checkNewDataAvailable(final long newAvailableSize, final long finalSize) {
protected void checkNewDataAvailable(final long newAvailableSize, final long finalSize, final Float progress) {
Utilities.stageQueue.postRunnable(() -> {
if (progress != null && estimatedSize != 0 && finalSize == 0) {
boolean needRecalculation = false;
if (progress > 0.75f && !recalculatedEstimatedSize[0]) {
recalculatedEstimatedSize[0] = true;
needRecalculation = true;
}
if (progress > 0.95f && !recalculatedEstimatedSize[1]) {
recalculatedEstimatedSize[1] = true;
needRecalculation = true;
}
if (needRecalculation) {
estimatedSize = (long) (newAvailableSize / progress);
}
}
if (estimatedSize != 0 && finalSize != 0) {
estimatedSize = 0;
totalFileSize = finalSize;

View file

@ -37,6 +37,7 @@ import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
@ -62,8 +63,6 @@ import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.widget.FrameLayout;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
@ -100,10 +99,10 @@ import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
public class MediaController implements AudioManager.OnAudioFocusChangeListener, NotificationCenter.NotificationCenterDelegate, SensorEventListener {
@ -523,6 +522,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private static final int AUDIO_NO_FOCUS_NO_DUCK = 0;
private static final int AUDIO_NO_FOCUS_CAN_DUCK = 1;
private static final int AUDIO_FOCUSED = 2;
private static final ConcurrentHashMap<String, Integer> cachedEncoderBitrates = new ConcurrentHashMap<>();
private static class VideoConvertMessage {
public MessageObject messageObject;
@ -1494,7 +1494,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
final int type = device.getType();
if ((
type == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP ||
type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO ||
// type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO ||
type == AudioDeviceInfo.TYPE_BLE_HEADSET ||
type == AudioDeviceInfo.TYPE_BLE_SPEAKER ||
type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES ||
@ -1505,7 +1505,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
return false;
} else {
return NotificationsController.audioManager.isWiredHeadsetOn() || NotificationsController.audioManager.isBluetoothA2dpOn() || NotificationsController.audioManager.isBluetoothScoOn();
return NotificationsController.audioManager.isWiredHeadsetOn() || NotificationsController.audioManager.isBluetoothA2dpOn()/* || NotificationsController.audioManager.isBluetoothScoOn()*/;
}
} catch (Exception e) {
FileLog.e(e);
@ -2388,7 +2388,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
playMusicAgain = true;
playMessage(currentPlayList.get(currentPlaylistNum));
}
private boolean traversePlaylist(ArrayList<MessageObject> playlist, int direction) {
boolean last = false;
final int wasCurrentPlaylistNum = currentPlaylistNum;
@ -3447,7 +3447,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public static boolean ignoreAccelerometerGestures() {
return Build.MANUFACTURER.equalsIgnoreCase("samsung");
}
public void updateSilent(boolean value) {
isSilent = value;
if (videoPlayer != null) {
@ -4960,6 +4960,20 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return -5;
}
public static boolean isH264Video(String videoPath) {
MediaExtractor extractor = new MediaExtractor();
try {
extractor.setDataSource(videoPath);
int videoIndex = MediaController.findTrack(extractor, false);
return videoIndex >= 0 && extractor.getTrackFormat(videoIndex).getString(MediaFormat.KEY_MIME).equals(MediaController.VIDEO_MIME_TYPE);
} catch (Exception e) {
FileLog.e(e);
} finally {
extractor.release();
}
return false;
}
private void didWriteData(final VideoConvertMessage message, final File file, final boolean last, final long lastFrameTimestamp, long availableSize, final boolean error, final float progress) {
final boolean firstWrite = message.videoEditedInfo.videoConvertFirstWrite;
if (firstWrite) {
@ -5211,6 +5225,31 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return Math.max(remeasuredBitrate, minBitrate);
}
/**
* Some encoders(e.g. OMX.Exynos) can forcibly raise bitrate during encoder initialization.
*/
public static int extractRealEncoderBitrate(int width, int height, int bitrate) {
String cacheKey = width + "" + height + "" + bitrate;
Integer cachedBitrate = cachedEncoderBitrates.get(cacheKey);
if (cachedBitrate != null) return cachedBitrate;
try {
MediaCodec encoder = MediaCodec.createEncoderByType(MediaController.VIDEO_MIME_TYPE);
MediaFormat outputFormat = MediaFormat.createVideoFormat(MediaController.VIDEO_MIME_TYPE, width, height);
outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
outputFormat.setInteger("max-bitrate", bitrate);
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
int encoderBitrate = (int) (encoder.getOutputFormat().getInteger(MediaFormat.KEY_BIT_RATE));
cachedEncoderBitrates.put(cacheKey, encoderBitrate);
encoder.release();
return encoderBitrate;
} catch (Exception e) {
return bitrate;
}
}
private static int getVideoBitrateWithFactor(float f) {
return (int) (f * 2000f * 1000f * 1.13f);
}

View file

@ -1045,8 +1045,9 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
String finalPath = (String) args[1];
long availableSize = (Long) args[2];
long finalSize = (Long) args[3];
Float progress = (Float) args[4];
boolean isEncrypted = DialogObject.isEncryptedDialog(messageObject.getDialogId());
getFileLoader().checkUploadNewDataAvailable(finalPath, isEncrypted, availableSize, finalSize);
getFileLoader().checkUploadNewDataAvailable(finalPath, isEncrypted, availableSize, finalSize, progress);
if (finalSize != 0) {
stopVideoService(messageObject.messageOwner.attachPath);
ArrayList<DelayedMessage> arr = delayedMessages.get(messageObject.messageOwner.attachPath);
@ -8220,6 +8221,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
return null;
}
long originalSize = new File(videoPath).length();
int originalBitrate = MediaController.getVideoBitrate(videoPath);
if (originalBitrate == -1) {
originalBitrate = params[AnimatedFileDrawable.PARAM_NUM_BITRATE];
@ -8329,11 +8331,13 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
videoEditedInfo.resultWidth = videoEditedInfo.originalWidth;
videoEditedInfo.resultHeight = videoEditedInfo.originalHeight;
videoEditedInfo.bitrate = bitrate;
videoEditedInfo.estimatedSize = originalSize;
} else {
videoEditedInfo.bitrate = bitrate;
int encoderBitrate = MediaController.extractRealEncoderBitrate(videoEditedInfo.resultWidth, videoEditedInfo.resultHeight, bitrate);
videoEditedInfo.estimatedSize = (long) (audioFramesSize + videoDuration / 1000.0f * encoderBitrate / 8);
}
videoEditedInfo.estimatedSize = (long) (audioFramesSize + videoDuration / 1000.0f * bitrate / 8);
if (videoEditedInfo.estimatedSize == 0) {
videoEditedInfo.estimatedSize = 1;
}

View file

@ -143,6 +143,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@SuppressLint("NewApi")
public class VoIPService extends Service implements SensorEventListener, AudioManager.OnAudioFocusChangeListener, VoIPController.ConnectionStateListener, NotificationCenter.NotificationCenterDelegate {
@ -314,6 +316,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
private boolean startedRinging;
private int classGuid;
private volatile CountDownLatch groupCallBottomSheetLatch;
private HashMap<String, Integer> currentStreamRequestTimestamp = new HashMap<>();
public boolean micSwitching;
@ -323,6 +326,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
public void run() {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
VoipAudioManager vam = VoipAudioManager.get();
am.abandonAudioFocus(VoIPService.this);
am.unregisterMediaButtonEventReceiver(new ComponentName(VoIPService.this, VoIPMediaButtonReceiver.class));
if (audioDeviceCallback != null) {
@ -335,7 +339,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
bluetoothScoActive = false;
bluetoothScoConnecting = false;
}
am.setSpeakerphoneOn(false);
vam.setSpeakerphoneOn(false);
}
Utilities.globalQueue.postRunnable(() -> soundPool.release());
@ -397,7 +401,8 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
if (isHeadsetPlugged) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
if (am.isSpeakerphoneOn()) {
VoipAudioManager vam = VoipAudioManager.get();
if (vam.isSpeakerphoneOn()) {
previousAudioOutput = 0;
} else if (am.isBluetoothScoOn()) {
previousAudioOutput = 2;
@ -438,7 +443,8 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
if (needSwitchToBluetoothAfterScoActivates) {
needSwitchToBluetoothAfterScoActivates = false;
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
am.setSpeakerphoneOn(false);
VoipAudioManager vam = VoipAudioManager.get();
vam.setSpeakerphoneOn(false);
am.setBluetoothScoOn(true);
}
}
@ -462,6 +468,10 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
};
public CountDownLatch getGroupCallBottomSheetLatch() {
return groupCallBottomSheetLatch;
}
public boolean isFrontFaceCamera() {
return isFrontFaceCamera;
}
@ -1710,8 +1720,14 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
req.schedule_date = scheduleDate;
req.flags |= 2;
}
groupCallBottomSheetLatch = new CountDownLatch(1);
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {
try {
groupCallBottomSheetLatch.await(800, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
FileLog.e(e);
}
TLRPC.Updates updates = (TLRPC.Updates) response;
for (int a = 0; a < updates.updates.size(); a++) {
TLRPC.Update update = updates.updates.get(a);
@ -2729,8 +2745,9 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
} else if (audioConfigured && !USE_CONNECTION_SERVICE) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
VoipAudioManager vam = VoipAudioManager.get();
if (hasEarpiece()) {
am.setSpeakerphoneOn(!am.isSpeakerphoneOn());
vam.setSpeakerphoneOn(!vam.isSpeakerphoneOn());
} else {
am.setBluetoothScoOn(!am.isBluetoothScoOn());
}
@ -2748,6 +2765,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
FileLog.d("setAudioOutput " + which);
}
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
VoipAudioManager vam = VoipAudioManager.get();
if (USE_CONNECTION_SERVICE && systemCallConnection != null) {
switch (which) {
case 2:
@ -2772,7 +2790,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
} else {
am.setBluetoothScoOn(true);
am.setSpeakerphoneOn(false);
vam.setSpeakerphoneOn(false);
}
audioRouteToSet = AUDIO_ROUTE_BLUETOOTH;
break;
@ -2783,7 +2801,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
bluetoothScoActive = false;
bluetoothScoConnecting = false;
}
am.setSpeakerphoneOn(false);
vam.setSpeakerphoneOn(false);
am.setBluetoothScoOn(false);
audioRouteToSet = AUDIO_ROUTE_EARPIECE;
break;
@ -2795,7 +2813,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
bluetoothScoConnecting = false;
}
am.setBluetoothScoOn(false);
am.setSpeakerphoneOn(true);
vam.setSpeakerphoneOn(true);
audioRouteToSet = AUDIO_ROUTE_SPEAKER;
break;
}
@ -2827,7 +2845,8 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
return hasEarpiece() ? route == CallAudioState.ROUTE_SPEAKER : route == CallAudioState.ROUTE_BLUETOOTH;
} else if (audioConfigured && !USE_CONNECTION_SERVICE) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
return hasEarpiece() ? am.isSpeakerphoneOn() : am.isBluetoothScoOn();
VoipAudioManager vam = VoipAudioManager.get();
return hasEarpiece() ? vam.isSpeakerphoneOn() : am.isBluetoothScoOn();
}
return speakerphoneStateToSet;
}
@ -2849,9 +2868,10 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
if (audioConfigured) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
VoipAudioManager vam = VoipAudioManager.get();
if (am.isBluetoothScoOn()) {
return AUDIO_ROUTE_BLUETOOTH;
} else if (am.isSpeakerphoneOn()) {
} else if (vam.isSpeakerphoneOn()) {
return AUDIO_ROUTE_SPEAKER;
} else {
return AUDIO_ROUTE_EARPIECE;
@ -3090,11 +3110,12 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
cpuWakelock.release();
if (!playingSound) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
VoipAudioManager vam = VoipAudioManager.get();
if (!USE_CONNECTION_SERVICE) {
if (isBtHeadsetConnected || bluetoothScoActive || bluetoothScoConnecting) {
am.stopBluetoothSco();
am.setBluetoothScoOn(false);
am.setSpeakerphoneOn(false);
vam.setSpeakerphoneOn(false);
bluetoothScoActive = false;
bluetoothScoConnecting = false;
}
@ -3696,6 +3717,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
AndroidUtilities.runOnUIThread(() -> {
am.requestAudioFocus(VoIPService.this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
final VoipAudioManager vam = VoipAudioManager.get();
if (isBluetoothHeadsetConnected() && hasEarpiece()) {
switch (audioRouteToSet) {
case AUDIO_ROUTE_BLUETOOTH:
@ -3708,22 +3730,22 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
} else {
am.setBluetoothScoOn(true);
am.setSpeakerphoneOn(false);
vam.setSpeakerphoneOn(false);
}
break;
case AUDIO_ROUTE_EARPIECE:
am.setBluetoothScoOn(false);
am.setSpeakerphoneOn(false);
vam.setSpeakerphoneOn(false);
break;
case AUDIO_ROUTE_SPEAKER:
am.setBluetoothScoOn(false);
am.setSpeakerphoneOn(true);
vam.setSpeakerphoneOn(true);
break;
}
} else if (isBluetoothHeadsetConnected()) {
am.setBluetoothScoOn(speakerphoneStateToSet);
} else {
am.setSpeakerphoneOn(speakerphoneStateToSet);
vam.setSpeakerphoneOn(speakerphoneStateToSet);
if (speakerphoneStateToSet) {
audioRouteToSet = AUDIO_ROUTE_SPEAKER;
} else {
@ -3771,7 +3793,8 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioRouteToSet != AUDIO_ROUTE_EARPIECE || isHeadsetPlugged || am.isSpeakerphoneOn() || (isBluetoothHeadsetConnected() && am.isBluetoothScoOn())) {
VoipAudioManager vam = VoipAudioManager.get();
if (audioRouteToSet != AUDIO_ROUTE_EARPIECE || isHeadsetPlugged || vam.isSpeakerphoneOn() || (isBluetoothHeadsetConnected() && am.isBluetoothScoOn())) {
return;
}
boolean newIsNear = event.values[0] < Math.min(event.sensor.getMaximumRange(), 3);
@ -4404,8 +4427,9 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
if (tgVoip[CAPTURE_DEVICE_CAMERA] != null) {
if (!USE_CONNECTION_SERVICE) {
final AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
tgVoip[CAPTURE_DEVICE_CAMERA].setAudioOutputGainControlEnabled(hasEarpiece() && !am.isSpeakerphoneOn() && !am.isBluetoothScoOn() && !isHeadsetPlugged);
tgVoip[CAPTURE_DEVICE_CAMERA].setEchoCancellationStrength(isHeadsetPlugged || (hasEarpiece() && !am.isSpeakerphoneOn() && !am.isBluetoothScoOn() && !isHeadsetPlugged) ? 0 : 1);
boolean isSpeakerPhoneOn = VoipAudioManager.get().isSpeakerphoneOn();
tgVoip[CAPTURE_DEVICE_CAMERA].setAudioOutputGainControlEnabled(hasEarpiece() && !isSpeakerPhoneOn && !am.isBluetoothScoOn() && !isHeadsetPlugged);
tgVoip[CAPTURE_DEVICE_CAMERA].setEchoCancellationStrength(isHeadsetPlugged || (hasEarpiece() && !isSpeakerPhoneOn && !am.isBluetoothScoOn() && !isHeadsetPlugged) ? 0 : 1);
} else {
final boolean isEarpiece = systemCallConnection.getCallAudioState().getRoute() == CallAudioState.ROUTE_EARPIECE;
tgVoip[CAPTURE_DEVICE_CAMERA].setAudioOutputGainControlEnabled(isEarpiece);

View file

@ -0,0 +1,53 @@
package org.telegram.messenger.voip;
import static android.content.Context.AUDIO_SERVICE;
import android.media.AudioManager;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.Utilities;
public class VoipAudioManager {
private Boolean isSpeakerphoneOn;
private VoipAudioManager() {
}
private static final class InstanceHolder {
static final VoipAudioManager instance = new VoipAudioManager();
}
public static VoipAudioManager get() {
return InstanceHolder.instance;
}
/**
* Sets the speakerphone on or off asynchronously.
* On Samsung devices {@link AudioManager#setSpeakerphoneOn} and {@link AudioManager#isSpeakerphoneOn} take too much time.
*/
public void setSpeakerphoneOn(boolean on) {
isSpeakerphoneOn = on;
final AudioManager audioManager = getAudioManager();
Utilities.globalQueue.postRunnable(() -> {
audioManager.setSpeakerphoneOn(on);
});
}
/**
* Checks whether the speakerphone is on or off.
* {@link AudioManager#isSpeakerphoneOn} is fast if {@link AudioManager#setSpeakerphoneOn} has not been called before.
*/
public boolean isSpeakerphoneOn() {
if (isSpeakerphoneOn == null) {
AudioManager audioManager = getAudioManager();
return audioManager.isSpeakerphoneOn();
}
return isSpeakerphoneOn;
}
private AudioManager getAudioManager() {
return (AudioManager) ApplicationLoader.applicationContext.getSystemService(AUDIO_SERVICE);
}
}

View file

@ -5282,6 +5282,23 @@ public class Theme {
}
}
public static Drawable getSelectorDrawableByColor(int colorValue, int backgroundColorValue) {
if (Build.VERSION.SDK_INT >= 21) {
Drawable maskDrawable = new ColorDrawable(0xffffffff);
ColorStateList colorStateList = new ColorStateList(
new int[][]{StateSet.WILD_CARD},
new int[]{colorValue}
);
return new RippleDrawable(colorStateList, new ColorDrawable(backgroundColorValue), maskDrawable);
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(colorValue));
stateListDrawable.addState(new int[]{android.R.attr.state_selected}, new ColorDrawable(colorValue));
stateListDrawable.addState(StateSet.WILD_CARD, new ColorDrawable(backgroundColorValue));
return stateListDrawable;
}
}
public static Drawable createSelectorDrawable(int color) {
return createSelectorDrawable(color, RIPPLE_MASK_CIRCLE_20DP, -1);
}

View file

@ -177,6 +177,7 @@ import java.util.concurrent.atomic.AtomicReference;
public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate, ImageReceiver.ImageReceiverDelegate, DownloadController.FileDownloadProgressListener, TextSelectionHelper.SelectableView, NotificationCenter.NotificationCenterDelegate {
private final static int TIME_APPEAR_MS = 200;
private final static int UPLOADING_ALLOWABLE_ERROR = 1024 * 1024;
public boolean clipToGroupBounds;
public boolean drawForBlur;
@ -6255,7 +6256,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (captionLayout != null && currentPosition != null && currentMessagesGroup != null && currentMessagesGroup.isDocuments) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
} else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && ((docTitleLayout != null && docTitleLayout.getLineCount() > 1) || currentMessageObject.hasValidReplyMessageObject())) {
} else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && ((docTitleLayout != null && docTitleLayout.getLineCount() > 1) || currentMessageObject.hasValidReplyMessageObject()) && !currentMessageObject.isForwarded()) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
} else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && !currentMessageObject.isOutOwner()) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
@ -6266,7 +6267,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (drawPhotoImage && captionLayout == null) {
reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(8);
}
if (captionLayout != null && currentMessageObject != null && currentMessageObject.isOutOwner() && currentMessageObject.isDocument() && currentMessagesGroup == null && !currentMessageObject.isForwarded() && !currentMessageObject.isReply()) {
if (!drawPhotoImage && captionLayout != null && currentMessageObject != null && currentMessageObject.isOutOwner() && currentMessageObject.isDocument() && currentMessagesGroup == null && !currentMessageObject.isForwarded() && !currentMessageObject.isReply()) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
}
@ -12053,6 +12054,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
radialProgress.setIcon(MediaActionDrawable.ICON_CHECK, false, true);
}
}
if (lastLoadingSizeTotal > 0 && Math.abs(lastLoadingSizeTotal - totalSize) > UPLOADING_ALLOWABLE_ERROR) {
lastLoadingSizeTotal = totalSize;
}
createLoadingProgressLayout(uploadedSize, totalSize);
}

View file

@ -19,7 +19,6 @@ import android.view.Gravity;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
@ -35,24 +34,25 @@ import org.telegram.ui.Components.LayoutHelper;
public class CheckBoxCell extends FrameLayout {
public final static int TYPE_CHECK_BOX_ROUND = 4;
public final static int
TYPE_CHECK_BOX_DEFAULT = 1,
TYPE_CHECK_BOX_ENTER_PHONE = 2,
TYPE_CHECK_BOX_UNKNOWN = 3,
TYPE_CHECK_BOX_ROUND = 4,
TYPE_CHECK_BOX_URL = 5;
private final Theme.ResourcesProvider resourcesProvider;
private TextView textView;
private TextView valueTextView;
private View checkBox;
private final TextView textView;
private final TextView valueTextView;
private final View checkBox;
private CheckBoxSquare checkBoxSquare;
private CheckBox2 checkBoxRound;
private View collapsedArrow;
private final int currentType;
private final int checkBoxSize;
private boolean needDivider;
private boolean isMultiline;
private int currentType;
private int checkBoxSize = 18;
private LinearLayout contentView;
private Boolean collapsed;
private View collapsedArrow;
private boolean collapseArrowSet;
public CheckBoxCell(Context context, int type) {
this(context, type, 17, null);
@ -65,8 +65,7 @@ public class CheckBoxCell extends FrameLayout {
public CheckBoxCell(Context context, int type, int padding, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.resourcesProvider = resourcesProvider;
currentType = type;
this.currentType = type;
textView = new TextView(context) {
@Override
@ -82,28 +81,28 @@ public class CheckBoxCell extends FrameLayout {
}
};
NotificationCenter.listenEmojiLoading(textView);
textView.setTag(getThemedColor(type == 1 || type == 5 ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setTag(getThemedColor(type == TYPE_CHECK_BOX_DEFAULT || type == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
if (type == 3) {
if (type == TYPE_CHECK_BOX_UNKNOWN) {
textView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 29, 0, 0, 0));
textView.setPadding(0, 0, 0, AndroidUtilities.dp(3));
} else {
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
if (type == 2) {
if (type == TYPE_CHECK_BOX_ENTER_PHONE) {
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 8 : 29), 0, (LocaleController.isRTL ? 29 : 8), 0));
} else {
int offset = type == 4 ? 56 : 46;
addView(textView, LayoutHelper.createFrame(type == 4 ? LayoutHelper.WRAP_CONTENT : LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? padding : offset + (padding - 17)), 0, (LocaleController.isRTL ? offset + (padding - 17) : padding), 0));
int offset = type == TYPE_CHECK_BOX_ROUND ? 56 : 46;
addView(textView, LayoutHelper.createFrame(type == TYPE_CHECK_BOX_ROUND ? LayoutHelper.WRAP_CONTENT : LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? padding : offset + (padding - 17)), 0, (LocaleController.isRTL ? offset + (padding - 17) : padding), 0));
}
}
valueTextView = new TextView(context);
valueTextView.setTag(type == 1 || type == 5 ? Theme.key_dialogTextBlue : Theme.key_windowBackgroundWhiteValueText);
valueTextView.setTag(type == TYPE_CHECK_BOX_DEFAULT || type == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextBlue : Theme.key_windowBackgroundWhiteValueText);
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
valueTextView.setLines(1);
valueTextView.setMaxLines(1);
@ -120,13 +119,13 @@ public class CheckBoxCell extends FrameLayout {
checkBoxSize = 21;
addView(checkBox, LayoutHelper.createFrame(checkBoxSize, checkBoxSize, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : padding), 16, (LocaleController.isRTL ? padding : 0), 0));
} else {
checkBox = checkBoxSquare = new CheckBoxSquare(context, type == 1 || type == 5, resourcesProvider);
checkBox = checkBoxSquare = new CheckBoxSquare(context, type == TYPE_CHECK_BOX_DEFAULT || type == TYPE_CHECK_BOX_URL, resourcesProvider);
checkBoxSize = 18;
if (type == 5) {
if (type == TYPE_CHECK_BOX_URL) {
addView(checkBox, LayoutHelper.createFrame(checkBoxSize, checkBoxSize, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL, (LocaleController.isRTL ? 0 : padding), 0, (LocaleController.isRTL ? padding : 0), 0));
} else if (type == 3) {
} else if (type == TYPE_CHECK_BOX_UNKNOWN) {
addView(checkBox, LayoutHelper.createFrame(checkBoxSize, checkBoxSize, Gravity.LEFT | Gravity.TOP, 0, 15, 0, 0));
} else if (type == 2) {
} else if (type == TYPE_CHECK_BOX_ENTER_PHONE) {
addView(checkBox, LayoutHelper.createFrame(checkBoxSize, checkBoxSize, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 0, 15, 0, 0));
} else {
addView(checkBox, LayoutHelper.createFrame(checkBoxSize, checkBoxSize, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 0 : padding), 16, (LocaleController.isRTL ? padding : 0), 0));
@ -136,9 +135,9 @@ public class CheckBoxCell extends FrameLayout {
}
public void updateTextColor() {
textView.setTextColor(getThemedColor(currentType == 1 || currentType == 5 ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setLinkTextColor(getThemedColor(currentType == 1 || currentType == 5 ? Theme.key_dialogTextLink : Theme.key_windowBackgroundWhiteLinkText));
valueTextView.setTextColor(getThemedColor(currentType == 1 || currentType == 5 ? Theme.key_dialogTextBlue : Theme.key_windowBackgroundWhiteValueText));
textView.setTextColor(getThemedColor(currentType == TYPE_CHECK_BOX_DEFAULT || currentType == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextBlack : Theme.key_windowBackgroundWhiteBlackText));
textView.setLinkTextColor(getThemedColor(currentType == TYPE_CHECK_BOX_DEFAULT || currentType == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextLink : Theme.key_windowBackgroundWhiteLinkText));
valueTextView.setTextColor(getThemedColor(currentType == TYPE_CHECK_BOX_DEFAULT || currentType == TYPE_CHECK_BOX_URL ? Theme.key_dialogTextBlue : Theme.key_windowBackgroundWhiteValueText));
}
private View click1Container, click2Container;
@ -190,7 +189,6 @@ public class CheckBoxCell extends FrameLayout {
collapsedArrow.animate().cancel();
collapsedArrow.animate().rotation(collapsed ? 0 : 180).setDuration(340).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).start();
}
this.collapsed = collapsed;
}
private void updateCollapseArrowTranslation() {
@ -210,13 +208,12 @@ public class CheckBoxCell extends FrameLayout {
translateX = textView.getLeft() + textWidth + AndroidUtilities.dp(4);
}
collapsedArrow.setTranslationX(translateX);
collapseArrowSet = true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
if (currentType == 3) {
if (currentType == TYPE_CHECK_BOX_UNKNOWN) {
valueTextView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(10), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(34), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(50), MeasureSpec.EXACTLY));
checkBox.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(checkBoxSize), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(checkBoxSize), MeasureSpec.EXACTLY));
@ -246,8 +243,8 @@ public class CheckBoxCell extends FrameLayout {
}
if (collapsedArrow != null) {
collapsedArrow.measure(
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(16), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(16), MeasureSpec.EXACTLY)
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(16), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(16), MeasureSpec.EXACTLY)
);
}
}
@ -259,6 +256,7 @@ public class CheckBoxCell extends FrameLayout {
public void setText(CharSequence text, String value, boolean checked, boolean divider) {
setText(text, value, checked, divider, false);
}
public void setText(CharSequence text, String value, boolean checked, boolean divider, boolean animated) {
textView.setText(text);
if (checkBoxRound != null) {
@ -269,7 +267,6 @@ public class CheckBoxCell extends FrameLayout {
valueTextView.setText(value);
needDivider = divider;
setWillNotDraw(!divider);
collapseArrowSet = false;
}
public void setPad(int pad) {
@ -286,7 +283,7 @@ public class CheckBoxCell extends FrameLayout {
}
}
public void setNeedDivider(boolean needDivider){
public void setNeedDivider(boolean needDivider) {
this.needDivider = needDivider;
}
@ -299,7 +296,7 @@ public class CheckBoxCell extends FrameLayout {
textView.setMaxLines(0);
textView.setSingleLine(false);
textView.setEllipsize(null);
if (currentType != 5) {
if (currentType != TYPE_CHECK_BOX_URL) {
textView.setPadding(0, 0, 0, AndroidUtilities.dp(5));
layoutParams.height = LayoutParams.WRAP_CONTENT;
layoutParams.topMargin = AndroidUtilities.dp(10);
@ -358,7 +355,7 @@ public class CheckBoxCell extends FrameLayout {
public void setCheckBoxColor(int background, int background1, int check) {
if (checkBoxRound != null) {
checkBoxRound.setColor(background,background,check);
checkBoxRound.setColor(background, background, check);
}
}

View file

@ -53,7 +53,6 @@ public class DialogsHintCell extends FrameLayout {
chevronView = new ImageView(context);
chevronView.setImageResource(R.drawable.arrow_newchat);
chevronView.setColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText), PorterDuff.Mode.SRC_IN);
addView(chevronView, LayoutHelper.createFrame(16, 16, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL));
updateColors();
@ -62,6 +61,8 @@ public class DialogsHintCell extends FrameLayout {
public void updateColors() {
titleView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
messageView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
chevronView.setColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText), PorterDuff.Mode.SRC_IN);
setBackground(Theme.AdaptiveRipple.filledRect());
}
public void setText(CharSequence title, CharSequence subtitle) {

View file

@ -33,7 +33,7 @@ public class PaymentInfoCell extends FrameLayout {
private TextView detailExTextView;
private BackupImageView imageView;
public PaymentInfoCell(Context context) {
public PaymentInfoCell(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context);
imageView = new BackupImageView(context);
@ -41,7 +41,7 @@ public class PaymentInfoCell extends FrameLayout {
addView(imageView, LayoutHelper.createFrame(100, 100, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), 10, 10, 10, 0));
nameTextView = new TextView(context);
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
nameTextView.setLines(1);
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
@ -52,7 +52,7 @@ public class PaymentInfoCell extends FrameLayout {
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 10 : 123, 9, LocaleController.isRTL ? 123 : 10, 0));
detailTextView = new TextView(context);
detailTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
detailTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
detailTextView.setMaxLines(3);
detailTextView.setEllipsize(TextUtils.TruncateAt.END);
@ -60,7 +60,7 @@ public class PaymentInfoCell extends FrameLayout {
addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 10 : 123, 33, LocaleController.isRTL ? 123 : 10, 0));
detailExTextView = new TextView(context);
detailExTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2));
detailExTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
detailExTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
detailExTextView.setLines(1);
detailExTextView.setMaxLines(1);

View file

@ -34,10 +34,14 @@ public class TextDetailSettingsCell extends FrameLayout {
private boolean multiline;
public TextDetailSettingsCell(Context context) {
this(context, null);
}
public TextDetailSettingsCell(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context);
textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
textView.setMaxLines(1);
@ -47,7 +51,7 @@ public class TextDetailSettingsCell extends FrameLayout {
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 21, 10, 21, 0));
valueTextView = new TextView(context);
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2));
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
valueTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
valueTextView.setLines(1);
@ -58,7 +62,7 @@ public class TextDetailSettingsCell extends FrameLayout {
imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.MULTIPLY));
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
imageView.setVisibility(GONE);
addView(imageView, LayoutHelper.createFrame(52, 52, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 8, 6, 8, 0));
}

View file

@ -23,12 +23,15 @@ import org.telegram.ui.Components.LayoutHelper;
public class TextPriceCell extends FrameLayout {
private Theme.ResourcesProvider resourcesProvider;
private TextView textView;
private TextView valueTextView;
public TextPriceCell(Context context) {
public TextPriceCell(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.resourcesProvider = resourcesProvider;
setWillNotDraw(false);
textView = new TextView(context);
@ -82,14 +85,14 @@ public class TextPriceCell extends FrameLayout {
}
if (bold) {
setTag(Theme.key_windowBackgroundWhiteBlackText);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
valueTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
} else {
setTag(Theme.key_windowBackgroundWhiteGrayText2);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2));
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2));
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
textView.setTypeface(Typeface.DEFAULT);
valueTextView.setTypeface(Typeface.DEFAULT);
}

View file

@ -4184,7 +4184,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int wasOutlineAlpha = skeletonOutlinePaint.getAlpha();
skeletonServicePaint.setAlpha((int) (0xFF * topSkeletonAlpha));
skeletonPaint.setAlpha((int) (topSkeletonAlpha * alpha));
skeletonOutlinePaint.setAlpha((int) (wasOutlineAlpha * alpha));
skeletonOutlinePaint.setAlpha((int) (topSkeletonAlpha * alpha));
while (lastTop > blurredViewTopOffset) {
lastTop -= AndroidUtilities.dp(3f);
@ -6721,7 +6721,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
bottomOverlayStartButton.setOnClickListener(v -> bottomOverlayChatText.callOnClick());
bottomOverlayChat.addView(bottomOverlayStartButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.CENTER, 8, 8, 8, 8));
if (currentUser != null && currentUser.bot && !UserObject.isReplyUser(currentUser) && !isInScheduleMode()) {
if (currentUser != null && currentUser.bot && !UserObject.isReplyUser(currentUser) && !isInScheduleMode() && chatMode != MODE_PINNED) {
bottomOverlayStartButton.setVisibility(View.VISIBLE);
bottomOverlayChat.setVisibility(View.VISIBLE);
}
@ -20039,7 +20039,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private void showInfoHint(MessageObject messageObject, CharSequence text, int type) {
int duration = Math.max(4000, Math.min((text == null ? 0 : text.length()) / 50 * 1600, 10000));
BulletinFactory.of(this).createSimpleBulletin(R.raw.chats_infotip, text, 3).setDuration(duration).setOnHideListener(() -> {
BulletinFactory.of(this).createSimpleBulletin(R.raw.chats_infotip, text, 9999).setDuration(duration).setOnHideListener(() -> {
if (chatListView != null) {
int count = chatListView.getChildCount();
for (int a = 0; a < count; a++) {
@ -22424,7 +22424,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public int getTopOffset(int tag) {
return (actionBar != null ? actionBar.getMeasuredHeight() + (int) actionBar.getTranslationY() : 0) + Math.max(0, (int) chatListViewPaddingTop - AndroidUtilities.dp(4));
return (actionBar != null ? actionBar.getMeasuredHeight() + (int) actionBar.getTranslationY() : 0) + Math.max(0, contentPaddingTop);
}
@Override

View file

@ -43,6 +43,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.Editable;
import android.text.Layout;
import android.text.Spannable;
@ -406,6 +407,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private Drawable sendButtonDrawable;
private Drawable inactinveSendButtonDrawable;
private Drawable sendButtonInverseDrawable;
private int sendButtonBackgroundColor;
private ActionBarPopupWindow sendPopupWindow;
private ActionBarPopupWindow.ActionBarPopupWindowLayout sendPopupLayout;
private ImageView cancelBotButton;
@ -3953,6 +3955,15 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
}
/**
* Samsung keyboard does not support incognito mode.
* Also on samsung keyboard when the EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING flag is set, the keyboard starts to lag.
*/
private boolean isKeyboardSupportIncognitoMode() {
String keyboardName = Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
return keyboardName == null || !keyboardName.startsWith("com.samsung");
}
private void createMessageEditText() {
if (messageEditText != null) {
return;
@ -3972,8 +3983,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
TLRPC.EncryptedChat encryptedChat = parentFragment != null ? parentFragment.getCurrentEncryptedChat() : null;
messageEditText.setAllowTextEntitiesIntersection(supportsSendingNewEntities());
int flags = EditorInfo.IME_FLAG_NO_EXTRACT_UI;
if (encryptedChat != null) {
flags |= 0x01000000; // EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING;
if (isKeyboardSupportIncognitoMode() && encryptedChat != null) {
flags |= EditorInfoCompat.IME_FLAG_NO_PERSONALIZED_LEARNING;
}
messageEditText.setIncludeFontPadding(false);
messageEditText.setImeOptions(flags);
@ -5797,7 +5808,12 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} else {
color = getThemedColor(Theme.key_chat_messagePanelSend);
}
Theme.setSelectorDrawableColor(sendButton.getBackground(), Color.argb(24, Color.red(color), Color.green(color), Color.blue(color)), true);
if (color != sendButtonBackgroundColor) {
sendButtonBackgroundColor = color;
Theme.setSelectorDrawableColor(sendButton.getBackground(), Color.argb(24, Color.red(color), Color.green(color), Color.blue(color)), true);
}
if (audioVideoButtonContainer.getVisibility() == VISIBLE || slowModeButton.getVisibility() == VISIBLE || showBotButton || showSendButton) {
if (animated) {
if (runningAnimationType == 1 && caption == null || runningAnimationType == 3 && caption != null) {

View file

@ -19,6 +19,7 @@ import org.telegram.ui.ActionBar.Theme;
public class ContextProgressView extends View {
private Theme.ResourcesProvider resourcesProvider;
private Paint innerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint outerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private RectF cicleRect = new RectF();
@ -31,7 +32,12 @@ public class ContextProgressView extends View {
private int outerColor;
public ContextProgressView(Context context, int colorType) {
this(context, colorType, null);
}
public ContextProgressView(Context context, int colorType, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.resourcesProvider = resourcesProvider;
innerPaint.setStyle(Paint.Style.STROKE);
innerPaint.setStrokeWidth(AndroidUtilities.dp(2));
outerPaint.setStyle(Paint.Style.STROKE);
@ -63,12 +69,12 @@ public class ContextProgressView extends View {
public void updateColors() {
if (innerKey >= 0) {
innerPaint.setColor(Theme.getColor(innerKey));
innerPaint.setColor(Theme.getColor(innerKey, resourcesProvider));
} else {
innerPaint.setColor(innerColor);
}
if (outerKey >= 0) {
outerPaint.setColor(Theme.getColor(outerKey));
outerPaint.setColor(Theme.getColor(outerKey, resourcesProvider));
} else {
outerPaint.setColor(outerColor);
}

View file

@ -26,6 +26,8 @@ public interface IPhotoPaintView {
void shutdown();
void onResume();
default void onAnimationStateChanged(boolean isStart) {}
default void setOffsetTranslationX(float x) {}
void setOffsetTranslationY(float y, float panProgress, int keyboardHeight, boolean isPan);
float getOffsetTranslationY();
void updateColors();

View file

@ -717,7 +717,6 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
textOptionsView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0);
textOptionsView.setVisibility(GONE);
textOptionsView.setDelegate(this);
textOptionsView.setTypeface(PersistColorPalette.getInstance(currentAccount).getCurrentTypeface());
textOptionsView.setAlignment(PersistColorPalette.getInstance(currentAccount).getCurrentAlignment());
bottomLayout.addView(textOptionsView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48));
@ -1483,6 +1482,7 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
@Override
public void init() {
textOptionsView.setTypeface(PersistColorPalette.getInstance(currentAccount).getCurrentTypeface());
entitiesView.setVisibility(VISIBLE);
renderView.setVisibility(View.VISIBLE);
renderInputView.setVisibility(View.VISIBLE);
@ -1564,16 +1564,25 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
renderView.redraw();
}
@Override
public void onAnimationStateChanged(boolean isStart) {
if (tabsSelectedIndex == 0) {
weightChooserView.setLayerType(isStart ? LAYER_TYPE_HARDWARE : LAYER_TYPE_NONE, null);
}
}
@Override
public void setOffsetTranslationX(float x) {
if (tabsSelectedIndex == 0) {
weightChooserView.setTranslationX(x);
}
}
@Override
public void setOffsetTranslationY(float y, float progress, int keyboardHeight, boolean isPan) {
offsetTranslationY = y;
if (!isPan) {
topLayout.setTranslationY(-y);
if (tabsSelectedIndex == 0) {
weightChooserView.setTranslationX(-y);
}
bottomLayout.setTranslationY(y);
} else {
setTranslationY(0);

View file

@ -64,7 +64,6 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
public static final int TYPE_SHARED_FOLDERS = 13;
private boolean canSendLink;
private TLRPC.TL_webPage linkPreview;
public static String limitTypeToServerString(int type) {
switch (type) {
@ -253,7 +252,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
}
for (Object obj : selectedChats) {
TLRPC.User user = (TLRPC.User) obj;
SendMessagesHelper.getInstance(currentAccount).sendMessage(link, user.id, null, null, linkPreview, false, null, null, null, false, 0, null, false);
SendMessagesHelper.getInstance(currentAccount).sendMessage(link, user.id, null, null, null, true, null, null, null, false, 0, null, false);
}
AndroidUtilities.runOnUIThread(() -> {
BulletinFactory factory = BulletinFactory.global();
@ -520,26 +519,8 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView {
}
updateRows();
updateButton();
TLRPC.ChatFull chatFull = MessagesController.getInstance(currentAccount).getChatFull(fromChat.id);
String link;
if (fromChat.username == null && chatFull != null && chatFull.exported_invite != null) {
link = chatFull.exported_invite.link;
TLRPC.TL_messages_getWebPage webPagePreview = new TLRPC.TL_messages_getWebPage();
webPagePreview.url = link;
ConnectionsManager.getInstance(currentAccount).sendRequest(webPagePreview,(response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response != null) {
if (response instanceof TLRPC.TL_webPage) {
linkPreview = (TLRPC.TL_webPage) response;
}
}
}));
}
}
private class HeaderView extends LinearLayout {
@SuppressLint("SetTextI18n")

View file

@ -34,8 +34,8 @@ public class ProxyDrawable extends Drawable {
public ProxyDrawable(Context context) {
super();
emptyDrawable = context.getResources().getDrawable(R.drawable.msg2_proxy_off);
fullDrawable = context.getResources().getDrawable(R.drawable.msg2_proxy_on);
emptyDrawable = context.getResources().getDrawable(R.drawable.msg2_proxy_off).mutate();
fullDrawable = context.getResources().getDrawable(R.drawable.msg2_proxy_on).mutate();
outerPaint.setStyle(Paint.Style.STROKE);
outerPaint.setStrokeWidth(AndroidUtilities.dp(1.66f));

View file

@ -398,6 +398,23 @@ public class SuggestEmojiView extends FrameLayout implements NotificationCenter.
private int lastQueryId;
private String[] lastLang;
private Runnable searchRunnable;
private long lastLangChangedTime = 0;
/**
* The user needs time to change the locale. We estimate this time to be at least 360 ms.
*/
private String[] detectKeyboardLangThrottleFirstWithDelay() {
long currentTime = System.currentTimeMillis();
int delay = 360;
if (lastLang == null || Math.abs(currentTime - lastLangChangedTime) > delay) {
lastLangChangedTime = currentTime;
return AndroidUtilities.getCurrentKeyboardLanguage();
} else {
lastLangChangedTime = currentTime;
}
return lastLang;
}
private void searchKeywords(String query) {
if (query == null) {
return;
@ -412,7 +429,7 @@ public class SuggestEmojiView extends FrameLayout implements NotificationCenter.
}
final int id = ++lastQueryId;
String[] lang = AndroidUtilities.getCurrentKeyboardLanguage();
String[] lang = detectKeyboardLangThrottleFirstWithDelay();
if (lastLang == null || !Arrays.equals(lang, lastLang)) {
MediaDataController.getInstance(currentAccount).fetchNewEmojiKeywords(lang);
}
@ -445,6 +462,7 @@ public class SuggestEmojiView extends FrameLayout implements NotificationCenter.
adapter.notifyDataSetChanged();
}
} else {
keywordResults = null;
clear = true;
forceClose();
}

View file

@ -3900,7 +3900,6 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
fragmentLocationContextView.setAdditionalContextView(fragmentContextView);
dialogsHintCell = new DialogsHintCell(context);
dialogsHintCell.setBackground(Theme.AdaptiveRipple.filledRect());
updateDialogsHint();
CacheControlActivity.calculateTotalSize(size -> {
cacheSize = size;
@ -4655,6 +4654,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
if (isPremiumRestoreHintVisible()) {
dialogsHintCell.setVisibility(View.VISIBLE);
dialogsHintCell.setOnClickListener(v -> {
if (rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment()) return;
presentFragment(new PremiumPreviewFragment("dialogs_hint").setSelectAnnualByDefault());
AndroidUtilities.runOnUIThread(() -> {
MessagesController.getInstance(currentAccount).removeSuggestion(0, "PREMIUM_RESTORE");
@ -4673,6 +4673,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} else if (isPremiumHintVisible()) {
dialogsHintCell.setVisibility(View.VISIBLE);
dialogsHintCell.setOnClickListener(v -> {
if (rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment()) return;
presentFragment(new PremiumPreviewFragment("dialogs_hint").setSelectAnnualByDefault());
AndroidUtilities.runOnUIThread(() -> {
MessagesController.getInstance(currentAccount).removeSuggestion(0, isPremiumHintUpgrade ? "PREMIUM_UPGRADE" : "PREMIUM_ANNUAL");
@ -4691,6 +4692,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} else if (isCacheHintVisible()) {
dialogsHintCell.setVisibility(View.VISIBLE);
dialogsHintCell.setOnClickListener(v -> {
if (rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment()) return;
presentFragment(new CacheControlActivity());
AndroidUtilities.runOnUIThread(() -> {
resetCacheHintVisible();
@ -7145,7 +7147,12 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
filterTabsView.setTranslationY(value);
}
if (dialogsHintCell != null) {
dialogsHintCell.setTranslationY(value);
if (rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment() && filterTabsView != null && filterTabsView.getVisibility() == View.VISIBLE) {
float tabsYOffset = (1f - filterTabsProgress) * filterTabsView.getMeasuredHeight();
dialogsHintCell.setTranslationY(value - tabsYOffset);
} else {
dialogsHintCell.setTranslationY(value);
}
}
if (animatedStatusView != null) {
animatedStatusView.translateY2((int) value);

View file

@ -96,6 +96,7 @@ import org.telegram.messenger.Utilities;
import org.telegram.messenger.support.LongSparseIntArray;
import org.telegram.messenger.voip.Instance;
import org.telegram.messenger.voip.VoIPService;
import org.telegram.messenger.voip.VoipAudioManager;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
@ -158,6 +159,7 @@ import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
public class GroupCallActivity extends BottomSheet implements NotificationCenter.NotificationCenterDelegate, VoIPService.StateListener {
@ -1721,6 +1723,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
private GroupCallActivity(Context context, AccountInstance account, ChatObject.Call groupCall, TLRPC.Chat chat, TLRPC.InputPeer schedulePeer, boolean scheduleHasFewPeers, String scheduledHash) {
super(context, false);
setOpenNoDelay(true);
this.accountInstance = account;
this.call = groupCall;
this.schedulePeer = schedulePeer;
@ -1740,6 +1743,14 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
@Override
public void onOpenAnimationEnd() {
VoIPService voipService = VoIPService.getSharedInstance();
if (voipService != null) {
CountDownLatch latch = voipService.getGroupCallBottomSheetLatch();
if (latch != null) {
latch.countDown();
}
}
if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
showReminderHint();
}
@ -4409,8 +4420,8 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
soundItem.setIcon(VoIPService.getSharedInstance().isHeadsetPlugged() ? R.drawable.msg_voice_headphones : R.drawable.msg_voice_phone);
soundItem.setSubtext(VoIPService.getSharedInstance().isHeadsetPlugged() ? LocaleController.getString("VoipAudioRoutingHeadset", R.string.VoipAudioRoutingHeadset) : LocaleController.getString("VoipAudioRoutingPhone", R.string.VoipAudioRoutingPhone));
} else if (rout == VoIPService.AUDIO_ROUTE_SPEAKER) {
AudioManager am = (AudioManager) context.getSystemService(AUDIO_SERVICE);
if (am.isSpeakerphoneOn()) {
VoipAudioManager vam = VoipAudioManager.get();
if (vam.isSpeakerphoneOn()) {
soundItem.setIcon(R.drawable.msg_voice_speaker);
soundItem.setSubtext(LocaleController.getString("VoipAudioRoutingSpeaker", R.string.VoipAudioRoutingSpeaker));
} else {

View file

@ -7158,7 +7158,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
}
} else {
boolean allow = true; // TODO: Make it a flag inside fragment itself, maybe BaseFragment#isDrawerOpenAllowed()?
if (fragment instanceof LoginActivity || fragment instanceof IntroActivity || fragment instanceof ProxyListActivity) {
if (fragment instanceof LoginActivity || fragment instanceof IntroActivity || fragment instanceof ProxyListActivity || fragment instanceof ProxySettingsActivity) {
if (mainFragmentsStack.size() == 0 || mainFragmentsStack.get(0) instanceof IntroActivity || mainFragmentsStack.get(0) instanceof LoginActivity) {
allow = false;
}
@ -7175,7 +7175,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
@Override
public boolean needAddFragmentToStack(BaseFragment fragment, INavigationLayout layout) {
if (AndroidUtilities.isTablet()) {
drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity || fragment instanceof IntroActivity || fragment instanceof CountrySelectActivity || fragment instanceof ProxyListActivity) && layersActionBarLayout.getView().getVisibility() != View.VISIBLE, true);
drawerLayoutContainer.setAllowOpenDrawer(!(fragment instanceof LoginActivity || fragment instanceof IntroActivity || fragment instanceof CountrySelectActivity || fragment instanceof ProxyListActivity || fragment instanceof ProxySettingsActivity) && layersActionBarLayout.getView().getVisibility() != View.VISIBLE, true);
if (fragment instanceof DialogsActivity) {
DialogsActivity dialogsActivity = (DialogsActivity) fragment;
if (dialogsActivity.isMainDialogList() && layout != actionBarLayout) {
@ -7241,7 +7241,7 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
}
} else {
boolean allow = true;
if (fragment instanceof LoginActivity || fragment instanceof IntroActivity || fragment instanceof ProxyListActivity) {
if (fragment instanceof LoginActivity || fragment instanceof IntroActivity || fragment instanceof ProxyListActivity || fragment instanceof ProxySettingsActivity) {
if (mainFragmentsStack.size() == 0 || mainFragmentsStack.get(0) instanceof IntroActivity) {
allow = false;
}

View file

@ -8253,17 +8253,17 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
currentConnectionState = state;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
String proxyAddress = preferences.getString("proxy_ip", "");
final boolean proxyEnabled = preferences.getBoolean("proxy_enabled", false);
final boolean proxyEnabled = preferences.getBoolean("proxy_enabled", false) && !TextUtils.isEmpty(proxyAddress);
final boolean connected = currentConnectionState == ConnectionsManager.ConnectionStateConnected || currentConnectionState == ConnectionsManager.ConnectionStateUpdating;
final boolean connecting = currentConnectionState == ConnectionsManager.ConnectionStateConnecting || currentConnectionState == ConnectionsManager.ConnectionStateWaitingForNetwork || currentConnectionState == ConnectionsManager.ConnectionStateConnectingToProxy;
final boolean show = (proxyEnabled && !TextUtils.isEmpty(proxyAddress)) || getMessagesController().blockedCountry && !SharedConfig.proxyList.isEmpty() || connecting;
if (show) {
if (proxyEnabled) {
proxyDrawable.setConnected(true, connected, animated);
showProxyButton(true, animated);
} else if (getMessagesController().blockedCountry && !SharedConfig.proxyList.isEmpty() || connecting) {
proxyDrawable.setConnected(true, connected, animated);
showProxyButtonDelayed();
} else {
showProxyButton(show, animated);
}
if (show) {
proxyDrawable.setConnected(true, connected, animated);
showProxyButton(false, animated);
}
}

View file

@ -25,6 +25,7 @@ import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@ -611,7 +612,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
case STEP_CHECKOUT:
case STEP_SET_PASSWORD_EMAIL:
doneItem = menu.addItemWithWidth(done_button, R.drawable.ic_ab_done, AndroidUtilities.dp(56), LocaleController.getString("Done", R.string.Done));
progressView = new ContextProgressView(context, 1);
progressView = new ContextProgressView(context, 1, resourcesProvider);
progressView.setAlpha(0.0f);
progressView.setScaleX(0.1f);
progressView.setScaleY(0.1f);
@ -629,7 +630,17 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
AndroidUtilities.setScrollViewEdgeEffectColor(scrollView, getThemedColor(Theme.key_actionBarDefault));
frameLayout.addView(scrollView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, currentStep == STEP_CHECKOUT ? 48 : 0));
linearLayout2 = new LinearLayout(context);
linearLayout2 = new LinearLayout(context) {
@Override
public void setBackgroundColor(int color) {
super.setBackgroundColor(color);
}
@Override
public void setBackground(Drawable background) {
super.setBackground(background);
}
};
linearLayout2.setOrientation(LinearLayout.VERTICAL);
linearLayout2.setClipChildren(false);
scrollView.addView(linearLayout2, new ScrollView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
@ -1022,7 +1033,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
checkCell1 = new TextCheckCell(context, resourcesProvider);
checkCell1.setBackgroundDrawable(Theme.getSelectorDrawable(true));
checkCell1.setBackgroundDrawable(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
checkCell1.setTextAndCheck(LocaleController.getString("PaymentShippingSave", R.string.PaymentShippingSave), saveShippingInfo, false);
linearLayout2.addView(checkCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
checkCell1.setOnClickListener(v -> {
@ -1178,7 +1189,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
linearLayout2.addView(sectionCell[2], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
checkCell1 = new TextCheckCell(context, resourcesProvider);
checkCell1.setBackgroundDrawable(Theme.getSelectorDrawable(true));
checkCell1.setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
checkCell1.setTextAndCheck(LocaleController.getString("PaymentCardSavePaymentInformation", R.string.PaymentCardSavePaymentInformation), saveCardInfo, false);
linearLayout2.addView(checkCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
checkCell1.setOnClickListener(v -> {
@ -1187,7 +1198,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
});
bottomCell[0] = new TextInfoPrivacyCell(context, resourcesProvider);
bottomCell[0].setBackgroundDrawable(Theme.getThemedDrawableByKey(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
bottomCell[0].setBackground(Theme.getThemedDrawableByKey(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
updateSavePaymentField();
linearLayout2.addView(bottomCell[0], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
} else {
@ -1618,7 +1629,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
linearLayout2.addView(sectionCell[2], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
checkCell1 = new TextCheckCell(context, resourcesProvider);
checkCell1.setBackgroundDrawable(Theme.getSelectorDrawable(true));
checkCell1.setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
checkCell1.setTextAndCheck(LocaleController.getString("PaymentCardSavePaymentInformation", R.string.PaymentCardSavePaymentInformation), saveCardInfo, false);
linearLayout2.addView(checkCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
checkCell1.setOnClickListener(v -> {
@ -1627,7 +1638,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
});
bottomCell[0] = new TextInfoPrivacyCell(context, resourcesProvider);
bottomCell[0].setBackgroundDrawable(Theme.getThemedDrawableByKey(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
bottomCell[0].setBackground(Theme.getThemedDrawableByKey(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
updateSavePaymentField();
linearLayout2.addView(bottomCell[0], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
} else if (a == FIELD_CARD) {
@ -1666,9 +1677,9 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
radioCells = new RadioCell[count];
for (int a = 0; a < count; a++) {
TLRPC.TL_shippingOption shippingOption = requestedInfo.shipping_options.get(a);
radioCells[a] = new RadioCell(context);
radioCells[a] = new RadioCell(context, resourcesProvider);
radioCells[a].setTag(a);
radioCells[a].setBackgroundDrawable(Theme.getSelectorDrawable(true));
radioCells[a].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
radioCells[a].setText(String.format("%s - %s", getTotalPriceString(shippingOption.prices), shippingOption.title), a == 0, a != count - 1);
radioCells[a].setOnClickListener(v -> {
int num = (Integer) v.getTag();
@ -1761,7 +1772,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
linearLayout2.addView(bottomCell[0], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
settingsCell[0] = new TextSettingsCell(context, resourcesProvider);
settingsCell[0].setBackgroundDrawable(Theme.getSelectorDrawable(true));
settingsCell[0].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
settingsCell[0].setText(LocaleController.getString("PaymentConfirmationNewCard", R.string.PaymentConfirmationNewCard), false);
linearLayout2.addView(settingsCell[0], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
settingsCell[0].setOnClickListener(v -> {
@ -1775,7 +1786,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
}
} else if (currentStep == STEP_CHECKOUT || currentStep == STEP_RECEIPT) {
paymentInfoCell = new PaymentInfoCell(context);
paymentInfoCell = new PaymentInfoCell(context, resourcesProvider);
paymentInfoCell.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
if (messageObject != null) {
paymentInfoCell.setInvoice((TLRPC.TL_messageMediaInvoice) messageObject.messageOwner.media, currentBotName);
@ -1798,20 +1809,20 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
for (int a = 0; a < prices.size(); a++) {
TLRPC.TL_labeledPrice price = prices.get(a);
TextPriceCell priceCell = new TextPriceCell(context);
TextPriceCell priceCell = new TextPriceCell(context, resourcesProvider);
priceCell.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
priceCell.setTextAndValue(price.label, LocaleController.getInstance().formatCurrencyString(price.amount, paymentForm.invoice.currency), false);
linearLayout2.addView(priceCell);
}
if (currentStep == STEP_RECEIPT && tipAmount != null) {
TextPriceCell priceCell = new TextPriceCell(context);
TextPriceCell priceCell = new TextPriceCell(context, resourcesProvider);
priceCell.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
priceCell.setTextAndValue(LocaleController.getString("PaymentTip", R.string.PaymentTip), LocaleController.getInstance().formatCurrencyString(tipAmount, paymentForm.invoice.currency), false);
linearLayout2.addView(priceCell);
}
totalCell = new TextPriceCell(context);
totalCell = new TextPriceCell(context, resourcesProvider);
totalCell.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
totalPrice[0] = getTotalPriceString(prices);
totalCell.setTextAndValue(LocaleController.getString("PaymentTransactionTotal", R.string.PaymentTransactionTotal), totalPrice[0], true);
@ -1826,7 +1837,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
AndroidUtilities.showKeyboard(inputFields[0]);
});
TextPriceCell cell = new TextPriceCell(context);
TextPriceCell cell = new TextPriceCell(context, resourcesProvider);
cell.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
cell.setTextAndValue(LocaleController.getString("PaymentTipOptional", R.string.PaymentTipOptional), "", false);
container.addView(cell);
@ -2095,8 +2106,8 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
sectionCell[2].setBackgroundDrawable(Theme.getThemedDrawableByKey(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
linearLayout2.addView(sectionCell[2], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
detailSettingsCell[0] = new TextDetailSettingsCell(context);
detailSettingsCell[0].setBackgroundDrawable(Theme.getSelectorDrawable(true));
detailSettingsCell[0] = new TextDetailSettingsCell(context, resourcesProvider);
detailSettingsCell[0].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
detailSettingsCell[0].setTextAndValueAndIcon(cardName != null && cardName.length() > 1 ? cardName.substring(0, 1).toUpperCase() + cardName.substring(1) : cardName, LocaleController.getString("PaymentCheckoutMethod", R.string.PaymentCheckoutMethod), R.drawable.msg_payment_card, true);
int cardInfoVisibility = View.VISIBLE;
if (isCheckoutPreview) {
@ -2120,8 +2131,8 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
providerUser = user;
}
}
detailSettingsCell[1] = new TextDetailSettingsCell(context);
detailSettingsCell[1].setBackground(Theme.getSelectorDrawable(true));
detailSettingsCell[1] = new TextDetailSettingsCell(context, resourcesProvider);
detailSettingsCell[1].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
String providerName;
if (providerUser != null) {
detailSettingsCell[1].setTextAndValueAndIcon(providerName = ContactsController.formatName(providerUser.first_name, providerUser.last_name), LocaleController.getString("PaymentCheckoutProvider", R.string.PaymentCheckoutProvider), R.drawable.msg_payment_provider, validateRequest != null && (validateRequest.info.shipping_address != null || shippingOption != null) || paymentForm.saved_info != null && (paymentForm.saved_info.shipping_address != null));
@ -2134,13 +2145,13 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
if (validateRequest != null || isCheckoutPreview && paymentForm != null && paymentForm.saved_info != null) {
TLRPC.TL_paymentRequestedInfo info = validateRequest != null ? validateRequest.info : paymentForm.saved_info;
detailSettingsCell[2] = new TextDetailSettingsCell(context);
detailSettingsCell[2] = new TextDetailSettingsCell(context, resourcesProvider);
detailSettingsCell[2].setVisibility(View.GONE);
linearLayout2.addView(detailSettingsCell[2]);
if (info.shipping_address != null) {
detailSettingsCell[2].setVisibility(View.VISIBLE);
if (currentStep == STEP_CHECKOUT) {
detailSettingsCell[2].setBackgroundDrawable(Theme.getSelectorDrawable(true));
detailSettingsCell[2].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
detailSettingsCell[2].setOnClickListener(v -> {
PaymentFormActivity activity = new PaymentFormActivity(paymentForm, messageObject, invoiceSlug, STEP_SHIPPING_INFORMATION, requestedInfo, shippingOption, tipAmount, null, cardName, validateRequest, saveCardInfo, null, parentFragment);
activity.setDelegate(new PaymentFormActivityDelegate() {
@ -2157,13 +2168,13 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
}
detailSettingsCell[3] = new TextDetailSettingsCell(context);
detailSettingsCell[3] = new TextDetailSettingsCell(context, resourcesProvider);
detailSettingsCell[3].setVisibility(View.GONE);
linearLayout2.addView(detailSettingsCell[3]);
if (info.name != null) {
detailSettingsCell[3].setVisibility(View.VISIBLE);
if (currentStep == STEP_CHECKOUT) {
detailSettingsCell[3].setBackgroundDrawable(Theme.getSelectorDrawable(true));
detailSettingsCell[3].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
detailSettingsCell[3].setOnClickListener(v -> {
PaymentFormActivity activity = new PaymentFormActivity(paymentForm, messageObject, invoiceSlug, STEP_SHIPPING_INFORMATION, requestedInfo, shippingOption, tipAmount, null, cardName, validateRequest, saveCardInfo, null, parentFragment);
activity.setDelegate(new PaymentFormActivityDelegate() {
@ -2180,13 +2191,13 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
}
detailSettingsCell[4] = new TextDetailSettingsCell(context);
detailSettingsCell[4] = new TextDetailSettingsCell(context, resourcesProvider);
detailSettingsCell[4].setVisibility(View.GONE);
linearLayout2.addView(detailSettingsCell[4]);
if (info.phone != null) {
detailSettingsCell[4].setVisibility(View.VISIBLE);
if (currentStep == STEP_CHECKOUT) {
detailSettingsCell[4].setBackgroundDrawable(Theme.getSelectorDrawable(true));
detailSettingsCell[4].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
detailSettingsCell[4].setOnClickListener(v -> {
PaymentFormActivity activity = new PaymentFormActivity(paymentForm, messageObject, invoiceSlug, STEP_SHIPPING_INFORMATION, requestedInfo, shippingOption, tipAmount, null, cardName, validateRequest, saveCardInfo, null, parentFragment);
activity.setDelegate(new PaymentFormActivityDelegate() {
@ -2203,13 +2214,13 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
}
detailSettingsCell[5] = new TextDetailSettingsCell(context);
detailSettingsCell[5] = new TextDetailSettingsCell(context, resourcesProvider);
detailSettingsCell[5].setVisibility(View.GONE);
linearLayout2.addView(detailSettingsCell[5]);
if (info.email != null) {
detailSettingsCell[5].setVisibility(View.VISIBLE);
if (currentStep == STEP_CHECKOUT) {
detailSettingsCell[5].setBackgroundDrawable(Theme.getSelectorDrawable(true));
detailSettingsCell[5].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
detailSettingsCell[5].setOnClickListener(v -> {
PaymentFormActivity activity = new PaymentFormActivity(paymentForm, messageObject, invoiceSlug, STEP_SHIPPING_INFORMATION, requestedInfo, shippingOption, tipAmount, null, cardName, validateRequest, saveCardInfo, null, parentFragment);
activity.setDelegate(new PaymentFormActivityDelegate() {
@ -2227,7 +2238,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
if (shippingOption != null) {
detailSettingsCell[6] = new TextDetailSettingsCell(context);
detailSettingsCell[6] = new TextDetailSettingsCell(context, resourcesProvider);
detailSettingsCell[6].setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
detailSettingsCell[6].setTextAndValueAndIcon(shippingOption.title, LocaleController.getString("PaymentCheckoutShippingMethod", R.string.PaymentCheckoutShippingMethod), R.drawable.msg_payment_delivery, false);
linearLayout2.addView(detailSettingsCell[6]);
@ -2252,8 +2263,14 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
} catch (Exception ignored) {}
return;
}
final boolean savedInfoMissing = (
paymentForm.invoice.shipping_address_requested && (paymentForm.saved_info == null || paymentForm.saved_info.shipping_address == null) ||
paymentForm.invoice.email_requested && (paymentForm.saved_info == null || paymentForm.saved_info.email == null) ||
paymentForm.invoice.name_requested && (paymentForm.saved_info == null || paymentForm.saved_info.name == null) ||
paymentForm.invoice.phone_requested && (paymentForm.saved_info == null || paymentForm.saved_info.phone == null)
);
if (isCheckoutPreview && paymentForm.saved_info != null && validateRequest == null) {
if (isCheckoutPreview && !savedInfoMissing && validateRequest == null) {
setDonePressed(true);
sendSavedForm(()->{
@ -2263,9 +2280,9 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
return;
}
if (isCheckoutPreview && (paymentForm.saved_info == null && (paymentForm.invoice.shipping_address_requested || paymentForm.invoice.email_requested || paymentForm.invoice.name_requested || paymentForm.invoice.phone_requested) || savedCredentialsCard == null && paymentJson == null && googlePayCredentials == null || shippingOption == null && paymentForm.invoice.flexible)) {
if (isCheckoutPreview && (savedInfoMissing || savedCredentialsCard == null && paymentJson == null && googlePayCredentials == null || shippingOption == null && paymentForm.invoice.flexible)) {
int step;
if (paymentForm.saved_info == null && (paymentForm.invoice.shipping_address_requested || paymentForm.invoice.email_requested || paymentForm.invoice.name_requested || paymentForm.invoice.phone_requested)) {
if (savedInfoMissing) {
step = STEP_SHIPPING_INFORMATION;
} else if (savedCredentialsCard == null && paymentJson == null && googlePayCredentials == null) {
step = STEP_PAYMENT_INFO;
@ -2324,7 +2341,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
payTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
bottomLayout.addView(payTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
progressViewButton = new ContextProgressView(context, 0);
progressViewButton = new ContextProgressView(context, 0, resourcesProvider);
progressViewButton.setVisibility(View.INVISIBLE);
int color = getThemedColor(Theme.key_contacts_inviteText);
progressViewButton.setColors(color & 0x2fffffff, color);
@ -2480,7 +2497,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
linearLayout2.addView(bottomCell[2], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
settingsCell[1] = new TextSettingsCell(context, resourcesProvider);
settingsCell[1].setBackgroundDrawable(Theme.getSelectorDrawable(true));
settingsCell[1].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
settingsCell[1].setTag(Theme.key_windowBackgroundWhiteBlackText);
settingsCell[1].setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
settingsCell[1].setText(LocaleController.getString("ResendCode", R.string.ResendCode), true);
@ -2498,7 +2515,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
});
settingsCell[0] = new TextSettingsCell(context, resourcesProvider);
settingsCell[0].setBackgroundDrawable(Theme.getSelectorDrawable(true));
settingsCell[0].setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundWhite)));
settingsCell[0].setTag(Theme.key_text_RedRegular);
settingsCell[0].setTextColor(getThemedColor(Theme.key_text_RedRegular));
settingsCell[0].setText(LocaleController.getString("AbortPassword", R.string.AbortPassword), false);
@ -2754,7 +2771,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
private void createGooglePayButton(Context context) {
googlePayContainer = new FrameLayout(context);
googlePayContainer.setBackgroundDrawable(Theme.getSelectorDrawable(true));
googlePayContainer.setBackground(Theme.getSelectorDrawableByColor(getThemedColor(Theme.key_listSelector), getThemedColor(Theme.key_windowBackgroundGray)));
googlePayContainer.setVisibility(View.GONE);
googlePayButton = new FrameLayout(context);
@ -4455,6 +4472,10 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
arrayList.add(new ThemeDescription(bottomLayout, ThemeDescription.FLAG_SELECTORWHITE, null, null, null, null, Theme.key_windowBackgroundWhite));
arrayList.add(new ThemeDescription(bottomLayout, ThemeDescription.FLAG_SELECTORWHITE, null, null, null, null, Theme.key_listSelector));
for (ThemeDescription description : arrayList) {
description.resourcesProvider = resourcesProvider;
}
return arrayList;
}

View file

@ -119,7 +119,6 @@ import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.FloatValueHolder;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import androidx.exifinterface.media.ExifInterface;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSmoothScrollerEnd;
@ -167,6 +166,7 @@ import org.telegram.messenger.Utilities;
import org.telegram.messenger.VideoEditedInfo;
import org.telegram.messenger.WebFile;
import org.telegram.messenger.browser.Browser;
import org.telegram.messenger.camera.Size;
import org.telegram.messenger.video.VideoPlayerRewinder;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
@ -10264,18 +10264,29 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
animators.add(ObjectAnimator.ofFloat(photoFilterView.getBlurControl(), View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(PhotoViewer.this, AnimationProperties.PHOTO_VIEWER_ANIMATION_VALUE, 0, 1));
} else if (currentEditMode == EDIT_MODE_PAINT) {
ValueAnimator animator = ValueAnimator.ofFloat(photoPaintView.getOffsetTranslationY(), AndroidUtilities.dp(126));
animator.addUpdateListener(animation -> photoPaintView.setOffsetTranslationY((Float) animation.getAnimatedValue(), 0, 0,false));
ValueAnimator animatorY = ValueAnimator.ofFloat(photoPaintView.getOffsetTranslationY(), AndroidUtilities.dp(126));
ValueAnimator animatorX = ValueAnimator.ofFloat(0, -AndroidUtilities.dp(12));
animatorY.addUpdateListener(animation -> photoPaintView.setOffsetTranslationY((Float) animation.getAnimatedValue(), 0, 0,false));
animatorX.addUpdateListener(animation -> photoPaintView.setOffsetTranslationX((Float) animation.getAnimatedValue()));
paintingOverlay.showAll();
containerView.invalidate();
photoPaintView.shutdown();
animators.add(animator);
animators.add(animatorY);
animators.add(animatorX);
animators.add(ObjectAnimator.ofFloat(PhotoViewer.this, AnimationProperties.PHOTO_VIEWER_ANIMATION_VALUE, 0, 1));
}
animators.add(ObjectAnimator.ofObject(navigationBar, "backgroundColor", new ArgbEvaluator(), navigationBarColorFrom, navigationBarColorTo));
imageMoveAnimation.playTogether(animators);
imageMoveAnimation.setDuration(200);
imageMoveAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
if (currentEditMode == EDIT_MODE_PAINT) {
photoPaintView.onAnimationStateChanged(true);
}
}
@Override
public void onAnimationEnd(Animator animation) {
if (currentEditMode == EDIT_MODE_CROP) {
@ -10292,6 +10303,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
}
photoFilterView = null;
} else if (currentEditMode == EDIT_MODE_PAINT) {
photoPaintView.onAnimationStateChanged(false);
try {
containerView.removeView(photoPaintView.getView());
} catch (Exception e) {
@ -10371,6 +10383,11 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
updateActionBarTitlePadding();
}
}
@Override
public void onAnimationEnd(Animator animation) {
if (videoConvertSupported && isCurrentVideo) updateVideoInfo();
}
});
animatorSet.start();
}
@ -10791,6 +10808,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
});
photoPaintView.getCancelView().setOnClickListener(v -> closePaintMode());
photoPaintView.setOffsetTranslationY(AndroidUtilities.dp(126), 0, 0, false);
photoPaintView.setOffsetTranslationX(-AndroidUtilities.dp(12));
}
}
@ -10869,21 +10887,25 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
windowView.setClipChildren(true);
navigationBar.setVisibility(View.INVISIBLE);
imageMoveAnimation = new AnimatorSet();
ValueAnimator animator = ValueAnimator.ofFloat(AndroidUtilities.dp(126), 0);
animator.addUpdateListener(animation -> photoPaintView.setOffsetTranslationY((Float) animation.getAnimatedValue(), 0, 0,false));
ValueAnimator animatorY = ValueAnimator.ofFloat(AndroidUtilities.dp(126), 0);
ValueAnimator animatorX = ValueAnimator.ofFloat(-AndroidUtilities.dp(12), 0);
animatorY.addUpdateListener(animation -> photoPaintView.setOffsetTranslationY((Float) animation.getAnimatedValue(), 0, 0,false));
animatorX.addUpdateListener(animation -> photoPaintView.setOffsetTranslationX((Float) animation.getAnimatedValue()));
imageMoveAnimation.playTogether(
ObjectAnimator.ofFloat(PhotoViewer.this, AnimationProperties.PHOTO_VIEWER_ANIMATION_VALUE, 0, 1),
animator
animatorY,
animatorX
);
imageMoveAnimation.setDuration(200);
imageMoveAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
photoPaintView.onAnimationStateChanged(true);
}
@Override
public void onAnimationEnd(Animator animation) {
photoPaintView.onAnimationStateChanged(false);
photoPaintView.init();
paintingOverlay.hideEntities();
imageMoveAnimation = null;
@ -17200,20 +17222,21 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
private long captureFrameReadyAtTime = -1;
private long needCaptureFrameReadyAtTime = -1;
private int selectedCompression;
private int compressionsCount = -1;
private volatile int selectedCompression;
private volatile int compressionsCount = -1;
private int previousCompression;
private int rotationValue;
private int originalWidth;
private int originalHeight;
private int resultWidth;
private int resultHeight;
private int bitrate;
private int originalBitrate;
private volatile int originalWidth;
private volatile int originalHeight;
private volatile int resultWidth;
private volatile int resultHeight;
private volatile int bitrate;
private volatile int originalBitrate;
private float videoDuration;
private int videoFramerate;
private boolean videoConvertSupported;
private volatile boolean videoConvertSupported;
private volatile boolean isH264Video;
private long startTime;
private long endTime;
private float videoCutStart;
@ -17391,6 +17414,26 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
}
}
private void calculateEstimatedVideoSize(boolean needEncoding, boolean isMute) {
if (needEncoding) {
estimatedSize = (long) (((isMute ? 0 : audioFramesSize) + videoFramesSize) * ((float) estimatedDuration / videoDuration));
estimatedSize += estimatedSize / (32 * 1024) * 16;
} else {
estimatedSize = (long) (originalSize * ((float) estimatedDuration / videoDuration));
if (isMute)
estimatedSize -= (long) (audioFramesSize * ((float) estimatedDuration / videoDuration));
}
}
private boolean needEncoding() {
Object mediaEntities = editState.croppedPaintPath != null
? (editState.croppedMediaEntities != null && !editState.croppedMediaEntities.isEmpty() ? editState.croppedMediaEntities : null)
: (editState.mediaEntities != null && !editState.mediaEntities.isEmpty() ? editState.mediaEntities : null);
Object paintPath = editState.croppedPaintPath != null ? editState.croppedPaintPath : editState.paintPath;
return !isH264Video || videoCutStart != 0 || rotationValue != 0 || resultWidth != originalWidth || resultHeight != originalHeight
|| editState.cropState != null || mediaEntities != null || paintPath != null || editState.savedFilterState != null || sendPhotoType == SELECT_TYPE_AVATAR;
}
private void updateVideoInfo() {
if (actionBar == null) {
return;
@ -17400,7 +17443,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return;
}
int compressIconWidth = 64;
if (selectedCompression < 2) {
compressItem.setImageResource(R.drawable.video_quality1);
} else if (selectedCompression == 2) {
@ -17411,13 +17453,14 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
itemsLayout.requestLayout();
estimatedDuration = (long) Math.ceil((videoTimelineView.getRightProgress() - videoTimelineView.getLeftProgress()) * videoDuration);
videoCutStart = videoTimelineView.getLeftProgress();
videoCutEnd = videoTimelineView.getRightProgress();
int width;
int height;
int width = rotationValue == 90 || rotationValue == 270 ? resultHeight : resultWidth;
int height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight;
boolean needEncoding = needEncoding();
if (muteVideo) {
width = rotationValue == 90 || rotationValue == 270 ? resultHeight : resultWidth;
height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight;
int bitrate;
if (sendPhotoType == SELECT_TYPE_AVATAR) {
if (estimatedDuration <= 2000) {
@ -17432,20 +17475,10 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
}
estimatedSize = (long) (bitrate / 8 * (estimatedDuration / 1000.0f));
estimatedSize += estimatedSize / (32 * 1024) * 16;
} else if (compressItem.getTag() == null) {
width = rotationValue == 90 || rotationValue == 270 ? originalHeight : originalWidth;
height = rotationValue == 90 || rotationValue == 270 ? originalWidth : originalHeight;
estimatedSize = (long) (originalSize * ((float) estimatedDuration / videoDuration));
} else {
width = rotationValue == 90 || rotationValue == 270 ? resultHeight : resultWidth;
height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight;
estimatedSize = (long) (((sendPhotoType == SELECT_TYPE_AVATAR ? 0 : audioFramesSize) + videoFramesSize) * ((float) estimatedDuration / videoDuration));
estimatedSize += estimatedSize / (32 * 1024) * 16;
calculateEstimatedVideoSize(needEncoding, sendPhotoType == SELECT_TYPE_AVATAR);
}
videoCutStart = videoTimelineView.getLeftProgress();
videoCutEnd = videoTimelineView.getRightProgress();
if (videoCutStart == 0) {
startTime = -1;
} else {
@ -17539,6 +17572,51 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
containerView.invalidate();
}
private Size calculateResultVideoSize() {
if (compressionsCount == 1) {
return new Size(originalWidth, originalHeight);
}
float maxSize;
int resultWidth;
int resultHeight;
switch (selectedCompression) {
case 0:
maxSize = 480.0f;
break;
case 1:
maxSize = 854.0f;
break;
case 2:
maxSize = 1280.0f;
break;
case 3:
default:
maxSize = 1920.0f;
break;
}
float scale = originalWidth > originalHeight ? maxSize / originalWidth : maxSize / originalHeight;
if (selectedCompression == compressionsCount - 1 && scale >= 1f) {
resultWidth = originalWidth;
resultHeight = originalHeight;
} else {
resultWidth = Math.round(originalWidth * scale / 2) * 2;
resultHeight = Math.round(originalHeight * scale / 2) * 2;
}
return new Size(resultWidth, resultHeight);
}
private void prepareRealEncoderBitrate() {
if (bitrate != 0 && sendPhotoType != SELECT_TYPE_AVATAR) {
Size resultSize = calculateResultVideoSize();
if (resultSize.getWidth() == originalWidth && resultSize.getHeight() == originalHeight) {
MediaController.extractRealEncoderBitrate(resultSize.getWidth(), resultSize.getHeight(), originalBitrate);
} else {
int targetBitrate = MediaController.makeVideoBitrate(originalHeight, originalWidth, originalBitrate, resultSize.getHeight(), resultSize.getWidth());
MediaController.extractRealEncoderBitrate(resultSize.getWidth(), resultSize.getHeight(), targetBitrate);
}
}
}
private void updateWidthHeightBitrateForCompression() {
if (compressionsCount <= 0) {
return;
@ -17552,41 +17630,24 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
resultWidth = Math.round(originalWidth * scale / 2) * 2;
resultHeight = Math.round(originalHeight * scale / 2) * 2;
} else {
float maxSize;
switch (selectedCompression) {
case 0:
maxSize = 480.0f;
break;
case 1:
maxSize = 854.0f;
break;
case 2:
maxSize = 1280.0f;
break;
case 3:
default:
maxSize = 1920.0f;
break;
}
float scale = originalWidth > originalHeight ? maxSize / originalWidth : maxSize / originalHeight;
if (selectedCompression == compressionsCount - 1 && scale >= 1f) {
resultWidth = originalWidth;
resultHeight = originalHeight;
} else {
resultWidth = Math.round(originalWidth * scale / 2) * 2;
resultHeight = Math.round(originalHeight * scale / 2) * 2;
}
Size resultSize = calculateResultVideoSize();
resultWidth = resultSize.getWidth();
resultHeight = resultSize.getHeight();
}
if (bitrate != 0) {
final int encoderBitrate;
if (sendPhotoType == SELECT_TYPE_AVATAR) {
bitrate = 1560000;
encoderBitrate = bitrate;
} else if (resultWidth == originalWidth && resultHeight == originalHeight) {
bitrate = originalBitrate;
encoderBitrate = MediaController.extractRealEncoderBitrate(resultWidth, resultHeight, bitrate);
} else {
bitrate = MediaController.makeVideoBitrate(originalHeight, originalWidth, originalBitrate, resultHeight, resultWidth);
encoderBitrate = MediaController.extractRealEncoderBitrate(resultWidth, resultHeight, bitrate);
}
videoFramesSize = (long) (bitrate / 8 * videoDuration / 1000);
videoFramesSize = (long) (encoderBitrate / 8 * videoDuration / 1000);
}
}
@ -17692,7 +17753,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return new ByteArrayInputStream(output, 0, outPos);
}
private void processOpenVideo(final String videoPath, boolean muted, float start, float end, int compressQality) {
private void processOpenVideo(final String videoPath, boolean muted, float start, float end, final int compressQuality) {
if (currentLoadingVideoRunnable != null) {
Utilities.globalQueue.cancelRunnable(currentLoadingVideoRunnable);
currentLoadingVideoRunnable = null;
@ -17714,9 +17775,22 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return;
}
int videoBitrate = MediaController.getVideoBitrate(videoPath);
int[] params = new int[AnimatedFileDrawable.PARAM_NUM_COUNT];
AnimatedFileDrawable.getVideoInfo(videoPath, params);
final boolean hasAudio = params[AnimatedFileDrawable.PARAM_NUM_HAS_AUDIO] != 0;
videoConvertSupported = params[AnimatedFileDrawable.PARAM_NUM_SUPPORTED_VIDEO_CODEC] != 0 && (!hasAudio || params[AnimatedFileDrawable.PARAM_NUM_SUPPORTED_AUDIO_CODEC] != 0);
originalBitrate = bitrate = videoBitrate == -1 ? params[AnimatedFileDrawable.PARAM_NUM_BITRATE] : videoBitrate;
if (videoConvertSupported) {
resultWidth = originalWidth = params[AnimatedFileDrawable.PARAM_NUM_WIDTH];
resultHeight = originalHeight = params[AnimatedFileDrawable.PARAM_NUM_HEIGHT];
updateCompressionsCount(originalWidth, originalHeight);
selectedCompression = compressQuality == -1 ? selectCompression() : compressQuality;
prepareRealEncoderBitrate();
isH264Video = MediaController.isH264Video(videoPath);
}
if (currentLoadingVideoRunnable != this) {
return;
}
@ -17726,30 +17800,13 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
return;
}
currentLoadingVideoRunnable = null;
boolean hasAudio = params[AnimatedFileDrawable.PARAM_NUM_HAS_AUDIO] != 0;
videoConvertSupported = params[AnimatedFileDrawable.PARAM_NUM_SUPPORTED_VIDEO_CODEC] != 0 &&
(!hasAudio || params[AnimatedFileDrawable.PARAM_NUM_SUPPORTED_AUDIO_CODEC] != 0);
audioFramesSize = params[AnimatedFileDrawable.PARAM_NUM_AUDIO_FRAME_SIZE];
videoDuration = params[AnimatedFileDrawable.PARAM_NUM_DURATION];
if (videoBitrate == -1) {
originalBitrate = bitrate = params[AnimatedFileDrawable.PARAM_NUM_BITRATE];
} else {
originalBitrate = bitrate = videoBitrate;
}
videoFramerate = params[AnimatedFileDrawable.PARAM_NUM_FRAMERATE];
videoFramesSize = (long) (bitrate / 8 * videoDuration / 1000);
if (videoConvertSupported) {
rotationValue = params[AnimatedFileDrawable.PARAM_NUM_ROTATION];
resultWidth = originalWidth = params[AnimatedFileDrawable.PARAM_NUM_WIDTH];
resultHeight = originalHeight = params[AnimatedFileDrawable.PARAM_NUM_HEIGHT];
updateCompressionsCount(originalWidth, originalHeight);
if (compressQality == -1) {
selectedCompression = selectCompression();
} else {
selectedCompression = compressQality;
}
updateWidthHeightBitrateForCompression();
if (selectedCompression > compressionsCount - 1) {
@ -17760,10 +17817,6 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
if (BuildVars.LOGS_ENABLED) {
FileLog.d("compressionsCount = " + compressionsCount + " w = " + originalWidth + " h = " + originalHeight + " r = " + rotationValue);
}
if (Build.VERSION.SDK_INT < 18 && compressItem.getTag() != null) {
videoConvertSupported = false;
setCompressItemEnabled(false, true);
}
qualityChooseView.invalidate();
} else {
setCompressItemEnabled(false, true);

View file

@ -4495,7 +4495,7 @@ public class ThemePreviewActivity extends BaseFragment implements DownloadContro
messageObject.resetLayout();
messages.add(messageObject);
if (dialogId != 0) {
if (dialogId != 0 && serverWallpaper == null) {
message = new TLRPC.TL_message();
message.message = "";
messageObject = new MessageObject(currentAccount, message, true, false);

View file

@ -471,10 +471,13 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
actionBarPaint.setColor(getThemedColor(Theme.key_windowBackgroundWhite));
actionBarPaint.setAlpha((int) (255 * searchAnimationProgress));
canvas.drawRect(0, 0, getWidth(), AndroidUtilities.statusBarHeight, actionBarPaint);
canvas.drawLine(0, 0, 0, getHeight(), Theme.dividerPaint);
}
}
};
contentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
contentView.needBlur = !inPreviewMode;
actionBar.setAddToContainer(false);
@ -3941,6 +3944,7 @@ public class TopicsFragment extends BaseFragment implements NotificationCenter.N
ArrayList<ThemeDescription> arrayList = new ArrayList<>();
arrayList.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
arrayList.add(new ThemeDescription(null, 0, null, null, null, cellDelegate, Theme.key_windowBackgroundWhite));
arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_actionBarDefault));
arrayList.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_actionBarDefaultIcon));

View file

@ -18,6 +18,8 @@ import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.os.PowerManager;
@ -259,6 +261,10 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
fragment.activity = activity;
instance = fragment;
VoIPWindowView windowView = new VoIPWindowView(activity, !transitionFromPip) {
private Path clipPath = new Path();
private RectF rectF = new RectF();
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (fragment.isFinished || fragment.switchingToPip) {
@ -280,6 +286,29 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
}
return super.dispatchKeyEvent(event);
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (fragment.switchingToPip && getAlpha() != 0) {
float width = fragment.callingUserTextureView.getWidth() * fragment.callingUserTextureView.getScaleX();
float height = fragment.callingUserTextureView.getHeight() * fragment.callingUserTextureView.getScaleY();
float padX = (fragment.callingUserTextureView.getWidth() - width) / 2;
float padY = (fragment.callingUserTextureView.getHeight() - height) / 2;
float x = fragment.callingUserTextureView.getX() + padX;
float y = fragment.callingUserTextureView.getY() + padY;
canvas.save();
clipPath.rewind();
rectF.set(x, y, x + width, y + height);
float round = AndroidUtilities.dp(4);
clipPath.addRoundRect(rectF, round, round, Path.Direction.CW);
clipPath.close();
canvas.clipPath(clipPath);
super.dispatchDraw(canvas);
canvas.restore();
} else {
super.dispatchDraw(canvas);
}
}
};
instance.deviceIsLocked = ((KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE)).inKeyguardRestrictedInputMode();
@ -1146,8 +1175,8 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
notificationsLocker.lock();
AndroidUtilities.runOnUIThread(() -> {
windowView.setAlpha(1f);
windowView.invalidate();
Animator animator = createPiPTransition(true);
backIcon.setAlpha(0f);
emojiLayout.setAlpha(0f);
statusLayout.setAlpha(0f);
@ -1296,7 +1325,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (!currentUserCameraFloatingLayout.measuredAsFloatingMode) {
currentUserTextureView.setScreenshareMiniProgress(v, false);
}
windowView.invalidate();
callingUserPhotoView.setScaleX(callingUserScale);
callingUserPhotoView.setScaleY(callingUserScale);
callingUserPhotoView.setTranslationX(tx);

View file

@ -13,8 +13,8 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Sat Mar 12 05:53:50 MSK 2016
APP_VERSION_CODE=3356
APP_VERSION_NAME=9.6.5
APP_VERSION_CODE=3362
APP_VERSION_NAME=9.6.6
APP_PACKAGE=org.telegram.messenger
RELEASE_KEY_PASSWORD=android
RELEASE_KEY_ALIAS=androidkey