mirror of
https://github.com/DrKLO/Telegram.git
synced 2024-12-22 06:25:14 +01:00
update to 9.7.4 (3712)
This commit is contained in:
parent
f10844350d
commit
6c1e8c1cf7
55 changed files with 1534 additions and 703 deletions
|
@ -182,12 +182,6 @@ public final class MediaCodecUtil {
|
|||
}
|
||||
}
|
||||
applyWorkarounds(mimeType, decoderInfos);
|
||||
for (int i = 0; i < decoderInfos.size(); i++) {
|
||||
if (decoderInfos.get(i).name.equals("c2.exynos.hevc.decoder")) {
|
||||
decoderInfos.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
ImmutableList<MediaCodecInfo> immutableDecoderInfos = ImmutableList.copyOf(decoderInfos);
|
||||
decoderInfosCache.put(key, immutableDecoderInfos);
|
||||
return immutableDecoderInfos;
|
||||
|
|
|
@ -177,6 +177,7 @@ import java.io.RandomAccessFile;
|
|||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.IDN;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -5360,4 +5361,19 @@ public class AndroidUtilities {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
public static ByteBuffer cloneByteBuffer(ByteBuffer original) {
|
||||
ByteBuffer clone;
|
||||
try {
|
||||
clone = ByteBuffer.allocate(original.capacity());
|
||||
} catch (OutOfMemoryError error) {
|
||||
System.gc();
|
||||
clone = ByteBuffer.allocate(original.capacity());
|
||||
}
|
||||
original.rewind();
|
||||
clone.put(original);
|
||||
original.rewind();
|
||||
clone.flip();
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = 3705;
|
||||
public static String BUILD_VERSION_STRING = "9.7.2";
|
||||
public static int BUILD_VERSION = 3712;
|
||||
public static String BUILD_VERSION_STRING = "9.7.4";
|
||||
public static int APP_ID = 4;
|
||||
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
|
||||
|
||||
|
|
|
@ -747,18 +747,18 @@ public class FileLoadOperation {
|
|||
return;
|
||||
}
|
||||
paused = true;
|
||||
if (isStory) {
|
||||
Utilities.stageQueue.postRunnable(() -> {
|
||||
Utilities.stageQueue.postRunnable(() -> {
|
||||
if (isStory) {
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("debug_loading:" + cacheFileFinal.getName() + " pause operation, clear requests");
|
||||
}
|
||||
clearOperaion(null, false);
|
||||
});
|
||||
} else {
|
||||
for (int i = 0; i < requestInfos.size(); i++) {
|
||||
ConnectionsManager.getInstance(currentAccount).failNotRunningRequest(requestInfos.get(i).requestToken);
|
||||
} else {
|
||||
for (int i = 0; i < requestInfos.size(); i++) {
|
||||
ConnectionsManager.getInstance(currentAccount).failNotRunningRequest(requestInfos.get(i).requestToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
|
@ -936,7 +936,7 @@ public class FileLoadOperation {
|
|||
boolean finalFileExist = cacheFileFinal.exists();
|
||||
if (finalFileExist && (parentObject instanceof TLRPC.TL_theme || (totalBytesCount != 0 && !ungzip && totalBytesCount != cacheFileFinal.length()))) {
|
||||
if (BuildVars.LOGS_ENABLED) {
|
||||
FileLog.d("debug_loading: delete existing file cause file size mismatch " + cacheFileFinal.getName() + " totalSize= " + totalBytesCount + " existingFileSize=" + cacheFileFinal.length());
|
||||
FileLog.d("debug_loading: delete existing file cause file size mismatch " + cacheFileFinal.getName() + " totalSize=" + totalBytesCount + " existingFileSize=" + cacheFileFinal.length());
|
||||
}
|
||||
if (!delegate.hasAnotherRefOnFile(cacheFileFinal.toString())) {
|
||||
cacheFileFinal.delete();
|
||||
|
|
|
@ -754,7 +754,7 @@ public class FileLoader extends BaseController {
|
|||
type = MEDIA_DIR_DOCUMENT;
|
||||
} else if (location != null) {
|
||||
documentId = location.volume_id;
|
||||
dcId = location.dc_id;
|
||||
dcId = location.dc_id + (location.local_id << 16);
|
||||
operation = new FileLoadOperation(imageLocation, parentObject, locationExt, locationSize);
|
||||
type = MEDIA_DIR_IMAGE;
|
||||
} else if (document != null) {
|
||||
|
@ -1230,8 +1230,7 @@ public class FileLoader extends BaseController {
|
|||
dir = getDirectory(type = MEDIA_DIR_IMAGE);
|
||||
}
|
||||
documentId = photoSize.location.volume_id;
|
||||
dcId = photoSize.location.dc_id;
|
||||
|
||||
dcId = photoSize.location.dc_id + (photoSize.location.local_id << 16);
|
||||
} else if (attach instanceof TLRPC.TL_videoSize) {
|
||||
TLRPC.TL_videoSize videoSize = (TLRPC.TL_videoSize) attach;
|
||||
if (videoSize.location == null || videoSize.location.key != null || videoSize.location.volume_id == Integer.MIN_VALUE && videoSize.location.local_id < 0 || videoSize.size < 0) {
|
||||
|
@ -1240,14 +1239,14 @@ public class FileLoader extends BaseController {
|
|||
dir = getDirectory(type = MEDIA_DIR_IMAGE);
|
||||
}
|
||||
documentId = videoSize.location.volume_id;
|
||||
dcId = videoSize.location.dc_id;
|
||||
dcId = videoSize.location.dc_id + (videoSize.location.local_id << 16);
|
||||
} else if (attach instanceof TLRPC.FileLocation) {
|
||||
TLRPC.FileLocation fileLocation = (TLRPC.FileLocation) attach;
|
||||
if (fileLocation.key != null || fileLocation.volume_id == Integer.MIN_VALUE && fileLocation.local_id < 0) {
|
||||
dir = getDirectory(MEDIA_DIR_CACHE);
|
||||
} else {
|
||||
documentId = fileLocation.volume_id;
|
||||
dcId = fileLocation.dc_id;
|
||||
dcId = fileLocation.dc_id + (fileLocation.local_id << 16);
|
||||
dir = getDirectory(type = MEDIA_DIR_IMAGE);
|
||||
}
|
||||
} else if (attach instanceof TLRPC.UserProfilePhoto || attach instanceof TLRPC.ChatPhoto) {
|
||||
|
|
|
@ -470,6 +470,7 @@ public class FilePathDatabase {
|
|||
synchronized (this) {
|
||||
if (dispatchQueue == null) {
|
||||
dispatchQueue = new DispatchQueue("files_database_queue_" + currentAccount);
|
||||
dispatchQueue.setPriority(Thread.MAX_PRIORITY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,6 +276,27 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
|
|||
blurExcludeBlurSize = stream.readFloat(exception);
|
||||
blurAngle = stream.readFloat(exception);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (
|
||||
Math.abs(enhanceValue) < 0.1f &&
|
||||
Math.abs(softenSkinValue) < 0.1f &&
|
||||
Math.abs(exposureValue) < 0.1f &&
|
||||
Math.abs(contrastValue) < 0.1f &&
|
||||
Math.abs(warmthValue) < 0.1f &&
|
||||
Math.abs(saturationValue) < 0.1f &&
|
||||
Math.abs(fadeValue) < 0.1f &&
|
||||
tintShadowsColor == 0 &&
|
||||
tintHighlightsColor == 0 &&
|
||||
Math.abs(highlightsValue) < 0.1f &&
|
||||
Math.abs(shadowsValue) < 0.1f &&
|
||||
Math.abs(vignetteValue) < 0.1f &&
|
||||
Math.abs(grainValue) < 0.1f &&
|
||||
blurType == 0 &&
|
||||
Math.abs(sharpenValue) < 0.1f &&
|
||||
Math.abs(blurExcludeSize) < 0.1f
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CropState {
|
||||
|
|
|
@ -6949,6 +6949,18 @@ public class MessageObject {
|
|||
return isVideoMessage(messageOwner);
|
||||
}
|
||||
|
||||
public boolean isVideoStory() {
|
||||
TLRPC.MessageMedia media = MessageObject.getMedia(messageOwner);
|
||||
if (media == null) {
|
||||
return false;
|
||||
}
|
||||
TLRPC.StoryItem storyItem = media.storyItem;
|
||||
if (storyItem == null || storyItem.media == null) {
|
||||
return false;
|
||||
}
|
||||
return MessageObject.isVideoDocument(storyItem.media.document);
|
||||
}
|
||||
|
||||
public boolean isPhoto() {
|
||||
return isPhoto(messageOwner);
|
||||
}
|
||||
|
@ -7087,6 +7099,12 @@ public class MessageObject {
|
|||
return attributeDuration;
|
||||
}
|
||||
TLRPC.Document document = getDocument();
|
||||
if (document == null && type == TYPE_STORY) {
|
||||
TLRPC.StoryItem storyItem = getMedia(messageOwner).storyItem;
|
||||
if (storyItem != null && storyItem.media != null) {
|
||||
document = storyItem.media.document;
|
||||
}
|
||||
}
|
||||
if (document == null) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6866,7 +6866,7 @@ public class MessagesStorage extends BaseController {
|
|||
|
||||
SQLiteCursor cursor = null;
|
||||
try {
|
||||
cursor = database.queryFinalized("SELECT uid, info, participants_count FROM chat_settings_v2 WHERE participants_count > 1 AND participants_count <= 20");
|
||||
cursor = database.queryFinalized("SELECT uid, info, participants_count FROM chat_settings_v2 WHERE participants_count > 1");
|
||||
while (cursor.next()) {
|
||||
TLRPC.ChatFull info = null;
|
||||
long id = cursor.longValue(0);
|
||||
|
|
|
@ -4658,7 +4658,7 @@ public class NotificationsController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
boolean needAddPerson = lastMessageObject != null && !(lastMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest);
|
||||
boolean needAddPerson = lastMessageObject == null || !(lastMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest);
|
||||
NotificationCompat.MessagingStyle messagingStyle;
|
||||
if (selfPerson != null && needAddPerson) {
|
||||
messagingStyle = new NotificationCompat.MessagingStyle(selfPerson);
|
||||
|
|
|
@ -611,6 +611,10 @@ public class CameraController implements MediaRecorder.OnInfoListener {
|
|||
}
|
||||
|
||||
public void recordVideo(final CameraSession session, final File path, boolean mirror, final VideoTakeCallback callback, final Runnable onVideoStartRecord, ICameraView cameraView) {
|
||||
recordVideo(session, path, mirror, callback, onVideoStartRecord, cameraView, true);
|
||||
}
|
||||
|
||||
public void recordVideo(final CameraSession session, final File path, boolean mirror, final VideoTakeCallback callback, final Runnable onVideoStartRecord, ICameraView cameraView, boolean createThumbnail) {
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -632,7 +636,7 @@ public class CameraController implements MediaRecorder.OnInfoListener {
|
|||
FileLog.e(e);
|
||||
}
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
cameraView.startRecording(path, this::finishRecordingVideo);
|
||||
cameraView.startRecording(path, () -> finishRecordingVideo(createThumbnail));
|
||||
|
||||
if (onVideoStartRecord != null) {
|
||||
onVideoStartRecord.run();
|
||||
|
@ -703,7 +707,7 @@ public class CameraController implements MediaRecorder.OnInfoListener {
|
|||
});
|
||||
}
|
||||
|
||||
private void finishRecordingVideo() {
|
||||
private void finishRecordingVideo(boolean createThumbnail) {
|
||||
MediaMetadataRetriever mediaMetadataRetriever = null;
|
||||
long duration = 0;
|
||||
try {
|
||||
|
@ -724,38 +728,47 @@ public class CameraController implements MediaRecorder.OnInfoListener {
|
|||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
Bitmap bitmap = SendMessagesHelper.createVideoThumbnail(recordedFile, MediaStore.Video.Thumbnails.MINI_KIND);
|
||||
if (mirrorRecorderVideo) {
|
||||
Bitmap b = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(b);
|
||||
canvas.scale(-1, 1, b.getWidth() / 2, b.getHeight() / 2);
|
||||
canvas.drawBitmap(bitmap, 0, 0, null);
|
||||
bitmap.recycle();
|
||||
bitmap = b;
|
||||
}
|
||||
String fileName = Integer.MIN_VALUE + "_" + SharedConfig.getLastLocalId() + ".jpg";
|
||||
final File cacheFile = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
|
||||
FileOutputStream stream = null;
|
||||
try {
|
||||
stream = new FileOutputStream(cacheFile);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 87, stream);
|
||||
} catch (Throwable e) {
|
||||
FileLog.e(e);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Throwable ignore) {}
|
||||
final File cacheFile;
|
||||
Bitmap bitmap = null;
|
||||
if (createThumbnail) {
|
||||
bitmap = SendMessagesHelper.createVideoThumbnail(recordedFile, MediaStore.Video.Thumbnails.MINI_KIND);
|
||||
if (mirrorRecorderVideo) {
|
||||
Bitmap b = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(b);
|
||||
canvas.scale(-1, 1, b.getWidth() / 2, b.getHeight() / 2);
|
||||
canvas.drawBitmap(bitmap, 0, 0, null);
|
||||
bitmap.recycle();
|
||||
bitmap = b;
|
||||
}
|
||||
String fileName = Integer.MIN_VALUE + "_" + SharedConfig.getLastLocalId() + ".jpg";
|
||||
cacheFile = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
|
||||
FileOutputStream stream = null;
|
||||
try {
|
||||
stream = new FileOutputStream(cacheFile);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 87, stream);
|
||||
} catch (Throwable e) {
|
||||
FileLog.e(e);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cacheFile = null;
|
||||
}
|
||||
SharedConfig.saveConfig();
|
||||
final long durationFinal = duration;
|
||||
final Bitmap bitmapFinal = bitmap;
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (onVideoTakeCallback != null) {
|
||||
String path = cacheFile.getAbsolutePath();
|
||||
if (bitmapFinal != null) {
|
||||
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal), Utilities.MD5(path), false);
|
||||
String path = null;
|
||||
if (cacheFile != null) {
|
||||
path = cacheFile.getAbsolutePath();
|
||||
if (bitmapFinal != null) {
|
||||
ImageLoader.getInstance().putImageToCache(new BitmapDrawable(bitmapFinal), Utilities.MD5(path), false);
|
||||
}
|
||||
}
|
||||
onVideoTakeCallback.onFinishVideoRecording(path, durationFinal);
|
||||
onVideoTakeCallback = null;
|
||||
|
@ -773,12 +786,16 @@ public class CameraController implements MediaRecorder.OnInfoListener {
|
|||
tempRecorder.release();
|
||||
}
|
||||
if (onVideoTakeCallback != null) {
|
||||
finishRecordingVideo();
|
||||
finishRecordingVideo(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stopVideoRecording(final CameraSession session, final boolean abandon) {
|
||||
stopVideoRecording(session, abandon, true);
|
||||
}
|
||||
|
||||
public void stopVideoRecording(final CameraSession session, final boolean abandon, final boolean createThumbnail) {
|
||||
if (recordingCurrentCameraView != null) {
|
||||
recordingCurrentCameraView.stopRecording();
|
||||
recordingCurrentCameraView = null;
|
||||
|
@ -830,7 +847,7 @@ public class CameraController implements MediaRecorder.OnInfoListener {
|
|||
}
|
||||
});
|
||||
if (!abandon && onVideoTakeCallback != null) {
|
||||
finishRecordingVideo();
|
||||
finishRecordingVideo(createThumbnail);
|
||||
} else {
|
||||
onVideoTakeCallback = null;
|
||||
}
|
||||
|
|
|
@ -556,25 +556,40 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
return false;
|
||||
}
|
||||
|
||||
private Integer shape;
|
||||
public void dualToggleShape() {
|
||||
if (flipping || !dual) {
|
||||
return;
|
||||
}
|
||||
Handler handler = cameraThread.getHandler();
|
||||
MessagesController.getGlobalMainSettings().edit().putInt("dualshape", (int) (cameraThread.shapeTo + 1)).apply();
|
||||
if (shape == null) {
|
||||
shape = MessagesController.getGlobalMainSettings().getInt("dualshape", 0);
|
||||
}
|
||||
shape++;
|
||||
MessagesController.getGlobalMainSettings().edit().putInt("dualshape", shape).apply();
|
||||
if (handler != null) {
|
||||
handler.sendMessage(handler.obtainMessage(cameraThread.DO_DUAL_TOGGLE_SHAPE));
|
||||
}
|
||||
}
|
||||
|
||||
public int getDualShape() {
|
||||
if (shape == null) {
|
||||
shape = MessagesController.getGlobalMainSettings().getInt("dualshape", 0);
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
private long lastDualSwitchTime;
|
||||
|
||||
public void switchCamera() {
|
||||
if (flipping || System.currentTimeMillis() < toggleDualUntil && !dualCameraAppeared) {
|
||||
return;
|
||||
}
|
||||
if (dual) {
|
||||
if (!dualCameraAppeared) {
|
||||
if (!dualCameraAppeared || System.currentTimeMillis() - lastDualSwitchTime < 420) {
|
||||
return;
|
||||
}
|
||||
lastDualSwitchTime = System.currentTimeMillis();
|
||||
CameraInfo info0 = info[0];
|
||||
info[0] = info[1];
|
||||
info[1] = info0;
|
||||
|
@ -2147,6 +2162,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
}
|
||||
}
|
||||
fileWriteQueue = new DispatchQueue("VR_FileWriteQueue");
|
||||
fileWriteQueue.setPriority(Thread.MAX_PRIORITY);
|
||||
|
||||
keyframeThumbs.clear();
|
||||
handler.sendMessage(handler.obtainMessage(MSG_START_RECORDING));
|
||||
|
@ -2806,7 +2822,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
bufferInfo.offset = videoBufferInfo.offset;
|
||||
bufferInfo.flags = videoBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = videoBufferInfo.presentationTimeUs;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
ByteBuffer byteBuffer = AndroidUtilities.cloneByteBuffer(encodedData);
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
try {
|
||||
mediaMuxer.writeSampleData(videoTrackIndex, byteBuffer, bufferInfo, true);
|
||||
|
@ -2891,7 +2907,7 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
|
|||
bufferInfo.offset = audioBufferInfo.offset;
|
||||
bufferInfo.flags = audioBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = audioBufferInfo.presentationTimeUs;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
ByteBuffer byteBuffer = AndroidUtilities.cloneByteBuffer(encodedData);
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
try {
|
||||
mediaMuxer.writeSampleData(audioTrackIndex, byteBuffer, bufferInfo, false);
|
||||
|
|
|
@ -1030,6 +1030,7 @@ public class TextureRenderer {
|
|||
entity.animatedFileDrawable = new AnimatedFileDrawable(new File(entity.text), true, 0, 0, null, null, null, 0, UserConfig.selectedAccount, true, 512, 512, null);
|
||||
entity.framesPerDraw = entity.animatedFileDrawable.getFps() / videoFps;
|
||||
entity.currentFrame = 0;
|
||||
entity.animatedFileDrawable.getNextFrame();
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
|
|
|
@ -1158,7 +1158,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
|
|||
if (!canCacnel || cancelDialog != null) {
|
||||
return;
|
||||
}
|
||||
Builder builder = new Builder(getContext());
|
||||
Builder builder = new Builder(getContext(), resourcesProvider);
|
||||
builder.setTitle(LocaleController.getString("StopLoadingTitle", R.string.StopLoadingTitle));
|
||||
builder.setMessage(LocaleController.getString("StopLoading", R.string.StopLoading));
|
||||
builder.setPositiveButton(LocaleController.getString("WaitMore", R.string.WaitMore), null);
|
||||
|
|
|
@ -68,6 +68,7 @@ import org.telegram.ui.Stories.StoryViewer;
|
|||
import java.time.YearMonth;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.SortedSet;
|
||||
|
||||
public class CalendarActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
|
@ -214,7 +215,7 @@ public class CalendarActivity extends BaseFragment implements NotificationCenter
|
|||
holder.drawAbove = storiesPlaceDrawAbove;
|
||||
holder.view = monthView;
|
||||
holder.clipParent = fragmentView;
|
||||
holder.clipTop = Math.max(0, - monthView.getY());
|
||||
holder.clipTop = AndroidUtilities.dp(36);
|
||||
holder.clipBottom = fragmentView.getBottom();
|
||||
holder.avatarImage = null;
|
||||
return true;
|
||||
|
@ -801,8 +802,7 @@ public class CalendarActivity extends BaseFragment implements NotificationCenter
|
|||
PeriodDay day = getDayAtCoord(e.getX(), e.getY());
|
||||
if (day != null && day.messageObject != null && callback != null) {
|
||||
if (storiesList != null) {
|
||||
int position = storiesList.messageObjects.indexOf(day.messageObject);
|
||||
getOrCreateStoryViewer().open(getContext(), day.messageObject.storyItem, Math.max(0, position), storiesList, true, storiesPlaceProvider);
|
||||
getOrCreateStoryViewer().open(getContext(), day.messageObject.storyItem, day.messageObject.getId(), storiesList, true, storiesPlaceProvider);
|
||||
} else {
|
||||
callback.onDateSelected(day.messageObject.getId(), day.startOffset);
|
||||
finishFragment();
|
||||
|
|
|
@ -11419,6 +11419,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
if (currentMessageObject == null) {
|
||||
return;
|
||||
}
|
||||
if (currentMessageObject.type == MessageObject.TYPE_STORY && currentMessageObject.isVideoStory()) {
|
||||
buttonState = 2;
|
||||
getIconForCurrentState();
|
||||
return;
|
||||
}
|
||||
if (animated && (PhotoViewer.isShowingImage(currentMessageObject) || !attachedToWindow)) {
|
||||
animated = false;
|
||||
}
|
||||
|
@ -12015,7 +12020,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
|
|||
}
|
||||
}
|
||||
} else if (buttonState == 2) {
|
||||
if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) {
|
||||
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_STORY) {
|
||||
delegate.didPressImage(this, 0, 0);
|
||||
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND && currentMessageObject != null && currentMessageObject.isVoiceTranscriptionOpen()) {
|
||||
if (miniButtonState == 0) {
|
||||
FileLoader.getInstance(currentAccount).loadFile(documentAttach, currentMessageObject, FileLoader.PRIORITY_NORMAL_UP, 0);
|
||||
currentMessageObject.loadingCancelled = false;
|
||||
|
|
|
@ -74,6 +74,7 @@ public class SharedPhotoVideoCell2 extends View {
|
|||
float crossfadeProgress;
|
||||
float crossfadeToColumnsCount;
|
||||
float highlightProgress;
|
||||
public boolean isFirst, isLast;
|
||||
|
||||
private Drawable gradientDrawable;
|
||||
private boolean gradientDrawableLoading;
|
||||
|
@ -303,8 +304,10 @@ public class SharedPhotoVideoCell2 extends View {
|
|||
super.onDraw(canvas);
|
||||
|
||||
final float padding = getPadding();
|
||||
final float leftpadding = isStory && isFirst ? 0 : padding;
|
||||
final float rightpadding = isStory && isLast ? 0 : padding;
|
||||
|
||||
float imageWidth = (getMeasuredWidth() - padding * 2) * imageScale;
|
||||
float imageWidth = (getMeasuredWidth() - leftpadding - rightpadding) * imageScale;
|
||||
float imageHeight = (getMeasuredHeight() - padding * 2) * imageScale;
|
||||
|
||||
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
|
||||
|
@ -317,23 +320,23 @@ public class SharedPhotoVideoCell2 extends View {
|
|||
globalGradientView.setParentSize(((View) SharedPhotoVideoCell2.this.getParent()).getMeasuredWidth(), SharedPhotoVideoCell2.this.getMeasuredHeight(), -getX());
|
||||
globalGradientView.updateColors();
|
||||
globalGradientView.updateGradient();
|
||||
float localPadding = padding;
|
||||
float padPlus = 0;
|
||||
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
|
||||
localPadding += 1;
|
||||
padPlus += 1;
|
||||
}
|
||||
canvas.drawRect(localPadding, localPadding, localPadding + imageWidth, localPadding + imageHeight, globalGradientView.getPaint());
|
||||
canvas.drawRect(leftpadding + padPlus, padding + padPlus, leftpadding + padPlus + imageWidth, padding + padPlus + imageHeight, globalGradientView.getPaint());
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
if (imageAlpha != 1f) {
|
||||
canvas.saveLayerAlpha(0, 0, padding * 2 + imageWidth, padding * 2 + imageHeight, (int) (255 * imageAlpha), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.saveLayerAlpha(0, 0, leftpadding + rightpadding + imageWidth, padding * 2 + imageHeight, (int) (255 * imageAlpha), Canvas.ALL_SAVE_FLAG);
|
||||
} else {
|
||||
canvas.save();
|
||||
}
|
||||
|
||||
if ((checkBoxBase != null && checkBoxBase.isChecked()) || PhotoViewer.isShowingImage(currentMessageObject)) {
|
||||
canvas.drawRect(padding, padding, imageWidth, imageHeight, sharedResources.backgroundPaint);
|
||||
canvas.drawRect(leftpadding, padding, leftpadding + imageWidth - rightpadding, imageHeight, sharedResources.backgroundPaint);
|
||||
}
|
||||
|
||||
if (isStory && currentParentColumnsCount == 1) {
|
||||
|
@ -357,21 +360,21 @@ public class SharedPhotoVideoCell2 extends View {
|
|||
imageReceiver.setImageCoords((imageWidth - w) / 2, 0, w, getHeight());
|
||||
} else if (checkBoxProgress > 0) {
|
||||
float offset = dp(10) * checkBoxProgress;
|
||||
imageReceiver.setImageCoords(padding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
|
||||
blurImageReceiver.setImageCoords(padding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
|
||||
imageReceiver.setImageCoords(leftpadding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
|
||||
blurImageReceiver.setImageCoords(leftpadding + offset, padding + offset, imageWidth - offset * 2, imageHeight - offset * 2);
|
||||
} else {
|
||||
float localPadding = padding;
|
||||
float padPlus = 0;
|
||||
if (crossfadeProgress > 0.5f && crossfadeToColumnsCount != 9 && currentParentColumnsCount != 9) {
|
||||
localPadding += 1;
|
||||
padPlus = 1;
|
||||
}
|
||||
imageReceiver.setImageCoords(localPadding, localPadding, imageWidth, imageHeight);
|
||||
blurImageReceiver.setImageCoords(localPadding, localPadding, imageWidth, imageHeight);
|
||||
imageReceiver.setImageCoords(leftpadding + padPlus, padding + padPlus, imageWidth, imageHeight);
|
||||
blurImageReceiver.setImageCoords(leftpadding + padPlus, padding + padPlus, imageWidth, imageHeight);
|
||||
}
|
||||
if (!PhotoViewer.isShowingImage(currentMessageObject)) {
|
||||
imageReceiver.draw(canvas);
|
||||
if (currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.isMediaSpoilersRevealedInSharedMedia) {
|
||||
canvas.save();
|
||||
canvas.clipRect(padding, padding, padding + imageWidth, padding + imageHeight);
|
||||
canvas.clipRect(leftpadding, padding, leftpadding + imageWidth - rightpadding, padding + imageHeight);
|
||||
|
||||
if (spoilerRevealProgress != 0f) {
|
||||
path.rewind();
|
||||
|
@ -397,7 +400,7 @@ public class SharedPhotoVideoCell2 extends View {
|
|||
}
|
||||
|
||||
bounds.set(imageReceiver.getImageX(), imageReceiver.getImageY(), imageReceiver.getImageX2(), imageReceiver.getImageY2());
|
||||
bounds.set(padding, padding, padding + imageWidth, padding + imageHeight);
|
||||
bounds.set(leftpadding, padding, leftpadding + imageWidth - rightpadding, padding + imageHeight);
|
||||
drawDuration(canvas, bounds, 1f);
|
||||
|
||||
if (checkBoxBase != null && (style == STYLE_CACHE || checkBoxBase.getProgress() != 0)) {
|
||||
|
|
|
@ -19870,6 +19870,32 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
|||
messageObject.generatePaymentSentMessageText(null);
|
||||
}
|
||||
}
|
||||
if (old.isWebpage() && messageObject.isWebpage()) {
|
||||
TLRPC.TL_messageMediaWebPage media = (TLRPC.TL_messageMediaWebPage) MessageObject.getMedia(old.messageOwner);
|
||||
if (media.webpage != null && "telegram_story".equals(media.webpage.type)) {
|
||||
TLRPC.StoryItem storyItem = null;
|
||||
for (int i = 0; i < media.webpage.attributes.size(); ++i) {
|
||||
TLRPC.WebPageAttribute attr = media.webpage.attributes.get(i);
|
||||
if (attr instanceof TLRPC.TL_webPageAttributeStory) {
|
||||
storyItem = ((TLRPC.TL_webPageAttributeStory) attr).storyItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (storyItem != null) {
|
||||
TLRPC.TL_messageMediaWebPage newMedia = (TLRPC.TL_messageMediaWebPage) MessageObject.getMedia(messageObject.messageOwner);
|
||||
for (int i = 0; i < newMedia.webpage.attributes.size(); ++i) {
|
||||
TLRPC.WebPageAttribute attr = newMedia.webpage.attributes.get(i);
|
||||
if (attr instanceof TLRPC.TL_webPageAttributeStory) {
|
||||
TLRPC.TL_webPageAttributeStory storyAttr = (TLRPC.TL_webPageAttributeStory) attr;
|
||||
if (!(storyAttr.storyItem instanceof TLRPC.TL_storyItem)) {
|
||||
storyAttr.storyItem = storyItem;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!old.isEditing()) {
|
||||
if (old.getFileName().equals(messageObject.getFileName())) {
|
||||
messageObject.messageOwner.attachPath = old.messageOwner.attachPath;
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.text.Layout;
|
|||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
|
|
|
@ -1844,4 +1844,9 @@ public class Bulletin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Bulletin setTag(int tag) {
|
||||
this.tag = tag;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package org.telegram.ui.Components;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.os.Build;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import androidx.core.graphics.PathParser;
|
||||
|
@ -14,7 +16,7 @@ public class CubicBezierInterpolator implements Interpolator {
|
|||
public static final CubicBezierInterpolator EASE_IN = new CubicBezierInterpolator(.42, 0, 1, 1);
|
||||
public static final CubicBezierInterpolator EASE_BOTH = new CubicBezierInterpolator(.42, 0, .58, 1);
|
||||
public static final CubicBezierInterpolator EASE_OUT_BACK = new CubicBezierInterpolator(.34, 1.56, .64, 1);
|
||||
public static final PathInterpolator Emphasized = new PathInterpolator(PathParser.createPathFromPathData("M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1"));
|
||||
public static final Interpolator Emphasized = Build.VERSION.SDK_INT >= 21 ? new PathInterpolator(PathParser.createPathFromPathData("M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1")) : new LinearInterpolator();
|
||||
protected PointF start;
|
||||
protected PointF end;
|
||||
protected PointF a = new PointF();
|
||||
|
|
|
@ -97,6 +97,7 @@ import org.telegram.messenger.camera.Size;
|
|||
import org.telegram.messenger.video.MP4Builder;
|
||||
import org.telegram.messenger.video.Mp4Movie;
|
||||
import org.telegram.tgnet.ConnectionsManager;
|
||||
import org.telegram.tgnet.NativeByteBuffer;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.ChatActivity;
|
||||
|
@ -125,7 +126,7 @@ import javax.microedition.khronos.egl.EGLSurface;
|
|||
@TargetApi(18)
|
||||
public class InstantCameraView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
public boolean WRITE_TO_FILE_IN_BACKGROUND = true;
|
||||
public boolean WRITE_TO_FILE_IN_BACKGROUND;
|
||||
|
||||
private int currentAccount = UserConfig.selectedAccount;
|
||||
private InstantViewCameraContainer cameraContainer;
|
||||
|
@ -241,6 +242,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
@SuppressLint("ClickableViewAccessibility")
|
||||
public InstantCameraView(Context context, Delegate delegate, Theme.ResourcesProvider resourcesProvider) {
|
||||
super(context);
|
||||
WRITE_TO_FILE_IN_BACKGROUND = SharedConfig.deviceIsAboveAverage();
|
||||
this.resourcesProvider = resourcesProvider;
|
||||
parentView = delegate.getFragmentView();
|
||||
setWillNotDraw(false);
|
||||
|
@ -1827,7 +1829,12 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
AudioBufferInfo buffer;
|
||||
if (buffers.isEmpty()) {
|
||||
buffer = new AudioBufferInfo();
|
||||
try {
|
||||
buffer = new AudioBufferInfo();
|
||||
} catch (OutOfMemoryError error) {
|
||||
System.gc();
|
||||
buffer = new AudioBufferInfo();
|
||||
}
|
||||
} else {
|
||||
buffer = buffers.poll();
|
||||
}
|
||||
|
@ -1925,6 +1932,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
|
||||
fileWriteQueue = new DispatchQueue("IVR_FileWriteQueue");
|
||||
fileWriteQueue.setPriority(Thread.MAX_PRIORITY);
|
||||
|
||||
keyframeThumbs.clear();
|
||||
frameCount = 0;
|
||||
|
@ -2700,7 +2708,6 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
if (encodedData == null) {
|
||||
throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
|
||||
}
|
||||
boolean needReleaseBuffers = true;
|
||||
if (videoBufferInfo.size > 1) {
|
||||
if ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
|
||||
if (prependHeaderSize != 0 && (videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_KEY_FRAME) != 0) {
|
||||
|
@ -2732,7 +2739,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
bufferInfo.offset = videoBufferInfo.offset;
|
||||
bufferInfo.flags = videoBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = videoBufferInfo.presentationTimeUs;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
ByteBuffer byteBuffer = AndroidUtilities.cloneByteBuffer(encodedData);
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
long availableSize = 0;
|
||||
try {
|
||||
|
@ -2779,9 +2786,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
|
||||
}
|
||||
}
|
||||
if (needReleaseBuffers) {
|
||||
videoEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
}
|
||||
videoEncoder.releaseOutputBuffer(encoderStatus, false);
|
||||
if ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -2827,7 +2832,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
|
|||
bufferInfo.offset = audioBufferInfo.offset;
|
||||
bufferInfo.flags = audioBufferInfo.flags;
|
||||
bufferInfo.presentationTimeUs = audioBufferInfo.presentationTimeUs;
|
||||
ByteBuffer byteBuffer = encodedData.duplicate();
|
||||
ByteBuffer byteBuffer = AndroidUtilities.cloneByteBuffer(encodedData);
|
||||
fileWriteQueue.postRunnable(() -> {
|
||||
long availableSize = 0;
|
||||
try {
|
||||
|
|
|
@ -338,6 +338,9 @@ public class JoinGroupAlert extends BottomSheet {
|
|||
|
||||
private CharSequence ellipsize(TextView textView, TLRPC.ChatInvite chatInvite, int pos) {
|
||||
String firstName = chatInvite.participants.get(pos).first_name;
|
||||
if (firstName == null) {
|
||||
firstName = "";
|
||||
}
|
||||
return TextUtils.ellipsize(firstName.trim(), textView.getPaint(), AndroidUtilities.dp(120), TextUtils.TruncateAt.END);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2408,9 +2408,10 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
|
|||
deleteView.setBackground(Theme.getSelectorDrawable(false));
|
||||
deleteView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
deleteView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(14), 0);
|
||||
deleteView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
deleteView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
deleteView.setTag(0);
|
||||
deleteView.setText(LocaleController.getString("PaintDelete", R.string.PaintDelete));
|
||||
deleteView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
deleteView.setOnClickListener(v -> {
|
||||
removeEntity(entityView);
|
||||
|
||||
|
@ -2426,7 +2427,8 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
|
|||
editView.setBackground(Theme.getSelectorDrawable(false));
|
||||
editView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
editView.setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0);
|
||||
editView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
editView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
editView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
editView.setTag(1);
|
||||
editView.setText(LocaleController.getString("PaintEdit", R.string.PaintEdit));
|
||||
editView.setOnClickListener(v -> {
|
||||
|
@ -2443,8 +2445,9 @@ public class LPhotoPaintView extends SizeNotifierFrameLayoutPhoto implements IPh
|
|||
duplicateView.setTextColor(getThemedColor(Theme.key_actionBarDefaultSubmenuItem));
|
||||
duplicateView.setBackgroundDrawable(Theme.getSelectorDrawable(false));
|
||||
duplicateView.setGravity(Gravity.CENTER_VERTICAL);
|
||||
duplicateView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
duplicateView.setPadding(AndroidUtilities.dp(14), 0, AndroidUtilities.dp(16), 0);
|
||||
duplicateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
|
||||
duplicateView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
|
||||
duplicateView.setTag(2);
|
||||
duplicateView.setText(LocaleController.getString("PaintDuplicate", R.string.PaintDuplicate));
|
||||
duplicateView.setOnClickListener(v -> {
|
||||
|
|
|
@ -66,7 +66,8 @@ public class PhotoView extends EntityView {
|
|||
centerImage.setParentView(containerView);
|
||||
centerImage.setRoundRadius(AndroidUtilities.dp(12));
|
||||
centerImage.setOrientation(orientation, invert, true);
|
||||
centerImage.setImage(ImageLocation.getForPath(path), null, null, null, null, 1);
|
||||
final int side = Math.round(Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * .8f / AndroidUtilities.density);
|
||||
centerImage.setImage(ImageLocation.getForPath(path), side + "_" + side, null, null, null, 1);
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
|
|
|
@ -616,30 +616,30 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati
|
|||
} else if (onlySelectedType) {
|
||||
if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) {
|
||||
title.setText(LocaleController.getString("AdditionalReactions", R.string.AdditionalReactions));
|
||||
description.setText(LocaleController.getString("AdditionalReactionsDescription", R.string.AdditionalReactionsDescription));
|
||||
description.setText(AndroidUtilities.replaceTags(LocaleController.getString("AdditionalReactionsDescription", R.string.AdditionalReactionsDescription)));
|
||||
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADS) {
|
||||
title.setText(LocaleController.getString("PremiumPreviewNoAds", R.string.PremiumPreviewNoAds));
|
||||
description.setText(LocaleController.getString("PremiumPreviewNoAdsDescription2", R.string.PremiumPreviewNoAdsDescription2));
|
||||
description.setText(AndroidUtilities.replaceTags(LocaleController.getString("PremiumPreviewNoAdsDescription2", R.string.PremiumPreviewNoAdsDescription2)));
|
||||
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) {
|
||||
title.setText(LocaleController.getString("PremiumPreviewAppIcon", R.string.PremiumPreviewAppIcon));
|
||||
description.setText(LocaleController.getString("PremiumPreviewAppIconDescription2", R.string.PremiumPreviewAppIconDescription2));
|
||||
description.setText(AndroidUtilities.replaceTags(LocaleController.getString("PremiumPreviewAppIconDescription2", R.string.PremiumPreviewAppIconDescription2)));
|
||||
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_DOWNLOAD_SPEED) {
|
||||
title.setText(LocaleController.getString(R.string.PremiumPreviewDownloadSpeed));
|
||||
description.setText(LocaleController.getString(R.string.PremiumPreviewDownloadSpeedDescription2));
|
||||
description.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PremiumPreviewDownloadSpeedDescription2)));
|
||||
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT) {
|
||||
title.setText(LocaleController.getString(R.string.PremiumPreviewAdvancedChatManagement));
|
||||
description.setText(LocaleController.getString(R.string.PremiumPreviewAdvancedChatManagementDescription2));
|
||||
description.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PremiumPreviewAdvancedChatManagementDescription2)));
|
||||
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_VOICE_TO_TEXT) {
|
||||
title.setText(LocaleController.getString(R.string.PremiumPreviewVoiceToText));
|
||||
description.setText(LocaleController.getString(R.string.PremiumPreviewVoiceToTextDescription2));
|
||||
description.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PremiumPreviewVoiceToTextDescription2)));
|
||||
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_TRANSLATIONS) {
|
||||
title.setText(LocaleController.getString(R.string.PremiumPreviewTranslations));
|
||||
description.setText(LocaleController.getString(R.string.PremiumPreviewTranslationsDescription));
|
||||
description.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PremiumPreviewTranslationsDescription)));
|
||||
}
|
||||
topViewOnFullHeight = false;
|
||||
} else {
|
||||
title.setText(featureData.title);
|
||||
description.setText(featureData.description);
|
||||
description.setText(AndroidUtilities.replaceTags(featureData.description));
|
||||
topViewOnFullHeight = false;
|
||||
}
|
||||
requestLayout();
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.telegram.messenger.AndroidUtilities;
|
|||
import org.telegram.messenger.ApplicationLoader;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Stories.recorder.HintView2;
|
||||
import org.telegram.ui.TopicsFragment;
|
||||
|
||||
public class PullForegroundDrawable {
|
||||
|
@ -88,9 +89,14 @@ public class PullForegroundDrawable {
|
|||
public float outImageSize;
|
||||
public float outOverScroll;
|
||||
|
||||
private final CharSequence pullTooltipText;
|
||||
private StaticLayout pullTooltipLayout;
|
||||
private float pullTooltipLayoutScale = 1;
|
||||
private float pullTooltipLayoutLeft, pullTooltipLayoutWidth;
|
||||
|
||||
private final CharSequence releaseTooltipText;
|
||||
private StaticLayout releaseTooltipLayout;
|
||||
private float releaseTooltipLayoutScale = 1;
|
||||
private float releaseTooltipLayoutLeft, releaseTooltipLayoutWidth;
|
||||
private boolean willDraw;
|
||||
|
||||
|
@ -120,18 +126,63 @@ public class PullForegroundDrawable {
|
|||
final ViewConfiguration vc = ViewConfiguration.get(ApplicationLoader.applicationContext);
|
||||
touchSlop = vc.getScaledTouchSlop();
|
||||
|
||||
pullTooltipLayout = new StaticLayout(pullText, 0, pullText.length(), tooltipTextPaint, AndroidUtilities.displaySize.x, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
|
||||
pullTooltipLayoutLeft = pullTooltipLayout.getLineCount() > 0 ? pullTooltipLayout.getLineLeft(0) : 0;
|
||||
pullTooltipLayoutWidth = pullTooltipLayout.getLineCount() > 0 ? pullTooltipLayout.getLineWidth(0) : 0;
|
||||
releaseTooltipLayout = new StaticLayout(releaseText, 0, releaseText.length(), tooltipTextPaint, AndroidUtilities.displaySize.x, Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
|
||||
releaseTooltipLayoutLeft = releaseTooltipLayout.getLineCount() > 0 ? releaseTooltipLayout.getLineLeft(0) : 0;
|
||||
releaseTooltipLayoutWidth = releaseTooltipLayout.getLineCount() > 0 ? releaseTooltipLayout.getLineWidth(0) : 0;
|
||||
pullTooltipText = pullText;
|
||||
releaseTooltipText = releaseText;
|
||||
|
||||
try {
|
||||
generalTopicDrawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.msg_filled_general).mutate();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
private int lastWidth;
|
||||
private void checkTextLayouts(int width) {
|
||||
if (width != lastWidth) {
|
||||
|
||||
float textWidth;
|
||||
int layoutWidth;
|
||||
|
||||
pullTooltipLayout = new StaticLayout(pullTooltipText, tooltipTextPaint, AndroidUtilities.displaySize.x, Layout.Alignment.ALIGN_CENTER, 1, 0, false);
|
||||
textWidth = 0;
|
||||
for (int i = 0; i < pullTooltipLayout.getLineCount(); ++i) {
|
||||
textWidth = Math.max(textWidth, pullTooltipLayout.getLineWidth(i));
|
||||
}
|
||||
pullTooltipLayoutScale = Math.min(1, width / textWidth);
|
||||
layoutWidth = (int) Math.ceil(textWidth);
|
||||
if (pullTooltipLayoutScale < .8f) {
|
||||
pullTooltipLayoutScale = .8f;
|
||||
layoutWidth = HintView2.cutInFancyHalf(pullTooltipText, tooltipTextPaint);
|
||||
}
|
||||
pullTooltipLayout = new StaticLayout(pullTooltipText, tooltipTextPaint, layoutWidth, Layout.Alignment.ALIGN_CENTER, 1, 0, false);
|
||||
pullTooltipLayoutLeft = layoutWidth;
|
||||
pullTooltipLayoutWidth = 0;
|
||||
for (int i = 0; i < pullTooltipLayout.getLineCount(); ++i) {
|
||||
pullTooltipLayoutLeft = Math.min(pullTooltipLayoutLeft, pullTooltipLayout.getLineLeft(i));
|
||||
pullTooltipLayoutWidth = Math.max(pullTooltipLayoutWidth, pullTooltipLayout.getLineWidth(i));
|
||||
}
|
||||
|
||||
releaseTooltipLayout = new StaticLayout(releaseTooltipText, tooltipTextPaint, AndroidUtilities.displaySize.x, Layout.Alignment.ALIGN_CENTER, 1, 0, false);
|
||||
textWidth = 0;
|
||||
for (int i = 0; i < releaseTooltipLayout.getLineCount(); ++i) {
|
||||
textWidth = Math.max(textWidth, releaseTooltipLayout.getLineWidth(i));
|
||||
}
|
||||
releaseTooltipLayoutScale = Math.min(1, width / textWidth);
|
||||
layoutWidth = (int) Math.ceil(textWidth);
|
||||
if (releaseTooltipLayoutScale < .8f) {
|
||||
releaseTooltipLayoutScale = .8f;
|
||||
layoutWidth = HintView2.cutInFancyHalf(releaseTooltipText, tooltipTextPaint);
|
||||
}
|
||||
releaseTooltipLayout = new StaticLayout(releaseTooltipText, tooltipTextPaint, layoutWidth, Layout.Alignment.ALIGN_CENTER, 1, 0, false);
|
||||
releaseTooltipLayoutLeft = layoutWidth;
|
||||
releaseTooltipLayoutWidth = 0;
|
||||
for (int i = 0; i < releaseTooltipLayout.getLineCount(); ++i) {
|
||||
releaseTooltipLayoutLeft = Math.min(releaseTooltipLayoutLeft, releaseTooltipLayout.getLineLeft(i));
|
||||
releaseTooltipLayoutWidth = Math.max(releaseTooltipLayoutWidth, releaseTooltipLayout.getLineWidth(i));
|
||||
}
|
||||
|
||||
lastWidth = width;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMaxOverscroll() {
|
||||
return AndroidUtilities.dp(72);
|
||||
}
|
||||
|
@ -191,6 +242,8 @@ public class PullForegroundDrawable {
|
|||
|
||||
float bounceP = bounceIn ? (0.07f * bounceProgress) - 0.05f : 0.02f * bounceProgress;
|
||||
|
||||
checkTextLayouts(cell.getWidth() - startPadding * 4 - AndroidUtilities.dp(16));
|
||||
|
||||
updateTextProgress(pullProgress);
|
||||
|
||||
float outProgressHalf = outProgress * 2f;
|
||||
|
@ -308,35 +361,40 @@ public class PullForegroundDrawable {
|
|||
}
|
||||
|
||||
float textY = cell.getHeight() - ((diameter + smallMargin * 2) / 2f) + AndroidUtilities.dp(6);
|
||||
float textCx = cell.getWidth() / 2f - AndroidUtilities.dp(2);
|
||||
float textCx = (cell.getWidth() + (isTopic ? startPadding * 2 : 0)) / 2f;
|
||||
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
canvas.save();
|
||||
float scale = 0.8f + 0.2f * textSwappingProgress;
|
||||
canvas.scale(scale, scale, textCx, textY + AndroidUtilities.dp(16) * (1f - textSwappingProgress));
|
||||
}
|
||||
canvas.saveLayerAlpha(0, 0, cell.getMeasuredWidth(), cell.getMeasuredHeight(), (int) (255 * textSwappingProgress * startPullProgress * textInProgress), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.translate(textCx - pullTooltipLayoutLeft - pullTooltipLayoutWidth / 2f, textY + AndroidUtilities.dp(8) * (1f - textSwappingProgress) - tooltipTextPaint.getTextSize());
|
||||
pullTooltipLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
if (pullTooltipLayout != null) {
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
canvas.save();
|
||||
float scale = 0.8f + 0.2f * textSwappingProgress;
|
||||
canvas.scale(scale, scale, textCx, textY + AndroidUtilities.dp(16) * (1f - textSwappingProgress));
|
||||
}
|
||||
canvas.saveLayerAlpha(0, 0, cell.getMeasuredWidth(), cell.getMeasuredHeight(), (int) (255 * textSwappingProgress * startPullProgress * textInProgress), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.translate(textCx - pullTooltipLayoutLeft - pullTooltipLayoutWidth / 2f, textY + AndroidUtilities.dp(8) * (1f - textSwappingProgress) - pullTooltipLayout.getHeight());
|
||||
canvas.scale(pullTooltipLayoutScale, pullTooltipLayoutScale, pullTooltipLayoutLeft + pullTooltipLayoutWidth / 2f, pullTooltipLayout.getHeight());
|
||||
pullTooltipLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
canvas.save();
|
||||
float scale = 0.9f + 0.1f * (1f - textSwappingProgress);
|
||||
canvas.scale(scale, scale, textCx, textY - AndroidUtilities.dp(8) * (textSwappingProgress));
|
||||
}
|
||||
canvas.saveLayerAlpha(0, 0, cell.getMeasuredWidth(), cell.getMeasuredHeight(), (int) (255 * (1f - textSwappingProgress) * startPullProgress * textInProgress), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.translate(textCx - releaseTooltipLayoutLeft - releaseTooltipLayoutWidth / 2f, textY + AndroidUtilities.dp(8) * (textSwappingProgress) - tooltipTextPaint.getTextSize());
|
||||
releaseTooltipLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
if (releaseTooltipLayout != null) {
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
canvas.save();
|
||||
float scale = 0.9f + 0.1f * (1f - textSwappingProgress);
|
||||
canvas.scale(scale, scale, textCx, textY - AndroidUtilities.dp(8) * (textSwappingProgress));
|
||||
}
|
||||
canvas.saveLayerAlpha(0, 0, cell.getMeasuredWidth(), cell.getMeasuredHeight(), (int) (255 * (1f - textSwappingProgress) * startPullProgress * textInProgress), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.translate(textCx - releaseTooltipLayoutLeft - releaseTooltipLayoutWidth / 2f, textY + AndroidUtilities.dp(8) * (textSwappingProgress) - releaseTooltipLayout.getHeight());
|
||||
canvas.scale(releaseTooltipLayoutScale, releaseTooltipLayoutScale, releaseTooltipLayoutLeft + releaseTooltipLayoutWidth / 2f, releaseTooltipLayout.getHeight());
|
||||
releaseTooltipLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
if (textSwappingProgress > 0 && textSwappingProgress < 1f) {
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
|
||||
if (!isTopic && changeAvatarColor && outProgress > 0) {
|
||||
|
|
|
@ -526,7 +526,7 @@ public class RecyclerListView extends RecyclerView {
|
|||
private boolean floatingDateVisible;
|
||||
private float floatingDateProgress;
|
||||
private int[] positionWithOffset = new int[2];
|
||||
boolean isVisible;
|
||||
public boolean isVisible;
|
||||
float touchSlop;
|
||||
Drawable fastScrollShadowDrawable;
|
||||
Drawable fastScrollBackgroundDrawable;
|
||||
|
|
|
@ -377,8 +377,8 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
public long lastCheckScrollTime;
|
||||
public boolean fastScrollEnabled;
|
||||
public ObjectAnimator fastScrollAnimator;
|
||||
private BlurredRecyclerView listView;
|
||||
private BlurredRecyclerView animationSupportingListView;
|
||||
private InternalListView listView;
|
||||
private InternalListView animationSupportingListView;
|
||||
private GridLayoutManager animationSupportingLayoutManager;
|
||||
private FlickerLoadingView progressView;
|
||||
private StickerEmptyView emptyView;
|
||||
|
@ -1880,7 +1880,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
if (archivedHintLayout == null || archivedHintLayout.getWidth() != width) {
|
||||
archivedHintLayout = new StaticLayout(LocaleController.getString("ProfileStoriesArchiveHint", R.string.ProfileStoriesArchiveHint), archivedHintPaint, width, Layout.Alignment.ALIGN_CENTER, 1f, 0f, false);
|
||||
archivedHintLayoutWidth = 0;
|
||||
archivedHintLayoutLeft = 0;
|
||||
archivedHintLayoutLeft = width;
|
||||
for (int i = 0; i < archivedHintLayout.getLineCount(); ++i) {
|
||||
archivedHintLayoutWidth = Math.max(archivedHintLayoutWidth, archivedHintLayout.getLineWidth(i));
|
||||
archivedHintLayoutLeft = Math.min(archivedHintLayoutLeft, archivedHintLayout.getLineLeft(i));
|
||||
|
@ -2225,7 +2225,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
mediaPages[a].listView.setSectionsType(RecyclerListView.SECTIONS_TYPE_DATE);
|
||||
mediaPages[a].listView.setLayoutManager(layoutManager);
|
||||
mediaPages[a].addView(mediaPages[a].listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
mediaPages[a].animationSupportingListView = new BlurredRecyclerView(context);
|
||||
mediaPages[a].animationSupportingListView = new InternalListView(context);
|
||||
mediaPages[a].animationSupportingListView.setLayoutManager(mediaPages[a].animationSupportingLayoutManager = new GridLayoutManager(context, 3) {
|
||||
|
||||
@Override
|
||||
|
@ -2243,6 +2243,26 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
});
|
||||
mediaPages[a].addView(mediaPages[a].animationSupportingListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
||||
mediaPages[a].animationSupportingListView.setVisibility(View.GONE);
|
||||
mediaPages[a].animationSupportingListView.addItemDecoration(new RecyclerView.ItemDecoration() {
|
||||
@Override
|
||||
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||
if (view instanceof SharedPhotoVideoCell2) {
|
||||
SharedPhotoVideoCell2 cell = (SharedPhotoVideoCell2) view;
|
||||
final int position = mediaPage.animationSupportingListView.getChildAdapterPosition(cell), spanCount = mediaPage.animationSupportingLayoutManager.getSpanCount();
|
||||
cell.isFirst = position % spanCount == 0;
|
||||
cell.isLast = position % spanCount == spanCount - 1;
|
||||
outRect.left = 0;
|
||||
outRect.top = 0;
|
||||
outRect.bottom = 0;
|
||||
outRect.right = 0;
|
||||
} else {
|
||||
outRect.left = 0;
|
||||
outRect.top = 0;
|
||||
outRect.bottom = 0;
|
||||
outRect.right = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mediaPages[a].listView.addItemDecoration(new RecyclerView.ItemDecoration() {
|
||||
|
@ -2258,6 +2278,15 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
outRect.top = 0;
|
||||
}
|
||||
outRect.right = mediaPage.layoutManager.isLastInRow(position) ? 0 : AndroidUtilities.dp(2);
|
||||
} else if (view instanceof SharedPhotoVideoCell2) {
|
||||
SharedPhotoVideoCell2 cell = (SharedPhotoVideoCell2) view;
|
||||
final int position = mediaPage.listView.getChildAdapterPosition(cell), spanCount = mediaPage.layoutManager.getSpanCount();
|
||||
cell.isFirst = position % spanCount == 0;
|
||||
cell.isLast = position % spanCount == spanCount - 1;
|
||||
outRect.left = 0;
|
||||
outRect.top = 0;
|
||||
outRect.bottom = 0;
|
||||
outRect.right = 0;
|
||||
} else {
|
||||
outRect.left = 0;
|
||||
outRect.top = 0;
|
||||
|
@ -2764,6 +2793,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
);
|
||||
|
||||
mediaPage.animationSupportingLayoutManager.setSpanCount(newColumnsCount);
|
||||
mediaPage.animationSupportingListView.invalidateItemDecorations();
|
||||
final MediaPage finalMediaPage = mediaPage;
|
||||
mediaPage.animationSupportingLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||
@Override
|
||||
|
@ -2837,6 +2867,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
mediaPages[i].animationSupportingListView.setVisibility(View.GONE);
|
||||
mediaPages[i].layoutManager.setSpanCount(mediaColumnsCount[ci]);
|
||||
mediaPages[i].listView.invalidateItemDecorations();
|
||||
mediaPages[i].listView.invalidate();
|
||||
if (adapter.getItemCount() == oldItemCount) {
|
||||
AndroidUtilities.updateVisibleRows(mediaPages[i].listView);
|
||||
|
@ -2903,6 +2934,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
if (forward) {
|
||||
mediaPages[i].layoutManager.setSpanCount(mediaColumnsCount[ci]);
|
||||
mediaPages[i].listView.invalidateItemDecorations();
|
||||
if (adapter.getItemCount() == oldItemCount) {
|
||||
AndroidUtilities.updateVisibleRows(mediaPages[i].listView);
|
||||
} else {
|
||||
|
@ -2956,11 +2988,12 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
mediaPage.animationSupportingListView.setPadding(
|
||||
mediaPage.animationSupportingListView.getPaddingLeft(),
|
||||
changeColumnsTab == TAB_ARCHIVED_STORIES ? AndroidUtilities.dp(2 + 64) : AndroidUtilities.dp(2),
|
||||
AndroidUtilities.dp(2) + (mediaPage.animationSupportingListView.hintPaddingTop = (changeColumnsTab == TAB_ARCHIVED_STORIES ? AndroidUtilities.dp(64) : 0)),
|
||||
mediaPage.animationSupportingListView.getPaddingRight(),
|
||||
mediaPage.animationSupportingListView.getPaddingBottom()
|
||||
);
|
||||
mediaPage.animationSupportingLayoutManager.setSpanCount(newColumnsCount);
|
||||
mediaPage.animationSupportingListView.invalidateItemDecorations();
|
||||
for (int i = 0; i < mediaPages.length; ++i) {
|
||||
if (mediaPages[i] != null && isTabZoomable(mediaPages[i].selectedType)) {
|
||||
AndroidUtilities.updateVisibleRows(mediaPages[i].listView);
|
||||
|
@ -3001,6 +3034,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
sharedMediaData[0].setListFrozen(false);
|
||||
}
|
||||
mediaPages[i].layoutManager.setSpanCount(mediaColumnsCount[ci]);
|
||||
mediaPages[i].listView.invalidateItemDecorations();
|
||||
if (adapter.getItemCount() == oldItemCount) {
|
||||
AndroidUtilities.updateVisibleRows(mediaPages[i].listView);
|
||||
} else {
|
||||
|
@ -5012,7 +5046,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
mediaPages[a].listView.setPinnedHeaderShadowDrawable(null);
|
||||
mediaPages[a].listView.setPadding(
|
||||
mediaPages[a].listView.getPaddingLeft(),
|
||||
mediaPages[a].selectedType == TAB_ARCHIVED_STORIES ? AndroidUtilities.dp(2 + 64) : AndroidUtilities.dp(2),
|
||||
AndroidUtilities.dp(2) + (mediaPages[a].listView.hintPaddingTop = mediaPages[a].selectedType == TAB_ARCHIVED_STORIES ? AndroidUtilities.dp(64) : 0),
|
||||
mediaPages[a].listView.getPaddingRight(),
|
||||
mediaPages[a].listView.getPaddingBottom()
|
||||
);
|
||||
|
@ -5169,6 +5203,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
mediaPages[a].fastScrollEnabled = fastScrollVisible;
|
||||
updateFastScrollVisibility(mediaPages[a], false);
|
||||
mediaPages[a].layoutManager.setSpanCount(spanCount);
|
||||
mediaPages[a].listView.invalidateItemDecorations();
|
||||
mediaPages[a].listView.setRecycledViewPool(viewPool);
|
||||
mediaPages[a].animationSupportingListView.setRecycledViewPool(viewPool);
|
||||
|
||||
|
@ -5350,15 +5385,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
} else if (selectedMode == TAB_STORIES || selectedMode == TAB_ARCHIVED_STORIES) {
|
||||
StoriesController.StoriesList storiesList = (selectedMode == TAB_STORIES ? storiesAdapter : archivedStoriesAdapter).storiesList;
|
||||
int pos = -1;
|
||||
for (int i = 0; i < storiesList.messageObjects.size(); ++i) {
|
||||
MessageObject messageObject = storiesList.messageObjects.get(i);
|
||||
if (messageObject != null && messageObject.isStory() && messageObject.getId() == message.getId()) {
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
profileActivity.getOrCreateStoryViewer().open(getContext(), message.storyItem, Math.max(0, pos), storiesList, StoriesListPlaceProvider.of(mediaPages[a].listView));
|
||||
profileActivity.getOrCreateStoryViewer().open(getContext(), message.getId(), storiesList, StoriesListPlaceProvider.of(mediaPages[a].listView));
|
||||
}
|
||||
}
|
||||
updateForwardItem();
|
||||
|
@ -7540,7 +7567,9 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
protected void onTabProgress(float progress) {}
|
||||
protected void onTabScroll(boolean scrolling) {}
|
||||
|
||||
private class InternalListView extends BlurredRecyclerView implements StoriesListPlaceProvider.ClippedView {
|
||||
public static class InternalListView extends BlurredRecyclerView implements StoriesListPlaceProvider.ClippedView {
|
||||
|
||||
public int hintPaddingTop;
|
||||
|
||||
public InternalListView(Context context) {
|
||||
super(context);
|
||||
|
@ -7548,7 +7577,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
|
|||
|
||||
@Override
|
||||
public void updateClip(int[] clip) {
|
||||
clip[0] = getPaddingTop() - AndroidUtilities.dp(2);
|
||||
clip[0] = getPaddingTop() - AndroidUtilities.dp(2) - hintPaddingTop;
|
||||
clip[1] = getMeasuredHeight() - getPaddingBottom();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -636,7 +636,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
|
|||
long dialogId = userCell.getDialogId();
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
final String key = NotificationsController.getSharedPrefKey(dialogId, 0);
|
||||
boolean muted = !NotificationsCustomSettingsActivity.isStoriesNotMuted(currentAccount, dialogId);
|
||||
boolean muted = !NotificationsCustomSettingsActivity.areStoriesNotMuted(currentAccount, dialogId);
|
||||
ItemOptions filterOptions = ItemOptions.makeOptions(ContactsActivity.this, view)
|
||||
//.setViewAdditionalOffsets(0, AndroidUtilities.dp(8), 0, 0)
|
||||
.setScrimViewBackground(Theme.createRoundRectDrawable(0, 0, Theme.getColor(Theme.key_windowBackgroundWhite)))
|
||||
|
|
|
@ -83,8 +83,6 @@ import androidx.recyclerview.widget.LinearSmoothScrollerCustom;
|
|||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
import org.telegram.messenger.AccountInstance;
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.AnimationNotificationsLocker;
|
||||
|
@ -4816,7 +4814,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
}, null);
|
||||
} else {
|
||||
final String key = NotificationsController.getSharedPrefKey(dialogId, 0);
|
||||
boolean muted = !NotificationsCustomSettingsActivity.isStoriesNotMuted(currentAccount, dialogId);
|
||||
boolean muted = !NotificationsCustomSettingsActivity.areStoriesNotMuted(currentAccount, dialogId);
|
||||
filterOptions
|
||||
.add(R.drawable.msg_discussion, LocaleController.getString("SendMessage", R.string.SendMessage), () -> {
|
||||
presentFragment(ChatActivity.of(dialogId));
|
||||
|
@ -11806,7 +11804,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
|
|||
}
|
||||
|
||||
public void updateStoriesVisibility(boolean animated) {
|
||||
if (storiesVisibilityAnimator != null || rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment() || searchIsShowed || actionBar.isActionModeShowed() || onlySelect) {
|
||||
if (dialogStoriesCell == null || storiesVisibilityAnimator != null || rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment() || searchIsShowed || actionBar.isActionModeShowed() || onlySelect) {
|
||||
return;
|
||||
}
|
||||
if (StoryRecorder.isVisible() || (storyViewer != null && storyViewer.isFullyVisible())) {
|
||||
|
|
|
@ -41,8 +41,6 @@ import androidx.recyclerview.widget.DefaultItemAnimator;
|
|||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.common.primitives.Chars;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.ContactsController;
|
||||
|
@ -55,7 +53,6 @@ import org.telegram.messenger.MessagesController;
|
|||
import org.telegram.messenger.NotificationCenter;
|
||||
import org.telegram.messenger.NotificationsController;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.UserObject;
|
||||
import org.telegram.messenger.Utilities;
|
||||
import org.telegram.tgnet.TLObject;
|
||||
|
@ -86,7 +83,6 @@ import org.telegram.ui.Components.EmptyTextProgressView;
|
|||
import org.telegram.ui.Components.ItemOptions;
|
||||
import org.telegram.ui.Components.LayoutHelper;
|
||||
import org.telegram.ui.Components.ListView.AdapterWithDiffUtils;
|
||||
import org.telegram.ui.Components.MediaActivity;
|
||||
import org.telegram.ui.Components.RecyclerListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -95,7 +91,6 @@ import java.util.Comparator;
|
|||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -189,7 +184,7 @@ public class NotificationsCustomSettingsActivity extends BaseFragment implements
|
|||
return index >= 0 && index >= topPeers.size() - 5;
|
||||
}
|
||||
|
||||
public static boolean isStoriesNotMuted(int currentAccount, long did) {
|
||||
public static boolean areStoriesNotMuted(int currentAccount, long did) {
|
||||
SharedPreferences prefs = MessagesController.getNotificationsSettings(currentAccount);
|
||||
if (prefs.contains("stories_" + did)) {
|
||||
return prefs.getBoolean("stories_" + did, true);
|
||||
|
|
|
@ -7264,7 +7264,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
|
|||
}
|
||||
|
||||
boolean divider = false;
|
||||
if (showAddToContacts && user != null && !user.contact) {
|
||||
if (showAddToContacts && user != null && !user.contact && !user.bot && !UserObject.isService(user.id)) {
|
||||
addToContactsRow = rowCount++;
|
||||
divider = true;
|
||||
}
|
||||
|
@ -8990,7 +8990,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
|
|||
totalHeight += listView.getChildAt(i).getMeasuredHeight();
|
||||
}
|
||||
}
|
||||
int paddingHeight = fragmentView.getMeasuredHeight() - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - totalHeight;
|
||||
int paddingHeight = (fragmentView == null ? 0 : fragmentView.getMeasuredHeight()) - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - totalHeight;
|
||||
if (paddingHeight > AndroidUtilities.dp(88)) {
|
||||
paddingHeight = 0;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.text.SpannableString;
|
|||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
|
@ -277,7 +278,10 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
|
|||
}
|
||||
|
||||
private void openStoryForCell(StoryCell cell) {
|
||||
if (cell != null && cell.isSelf && !storiesController.hasSelfStories()) {
|
||||
if (cell == null) {
|
||||
return;
|
||||
}
|
||||
if (cell.isSelf && !storiesController.hasSelfStories()) {
|
||||
if (!MessagesController.getInstance(currentAccount).storiesEnabled()) {
|
||||
showPremiumHint();
|
||||
} else {
|
||||
|
@ -286,8 +290,12 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
|
|||
return;
|
||||
}
|
||||
int position = cell.position;
|
||||
long startFromDialogId = cell.dialogId;
|
||||
ArrayList<Long> peerIds = new ArrayList<>();
|
||||
boolean allStoriesIsRead = true;
|
||||
if (!storiesController.hasStories(cell.dialogId)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
long dialogId = items.get(i).dialogId;
|
||||
if (dialogId != UserConfig.getInstance(currentAccount).clientUserId && storiesController.hasUnreadStories(dialogId)) {
|
||||
|
@ -874,6 +882,7 @@ public class DialogStoriesCell extends FrameLayout implements NotificationCenter
|
|||
|
||||
public void openOverscrollSelectedStory() {
|
||||
openStoryForCell(overscrollSelectedView);
|
||||
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||
}
|
||||
|
||||
public void setActionBar(ActionBar actionBar) {
|
||||
|
|
|
@ -51,8 +51,6 @@ import androidx.core.graphics.ColorUtils;
|
|||
import androidx.core.math.MathUtils;
|
||||
import androidx.recyclerview.widget.ChatListItemAnimator;
|
||||
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
import org.telegram.messenger.AccountInstance;
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.AnimationNotificationsLocker;
|
||||
|
@ -154,9 +152,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.SortedSet;
|
||||
|
||||
public class PeerStoriesView extends SizeNotifierFrameLayout implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
|
@ -207,6 +203,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
final SharedResources sharedResources;
|
||||
RoundRectOutlineProvider outlineProvider;
|
||||
|
||||
ArrayList<Integer> day;
|
||||
|
||||
int count;
|
||||
private long dialogId;
|
||||
boolean isSelf;
|
||||
|
@ -216,6 +214,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
private int selectedPosition;
|
||||
boolean isActive;
|
||||
|
||||
private int listPosition;
|
||||
private int linesPosition, linesCount;
|
||||
|
||||
public final StoryItemHolder currentStory = new StoryItemHolder();
|
||||
|
@ -263,8 +262,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
private AnimatedFloat progressToHideInterface = new AnimatedFloat(this);
|
||||
private float prevToHideProgress;
|
||||
private long videoDuration;
|
||||
private boolean allowShare;
|
||||
public boolean allowScreenshots;
|
||||
private boolean allowShare, allowShareLink;
|
||||
public boolean forceUpdateOffsets;
|
||||
private HintView mediaBanTooltip;
|
||||
|
||||
|
@ -588,15 +586,11 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
});
|
||||
}
|
||||
if (storyViewer.storiesList != null && storyViewer.storiesList.getCount() != linesCount) {
|
||||
if (storyViewer.storiesList != null) {
|
||||
if (storyPositionView == null) {
|
||||
storyPositionView = new StoryPositionView();
|
||||
}
|
||||
int position = selectedPosition;
|
||||
if (storyViewer.reversed) {
|
||||
position = storyViewer.storiesList.getCount() - 1 - position;
|
||||
}
|
||||
storyPositionView.draw(canvas, hideInterfaceAlpha * alpha * (1f - outT), position, storyViewer.storiesList.getCount(), this, headerView);
|
||||
storyPositionView.draw(canvas, hideInterfaceAlpha * alpha * (1f - outT), listPosition, storyViewer.storiesList.getCount(), this, headerView);
|
||||
}
|
||||
canvas.save();
|
||||
canvas.translate(0, dp(8) - dp(8) * outT);
|
||||
|
@ -615,7 +609,21 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
|
||||
public boolean clipWithGradient(int tag) {
|
||||
return tag == 1;
|
||||
return tag == 1 || tag == 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow(Bulletin bulletin) {
|
||||
if (bulletin != null && bulletin.tag == 2 && delegate != null) {
|
||||
delegate.setBulletinIsVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide(Bulletin bulletin) {
|
||||
if (bulletin != null && bulletin.tag == 2 && delegate != null) {
|
||||
delegate.setBulletinIsVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -629,6 +637,9 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
Bulletin.removeDelegate(this);
|
||||
if (delegate != null) {
|
||||
delegate.setBulletinIsVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -769,8 +780,12 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
storyCaptionView.captionTextview.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
checkBlackoutMode = true;
|
||||
storyCaptionView.expand();
|
||||
if (storyCaptionView.expanded) {
|
||||
storyCaptionView.collapse();
|
||||
} else {
|
||||
checkBlackoutMode = true;
|
||||
storyCaptionView.expand();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -958,7 +973,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
});
|
||||
}
|
||||
|
||||
if (allowShare || MessagesController.getInstance(currentAccount).storiesExportNopublicLink) {
|
||||
if (allowShare) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_shareout, LocaleController.getString("BotShare", R.string.BotShare), false, resourcesProvider).setOnClickListener(v -> {
|
||||
shareStory(false);
|
||||
if (popupMenu != null) {
|
||||
|
@ -985,7 +1000,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
|
||||
|
||||
final String key = NotificationsController.getSharedPrefKey(dialogId, 0);
|
||||
boolean muted = !NotificationsCustomSettingsActivity.isStoriesNotMuted(currentAccount, dialogId);
|
||||
boolean muted = !NotificationsCustomSettingsActivity.areStoriesNotMuted(currentAccount, dialogId);
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
if (!UserObject.isService(dialogId)) {
|
||||
if (!muted) {
|
||||
|
@ -998,7 +1013,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
if (index > 0) {
|
||||
name = name.substring(0, index);
|
||||
}
|
||||
BulletinFactory.global().createUsersBulletin(Arrays.asList(user), AndroidUtilities.replaceTags(LocaleController.formatString("NotificationsStoryMutedHint", R.string.NotificationsStoryMutedHint, name))).show();
|
||||
BulletinFactory.of(storyContainer, resourcesProvider).createUsersBulletin(Arrays.asList(user), AndroidUtilities.replaceTags(LocaleController.formatString("NotificationsStoryMutedHint", R.string.NotificationsStoryMutedHint, name))).setTag(2).show();
|
||||
if (popupMenu != null) {
|
||||
popupMenu.dismiss();
|
||||
}
|
||||
|
@ -1014,7 +1029,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
if (index > 0) {
|
||||
name = name.substring(0, index);
|
||||
}
|
||||
BulletinFactory.global().createUsersBulletin(Arrays.asList(user), AndroidUtilities.replaceTags(LocaleController.formatString("NotificationsStoryUnmutedHint", R.string.NotificationsStoryUnmutedHint, name))).show();
|
||||
BulletinFactory.of(storyContainer, resourcesProvider).createUsersBulletin(Arrays.asList(user), AndroidUtilities.replaceTags(LocaleController.formatString("NotificationsStoryUnmutedHint", R.string.NotificationsStoryUnmutedHint, name))).setTag(2).show();
|
||||
if (popupMenu != null) {
|
||||
popupMenu.dismiss();
|
||||
}
|
||||
|
@ -1024,14 +1039,14 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
if (user.contact) {
|
||||
if (!user.stories_hidden) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_archive, LocaleController.getString("ArchivePeerStories", R.string.ArchivePeerStories), false, resourcesProvider).setOnClickListener(v -> {
|
||||
toggleArciveForStory(dialogId);
|
||||
toggleArchiveForStory(dialogId);
|
||||
if (popupMenu != null) {
|
||||
popupMenu.dismiss();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_unarchive, LocaleController.getString("UnarchiveStories", R.string.UnarchiveStories), false, resourcesProvider).setOnClickListener(v -> {
|
||||
toggleArciveForStory(dialogId);
|
||||
toggleArchiveForStory(dialogId);
|
||||
if (popupMenu != null) {
|
||||
popupMenu.dismiss();
|
||||
}
|
||||
|
@ -1050,7 +1065,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
});
|
||||
}
|
||||
}
|
||||
if (allowShare || MessagesController.getInstance(currentAccount).storiesExportNopublicLink) {
|
||||
if (allowShareLink) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_link, LocaleController.getString("CopyLink", R.string.CopyLink), false, resourcesProvider).setOnClickListener(v -> {
|
||||
AndroidUtilities.addToClipboard(currentStory.createLink());
|
||||
onLickCopied();
|
||||
|
@ -1058,7 +1073,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
popupMenu.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
if (allowShare) {
|
||||
ActionBarMenuItem.addItem(popupLayout, R.drawable.msg_shareout, LocaleController.getString("BotShare", R.string.BotShare), false, resourcesProvider).setOnClickListener(v -> {
|
||||
shareStory(false);
|
||||
if (popupMenu != null) {
|
||||
|
@ -1164,15 +1180,19 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
CharSequence text;
|
||||
boolean twoLines = true;
|
||||
if (storyItem.close_friends) {
|
||||
privacyHint.setInnerPadding(15, 8, 15, 8);
|
||||
text = AndroidUtilities.replaceTags(LocaleController.formatString("StoryCloseFriendsHint", R.string.StoryCloseFriendsHint, firstName));
|
||||
} else if (storyItem.contacts) {
|
||||
privacyHint.setInnerPadding(11, 6, 11, 7);
|
||||
text = AndroidUtilities.replaceTags(LocaleController.formatString("StoryContactsHint", R.string.StoryContactsHint, firstName));
|
||||
twoLines = false;
|
||||
} else if (storyItem.selected_contacts) {
|
||||
privacyHint.setInnerPadding(15, 8, 15, 8);
|
||||
text = AndroidUtilities.replaceTags(LocaleController.formatString("StorySelectedContactsHint", R.string.StorySelectedContactsHint, firstName));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
text = Emoji.replaceEmoji(text, privacyHint.getTextPaint().getFontMetricsInt(), false);
|
||||
privacyHint.setMaxWidthPx(twoLines ? HintView2.cutInFancyHalf(text, privacyHint.getTextPaint()) : storyContainer.getMeasuredWidth());
|
||||
privacyHint.setText(text);
|
||||
privacyHint.setJoint(1, -(storyContainer.getWidth() - privacyButton.getCenterX()) / AndroidUtilities.density);
|
||||
|
@ -1265,7 +1285,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
return null;
|
||||
}
|
||||
|
||||
private void toggleArciveForStory(long dialogId) {
|
||||
private void toggleArchiveForStory(long dialogId) {
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
boolean hide = !user.stories_hidden;
|
||||
MessagesController messagesController = MessagesController.getInstance(currentAccount);
|
||||
|
@ -1285,11 +1305,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
} else {
|
||||
str = AndroidUtilities.replaceTags(LocaleController.formatString("StoriesMovedToContacts", R.string.StoriesMovedToContacts, ContactsController.formatName(user.first_name, null, 10)));
|
||||
}
|
||||
BulletinFactory.global().createUsersBulletin(
|
||||
Arrays.asList(user),
|
||||
str,
|
||||
null,
|
||||
undoObject).show();
|
||||
BulletinFactory.of(storyContainer, resourcesProvider).createUsersBulletin(Arrays.asList(user), str, null, undoObject).setTag(2).show();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
|
@ -1860,6 +1876,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
} else {
|
||||
bulletinFactory.createSimpleBulletin(R.raw.forward, AndroidUtilities.replaceTags(LocaleController.formatPluralString("StorySharedToManyChats", dids.size(), dids.size()))).hideAfterBottomSheet(false).show();
|
||||
}
|
||||
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1898,14 +1915,29 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
});
|
||||
}
|
||||
|
||||
public void setDialogId(long dialogId) {
|
||||
boolean peerIdChanged = this.dialogId != dialogId;
|
||||
public void setDay(long dialogId, ArrayList<Integer> day) {
|
||||
this.dialogId = dialogId;
|
||||
deletedPeer = false;
|
||||
forceUpdateOffsets = true;
|
||||
if (peerIdChanged) {
|
||||
this.day = day;
|
||||
bindInternal();
|
||||
}
|
||||
|
||||
public void setDialogId(long dialogId) {
|
||||
if (this.dialogId != dialogId) {
|
||||
currentStory.clear();
|
||||
}
|
||||
this.dialogId = dialogId;
|
||||
this.day = null;
|
||||
bindInternal();
|
||||
if (storyViewer.overrideUserStories != null) {
|
||||
storiesController.loadSkippedStories(storyViewer.overrideUserStories, true);
|
||||
} else {
|
||||
storiesController.loadSkippedStories(dialogId);
|
||||
}
|
||||
}
|
||||
|
||||
private void bindInternal() {
|
||||
deletedPeer = false;
|
||||
forceUpdateOffsets = true;
|
||||
if (dialogId >= 0) {
|
||||
isSelf = dialogId == UserConfig.getInstance(currentAccount).getClientUserId();
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
|
@ -1953,8 +1985,18 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
if (chatActivityEnterView != null) {
|
||||
chatActivityEnterView.setVisibility(View.GONE);
|
||||
}
|
||||
if (storyViewer.storiesList != null) {
|
||||
selectedPosition = storyViewer.storiesListStartPosition;
|
||||
if (day != null) {
|
||||
int index = day.indexOf(storyViewer.dayStoryId);
|
||||
if (index < 0) {
|
||||
if (!day.isEmpty()) {
|
||||
if (storyViewer.dayStoryId > day.get(0)) {
|
||||
index = 0;
|
||||
} else if (storyViewer.dayStoryId < day.get(day.size() - 1)) {
|
||||
index = day.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedPosition = Math.max(0, index);
|
||||
} else if (!uploadingStories.isEmpty()) {
|
||||
selectedPosition = storyItems.size();
|
||||
} else {
|
||||
|
@ -1995,11 +2037,6 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
storyContainer.invalidate();
|
||||
invalidate();
|
||||
}
|
||||
if (storyViewer.overrideUserStories != null) {
|
||||
storiesController.loadSkippedStories(storyViewer.overrideUserStories, true);
|
||||
} else {
|
||||
storiesController.loadSkippedStories(dialogId);
|
||||
}
|
||||
}
|
||||
|
||||
private void createUnsupportedContainer() {
|
||||
|
@ -2046,13 +2083,13 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
|
||||
|
||||
public void preloadMainImage(long dialogId) {
|
||||
if (this.dialogId == dialogId) {
|
||||
if (this.dialogId == dialogId && day == null) {
|
||||
return;
|
||||
}
|
||||
this.dialogId = dialogId;
|
||||
updateStoryItems();
|
||||
updateSelectedPosition();
|
||||
updatePosition();
|
||||
updatePosition(true);
|
||||
if (storyViewer.overrideUserStories != null) {
|
||||
storiesController.loadSkippedStories(storyViewer.overrideUserStories, true);
|
||||
} else {
|
||||
|
@ -2061,15 +2098,27 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
|
||||
private void updateSelectedPosition() {
|
||||
selectedPosition = storyViewer.savedPositions.get(dialogId, -1);
|
||||
if (selectedPosition == -1) {
|
||||
if (storyViewer.storiesList != null) {
|
||||
selectedPosition = storyViewer.storiesListStartPosition;
|
||||
} else if (!storyViewer.isSingleStory && userStories != null && userStories.max_read_id > 0) {
|
||||
for (int i = 0; i < storyItems.size(); i++) {
|
||||
if (storyItems.get(i).id > userStories.max_read_id) {
|
||||
selectedPosition = i;
|
||||
break;
|
||||
if (day != null) {
|
||||
int index = day.indexOf(storyViewer.dayStoryId);
|
||||
if (index < 0) {
|
||||
if (!day.isEmpty()) {
|
||||
if (storyViewer.dayStoryId > day.get(0)) {
|
||||
index = 0;
|
||||
} else if (storyViewer.dayStoryId < day.get(day.size() - 1)) {
|
||||
index = day.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedPosition = index;
|
||||
} else {
|
||||
selectedPosition = storyViewer.savedPositions.get(dialogId, -1);
|
||||
if (selectedPosition == -1) {
|
||||
if (!storyViewer.isSingleStory && userStories != null && userStories.max_read_id > 0) {
|
||||
for (int i = 0; i < storyItems.size(); i++) {
|
||||
if (storyItems.get(i).id > userStories.max_read_id) {
|
||||
selectedPosition = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2083,6 +2132,13 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
storyItems.clear();
|
||||
if (storyViewer.isSingleStory) {
|
||||
storyItems.add(storyViewer.singleStory);
|
||||
} else if (day != null && storyViewer.storiesList != null) {
|
||||
for (int id : day) {
|
||||
MessageObject messageObject = storyViewer.storiesList.findMessageObject(id);
|
||||
if (messageObject != null && messageObject.storyItem != null) {
|
||||
storyItems.add(messageObject.storyItem);
|
||||
}
|
||||
}
|
||||
} else if (storyViewer.storiesList != null) {
|
||||
// TODO: actually load more stories
|
||||
for (int i = 0; i < storyViewer.storiesList.messageObjects.size(); ++i) {
|
||||
|
@ -2308,7 +2364,11 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
}
|
||||
|
||||
private void updatePosition() {
|
||||
public void updatePosition() {
|
||||
updatePosition(false);
|
||||
}
|
||||
|
||||
private void updatePosition(boolean preload) {
|
||||
if (storyItems.isEmpty() && uploadingStories.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -2320,8 +2380,6 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
|
||||
lastNoThumb = false;
|
||||
unsupported = false;
|
||||
boolean oldAllowScreenshots = allowScreenshots;
|
||||
allowScreenshots = true;
|
||||
int position = selectedPosition;
|
||||
|
||||
final boolean wasUploading = isUploading;
|
||||
|
@ -2350,12 +2408,13 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
imageReceiver.setImage(null, null, ImageLocation.getForPath(uploadingStory.path), filter, null, null, thumbDrawable, 0, null, null, 0);
|
||||
}
|
||||
currentStory.set(uploadingStory);
|
||||
allowShare = false;
|
||||
allowShare = allowShareLink = false;
|
||||
} else {
|
||||
isUploading = false;
|
||||
isEditing = false;
|
||||
if (position < 0 || position > storyItems.size() - 1) {
|
||||
storyViewer.close(true);
|
||||
return;
|
||||
}
|
||||
TLRPC.StoryItem storyItem = storyItems.get(position);
|
||||
StoriesController.UploadingStory editingStory = storiesController.findEditingStory(storyItem);
|
||||
|
@ -2370,7 +2429,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
currentStory.set(editingStory);
|
||||
currentStory.editingSourceItem = storyItem;
|
||||
allowShare = false;
|
||||
allowShare = allowShareLink = false;
|
||||
} else {
|
||||
boolean isVideo = storyItem.media != null && MessageObject.isVideoDocument(storyItem.media.document);
|
||||
Drawable thumbDrawable = null;
|
||||
|
@ -2404,7 +2463,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if ((storyViewer.isSingleStory || storyViewer.storiesList != null) && storyViewer.transitionViewHolder.storyImage != null && !storyViewer.reversed) {
|
||||
if (storyViewer.isSingleStory && storyViewer.transitionViewHolder.storyImage != null) {
|
||||
thumbDrawable = storyViewer.transitionViewHolder.storyImage.getDrawable();
|
||||
}
|
||||
storyItem.dialogId = dialogId;
|
||||
|
@ -2435,19 +2494,23 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
}
|
||||
storyItem.dialogId = dialogId;
|
||||
currentStory.set(storyItem);
|
||||
allowShare = !unsupported && currentStory.storyItem != null && !(currentStory.storyItem instanceof TLRPC.TL_storyItemDeleted) && !(currentStory.storyItem instanceof TLRPC.TL_storyItemSkipped);
|
||||
allowShare = allowShareLink = !unsupported && currentStory.storyItem != null && !(currentStory.storyItem instanceof TLRPC.TL_storyItemDeleted) && !(currentStory.storyItem instanceof TLRPC.TL_storyItemSkipped);
|
||||
if (allowShare) {
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
allowShare = !currentStory.storyItem.noforwards && currentStory.storyItem.isPublic && user != null && UserObject.getPublicUsername(user) != null;
|
||||
allowShare = currentStory.allowScreenshots() && currentStory.storyItem.isPublic;
|
||||
}
|
||||
if (allowShareLink) {
|
||||
final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
|
||||
allowShareLink = user != null && UserObject.getPublicUsername(user) != null && currentStory.storyItem.isPublic;
|
||||
}
|
||||
NotificationsController.getInstance(currentAccount).processReadStories(dialogId, storyItem.id);
|
||||
}
|
||||
}
|
||||
|
||||
allowScreenshots = currentStory.allowScreenshots();
|
||||
if (oldAllowScreenshots != allowScreenshots) {
|
||||
storyViewer.storiesViewPager.checkAllowScreenshots();
|
||||
if (currentStory.storyItem != null && !preload) {
|
||||
storyViewer.dayStoryId = currentStory.storyItem.id;
|
||||
}
|
||||
|
||||
storyViewer.storiesViewPager.checkAllowScreenshots();
|
||||
imageChanged = true;
|
||||
if (isSelf) {
|
||||
updateUserViews();
|
||||
|
@ -2534,7 +2597,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
createReplyDisabledView();
|
||||
unsupportedContainer.setVisibility(View.VISIBLE);
|
||||
replyDisabledTextView.setVisibility(View.VISIBLE);
|
||||
allowShare = false;
|
||||
allowShare = allowShareLink = false;
|
||||
if (chatActivityEnterView != null) {
|
||||
chatActivityEnterView.setVisibility(View.GONE);
|
||||
}
|
||||
|
@ -2586,28 +2649,19 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
imageReceiver.bumpPriority();
|
||||
}
|
||||
|
||||
if (storyViewer.storiesList != null && selectedPosition >= 0 && selectedPosition < storyViewer.storiesList.messageObjects.size()) {
|
||||
MessageObject messageObject = storyViewer.storiesList.messageObjects.get(selectedPosition);
|
||||
SortedSet<Integer> dayGroup = storyViewer.storiesList.getStoryDayGroup(messageObject);
|
||||
if (dayGroup == null) {
|
||||
linesPosition = selectedPosition;
|
||||
linesCount = count;
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
Iterator<Integer> it = dayGroup.iterator();
|
||||
while (it.hasNext()) {
|
||||
if (it.next() == messageObject.getId()) {
|
||||
listPosition = 0;
|
||||
if (storyViewer.storiesList != null && currentStory.storyItem != null) {
|
||||
int id = currentStory.storyItem.id;
|
||||
for (int i = 0; i < storyViewer.storiesList.messageObjects.size(); ++i) {
|
||||
MessageObject obj = storyViewer.storiesList.messageObjects.get(i);
|
||||
if (obj != null && obj.getId() == id) {
|
||||
listPosition = i;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
linesPosition = i;
|
||||
linesCount = dayGroup.size();
|
||||
} else {
|
||||
linesPosition = selectedPosition;
|
||||
linesCount = count;
|
||||
}
|
||||
linesPosition = selectedPosition;
|
||||
linesCount = count;
|
||||
if (storyViewer.reversed) {
|
||||
linesPosition = linesCount - 1 - linesPosition;
|
||||
}
|
||||
|
@ -2972,6 +3026,10 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
return dialogId;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getCurrentDay() {
|
||||
return day;
|
||||
}
|
||||
|
||||
public void setPaused(boolean paused) {
|
||||
if (this.paused != paused) {
|
||||
this.paused = paused;
|
||||
|
@ -3345,7 +3403,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
super.onDraw(canvas);
|
||||
}
|
||||
};
|
||||
backupImageView.setRoundRadius(AndroidUtilities.dp(16));
|
||||
backupImageView.setRoundRadius(dp(16));
|
||||
addView(backupImageView, LayoutHelper.createFrame(32, 32, 0, 12, 2, 0, 0));
|
||||
setClipChildren(false);
|
||||
|
||||
|
@ -3353,6 +3411,7 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
titleView.setTextSize(14);
|
||||
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
|
||||
titleView.setMaxLines(1);
|
||||
titleView.setEllipsizeByGradient(dp(4));
|
||||
// titleView.setSingleLine(true);
|
||||
// titleView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
NotificationCenter.listenEmojiLoading(titleView);
|
||||
|
@ -3533,6 +3592,8 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
|
|||
|
||||
void setPopupIsVisible(boolean b);
|
||||
|
||||
void setBulletinIsVisible(boolean b);
|
||||
|
||||
void setIsInPinchToZoom(boolean b);
|
||||
|
||||
void preparePlayer(ArrayList<TLRPC.Document> documents, ArrayList<Uri> uries);
|
||||
|
|
|
@ -1164,6 +1164,7 @@ public class StoriesController {
|
|||
}
|
||||
storiesStorage.deleteAllUserStories(dialogId);
|
||||
MessagesController.getInstance(currentAccount).checkArchiveFolder();
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated);
|
||||
}
|
||||
|
||||
public StoriesStorage getStoriesStorage() {
|
||||
|
@ -1180,6 +1181,7 @@ public class StoriesController {
|
|||
}
|
||||
|
||||
private void checkExpireStories(ArrayList<TLRPC.TL_userStories> dialogListStories) {
|
||||
boolean notify = false;
|
||||
for (int k = 0; k < dialogListStories.size(); k++) {
|
||||
TLRPC.TL_userStories stories = dialogListStories.get(k);
|
||||
for (int i = 0; i < stories.stories.size(); i++) {
|
||||
|
@ -1191,8 +1193,12 @@ public class StoriesController {
|
|||
if (stories.stories.isEmpty()) {
|
||||
allStoriesMap.remove(stories.user_id);
|
||||
dialogListStories.remove(stories);
|
||||
notify = true;
|
||||
}
|
||||
}
|
||||
if (notify) {
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkExpiredStories(long dialogId) {
|
||||
|
@ -1206,6 +1212,7 @@ public class StoriesController {
|
|||
if (userStories.stories.isEmpty()) {
|
||||
dialogListStories.remove(userStories);
|
||||
hiddenListStories.remove(userStories);
|
||||
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.storiesUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1588,7 +1595,7 @@ public class StoriesController {
|
|||
}
|
||||
}
|
||||
|
||||
private HashMap<Integer, StoriesList> storiesLists;
|
||||
private final HashMap<Long, StoriesList>[] storiesLists = new HashMap[2];
|
||||
|
||||
@NonNull
|
||||
public StoriesList getStoriesList(long userId, int type) {
|
||||
|
@ -1596,13 +1603,12 @@ public class StoriesController {
|
|||
}
|
||||
|
||||
private StoriesList getStoriesList(long userId, int type, boolean createIfNotExist) {
|
||||
int key = Objects.hash(userId, type);
|
||||
if (storiesLists == null) {
|
||||
storiesLists = new HashMap<>();
|
||||
if (storiesLists[type] == null) {
|
||||
storiesLists[type] = new HashMap<>();
|
||||
}
|
||||
StoriesList list = storiesLists.get(key);
|
||||
StoriesList list = storiesLists[type].get(userId);
|
||||
if (list == null && createIfNotExist) {
|
||||
storiesLists.put(key, list = new StoriesList(currentAccount, userId, type, this::destroyStoryList));
|
||||
storiesLists[type].put(userId, list = new StoriesList(currentAccount, userId, type, this::destroyStoryList));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
@ -1630,9 +1636,8 @@ public class StoriesController {
|
|||
}
|
||||
|
||||
public void destroyStoryList(StoriesList list) {
|
||||
int key = Objects.hash(list.userId, list.type);
|
||||
if (storiesLists != null) {
|
||||
storiesLists.remove(key);
|
||||
if (storiesLists[list.type] != null) {
|
||||
storiesLists[list.type].remove(list.userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1861,7 +1866,7 @@ public class StoriesController {
|
|||
return false;
|
||||
}
|
||||
|
||||
private long day(MessageObject messageObject) {
|
||||
public static long day(MessageObject messageObject) {
|
||||
if (messageObject == null) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1878,6 +1883,19 @@ public class StoriesController {
|
|||
return groupedByDay.get(day(messageObject));
|
||||
}
|
||||
|
||||
public ArrayList<ArrayList<Integer>> getDays() {
|
||||
final ArrayList<Long> keys = new ArrayList<>(groupedByDay.keySet());
|
||||
Collections.sort(keys, (a, b) -> (int) (b - a));
|
||||
final ArrayList<ArrayList<Integer>> days = new ArrayList<>();
|
||||
for (Long key : keys) {
|
||||
TreeSet<Integer> storyIds = groupedByDay.get(key);
|
||||
if (storyIds != null) {
|
||||
days.add(new ArrayList<>(storyIds));
|
||||
}
|
||||
}
|
||||
return days;
|
||||
}
|
||||
|
||||
public void invalidateCache() {
|
||||
if (preloading) {
|
||||
invalidateAfterPreload = true;
|
||||
|
@ -2159,6 +2177,10 @@ public class StoriesController {
|
|||
}
|
||||
}
|
||||
|
||||
public MessageObject findMessageObject(int storyId) {
|
||||
return messageObjectsMap.get(storyId);
|
||||
}
|
||||
|
||||
public boolean equal(TLRPC.StoryItem a, TLRPC.StoryItem b) {
|
||||
if (a == null && b == null) {
|
||||
return true;
|
||||
|
|
|
@ -3,11 +3,13 @@ package org.telegram.ui.Stories;
|
|||
import android.graphics.Canvas;
|
||||
import android.view.View;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.MessageObject;
|
||||
import org.telegram.messenger.MessagesController;
|
||||
import org.telegram.messenger.SharedConfig;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.tgnet.TLRPC;
|
||||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Cells.ChatActionCell;
|
||||
import org.telegram.ui.Cells.ChatMessageCell;
|
||||
import org.telegram.ui.Cells.DialogCell;
|
||||
|
@ -16,6 +18,7 @@ import org.telegram.ui.Cells.SharedPhotoVideoCell2;
|
|||
import org.telegram.ui.Cells.UserCell;
|
||||
import org.telegram.ui.Components.BlurredRecyclerView;
|
||||
import org.telegram.ui.Components.RecyclerListView;
|
||||
import org.telegram.ui.Components.SharedMediaLayout;
|
||||
|
||||
public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
|
||||
|
||||
|
@ -30,6 +33,7 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
|
|||
public static StoriesListPlaceProvider of(RecyclerListView recyclerListView, boolean hiddenArchive) {
|
||||
return new StoriesListPlaceProvider(recyclerListView, hiddenArchive);
|
||||
}
|
||||
|
||||
public StoriesListPlaceProvider(RecyclerListView recyclerListView, boolean hiddenArchive) {
|
||||
this.recyclerListView = recyclerListView;
|
||||
this.isHiddenArchive = hiddenArchive;
|
||||
|
@ -127,27 +131,32 @@ public class StoriesListPlaceProvider implements StoryViewer.PlaceProvider {
|
|||
updateClip(holder);
|
||||
return true;
|
||||
}
|
||||
}else if (child instanceof SharedPhotoVideoCell2) {
|
||||
} else if (child instanceof SharedPhotoVideoCell2) {
|
||||
SharedPhotoVideoCell2 cell = (SharedPhotoVideoCell2) child;
|
||||
if (cell.getStyle() == SharedPhotoVideoCell2.STYLE_CACHE) {
|
||||
if (cell.storyId == storyId) {
|
||||
holder.view = child;
|
||||
holder.storyImage = cell.imageReceiver;
|
||||
holder.clipParent = (View) cell.getParent();
|
||||
holder.drawAbove = cell::drawDuration;
|
||||
updateClip(holder);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
MessageObject msg = cell.getMessageObject();
|
||||
if (msg != null && msg.isStory() && msg.getId() == messageId && msg.storyItem.dialogId == dialogId) {
|
||||
holder.view = child;
|
||||
holder.storyImage = cell.imageReceiver;
|
||||
holder.clipParent = (View) cell.getParent();
|
||||
holder.drawAbove = cell::drawDuration;
|
||||
updateClip(holder);
|
||||
return true;
|
||||
MessageObject msg = cell.getMessageObject();
|
||||
if (
|
||||
cell.getStyle() == SharedPhotoVideoCell2.STYLE_CACHE && cell.storyId == storyId ||
|
||||
msg != null && msg.isStory() && msg.getId() == storyId && msg.storyItem.dialogId == dialogId
|
||||
) {
|
||||
final RecyclerListView.FastScroll fastScroll = listView.getFastScroll();
|
||||
final int[] loc = new int[2];
|
||||
if (fastScroll != null) {
|
||||
fastScroll.getLocationInWindow(loc);
|
||||
}
|
||||
holder.view = child;
|
||||
holder.storyImage = cell.imageReceiver;
|
||||
holder.drawAbove = (canvas, bounds, alpha) -> {
|
||||
cell.drawDuration(canvas, bounds, alpha);
|
||||
if (fastScroll != null && fastScroll.isVisible && fastScroll.getVisibility() == View.VISIBLE) {
|
||||
canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), (int) (0xFF * alpha), Canvas.ALL_SAVE_FLAG);
|
||||
canvas.translate(loc[0], loc[1]);
|
||||
fastScroll.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
};
|
||||
holder.clipParent = (View) cell.getParent();
|
||||
updateClip(holder);
|
||||
return true;
|
||||
}
|
||||
} else if (child instanceof UserCell) {
|
||||
UserCell cell = (UserCell) child;
|
||||
|
|
|
@ -46,7 +46,7 @@ import java.util.Collections;
|
|||
|
||||
public class StoriesUtilities {
|
||||
|
||||
private final static int ANIMATION_SEGMENT_COUNT = 20;
|
||||
private final static int ANIMATION_SEGMENT_COUNT = 16;
|
||||
public static final int STATE_EMPTY = 0;
|
||||
public static final int STATE_HAS_UNREAD = 1;
|
||||
public static final int STATE_READ = 2;
|
||||
|
@ -155,11 +155,8 @@ public class StoriesUtilities {
|
|||
|
||||
float scale = params.buttonBounce != null ? params.buttonBounce.getScale(0.08f) : 1f;
|
||||
if (params.showProgress != showProgress && showProgress) {
|
||||
params.alphas = new float[ANIMATION_SEGMENT_COUNT];
|
||||
for (int i = 0; i < ANIMATION_SEGMENT_COUNT; i++) {
|
||||
params.alphas[i] = 1f;
|
||||
}
|
||||
params.sweepAngle = 180;
|
||||
params.sweepAngle = 1f;
|
||||
params.inc = false;
|
||||
}
|
||||
params.showProgress = showProgress;
|
||||
if (params.currentState == STATE_EMPTY && params.progressToSate == 1f) {
|
||||
|
@ -387,36 +384,19 @@ public class StoriesUtilities {
|
|||
float len = 360 / (float) ANIMATION_SEGMENT_COUNT;
|
||||
params.updateProgressParams();
|
||||
view.invalidate();
|
||||
float originalStrokeWidth = paint.getStrokeWidth();
|
||||
for (int i = 0; i < ANIMATION_SEGMENT_COUNT; i++) {
|
||||
float startAngle = i * len;
|
||||
float endAngle = startAngle + len;
|
||||
float segmentLen = endAngle - startAngle;
|
||||
float centerA = (startAngle + segmentLen / 2f);
|
||||
if (params.alphas == null) {
|
||||
params.alphas = new float[ANIMATION_SEGMENT_COUNT];
|
||||
}
|
||||
if ((centerA > params.globalAngle && centerA < params.globalAngle + params.sweepAngle) || (centerA + 360 > params.globalAngle) && (centerA + 360 < params.globalAngle + params.sweepAngle)) {
|
||||
params.alphas[i] += AndroidUtilities.screenRefreshTime / 150f;
|
||||
if (params.alphas[i] > 1) {
|
||||
params.alphas[i] = 1f;
|
||||
}
|
||||
} else {
|
||||
params.alphas[i] -= AndroidUtilities.screenRefreshTime / 500f;
|
||||
if (params.alphas[i] < 0) {
|
||||
params.alphas[i] = 0;
|
||||
}
|
||||
}
|
||||
if (params.alphas[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
startAngle += segmentLen / 2f * (1f - params.alphas[i]);
|
||||
endAngle -= segmentLen / 2f * (1f - params.alphas[i]);
|
||||
paint.setStrokeWidth(originalStrokeWidth * params.alphas[i]);
|
||||
|
||||
canvas.drawArc(rectTmp, startAngle, endAngle - startAngle, false, paint);
|
||||
if (params.inc) {
|
||||
canvas.drawArc(rectTmp, params.globalAngle, 360 * params.sweepAngle, false, paint);
|
||||
} else {
|
||||
canvas.drawArc(rectTmp, params.globalAngle + 360, -360 * (params.sweepAngle), false, paint);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ANIMATION_SEGMENT_COUNT; i++) {
|
||||
float startAngle = i * len + 10;
|
||||
float endAngle = startAngle + len - 10;
|
||||
float segmentLen = endAngle - startAngle;
|
||||
canvas.drawArc(rectTmp, params.globalAngle + startAngle, segmentLen, false, paint);
|
||||
}
|
||||
paint.setStrokeWidth(originalStrokeWidth);
|
||||
}
|
||||
|
||||
private static void checkStoryCellGrayPaint(boolean isArchive) {
|
||||
|
@ -787,8 +767,6 @@ public class StoriesUtilities {
|
|||
public AvatarStoryParams(boolean isStoryCell) {
|
||||
this.isStoryCell = isStoryCell;
|
||||
}
|
||||
|
||||
public float[] alphas;
|
||||
float sweepAngle;
|
||||
boolean inc;
|
||||
float globalAngle;
|
||||
|
@ -796,27 +774,20 @@ public class StoriesUtilities {
|
|||
UserStoriesLoadOperation operation;
|
||||
|
||||
private void updateProgressParams() {
|
||||
float sweepStep = 360 * AndroidUtilities.screenRefreshTime / 1500f;
|
||||
int len = 360 / ANIMATION_SEGMENT_COUNT;
|
||||
if (inc) {
|
||||
sweepAngle += sweepStep;
|
||||
if (sweepAngle >= 300) {
|
||||
sweepAngle += 16 / 1000f;
|
||||
if (sweepAngle >= 1f) {
|
||||
sweepAngle = 1f;
|
||||
inc = false;
|
||||
}
|
||||
} else {
|
||||
sweepAngle -= sweepStep;
|
||||
if (sweepAngle < 10) {
|
||||
sweepAngle -= 16 / 1000f;
|
||||
if (sweepAngle < 0) {
|
||||
sweepAngle = 0;
|
||||
inc = true;
|
||||
}
|
||||
}
|
||||
float angleStep = 360 * AndroidUtilities.screenRefreshTime / 900.0f;
|
||||
globalAngle += angleStep;
|
||||
if (!inc) {
|
||||
globalAngle += sweepStep;
|
||||
}
|
||||
if (globalAngle > 360) {
|
||||
globalAngle %= 360;
|
||||
}
|
||||
globalAngle += 16 / 5000f * 360;
|
||||
}
|
||||
|
||||
float startX, startY;
|
||||
|
|
|
@ -18,9 +18,13 @@ import org.telegram.messenger.UserConfig;
|
|||
import org.telegram.ui.ActionBar.Theme;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class StoriesViewPager extends ViewPager {
|
||||
|
||||
long daysDialogId;
|
||||
ArrayList<ArrayList<Integer>> days;
|
||||
|
||||
int currentAccount = UserConfig.selectedAccount;
|
||||
PagerAdapter pagerAdapter;
|
||||
ArrayList<Long> dialogs = new ArrayList<>();
|
||||
|
@ -55,10 +59,13 @@ public class StoriesViewPager extends ViewPager {
|
|||
setAdapter(pagerAdapter = new PagerAdapter() {
|
||||
@Override
|
||||
public int getCount() {
|
||||
if (days != null) {
|
||||
return days.size();
|
||||
}
|
||||
return dialogs.size();
|
||||
}
|
||||
|
||||
ArrayList<PeerStoriesView> cachedViews = new ArrayList<>();
|
||||
private final ArrayList<PeerStoriesView> cachedViews = new ArrayList<>();
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
|
@ -84,7 +91,13 @@ public class StoriesViewPager extends ViewPager {
|
|||
view.setDelegate(delegate);
|
||||
view.setLongpressed(storyViewer.isLongpressed);
|
||||
pageLayout.setTag(position);
|
||||
pageLayout.dialogId = dialogs.get(position);
|
||||
if (days != null) {
|
||||
pageLayout.day = days.get(storyViewer.reversed ? days.size() - 1 - position : position);
|
||||
pageLayout.dialogId = daysDialogId;
|
||||
} else {
|
||||
pageLayout.day = null;
|
||||
pageLayout.dialogId = dialogs.get(position);
|
||||
}
|
||||
pageLayout.addView(view);
|
||||
view.requestLayout();
|
||||
container.addView(pageLayout);
|
||||
|
@ -110,13 +123,20 @@ public class StoriesViewPager extends ViewPager {
|
|||
if (Math.abs(position) >= 1f) {
|
||||
pageLayout.setVisible(false);
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (pageLayout.day != null) {
|
||||
pageLayout.peerStoryView.day = pageLayout.day;
|
||||
}
|
||||
pageLayout.peerStoryView.preloadMainImage(pageLayout.dialogId);
|
||||
}, 16);
|
||||
return;
|
||||
}
|
||||
if (!pageLayout.isVisible) {
|
||||
pageLayout.setVisible(true);
|
||||
pageLayout.peerStoryView.setDialogId(pageLayout.dialogId);
|
||||
if (days != null) {
|
||||
pageLayout.peerStoryView.setDay(pageLayout.dialogId, pageLayout.day);
|
||||
} else {
|
||||
pageLayout.peerStoryView.setDialogId(pageLayout.dialogId);
|
||||
}
|
||||
}
|
||||
pageLayout.peerStoryView.setOffset(position);
|
||||
page.setCameraDistance(page.getWidth() * 15);
|
||||
|
@ -135,9 +155,11 @@ public class StoriesViewPager extends ViewPager {
|
|||
toPosition = positionOffsetPixels > 0 ? selectedPosition + 1 : selectedPosition - 1;
|
||||
progress = positionOffset;
|
||||
|
||||
if (selectedPosition >= 0 && selectedPosition < dialogs.size() && dialogs.get(selectedPosition) == UserConfig.getInstance(currentAccount).clientUserId) {
|
||||
final long me = UserConfig.getInstance(currentAccount).clientUserId;
|
||||
|
||||
if (selectedPosition >= 0 && (days == null ? selectedPosition < dialogs.size() && dialogs.get(selectedPosition) == me : daysDialogId == me)) {
|
||||
delegate.setHideEnterViewProgress(1f - progress);
|
||||
} else if (toPosition >= 0 && toPosition < dialogs.size() && dialogs.get(toPosition) == UserConfig.getInstance(currentAccount).clientUserId) {
|
||||
} else if (toPosition >= 0 && (days == null ? toPosition < dialogs.size() && dialogs.get(toPosition) == me : daysDialogId == me)) {
|
||||
delegate.setHideEnterViewProgress(progress);
|
||||
} else {
|
||||
delegate.setHideEnterViewProgress(0);
|
||||
|
@ -178,7 +200,7 @@ public class StoriesViewPager extends ViewPager {
|
|||
boolean allowScreenshots = true;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
PageLayout layout = (PageLayout) getChildAt(i);
|
||||
if (layout.isVisible && !layout.peerStoryView.allowScreenshots) {
|
||||
if (layout.isVisible && !layout.peerStoryView.currentStory.allowScreenshots()) {
|
||||
allowScreenshots = false;
|
||||
break;
|
||||
}
|
||||
|
@ -218,6 +240,25 @@ public class StoriesViewPager extends ViewPager {
|
|||
updateDelegate = true;
|
||||
}
|
||||
|
||||
public void setDays(long dialogId, ArrayList<ArrayList<Integer>> days, int currentAccount) {
|
||||
this.daysDialogId = dialogId;
|
||||
this.days = days;
|
||||
this.currentAccount = currentAccount;
|
||||
setAdapter(null);
|
||||
setAdapter(pagerAdapter);
|
||||
int position;
|
||||
for (position = 0; position < days.size(); ++position) {
|
||||
if (days.get(position).contains(storyViewer.dayStoryId)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (storyViewer.reversed) {
|
||||
position = days.size() - 1 - position;
|
||||
}
|
||||
setCurrentItem(position);
|
||||
updateDelegate = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
|
@ -240,7 +281,7 @@ public class StoriesViewPager extends ViewPager {
|
|||
}
|
||||
|
||||
public boolean switchToNext(boolean forward) {
|
||||
if (forward && getCurrentItem() < dialogs.size() - 1) {
|
||||
if (forward && getCurrentItem() < (days != null ? days : dialogs).size() - 1) {
|
||||
setCurrentItem(getCurrentItem() + 1, !useSurfaceInViewPagerWorkAround());
|
||||
return true;
|
||||
}
|
||||
|
@ -286,6 +327,9 @@ public class StoriesViewPager extends ViewPager {
|
|||
}
|
||||
|
||||
public long getCurrentDialogId() {
|
||||
if (days != null) {
|
||||
return daysDialogId;
|
||||
}
|
||||
if (getCurrentItem() < dialogs.size()) {
|
||||
return dialogs.get(getCurrentItem());
|
||||
}
|
||||
|
@ -337,8 +381,12 @@ public class StoriesViewPager extends ViewPager {
|
|||
private class PageLayout extends FrameLayout {
|
||||
|
||||
public PeerStoriesView peerStoryView;
|
||||
|
||||
long dialogId;
|
||||
ArrayList<Integer> day;
|
||||
|
||||
boolean isVisible;
|
||||
|
||||
public PageLayout(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.widget.FrameLayout;
|
|||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.Utilities;
|
||||
import org.telegram.ui.Cells.DialogCell;
|
||||
import org.telegram.ui.Components.AnimatedTextView;
|
||||
|
||||
|
@ -46,7 +47,10 @@ public class StoryPositionView {
|
|||
}
|
||||
canvas.save();
|
||||
float top = headerView.getY() + headerView.titleView.getTop() + textDrawable.getHeight() / 2f - 1;// + //(headerView.titleView.getMeasuredHeight() - textDrawable.getHeight()) / 2f + AndroidUtilities.dp(1);
|
||||
int rightPadding = (int) textDrawable.getCurrentWidth();
|
||||
headerView.titleView.setRightPadding(rightPadding);
|
||||
float left = AndroidUtilities.dp(4) + headerView.getLeft() + headerView.titleView.getLeft() + headerView.titleView.getTextWidth();
|
||||
left -= Utilities.clamp(headerView.titleView.getTextWidth() + rightPadding - headerView.titleView.getWidth(), rightPadding, 0);
|
||||
canvas.translate(left, top);
|
||||
|
||||
float horizontalPadding = AndroidUtilities.dp(8);
|
||||
|
|
|
@ -32,7 +32,7 @@ public class StoryPrivacyButton extends View {
|
|||
private final Paint[] backgroundPaint = new Paint[2];
|
||||
private final AnimatedFloat crossfadeT = new AnimatedFloat(this, 0, 260, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
|
||||
private boolean draw;
|
||||
public boolean draw;
|
||||
private int iconResId;
|
||||
private final Drawable[] icon = new Drawable[2];
|
||||
private final float[] iconSize = new float[2];
|
||||
|
@ -77,6 +77,7 @@ public class StoryPrivacyButton extends View {
|
|||
} else {
|
||||
draw = false;
|
||||
}
|
||||
setVisibility(draw ? View.VISIBLE : View.GONE);
|
||||
invalidate();
|
||||
return draw;
|
||||
}
|
||||
|
@ -105,6 +106,7 @@ public class StoryPrivacyButton extends View {
|
|||
} else {
|
||||
draw = false;
|
||||
}
|
||||
setVisibility(draw ? View.VISIBLE : View.GONE);
|
||||
invalidate();
|
||||
return draw;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.graphics.SurfaceTexture;
|
|||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Gravity;
|
||||
|
@ -73,6 +74,7 @@ import org.telegram.ui.LaunchActivity;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class StoryViewer {
|
||||
|
||||
|
@ -83,7 +85,7 @@ public class StoryViewer {
|
|||
public boolean foundViewToClose = false;
|
||||
|
||||
public int allowScreenshotsCounter;
|
||||
public boolean allowScreenshots;
|
||||
public boolean allowScreenshots = true;
|
||||
public static ArrayList<StoryViewer> globalInstances = new ArrayList<>();
|
||||
|
||||
BaseFragment fragment;
|
||||
|
@ -175,8 +177,8 @@ public class StoryViewer {
|
|||
|
||||
boolean isSingleStory;
|
||||
StoriesController.StoriesList storiesList;
|
||||
public int dayStoryId;
|
||||
TLRPC.TL_userStories overrideUserStories;
|
||||
int storiesListStartPosition;
|
||||
boolean reversed;
|
||||
|
||||
TLRPC.StoryItem singleStory;
|
||||
|
@ -185,6 +187,7 @@ public class StoryViewer {
|
|||
private int fromRadius;
|
||||
private static boolean runOpenAnimationAfterLayout;
|
||||
private boolean isPopupVisible;
|
||||
private boolean isBulletinVisible;
|
||||
|
||||
public boolean isLongpressed;
|
||||
|
||||
|
@ -261,12 +264,12 @@ public class StoryViewer {
|
|||
open(context, null, peerIds, position, null, null, placeProvider, false);
|
||||
}
|
||||
|
||||
public void open(Context context, TLRPC.StoryItem storyItem, int startPosition, StoriesController.StoriesList storiesList, PlaceProvider placeProvider) {
|
||||
public void open(Context context, int startStoryId, StoriesController.StoriesList storiesList, PlaceProvider placeProvider) {
|
||||
currentAccount = UserConfig.selectedAccount;
|
||||
ArrayList<Long> peerIds = new ArrayList<>();
|
||||
peerIds.add(storiesList.userId);
|
||||
storiesListStartPosition = startPosition;
|
||||
open(context, storyItem, peerIds, 0, storiesList, null, placeProvider, false);
|
||||
dayStoryId = startStoryId;
|
||||
open(context, null, peerIds, 0, storiesList, null, placeProvider, false);
|
||||
}
|
||||
|
||||
public void open(Context context, TLRPC.TL_userStories userStories, PlaceProvider placeProvider) {
|
||||
|
@ -276,14 +279,14 @@ public class StoryViewer {
|
|||
currentAccount = UserConfig.selectedAccount;
|
||||
ArrayList<Long> peerIds = new ArrayList<>();
|
||||
peerIds.add(userStories.user_id);
|
||||
open(context, userStories.stories.get(0), peerIds, 0, null, userStories, placeProvider, reversed);
|
||||
open(context, userStories.stories.get(0), peerIds, 0, null, userStories, placeProvider, false);
|
||||
}
|
||||
|
||||
public void open(Context context, TLRPC.StoryItem storyItem, int startPosition, StoriesController.StoriesList storiesList, boolean reversed, PlaceProvider placeProvider) {
|
||||
public void open(Context context, TLRPC.StoryItem storyItem, int startStoryId, StoriesController.StoriesList storiesList, boolean reversed, PlaceProvider placeProvider) {
|
||||
currentAccount = UserConfig.selectedAccount;
|
||||
ArrayList<Long> peerIds = new ArrayList<>();
|
||||
peerIds.add(storiesList.userId);
|
||||
storiesListStartPosition = startPosition;
|
||||
dayStoryId = startStoryId;
|
||||
open(context, storyItem, peerIds, 0, storiesList, null, placeProvider, reversed);
|
||||
}
|
||||
|
||||
|
@ -314,6 +317,9 @@ public class StoryViewer {
|
|||
currentAccount = UserConfig.selectedAccount;
|
||||
swipeToDismissOffset = 0;
|
||||
swipeToDismissHorizontalOffset = 0;
|
||||
if (storiesViewPager != null) {
|
||||
storiesViewPager.setHorizontalProgressToDismiss(0);
|
||||
}
|
||||
swipeToReplyProgress = 0;
|
||||
swipeToReplyOffset = 0;
|
||||
allowSwipeToReply = false;
|
||||
|
@ -393,7 +399,7 @@ public class StoryViewer {
|
|||
int maxOffset = AndroidUtilities.dp(200);
|
||||
if (swipeToReplyOffset > maxOffset && !swipeToReplyWaitingKeyboard) {
|
||||
swipeToReplyWaitingKeyboard = true;
|
||||
storiesViewPager.getCurrentPeerView().showKeyboard();
|
||||
showKeyboard();
|
||||
windowView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||
}
|
||||
swipeToReplyProgress = Utilities.clamp(swipeToReplyOffset / maxOffset, 1f, 0);
|
||||
|
@ -411,11 +417,6 @@ public class StoryViewer {
|
|||
} else {
|
||||
selfStoriesViewsOffset += distanceY;
|
||||
}
|
||||
// int maxOffset = AndroidUtilities.dp(200);
|
||||
// if (selfStoriesViewsOffset > maxOffset) {
|
||||
// storiesViewPager.getCurrentPeerView().showKeyboard();
|
||||
// }
|
||||
// swipeToReplyProgress = Utilities.clamp(swipeToReplyOffset / maxOffset, 1f, 0);
|
||||
storiesViewPager.getCurrentPeerView().invalidate();
|
||||
containerView.invalidate();
|
||||
if (selfStoriesViewsOffset < 0) {
|
||||
|
@ -447,10 +448,7 @@ public class StoryViewer {
|
|||
if (velocityY < -1000 && !swipeToReplyWaitingKeyboard) {
|
||||
swipeToReplyWaitingKeyboard = true;
|
||||
windowView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
|
||||
storiesViewPager.getCurrentPeerView().showKeyboard();
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
cancelSwipeToReply();
|
||||
}, 200);
|
||||
showKeyboard();
|
||||
}
|
||||
}
|
||||
if (selfStoriesViewsOffset != 0) {
|
||||
|
@ -1097,20 +1095,41 @@ public class StoryViewer {
|
|||
|
||||
@Override
|
||||
public void switchToNextAndRemoveCurrentPeer() {
|
||||
ArrayList<Long> newPeers = new ArrayList<>(peerIds);
|
||||
int index = newPeers.indexOf(storiesViewPager.getCurrentPeerView().getCurrentPeer());
|
||||
if (index >= 0) {
|
||||
newPeers.remove(index);
|
||||
if (storiesList != null) {
|
||||
if (storiesViewPager.days == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<ArrayList<Integer>> newDays = new ArrayList<>(storiesViewPager.days);
|
||||
int index = newDays.indexOf(storiesViewPager.getCurrentPeerView().getCurrentDay());
|
||||
if (index >= 0) {
|
||||
newDays.remove(index);
|
||||
} else {
|
||||
close(false);
|
||||
return;
|
||||
}
|
||||
if (!storiesViewPager.switchToNext(true)) {
|
||||
close(false);
|
||||
} else {
|
||||
storiesViewPager.onNextIdle(() -> {
|
||||
storiesViewPager.setDays(storiesList.userId, newDays, currentAccount);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
close(false);
|
||||
return;
|
||||
}
|
||||
if (!storiesViewPager.switchToNext(true)) {
|
||||
close(false);
|
||||
} else {
|
||||
storiesViewPager.onNextIdle(() -> {
|
||||
storiesViewPager.setPeerIds(newPeers, currentAccount, index);
|
||||
});
|
||||
ArrayList<Long> newPeers = new ArrayList<>(peerIds);
|
||||
int index = newPeers.indexOf(storiesViewPager.getCurrentPeerView().getCurrentPeer());
|
||||
if (index >= 0) {
|
||||
newPeers.remove(index);
|
||||
} else {
|
||||
close(false);
|
||||
return;
|
||||
}
|
||||
if (!storiesViewPager.switchToNext(true)) {
|
||||
close(false);
|
||||
} else {
|
||||
storiesViewPager.onNextIdle(() -> {
|
||||
storiesViewPager.setPeerIds(newPeers, currentAccount, index);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1164,10 +1183,14 @@ public class StoryViewer {
|
|||
|
||||
@Override
|
||||
public void requestPlayer(TLRPC.Document document, Uri uri, long t, PeerStoriesView.VideoPlayerSharedScope scope) {
|
||||
if (isClosed) {
|
||||
if (isClosed || progressToOpen != 1f) {
|
||||
scope.firstFrameRendered = false;
|
||||
scope.player = null;
|
||||
return;
|
||||
}
|
||||
boolean sameUri = Objects.equals(lastUri, uri);
|
||||
String lastAutority = lastUri == null ? null : lastUri.getAuthority();
|
||||
String autority = uri == null ? null : uri.getAuthority();
|
||||
boolean sameUri = Objects.equals(lastAutority, autority);
|
||||
if (!sameUri || playerHolder == null) {
|
||||
lastUri = uri;
|
||||
if (playerHolder != null) {
|
||||
|
@ -1218,6 +1241,13 @@ public class StoryViewer {
|
|||
currentPlayerScope.textureView = textureView;
|
||||
currentPlayerScope.surfaceView = surfaceView;
|
||||
}
|
||||
if (USE_SURFACE_VIEW) {
|
||||
if (uri == null) {
|
||||
surfaceView.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
surfaceView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1259,6 +1289,12 @@ public class StoryViewer {
|
|||
updatePlayingMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBulletinIsVisible(boolean b) {
|
||||
StoryViewer.this.isBulletinVisible = b;
|
||||
updatePlayingMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsInPinchToZoom(boolean b) {
|
||||
StoryViewer.this.isInPinchToZoom = b;
|
||||
|
@ -1335,15 +1371,14 @@ public class StoryViewer {
|
|||
aspectRatioFrameLayout.addView(textureView);
|
||||
}
|
||||
|
||||
|
||||
|
||||
volumeControl = new StoriesVolumeContorl(context);
|
||||
containerView.addView(volumeControl, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 4, 0, 4, 0));
|
||||
}
|
||||
AndroidUtilities.removeFromParent(containerView);
|
||||
windowView.addView(containerView);
|
||||
AndroidUtilities.removeFromParent(aspectRatioFrameLayout);
|
||||
windowView.addView(aspectRatioFrameLayout);
|
||||
|
||||
AndroidUtilities.removeFromParent(containerView);
|
||||
windowView.addView(containerView);
|
||||
windowView.setClipChildren(false);
|
||||
|
||||
if (ATTACH_TO_FRAGMENT) {
|
||||
|
@ -1355,7 +1390,11 @@ public class StoryViewer {
|
|||
if (isSingleStory) {
|
||||
updateTransitionParams();
|
||||
}
|
||||
storiesViewPager.setPeerIds(peerIds, currentAccount, position);
|
||||
if (storiesList != null) {
|
||||
storiesViewPager.setDays(storiesList.userId, storiesList.getDays(), currentAccount);
|
||||
} else {
|
||||
storiesViewPager.setPeerIds(peerIds, currentAccount, position);
|
||||
}
|
||||
|
||||
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
if (ATTACH_TO_FRAGMENT) {
|
||||
|
@ -1412,6 +1451,13 @@ public class StoryViewer {
|
|||
AndroidUtilities.hideKeyboard(fragment.getFragmentView());
|
||||
}
|
||||
|
||||
private void showKeyboard() {
|
||||
storiesViewPager.getCurrentPeerView().showKeyboard();
|
||||
AndroidUtilities.runOnUIThread(() -> {
|
||||
cancelSwipeToReply();
|
||||
}, 200);
|
||||
}
|
||||
|
||||
ValueAnimator swipeToViewsAnimator;
|
||||
|
||||
public void cancelSwipeToViews(boolean open) {
|
||||
|
@ -1474,17 +1520,21 @@ public class StoryViewer {
|
|||
}
|
||||
|
||||
public void cancelSwipeToReply() {
|
||||
if (swipeToReplyOffset != 0 && allowSwipeToReply) {
|
||||
if (swipeToReplyBackAnimator == null) {
|
||||
inSwipeToDissmissMode = false;
|
||||
allowSwipeToReply = false;
|
||||
swipeToReplyBackAnimator = ValueAnimator.ofFloat(swipeToReplyProgress, 0);
|
||||
swipeToReplyBackAnimator = ValueAnimator.ofFloat(swipeToReplyOffset, 0);
|
||||
swipeToReplyBackAnimator.addUpdateListener(animation -> {
|
||||
swipeToReplyProgress = (float) animation.getAnimatedValue();
|
||||
swipeToReplyOffset = (float) animation.getAnimatedValue();
|
||||
int maxOffset = AndroidUtilities.dp(200);
|
||||
swipeToReplyProgress = Utilities.clamp(swipeToReplyOffset / maxOffset, 1f, 0);
|
||||
storiesViewPager.getCurrentPeerView().invalidate();
|
||||
});
|
||||
swipeToReplyBackAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
swipeToReplyBackAnimator = null;
|
||||
swipeToReplyOffset = 0;
|
||||
swipeToReplyProgress = 0;
|
||||
storiesViewPager.getCurrentPeerView().invalidate();
|
||||
}
|
||||
|
@ -1610,9 +1660,11 @@ public class StoryViewer {
|
|||
int position = peerView == null ? 0 : peerView.getSelectedPosition();
|
||||
int storyId = peerView == null || position < 0 || position >= peerView.storyItems.size() ? 0 : peerView.storyItems.get(position).id;
|
||||
TLRPC.StoryItem storyItem = peerView == null || position < 0 || position >= peerView.storyItems.size() ? null : peerView.storyItems.get(position);
|
||||
|
||||
if (storyItem == null && isSingleStory) {
|
||||
storyItem = singleStory;
|
||||
}
|
||||
transitionViewHolder.clear();
|
||||
if (placeProvider.findView(storiesViewPager.getCurrentDialogId(), messageId, storyId, storyItem == null ? -1 : storyItem.messageType, transitionViewHolder)) {
|
||||
if (placeProvider.findView(storiesViewPager.getCurrentDialogId(), messageId, storiesList != null ? dayStoryId : storyId, storyItem == null ? -1 : storyItem.messageType, transitionViewHolder)) {
|
||||
if (transitionViewHolder.view != null) {
|
||||
int[] loc = new int[2];
|
||||
transitionViewHolder.view.getLocationOnScreen(loc);
|
||||
|
@ -1707,7 +1759,7 @@ public class StoryViewer {
|
|||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
return isPopupVisible || isCaption || isWaiting || isInTouchMode || keyboardVisible || currentDialog != null || allowTouchesByViewpager || isClosed || isRecording || progressToOpen != 1f || selfStoriesViewsOffset != 0 || isHintVisible || (isSwiping && USE_SURFACE_VIEW) || isOverlayVisible;
|
||||
return isPopupVisible || isBulletinVisible || isCaption || isWaiting || isInTouchMode || keyboardVisible || currentDialog != null || allowTouchesByViewpager || isClosed || isRecording || progressToOpen != 1f || selfStoriesViewsOffset != 0 || isHintVisible || (isSwiping && USE_SURFACE_VIEW) || isOverlayVisible;
|
||||
}
|
||||
|
||||
public void updatePlayingMode() {
|
||||
|
@ -1836,6 +1888,10 @@ public class StoryViewer {
|
|||
transitionViewHolder.storyImage.setAlpha(1f);
|
||||
transitionViewHolder.storyImage.setVisible(true, true);
|
||||
}
|
||||
PeerStoriesView peerStoriesView = getCurrentPeerView();
|
||||
if (peerStoriesView != null) {
|
||||
peerStoriesView.updatePosition();
|
||||
}
|
||||
updatePlayingMode();
|
||||
locker.unlock();
|
||||
}
|
||||
|
@ -2183,7 +2239,6 @@ public class StoryViewer {
|
|||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2411,7 +2466,7 @@ public class StoryViewer {
|
|||
onReadyListener.run();
|
||||
onReadyListener = null;
|
||||
}
|
||||
});
|
||||
}, 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -58,6 +58,9 @@ public class UserListPoller {
|
|||
ArrayList<TLRPC.User> usersToUpdate = new ArrayList<>();
|
||||
for (int i = 0; i < vector.objects.size(); i++) {
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogsFinal.get(i));
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
user.stories_max_id = (int) vector.objects.get(i);
|
||||
if (user.stories_max_id != 0) {
|
||||
user.flags2 |= 32;
|
||||
|
|
|
@ -58,12 +58,13 @@ public class DownloadButton extends ImageView {
|
|||
|
||||
private boolean downloading;
|
||||
private boolean downloadingVideo;
|
||||
private boolean preparing;
|
||||
private CircularProgressDrawable progressDrawable;
|
||||
private Runnable prepare;
|
||||
private Utilities.Callback<Runnable> prepare;
|
||||
|
||||
private PreparingVideoToast toast;
|
||||
|
||||
public DownloadButton(Context context, Runnable prepare, int currentAccount, FrameLayout container, Theme.ResourcesProvider resourcesProvider) {
|
||||
public DownloadButton(Context context, Utilities.Callback<Runnable> prepare, int currentAccount, FrameLayout container, Theme.ResourcesProvider resourcesProvider) {
|
||||
super(context);
|
||||
|
||||
this.prepare = prepare;
|
||||
|
@ -117,15 +118,6 @@ public class DownloadButton extends ImageView {
|
|||
if (downloading || currentEntry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
downloading = true;
|
||||
if (toast != null) {
|
||||
toast.hide();
|
||||
toast = null;
|
||||
}
|
||||
if (prepare != null) {
|
||||
prepare.run();
|
||||
}
|
||||
if (savedToGalleryUri != null) {
|
||||
if (Build.VERSION.SDK_INT >= 30) {
|
||||
getContext().getContentResolver().delete(savedToGalleryUri, null);
|
||||
|
@ -139,16 +131,28 @@ public class DownloadButton extends ImageView {
|
|||
savedToGalleryUri = null;
|
||||
}
|
||||
}
|
||||
|
||||
downloading = true;
|
||||
if (toast != null) {
|
||||
toast.hide();
|
||||
toast = null;
|
||||
}
|
||||
if (prepare != null) {
|
||||
preparing = true;
|
||||
prepare.run(this::onClickInternal);
|
||||
}
|
||||
if (currentEntry.wouldBeVideo()) {
|
||||
downloadingVideo = true;
|
||||
final File file = AndroidUtilities.generateVideoPath();
|
||||
if (buildingVideo != null) {
|
||||
buildingVideo.stop(true);
|
||||
buildingVideo = null;
|
||||
}
|
||||
toast = new PreparingVideoToast(getContext());
|
||||
toast.setOnCancelListener(() -> {
|
||||
preparing = false;
|
||||
if (buildingVideo != null) {
|
||||
buildingVideo.stop(true);
|
||||
buildingVideo = null;
|
||||
}
|
||||
if (toast != null) {
|
||||
toast.hide();
|
||||
|
@ -157,6 +161,22 @@ public class DownloadButton extends ImageView {
|
|||
updateImage();
|
||||
});
|
||||
container.addView(toast);
|
||||
} else {
|
||||
downloadingVideo = false;
|
||||
}
|
||||
updateImage();
|
||||
if (prepare == null) {
|
||||
onClickInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private void onClickInternal() {
|
||||
if (!preparing) {
|
||||
return;
|
||||
}
|
||||
preparing = false;
|
||||
if (currentEntry.wouldBeVideo()) {
|
||||
final File file = AndroidUtilities.generateVideoPath();
|
||||
buildingVideo = new BuildingVideo(currentAccount, currentEntry, file, () -> {
|
||||
if (!downloading || currentEntry == null) {
|
||||
return;
|
||||
|
@ -172,7 +192,9 @@ public class DownloadButton extends ImageView {
|
|||
savedToGalleryUri = uri;
|
||||
}, false);
|
||||
}, progress -> {
|
||||
toast.setProgress(progress);
|
||||
if (toast != null) {
|
||||
toast.setProgress(progress);
|
||||
}
|
||||
}, () -> {
|
||||
if (!downloading || currentEntry == null) {
|
||||
return;
|
||||
|
@ -182,7 +204,6 @@ public class DownloadButton extends ImageView {
|
|||
updateImage();
|
||||
});
|
||||
} else {
|
||||
downloadingVideo = false;
|
||||
final File file = AndroidUtilities.generatePicturePath(false, "png");
|
||||
if (file == null) {
|
||||
toast.setDone(R.raw.error, LocaleController.getString("UnknownError"), 3500);
|
||||
|
@ -282,6 +303,9 @@ public class DownloadButton extends ImageView {
|
|||
message.attachPath = file.getAbsolutePath();
|
||||
messageObject = new MessageObject(currentAccount, message, (MessageObject) null, false, false);
|
||||
entry.getVideoEditedInfo(info -> {
|
||||
if (messageObject == null) {
|
||||
return;
|
||||
}
|
||||
messageObject.videoEditedInfo = info;
|
||||
MediaController.getInstance().scheduleVideoConvert(messageObject);
|
||||
});
|
||||
|
|
|
@ -171,8 +171,8 @@ public class DualCameraView extends CameraView implements CameraController.Error
|
|||
if (setDefault) {
|
||||
matrix.postConcat(toScreen);
|
||||
|
||||
float w = getMeasuredWidth() * .4f;
|
||||
float h = getMeasuredHeight() * .4f;
|
||||
float w = getMeasuredWidth() * .43f;
|
||||
float h = getMeasuredHeight() * .43f;
|
||||
float px = Math.min(getMeasuredWidth(), getMeasuredWidth()) * .025f;
|
||||
float py = px * 2;
|
||||
|
||||
|
@ -192,30 +192,56 @@ public class DualCameraView extends CameraView implements CameraController.Error
|
|||
toGL.mapPoints(vertex);
|
||||
getDualPosition().invert(invMatrix);
|
||||
invMatrix.mapPoints(vertex);
|
||||
return vertex[0] >= -1 && vertex[0] <= 1 && vertex[1] >= -1 && vertex[1] <= 1;
|
||||
int shape = getDualShape() % 3;
|
||||
boolean square = shape == 0 || shape == 1 || shape == 3;
|
||||
float H = square ? 9 / 16f : 1f;
|
||||
return vertex[0] >= -1 && vertex[0] <= 1 && vertex[1] >= -H && vertex[1] <= H;
|
||||
}
|
||||
|
||||
private float tapX, tapY;
|
||||
private long tapTime;
|
||||
private Matrix invMatrix = new Matrix();
|
||||
private Runnable longpressRunnable;
|
||||
private boolean checkTap(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
tapTime = System.currentTimeMillis();
|
||||
tapX = ev.getX();
|
||||
tapY = ev.getY();
|
||||
lastFocusToPoint = null;
|
||||
if (longpressRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(longpressRunnable);
|
||||
longpressRunnable = null;
|
||||
}
|
||||
if (isAtDual(tapX, tapY)) {
|
||||
AndroidUtilities.runOnUIThread(longpressRunnable = () -> {
|
||||
if (tapTime > 0) {
|
||||
this.dualToggleShape();
|
||||
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
}
|
||||
}, ViewConfiguration.getLongPressTimeout());
|
||||
}
|
||||
return true;
|
||||
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (System.currentTimeMillis() - tapTime <= ViewConfiguration.getTapTimeout() && MathUtils.distance(tapX, tapY, ev.getX(), ev.getY()) < AndroidUtilities.dp(10)) {
|
||||
if (isAtDual(tapX, tapY)) {
|
||||
lastFocusToPoint = this::dualToggleShape;
|
||||
switchCamera();
|
||||
lastFocusToPoint = null;
|
||||
} else {
|
||||
lastFocusToPoint = () -> focusToPoint((int) tapX, (int) tapY);
|
||||
}
|
||||
}
|
||||
tapTime = -1;
|
||||
if (longpressRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(longpressRunnable);
|
||||
longpressRunnable = null;
|
||||
}
|
||||
} else if (ev.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
tapTime = -1;
|
||||
lastFocusToPoint = null;
|
||||
if (longpressRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(longpressRunnable);
|
||||
longpressRunnable = null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -270,6 +296,12 @@ public class DualCameraView extends CameraView implements CameraController.Error
|
|||
down = isPointInsideDual(touchMatrix, touch.x, touch.y);
|
||||
}
|
||||
if (ev.getAction() == MotionEvent.ACTION_MOVE && down) {
|
||||
if (MathUtils.distance(tx, ty, ltx, lty) > AndroidUtilities.dp(2)) {
|
||||
if (longpressRunnable != null) {
|
||||
AndroidUtilities.cancelRunOnUIThread(longpressRunnable);
|
||||
longpressRunnable = null;
|
||||
}
|
||||
}
|
||||
if (ev.getPointerCount() > 1) {
|
||||
if (lastTouchDistance != 0) {
|
||||
extractPointsData(touchMatrix);
|
||||
|
@ -326,8 +358,8 @@ public class DualCameraView extends CameraView implements CameraController.Error
|
|||
}
|
||||
if (cy < 0) {
|
||||
finalMatrix.postTranslate(0, -cy);
|
||||
} else if (cy > getHeight()) {
|
||||
finalMatrix.postTranslate(0, getHeight() - cy);
|
||||
} else if (cy > getHeight() - AndroidUtilities.dp(150)) {
|
||||
finalMatrix.postTranslate(0, getHeight() - AndroidUtilities.dp(150) - cy);
|
||||
}
|
||||
finalMatrix.postConcat(toGL);
|
||||
matrix.set(finalMatrix);
|
||||
|
@ -420,14 +452,17 @@ public class DualCameraView extends CameraView implements CameraController.Error
|
|||
if (verticesDst == null) {
|
||||
verticesDst = new float[8];
|
||||
}
|
||||
int shape = getDualShape() % 3;
|
||||
boolean square = shape == 0 || shape == 1 || shape == 3;
|
||||
float H = square ? 9 / 16f : 1f;
|
||||
verticesSrc[0] = -1;
|
||||
verticesSrc[1] = -1;
|
||||
verticesSrc[1] = -H;
|
||||
verticesSrc[2] = 1;
|
||||
verticesSrc[3] = -1;
|
||||
verticesSrc[3] = -H;
|
||||
verticesSrc[4] = 1;
|
||||
verticesSrc[5] = 1;
|
||||
verticesSrc[5] = H;
|
||||
verticesSrc[6] = -1;
|
||||
verticesSrc[7] = 1;
|
||||
verticesSrc[7] = H;
|
||||
matrix.mapPoints(verticesDst, verticesSrc);
|
||||
|
||||
double a1 = Math.sqrt((verticesDst[0] - verticesDst[2]) * (verticesDst[0] - verticesDst[2]) + (verticesDst[1] - verticesDst[3]) * (verticesDst[1] - verticesDst[3]));
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.telegram.messenger.AndroidUtilities;
|
|||
import org.telegram.messenger.ApplicationLoader;
|
||||
import org.telegram.messenger.DispatchQueue;
|
||||
import org.telegram.messenger.DispatchQueuePool;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.ImageLocation;
|
||||
import org.telegram.messenger.ImageReceiver;
|
||||
import org.telegram.messenger.LocaleController;
|
||||
|
@ -77,6 +78,7 @@ import org.telegram.ui.Components.RecyclerListView;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -607,28 +609,16 @@ public class GalleryListView extends FrameLayout implements NotificationCenter.N
|
|||
Bitmap bitmap = null;
|
||||
if (entry instanceof MediaController.PhotoEntry) {
|
||||
MediaController.PhotoEntry photoEntry = (MediaController.PhotoEntry) entry;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
Uri uri;
|
||||
if (photoEntry.isVideo) {
|
||||
uri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, photoEntry.imageId);
|
||||
} else {
|
||||
uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, photoEntry.imageId);
|
||||
}
|
||||
|
||||
try {
|
||||
bitmap = getContext().getContentResolver().loadThumbnail(uri, new Size(rw, rh), null);
|
||||
} catch (Exception ignore) {}
|
||||
} else {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
readBitmap(photoEntry, opts);
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
readBitmap(photoEntry, opts);
|
||||
|
||||
opts.inSampleSize = StoryEntry.calculateInSampleSize(opts, rw, rh);
|
||||
opts.inPreferredConfig = Bitmap.Config.RGB_565;
|
||||
opts.inDither = true;
|
||||
opts.inJustDecodeBounds = false;
|
||||
bitmap = readBitmap(photoEntry, opts);
|
||||
}
|
||||
StoryEntry.setupScale(opts, rw, rh);
|
||||
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
opts.inDither = true;
|
||||
opts.inJustDecodeBounds = false;
|
||||
bitmap = readBitmap(photoEntry, opts);
|
||||
|
||||
final boolean needGradient = bitmap != null && ((float) bitmap.getHeight() / bitmap.getWidth()) < ASPECT_RATIO;
|
||||
if (needGradient) {
|
||||
|
@ -648,8 +638,8 @@ public class GalleryListView extends FrameLayout implements NotificationCenter.N
|
|||
opts.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(file.getPath(), opts);
|
||||
|
||||
opts.inSampleSize = StoryEntry.calculateInSampleSize(opts, rw, rh);
|
||||
opts.inPreferredConfig = Bitmap.Config.RGB_565;
|
||||
StoryEntry.setupScale(opts, rw, rh);
|
||||
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
|
||||
opts.inDither = true;
|
||||
opts.inJustDecodeBounds = false;
|
||||
bitmap = BitmapFactory.decodeFile(file.getPath(), opts);
|
||||
|
@ -761,8 +751,28 @@ public class GalleryListView extends FrameLayout implements NotificationCenter.N
|
|||
} else if (photoEntry.isVideo) {
|
||||
return MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), photoEntry.imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
} else {
|
||||
return BitmapFactory.decodeFile(photoEntry.path, options);
|
||||
// return MediaStore.Images.Thumbnails.getThumbnail(getContext().getContentResolver(), photoEntry.imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
// Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, photoEntry.imageId);
|
||||
//
|
||||
// Bitmap bitmap = null;
|
||||
// InputStream is = null;
|
||||
// try {
|
||||
// is = getContext().getContentResolver().openInputStream(uri);
|
||||
// bitmap = BitmapFactory.decodeStream(is, null, options);
|
||||
// } catch (Exception e) {
|
||||
// FileLog.e(e, false);
|
||||
// } finally {
|
||||
// if (is != null) {
|
||||
// try {
|
||||
// is.close();
|
||||
// } catch (Exception e2) {}
|
||||
// }
|
||||
// }
|
||||
// if (bitmap == null && options != null && !options.inJustDecodeBounds) {
|
||||
// return BitmapFactory.decodeFile(photoEntry.path, options);
|
||||
// } else {
|
||||
// return bitmap;
|
||||
// }
|
||||
return MediaStore.Images.Thumbnails.getThumbnail(getContext().getContentResolver(), photoEntry.imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -198,17 +198,27 @@ public class HintView2 extends View {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static int getTextWidth(CharSequence text, TextPaint paint) {
|
||||
if (text instanceof Spannable) {
|
||||
StaticLayout layout = new StaticLayout(text, paint, 99999, Layout.Alignment.ALIGN_NORMAL, 1f, 0f, false);
|
||||
if (layout.getLineCount() > 0)
|
||||
return (int) Math.ceil(layout.getLineWidth(0));
|
||||
return 0;
|
||||
}
|
||||
return (int) paint.measureText(text.toString());
|
||||
}
|
||||
|
||||
// returns max width
|
||||
public static int cutInFancyHalf(CharSequence text, TextPaint paint) {
|
||||
if (text == null) {
|
||||
return 0;
|
||||
}
|
||||
float fullLineWidth = paint.measureText(text.toString());
|
||||
float fullLineWidth = getTextWidth(text, paint);
|
||||
final int L = text.toString().length(), m = L / 2;
|
||||
if (L <= 0) {
|
||||
if (L <= 0 || contains(text, '\n')) {
|
||||
return (int) Math.ceil(fullLineWidth);
|
||||
}
|
||||
int l = m - 2, r = m + 2;
|
||||
int l = m - 1, r = m + 1;
|
||||
int c = m;
|
||||
while (l >= 0 && r < L) {
|
||||
if (text.charAt(l) == ' ') {
|
||||
|
@ -222,7 +232,7 @@ public class HintView2 extends View {
|
|||
l--;
|
||||
r++;
|
||||
}
|
||||
return (int) Math.ceil(Math.max(fullLineWidth * .3f, Math.max(c, L - c) / (float) L * fullLineWidth));
|
||||
return (int) Math.ceil(Math.max(fullLineWidth * .3f, Math.max(c + .5f, L - c + .5f) / (float) L * fullLineWidth));
|
||||
}
|
||||
|
||||
public HintView2 useScale(boolean enable) {
|
||||
|
|
|
@ -52,6 +52,8 @@ import java.util.Map;
|
|||
public class PreviewView extends FrameLayout {
|
||||
|
||||
private Bitmap bitmap;
|
||||
private Bitmap thumbBitmap;
|
||||
|
||||
private StoryEntry entry;
|
||||
private VideoPlayer videoPlayer;
|
||||
private int videoWidth, videoHeight;
|
||||
|
@ -254,6 +256,10 @@ public class PreviewView extends FrameLayout {
|
|||
bitmap.recycle();
|
||||
bitmap = null;
|
||||
}
|
||||
if (thumbBitmap != null) {
|
||||
thumbBitmap.recycle();
|
||||
thumbBitmap = null;
|
||||
}
|
||||
if (entry != null) {
|
||||
final int rw = getMeasuredWidth() <= 0 ? AndroidUtilities.displaySize.x : getMeasuredWidth();
|
||||
final int rh = (int) (rw * 16 / 9f);
|
||||
|
@ -284,41 +290,77 @@ public class PreviewView extends FrameLayout {
|
|||
}
|
||||
if (bitmap == null) {
|
||||
String path = entry.getOriginalFile().getPath();
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
if (entry.isVideo) {
|
||||
if (entry.thumbPath != null) {
|
||||
BitmapFactory.decodeFile(entry.thumbPath, options);
|
||||
} else {
|
||||
try {
|
||||
MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
} catch (Throwable e) {
|
||||
bitmap = null;
|
||||
invalidate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BitmapFactory.decodeFile(path, options);
|
||||
}
|
||||
|
||||
options.inJustDecodeBounds = false;
|
||||
StoryEntry.setupScale(options, rw, rh);
|
||||
if (entry.isVideo) {
|
||||
if (entry.thumbPath != null) {
|
||||
BitmapFactory.decodeFile(entry.thumbPath, options);
|
||||
} else {
|
||||
try {
|
||||
bitmap = MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageId, MediaStore.Video.Thumbnails.MINI_KIND, options);
|
||||
} catch (Throwable e) {
|
||||
bitmap = null;
|
||||
invalidate();
|
||||
return;
|
||||
final long imageIdFinal = imageId;
|
||||
bitmap = StoryEntry.getScaledBitmap(opts -> {
|
||||
if (entry.isVideo) {
|
||||
if (entry.thumbPath != null) {
|
||||
return BitmapFactory.decodeFile(entry.thumbPath, opts);
|
||||
} else {
|
||||
try {
|
||||
return MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageIdFinal, MediaStore.Video.Thumbnails.MINI_KIND, opts);
|
||||
} catch (Throwable e) {
|
||||
invalidate();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return BitmapFactory.decodeFile(path, opts);
|
||||
}
|
||||
} else {
|
||||
bitmap = BitmapFactory.decodeFile(path, options);
|
||||
}
|
||||
}, rw, rh, false);
|
||||
|
||||
// this.thumbAlpha.set(0, true);
|
||||
// thumbBitmap = StoryEntry.getScaledBitmap(opts -> {
|
||||
// if (entry.isVideo) {
|
||||
// if (entry.thumbPath != null) {
|
||||
// return BitmapFactory.decodeFile(entry.thumbPath, opts);
|
||||
// } else {
|
||||
// try {
|
||||
// return MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageIdFinal, MediaStore.Video.Thumbnails.MINI_KIND, opts);
|
||||
// } catch (Throwable e) {
|
||||
// invalidate();
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// return BitmapFactory.decodeFile(path, opts);
|
||||
// }
|
||||
// }, rw / 4, rh / 4, false);
|
||||
//
|
||||
// Utilities.themeQueue.postRunnable(() -> {
|
||||
// final Bitmap bitmapFinal = StoryEntry.getScaledBitmap(opts -> {
|
||||
// if (entry.isVideo) {
|
||||
// if (entry.thumbPath != null) {
|
||||
// return BitmapFactory.decodeFile(entry.thumbPath, opts);
|
||||
// } else {
|
||||
// try {
|
||||
// return MediaStore.Video.Thumbnails.getThumbnail(getContext().getContentResolver(), imageIdFinal, MediaStore.Video.Thumbnails.MINI_KIND, opts);
|
||||
// } catch (Throwable e) {
|
||||
// invalidate();
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// return BitmapFactory.decodeFile(path, opts);
|
||||
// }
|
||||
// }, rw, rh, true);
|
||||
// AndroidUtilities.runOnUIThread(() -> {
|
||||
// if (PreviewView.this.entry != entry) {
|
||||
// if (bitmapFinal != null) {
|
||||
// bitmapFinal.recycle();
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// bitmap = bitmapFinal;
|
||||
// if (!entry.isDraft && entry.isVideo && bitmap != null && entry.width <= 0) {
|
||||
// entry.width = bitmap.getWidth();
|
||||
// entry.height = bitmap.getHeight();
|
||||
// entry.setupMatrix();
|
||||
// }
|
||||
// invalidate();
|
||||
// });
|
||||
// });
|
||||
return;
|
||||
}
|
||||
if (!entry.isDraft && entry.isVideo && bitmap != null) {
|
||||
entry.width = bitmap.getWidth();
|
||||
|
@ -339,6 +381,13 @@ public class PreviewView extends FrameLayout {
|
|||
gradientPaint.setShader(new LinearGradient(0, 0, 0, height, colors, new float[]{0, 1}, Shader.TileMode.CLAMP));
|
||||
invalidate();
|
||||
});
|
||||
} else if (thumbBitmap != null) {
|
||||
DominantColors.getColors(true, thumbBitmap, true, colors -> {
|
||||
entry.gradientTopColor = colors[0];
|
||||
entry.gradientBottomColor = colors[1];
|
||||
gradientPaint.setShader(new LinearGradient(0, 0, 0, height, colors, new float[]{0, 1}, Shader.TileMode.CLAMP));
|
||||
invalidate();
|
||||
});
|
||||
} else {
|
||||
gradientPaint.setShader(null);
|
||||
}
|
||||
|
@ -628,14 +677,27 @@ public class PreviewView extends FrameLayout {
|
|||
invalidate();
|
||||
}
|
||||
|
||||
private final AnimatedFloat thumbAlpha = new AnimatedFloat(this, 0, 320, CubicBezierInterpolator.EASE_OUT);
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.drawRect(0, 0, getWidth(), getHeight(), gradientPaint);
|
||||
if (draw && entry != null && bitmap != null) {
|
||||
matrix.set(entry.matrix);
|
||||
matrix.preScale((float) entry.width / bitmap.getWidth(), (float) entry.height / bitmap.getHeight());
|
||||
matrix.postScale((float) getWidth() / entry.resultWidth, (float) getHeight() / entry.resultHeight);
|
||||
canvas.drawBitmap(bitmap, matrix, bitmapPaint);
|
||||
if (draw && entry != null) {
|
||||
float alpha = this.thumbAlpha.set(bitmap != null);
|
||||
if (thumbBitmap != null && (1f - alpha) > 0) {
|
||||
matrix.set(entry.matrix);
|
||||
matrix.preScale((float) entry.width / thumbBitmap.getWidth(), (float) entry.height / thumbBitmap.getHeight());
|
||||
matrix.postScale((float) getWidth() / entry.resultWidth, (float) getHeight() / entry.resultHeight);
|
||||
bitmapPaint.setAlpha(0xFF);
|
||||
canvas.drawBitmap(thumbBitmap, matrix, bitmapPaint);
|
||||
}
|
||||
if (bitmap != null) {
|
||||
matrix.set(entry.matrix);
|
||||
matrix.preScale((float) entry.width / bitmap.getWidth(), (float) entry.height / bitmap.getHeight());
|
||||
matrix.postScale((float) getWidth() / entry.resultWidth, (float) getHeight() / entry.resultHeight);
|
||||
bitmapPaint.setAlpha((int) (0xFF * alpha));
|
||||
canvas.drawBitmap(bitmap, matrix, bitmapPaint);
|
||||
}
|
||||
}
|
||||
super.dispatchDraw(canvas);
|
||||
if (draw && entry != null) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.graphics.RadialGradient;
|
|||
import android.graphics.Shader;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.TextureView;
|
||||
|
@ -38,6 +39,7 @@ import org.telegram.messenger.Utilities;
|
|||
import org.telegram.ui.ActionBar.Theme;
|
||||
import org.telegram.ui.Components.AnimatedFloat;
|
||||
import org.telegram.ui.Components.ButtonBounce;
|
||||
import org.telegram.ui.Components.CircularProgressDrawable;
|
||||
import org.telegram.ui.Components.CombinedDrawable;
|
||||
import org.telegram.ui.Components.CubicBezierInterpolator;
|
||||
import org.telegram.ui.Components.Point;
|
||||
|
@ -101,7 +103,6 @@ public class RecordControl extends View {
|
|||
|
||||
private final ButtonBounce recordButton = new ButtonBounce(this);
|
||||
private final ButtonBounce flipButton = new ButtonBounce(this);
|
||||
private final ButtonBounce galleryButton = new ButtonBounce(this);
|
||||
private final ButtonBounce lockButton = new ButtonBounce(this);
|
||||
|
||||
private float flipDrawableRotate;
|
||||
|
@ -245,6 +246,11 @@ public class RecordControl extends View {
|
|||
private final AnimatedFloat recordingLongT = new AnimatedFloat(this, 0, 850, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
private boolean recording;
|
||||
|
||||
private float loadingSegments[] = new float[2];
|
||||
private final AnimatedFloat recordingLoadingT = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
private boolean recordingLoading;
|
||||
private long recordingLoadingStart;
|
||||
|
||||
private boolean touch;
|
||||
private boolean discardParentTouch;
|
||||
private long touchStart;
|
||||
|
@ -266,7 +272,6 @@ public class RecordControl extends View {
|
|||
touch = false;
|
||||
recordButton.setPressed(false);
|
||||
flipButton.setPressed(false);
|
||||
galleryButton.setPressed(false);
|
||||
lockButton.setPressed(false);
|
||||
return;
|
||||
}
|
||||
|
@ -287,7 +292,6 @@ public class RecordControl extends View {
|
|||
touch = false;
|
||||
recordButton.setPressed(false);
|
||||
flipButton.setPressed(false);
|
||||
galleryButton.setPressed(false);
|
||||
lockButton.setPressed(false);
|
||||
}
|
||||
};
|
||||
|
@ -326,11 +330,11 @@ public class RecordControl extends View {
|
|||
}
|
||||
|
||||
canvas.save();
|
||||
scale = lerp(recordButton.getScale(.2f), 1, recordingT);
|
||||
scale = lerp(recordButton.getScale(startModeIsVideo ? 0 : .2f), 1, recordingT);
|
||||
canvas.scale(scale, scale, cx, cy);
|
||||
mainPaint.setColor(ColorUtils.blendARGB(WHITE, RED, isVideo));
|
||||
float acx = lerp(cx, recordCx.set(cx + dp(4) * touchCenterT16), touchIsCenterT);
|
||||
float r = lerp(lerp(dp(29), dp(12), recordingT), dp(32), touchIsCenterT);
|
||||
float r = lerp(lerp(dp(29), dp(12), recordingT), dp(32) - dp(4) * Math.abs(touchCenterT96), touchIsCenterT);
|
||||
float rad = lerp(lerp(dp(32), dp(7), recordingT), dp(32), touchIsCenterT);
|
||||
AndroidUtilities.rectTmp.set(acx - r, cy - r, acx + r, cy + r);
|
||||
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, mainPaint);
|
||||
|
@ -346,10 +350,32 @@ public class RecordControl extends View {
|
|||
long duration = System.currentTimeMillis() - recordingStart;
|
||||
AndroidUtilities.rectTmp.set(cx - or, cy - or, cx + or, cy + or);
|
||||
float recordEndT = recording ? 0 : 1f - recordingLongT;
|
||||
float sweepAngle = /*lerp(*/duration / (float) MAX_DURATION * 360/*, 0, recordEndT)*/;
|
||||
float sweepAngle = duration / (float) MAX_DURATION * 360;
|
||||
|
||||
float recordingLoading = this.recordingLoadingT.set(this.recordingLoading);
|
||||
|
||||
outlineFilledPaint.setStrokeWidth(dp(3));
|
||||
outlineFilledPaint.setAlpha((int) (0xFF * (1f - recordEndT)));
|
||||
canvas.drawArc(AndroidUtilities.rectTmp, -90/* + 360 * recordEndT*/, sweepAngle, false, outlineFilledPaint);
|
||||
outlineFilledPaint.setAlpha((int) (0xFF * Math.max(.7f * recordingLoading, 1f - recordEndT)));
|
||||
|
||||
if (recordingLoading <= 0) {
|
||||
canvas.drawArc(AndroidUtilities.rectTmp, -90, sweepAngle, false, outlineFilledPaint);
|
||||
} else {
|
||||
final long now = SystemClock.elapsedRealtime();
|
||||
CircularProgressDrawable.getSegments((now - recordingLoadingStart) % 5400, loadingSegments);
|
||||
invalidate();
|
||||
float fromAngle = loadingSegments[0], toAngle = loadingSegments[1];
|
||||
|
||||
float center = (fromAngle + toAngle) / 2f;
|
||||
float amplitude = Math.abs(toAngle - fromAngle) / 2f;
|
||||
|
||||
if (this.recordingLoading) {
|
||||
center = lerp(-90 + sweepAngle / 2f, center, recordingLoading);
|
||||
amplitude = lerp(sweepAngle / 2f, amplitude, recordingLoading);
|
||||
}
|
||||
|
||||
canvas.drawArc(AndroidUtilities.rectTmp, center - amplitude, amplitude * 2, false, outlineFilledPaint);
|
||||
}
|
||||
|
||||
if (recording) {
|
||||
invalidate();
|
||||
|
||||
|
@ -360,10 +386,11 @@ public class RecordControl extends View {
|
|||
post(() -> {
|
||||
recording = false;
|
||||
longpressRecording = false;
|
||||
this.recordingLoadingStart = SystemClock.elapsedRealtime();
|
||||
this.recordingLoading = true;
|
||||
touch = false;
|
||||
recordButton.setPressed(false);
|
||||
flipButton.setPressed(false);
|
||||
galleryButton.setPressed(false);
|
||||
lockButton.setPressed(false);
|
||||
delegate.onVideoRecordEnd(true);
|
||||
});
|
||||
|
@ -412,7 +439,25 @@ public class RecordControl extends View {
|
|||
canvas.restore();
|
||||
}
|
||||
|
||||
final float tr = longpressRecording ? touchT * isVideo * recordingT * lerp(dp(16), lerp(dp(8) + dp(8) * Math.abs(touchCenterT96), dp(22), touchIsButtonT), Math.max(touchIsButtonT, touchIsCenterT)) : 0;
|
||||
final float tr;
|
||||
if (longpressRecording) {
|
||||
tr = (
|
||||
touchT *
|
||||
isVideo *
|
||||
recordingT *
|
||||
lerp(
|
||||
dp(16),
|
||||
lerp(
|
||||
dp(8) + dp(8) * Math.abs(touchCenterT96),
|
||||
dp(22),
|
||||
touchIsButtonT
|
||||
),
|
||||
Math.max(touchIsButtonT, touchIsCenterT)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
tr = 0;
|
||||
}
|
||||
float locked = lockedT.set(!longpressRecording && recording ? 1 : 0);
|
||||
if (tr > 0) {
|
||||
redPaint.setAlpha(0xFF);
|
||||
|
@ -556,7 +601,11 @@ public class RecordControl extends View {
|
|||
final float x = Utilities.clamp(event.getX() + ox, rightCx, leftCx), y = event.getY() + oy;
|
||||
|
||||
final boolean innerFlipButton = isPressed(x, y, rightCx, cy, dp(7), true);
|
||||
if (action == MotionEvent.ACTION_DOWN || touch) {
|
||||
if (recordingLoading) {
|
||||
recordButton.setPressed(false);
|
||||
flipButton.setPressed(false);
|
||||
lockButton.setPressed(false);
|
||||
} else if (action == MotionEvent.ACTION_DOWN || touch) {
|
||||
recordButton.setPressed(isPressed(x, y, cx, cy, dp(60), false));
|
||||
flipButton.setPressed(isPressed(x, y, rightCx, cy, dp(30), true));
|
||||
lockButton.setPressed(isPressed(x, y, leftCx, cy, dp(30), false));
|
||||
|
@ -619,6 +668,8 @@ public class RecordControl extends View {
|
|||
delegate.onVideoRecordLocked();
|
||||
} else {
|
||||
recording = false;
|
||||
this.recordingLoadingStart = SystemClock.elapsedRealtime();
|
||||
this.recordingLoading = true;
|
||||
delegate.onVideoRecordEnd(false);
|
||||
}
|
||||
} else if (recordButton.isPressed()) {
|
||||
|
@ -638,6 +689,8 @@ public class RecordControl extends View {
|
|||
}
|
||||
} else {
|
||||
recording = false;
|
||||
this.recordingLoadingStart = SystemClock.elapsedRealtime();
|
||||
this.recordingLoading = true;
|
||||
delegate.onVideoRecordEnd(false);
|
||||
}
|
||||
}
|
||||
|
@ -651,7 +704,6 @@ public class RecordControl extends View {
|
|||
|
||||
recordButton.setPressed(false);
|
||||
flipButton.setPressed(false);
|
||||
galleryButton.setPressed(false);
|
||||
lockButton.setPressed(false);
|
||||
|
||||
invalidate();
|
||||
|
@ -667,11 +719,20 @@ public class RecordControl extends View {
|
|||
return;
|
||||
}
|
||||
recording = false;
|
||||
this.recordingLoadingStart = SystemClock.elapsedRealtime();
|
||||
this.recordingLoading = true;
|
||||
delegate.onVideoRecordEnd(false);
|
||||
recordButton.setPressed(false);
|
||||
flipButton.setPressed(false);
|
||||
galleryButton.setPressed(false);
|
||||
lockButton.setPressed(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void stopRecordingLoading(boolean animated) {
|
||||
this.recordingLoading = false;
|
||||
if (!animated) {
|
||||
this.recordingLoadingT.set(false, true);
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package org.telegram.ui.Stories.recorder;
|
|||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.BlurMaskFilter;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Matrix;
|
||||
|
@ -197,12 +199,7 @@ public class StoryEntry extends IStoryPart {
|
|||
File file = filterFile != null ? filterFile : this.file;
|
||||
if (file != null) {
|
||||
try {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(file.getPath(), opts);
|
||||
opts.inJustDecodeBounds = false;
|
||||
setupScale(opts, resultWidth, resultHeight);
|
||||
Bitmap fileBitmap = BitmapFactory.decodeFile(file.getPath(), opts);
|
||||
Bitmap fileBitmap = getScaledBitmap(opts -> BitmapFactory.decodeFile(file.getPath(), opts), resultWidth, resultHeight, true);
|
||||
final float scale = (float) width / fileBitmap.getWidth();
|
||||
tempMatrix.preScale(scale, scale);
|
||||
canvas.drawBitmap(fileBitmap, tempMatrix, bitmapPaint);
|
||||
|
@ -214,13 +211,8 @@ public class StoryEntry extends IStoryPart {
|
|||
|
||||
for (int i = 0; i < parts.size(); ++i) {
|
||||
try {
|
||||
Part part = parts.get(i);
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(part.file.getPath(), opts);
|
||||
opts.inJustDecodeBounds = false;
|
||||
setupScale(opts, resultWidth, resultHeight);
|
||||
Bitmap fileBitmap = BitmapFactory.decodeFile(part.file.getPath(), opts);
|
||||
final Part part = parts.get(i);
|
||||
Bitmap fileBitmap = getScaledBitmap(opts -> BitmapFactory.decodeFile(part.file.getPath(), opts), resultWidth, resultHeight, false);
|
||||
final float scale = (float) part.width / fileBitmap.getWidth();
|
||||
tempMatrix.set(part.matrix);
|
||||
tempMatrix.preScale(scale, scale);
|
||||
|
@ -233,12 +225,7 @@ public class StoryEntry extends IStoryPart {
|
|||
|
||||
if (paintFile != null) {
|
||||
try {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(paintFile.getPath(), opts);
|
||||
opts.inJustDecodeBounds = false;
|
||||
setupScale(opts, resultWidth, resultHeight);
|
||||
Bitmap paintBitmap = BitmapFactory.decodeFile(paintFile.getPath(), opts);
|
||||
Bitmap paintBitmap = getScaledBitmap(opts -> BitmapFactory.decodeFile(paintFile.getPath(), opts), resultWidth, resultHeight, false);
|
||||
canvas.save();
|
||||
float scale = resultWidth / (float) paintBitmap.getWidth();
|
||||
canvas.scale(scale, scale);
|
||||
|
@ -254,7 +241,7 @@ public class StoryEntry extends IStoryPart {
|
|||
|
||||
try {
|
||||
FileOutputStream stream = new FileOutputStream(dest);
|
||||
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
|
||||
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 95, stream);
|
||||
stream.close();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
|
@ -263,6 +250,64 @@ public class StoryEntry extends IStoryPart {
|
|||
finalBitmap.recycle();
|
||||
}
|
||||
|
||||
public static interface DecodeBitmap {
|
||||
public Bitmap decode(BitmapFactory.Options options);
|
||||
}
|
||||
|
||||
public static Bitmap getScaledBitmap(DecodeBitmap decode, int maxWidth, int maxHeight, boolean allowBlur) {
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
decode.decode(opts);
|
||||
|
||||
opts.inJustDecodeBounds = false;
|
||||
opts.inScaled = false;
|
||||
|
||||
final Runtime runtime = Runtime.getRuntime();
|
||||
final long availableMemory = runtime.maxMemory() - (runtime.totalMemory() - runtime.freeMemory());
|
||||
final boolean enoughMemory = (opts.outWidth * opts.outHeight * 4L + maxWidth * maxHeight * 4L) * 1.1 <= availableMemory;
|
||||
|
||||
if (opts.outWidth <= maxWidth && opts.outHeight <= maxHeight) {
|
||||
return decode.decode(opts);
|
||||
}
|
||||
|
||||
if (enoughMemory && SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_AVERAGE) {
|
||||
Bitmap bitmap = decode.decode(opts);
|
||||
|
||||
final float scaleX = maxWidth / (float) bitmap.getWidth(), scaleY = maxHeight / (float) bitmap.getHeight();
|
||||
float scale = Math.max(scaleX, scaleY);
|
||||
// if (SharedConfig.getDevicePerformanceClass() >= SharedConfig.PERFORMANCE_CLASS_HIGH) {
|
||||
// scale = Math.min(scale * 2, 1);
|
||||
// }
|
||||
final int w = (int) (bitmap.getWidth() * scale), h = (int) (bitmap.getHeight() * scale);
|
||||
|
||||
Bitmap scaledBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(scaledBitmap);
|
||||
|
||||
final Matrix matrix = new Matrix();
|
||||
final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||
paint.setShader(shader);
|
||||
|
||||
int blurRadius = Utilities.clamp(Math.round(1f / scale), 8, 0);
|
||||
|
||||
matrix.reset();
|
||||
matrix.postScale(scale, scale);
|
||||
shader.setLocalMatrix(matrix);
|
||||
canvas.drawRect(0, 0, w, h, paint);
|
||||
|
||||
if (allowBlur && blurRadius > 0) {
|
||||
Utilities.stackBlurBitmap(scaledBitmap, blurRadius);
|
||||
}
|
||||
|
||||
return scaledBitmap;
|
||||
} else {
|
||||
opts.inScaled = true;
|
||||
opts.inDensity = opts.outWidth;
|
||||
opts.inTargetDensity = maxWidth;
|
||||
return decode.decode(opts);
|
||||
}
|
||||
}
|
||||
|
||||
public File getOriginalFile() {
|
||||
if (filterFile != null) {
|
||||
return filterFile;
|
||||
|
@ -270,11 +315,18 @@ public class StoryEntry extends IStoryPart {
|
|||
return file;
|
||||
}
|
||||
|
||||
public void updateFilter(PhotoFilterView filterView) {
|
||||
public void updateFilter(PhotoFilterView filterView, Runnable whenDone) {
|
||||
clearFilter();
|
||||
|
||||
filterState = filterView.getSavedFilterState();
|
||||
if (!isVideo) {
|
||||
if (filterState.isEmpty()) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Bitmap bitmap = filterView.getBitmap();
|
||||
if (bitmap == null) {
|
||||
return;
|
||||
|
@ -290,14 +342,40 @@ public class StoryEntry extends IStoryPart {
|
|||
|
||||
bitmap.recycle();
|
||||
|
||||
filterFile = makeCacheFile(currentAccount, false);
|
||||
try {
|
||||
FileOutputStream stream = new FileOutputStream(filterFile);
|
||||
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
if (filterFile != null && filterFile.exists()) {
|
||||
filterFile.delete();
|
||||
}
|
||||
filterFile = makeCacheFile(currentAccount, "webp");
|
||||
if (whenDone == null) {
|
||||
try {
|
||||
FileOutputStream stream = new FileOutputStream(filterFile);
|
||||
rotatedBitmap.compress(Bitmap.CompressFormat.WEBP, 90, stream);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
rotatedBitmap.recycle();
|
||||
} else {
|
||||
Utilities.themeQueue.postRunnable(() -> {
|
||||
try {
|
||||
FileOutputStream stream = new FileOutputStream(filterFile);
|
||||
rotatedBitmap.compress(Bitmap.CompressFormat.WEBP, 90, stream);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e, false);
|
||||
try {
|
||||
FileOutputStream stream = new FileOutputStream(filterFile);
|
||||
rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
|
||||
} catch (Exception e2) {
|
||||
FileLog.e(e2, false);
|
||||
}
|
||||
}
|
||||
rotatedBitmap.recycle();
|
||||
AndroidUtilities.runOnUIThread(whenDone);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
rotatedBitmap.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,6 +747,10 @@ public class StoryEntry extends IStoryPart {
|
|||
}
|
||||
|
||||
public static File makeCacheFile(final int account, boolean video) {
|
||||
return makeCacheFile(account, video ? "mp4" : "jpg");
|
||||
}
|
||||
|
||||
public static File makeCacheFile(final int account, String ext) {
|
||||
TLRPC.TL_fileLocationToBeDeprecated location = new TLRPC.TL_fileLocationToBeDeprecated();
|
||||
location.volume_id = Integer.MIN_VALUE;
|
||||
location.dc_id = Integer.MIN_VALUE;
|
||||
|
@ -676,7 +758,7 @@ public class StoryEntry extends IStoryPart {
|
|||
location.file_reference = new byte[0];
|
||||
|
||||
TLObject object;
|
||||
if (video) {
|
||||
if ("mp4".equals(ext)) {
|
||||
TLRPC.VideoSize videoSize = new TLRPC.TL_videoSize_layer127();
|
||||
videoSize.location = location;
|
||||
object = videoSize;
|
||||
|
@ -686,7 +768,7 @@ public class StoryEntry extends IStoryPart {
|
|||
object = photoSize;
|
||||
}
|
||||
|
||||
return FileLoader.getInstance(account).getPathToAttach(object, video ? "mp4" : "jpg", true);
|
||||
return FileLoader.getInstance(account).getPathToAttach(object, ext, true);
|
||||
}
|
||||
|
||||
public static class HDRInfo {
|
||||
|
|
|
@ -13,9 +13,11 @@ import android.app.Activity;
|
|||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -35,6 +37,7 @@ import android.util.Log;
|
|||
import android.util.TypedValue;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
@ -64,6 +67,7 @@ import com.google.zxing.common.detector.MathUtils;
|
|||
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.telegram.messenger.AndroidUtilities;
|
||||
import org.telegram.messenger.BotWebViewVibrationEffect;
|
||||
import org.telegram.messenger.ChatObject;
|
||||
import org.telegram.messenger.ContactsController;
|
||||
import org.telegram.messenger.DialogObject;
|
||||
|
@ -212,7 +216,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
@Override
|
||||
public void setContainerHeight(float value) {
|
||||
super.setContainerHeight(value);
|
||||
sectionCell.setTranslationY(getY() - (contentView == null ? 0 : contentView.getPaddingTop()) + containerHeight - 1);
|
||||
sectionCell.setTranslationY(getY() - (contentView == null ? 0 : contentView.getPaddingTop()) + Math.min(dp(150), containerHeight) - 1);
|
||||
if (contentView != null) {
|
||||
contentView.invalidate();
|
||||
}
|
||||
|
@ -221,7 +225,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
@Override
|
||||
public void setTranslationY(float translationY) {
|
||||
super.setTranslationY(translationY);
|
||||
sectionCell.setTranslationY(getY() - (contentView == null ? 0 : contentView.getPaddingTop()) + containerHeight - 1);
|
||||
sectionCell.setTranslationY(getY() - (contentView == null ? 0 : contentView.getPaddingTop()) + Math.min(dp(150), containerHeight) - 1);
|
||||
if (contentView != null) {
|
||||
contentView.invalidate();
|
||||
}
|
||||
|
@ -239,87 +243,63 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
});
|
||||
|
||||
contentView = new FrameLayout(context) {
|
||||
private final AnimatedFloat topGradientAlpha = new AnimatedFloat(this, 0, 200, CubicBezierInterpolator.DEFAULT);
|
||||
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
{
|
||||
paint.setShader(new LinearGradient(0, 0, 0, dp(12), new int[] { getThemedColor(Theme.key_dialogBackground), ColorUtils.setAlphaComponent(getThemedColor(Theme.key_dialogBackground), 0)}, new float[] { 0, 1 }, Shader.TileMode.CLAMP));
|
||||
backgroundPaint.setColor(getThemedColor(Theme.key_dialogBackground));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
||||
if (child == searchField && listView != null && searchPosition >= 0) {
|
||||
float gradientAlpha = topGradientAlpha.set(searchField.getTranslationY() < 0);
|
||||
if (gradientAlpha > 0) {
|
||||
boolean r = super.drawChild(canvas, child, drawingTime);
|
||||
canvas.save();
|
||||
canvas.translate(0, getPaddingTop());
|
||||
paint.setAlpha((int) (0xFF * gradientAlpha));
|
||||
canvas.drawRect(0, 0, getWidth(), dp(12), paint);
|
||||
canvas.restore();
|
||||
float t = child.getY() + child.getHeight() - 3, b = sectionCell.getY();
|
||||
if (t < b) {
|
||||
canvas.drawRect(0, t, getWidth(), b, backgroundPaint);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return super.drawChild(canvas, child, drawingTime);
|
||||
}
|
||||
};
|
||||
contentView = new FrameLayout(context);
|
||||
contentView.setPadding(0, AndroidUtilities.statusBarHeight + AndroidUtilities.dp(56), 0, 0);
|
||||
contentView.setClipToPadding(true);
|
||||
addView(contentView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL));
|
||||
|
||||
listView = new RecyclerListView(context, resourcesProvider) {
|
||||
private long tapTime;
|
||||
private float tapX, tapY;
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
tapTime = System.currentTimeMillis();
|
||||
tapX = ev.getX();
|
||||
tapY = ev.getY();
|
||||
} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (MathUtils.distance(tapX, tapY, ev.getX(), ev.getY()) >= AndroidUtilities.touchSlop) {
|
||||
tapTime = -1;
|
||||
if (searchField.currentDeletingSpan != null) {
|
||||
searchField.currentDeletingSpan.cancelDeleteAnimation();
|
||||
searchField.currentDeletingSpan = null;
|
||||
}
|
||||
}
|
||||
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (MathUtils.distance(tapX, tapY, ev.getX(), ev.getY()) <= AndroidUtilities.touchSlop && System.currentTimeMillis() - tapTime <= ViewConfiguration.getTapTimeout() && searchField != null && searchField.spansContainer != null) {
|
||||
float x = ev.getX(), y = contentView.getPaddingTop() + ev.getY();
|
||||
x -= searchField.getX();
|
||||
y -= searchField.getY();
|
||||
if (x < 0 || y < 0 || x > searchField.getWidth() || y > searchField.getHeight()) {
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
for (int i = 0; i < searchField.spansContainer.getChildCount(); ++i) {
|
||||
View child = searchField.spansContainer.getChildAt(i);
|
||||
if (x < child.getX() || y < child.getY() || x >= child.getX() + child.getWidth() || y >= child.getY() + child.getHeight() || !(child instanceof GroupCreateSpan)) {
|
||||
continue;
|
||||
}
|
||||
GroupCreateSpan span = (GroupCreateSpan) child;
|
||||
onClick(span);
|
||||
break;
|
||||
}
|
||||
tapTime = -1;
|
||||
return true;
|
||||
}
|
||||
tapTime = -1;
|
||||
} else if (ev.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
tapTime = -1;
|
||||
if (searchField.currentDeletingSpan != null) {
|
||||
searchField.currentDeletingSpan.cancelDeleteAnimation();
|
||||
searchField.currentDeletingSpan = null;
|
||||
}
|
||||
}
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
// private long tapTime;
|
||||
// private float tapX, tapY;
|
||||
// @Override
|
||||
// public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
// if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
// tapTime = System.currentTimeMillis();
|
||||
// tapX = ev.getX();
|
||||
// tapY = ev.getY();
|
||||
// } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
// if (MathUtils.distance(tapX, tapY, ev.getX(), ev.getY()) >= AndroidUtilities.touchSlop) {
|
||||
// tapTime = -1;
|
||||
// if (searchField.currentDeletingSpan != null) {
|
||||
// searchField.currentDeletingSpan.cancelDeleteAnimation();
|
||||
// searchField.currentDeletingSpan = null;
|
||||
// }
|
||||
// }
|
||||
// } else if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||
// if (MathUtils.distance(tapX, tapY, ev.getX(), ev.getY()) <= AndroidUtilities.touchSlop && System.currentTimeMillis() - tapTime <= ViewConfiguration.getTapTimeout() && searchField != null && searchField.spansContainer != null) {
|
||||
// float x = ev.getX(), y = contentView.getPaddingTop() + ev.getY();
|
||||
// x -= searchField.getX();
|
||||
// y -= searchField.getY();
|
||||
// if (x < 0 || y < 0 || x > searchField.getWidth() || y > searchField.getHeight()) {
|
||||
// return super.dispatchTouchEvent(ev);
|
||||
// }
|
||||
// for (int i = 0; i < searchField.spansContainer.getChildCount(); ++i) {
|
||||
// View child = searchField.spansContainer.getChildAt(i);
|
||||
// if (x < child.getX() || y < child.getY() || x >= child.getX() + child.getWidth() || y >= child.getY() + child.getHeight() || !(child instanceof GroupCreateSpan)) {
|
||||
// continue;
|
||||
// }
|
||||
// GroupCreateSpan span = (GroupCreateSpan) child;
|
||||
// onClick(span);
|
||||
// break;
|
||||
// }
|
||||
// tapTime = -1;
|
||||
// return true;
|
||||
// }
|
||||
// tapTime = -1;
|
||||
// } else if (ev.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
// tapTime = -1;
|
||||
// if (searchField.currentDeletingSpan != null) {
|
||||
// searchField.currentDeletingSpan.cancelDeleteAnimation();
|
||||
// searchField.currentDeletingSpan = null;
|
||||
// }
|
||||
// }
|
||||
// return super.dispatchTouchEvent(ev);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean onTouchEvent(MotionEvent e) {
|
||||
// return super.onTouchEvent(e);
|
||||
// }
|
||||
};
|
||||
listView.setClipToPadding(false);
|
||||
listView.setTranslateSelector(true);
|
||||
|
@ -386,7 +366,18 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
searchField.spansContainer.removeAllSpans(true);
|
||||
} else if (item.chat != null) {
|
||||
final long id = item.chat.id;
|
||||
if (selectedUsersByGroup.containsKey(id)) {
|
||||
if (getParticipantsCount(item.chat) > 200) {
|
||||
// AndroidUtilities.shakeViewSpring(view, shiftDp = -shiftDp);
|
||||
// BotWebViewVibrationEffect.APP_ERROR.vibrate();
|
||||
try {
|
||||
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
} catch (Throwable ignore) {}
|
||||
new AlertDialog.Builder(getContext(), resourcesProvider)
|
||||
.setTitle(LocaleController.getString("GroupTooLarge", R.string.GroupTooLarge))
|
||||
.setMessage(LocaleController.getString("GroupTooLargeMessage", R.string.GroupTooLargeMessage))
|
||||
.setPositiveButton(LocaleController.getString("OK", R.string.OK), null)
|
||||
.show();
|
||||
} else if (selectedUsersByGroup.containsKey(id)) {
|
||||
selectedUsersByGroup.remove(id);
|
||||
updateSpans(true);
|
||||
} else {
|
||||
|
@ -394,7 +385,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
TLRPC.ChatFull chatFull = MessagesController.getInstance(currentAccount).getChatFull(id);
|
||||
if (chatFull != null && chatFull.participants != null && !chatFull.participants.participants.isEmpty()) {
|
||||
selectChat(id, chatFull.participants);
|
||||
} else if (chatFull == null) {
|
||||
} else {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.dismiss();
|
||||
progressDialog = null;
|
||||
|
@ -489,6 +480,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
updateButton(true);
|
||||
updateCheckboxes(true);
|
||||
searchField.scrollToBottom();
|
||||
} else if (item.viewType == VIEW_TYPE_CHECK) {
|
||||
if (!(view instanceof TextCell)) {
|
||||
return;
|
||||
|
@ -501,12 +493,12 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
boolean allowShare = selectedType == TYPE_EVERYONE;
|
||||
if (allowScreenshots) {
|
||||
BulletinFactory.of(container, resourcesProvider)
|
||||
.createSimpleBulletin(R.raw.ic_save_to_gallery, LocaleController.getString(allowShare ? R.string.StoryEnabledScreenshotsShare : R.string.StoryEnabledScreenshots))
|
||||
.createSimpleBulletin(R.raw.ic_save_to_gallery, LocaleController.getString(allowShare ? R.string.StoryEnabledScreenshotsShare : R.string.StoryEnabledScreenshots), 4)
|
||||
.setDuration(5000)
|
||||
.show(true);
|
||||
} else {
|
||||
BulletinFactory.of(container, resourcesProvider)
|
||||
.createSimpleBulletin(R.raw.passcode_lock_close, LocaleController.getString(allowShare ? R.string.StoryDisabledScreenshotsShare : R.string.StoryDisabledScreenshots))
|
||||
.createSimpleBulletin(R.raw.passcode_lock_close, LocaleController.getString(allowShare ? R.string.StoryDisabledScreenshotsShare : R.string.StoryDisabledScreenshots), 4)
|
||||
.setDuration(5000)
|
||||
.show(true);
|
||||
}
|
||||
|
@ -514,12 +506,12 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
keepOnMyPage = cell.isChecked();
|
||||
if (keepOnMyPage) {
|
||||
BulletinFactory.of(container, resourcesProvider)
|
||||
.createSimpleBulletin(R.raw.msg_story_keep, LocaleController.getString(R.string.StoryEnableKeep))
|
||||
.createSimpleBulletin(R.raw.msg_story_keep, LocaleController.getString(R.string.StoryEnableKeep), 4)
|
||||
.setDuration(5000)
|
||||
.show(true);
|
||||
} else {
|
||||
BulletinFactory.of(container, resourcesProvider)
|
||||
.createSimpleBulletin(R.raw.fire_on, LocaleController.getString(R.string.StoryDisableKeep))
|
||||
.createSimpleBulletin(R.raw.fire_on, LocaleController.getString(R.string.StoryDisableKeep), 4)
|
||||
.setDuration(5000)
|
||||
.show(true);
|
||||
}
|
||||
|
@ -671,20 +663,49 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
|
||||
private void selectChat(long id, TLRPC.ChatParticipants participants) {
|
||||
ArrayList<Long> groupUsers = new ArrayList<>();
|
||||
ArrayList<Long> nonContactsUsers = new ArrayList<>();
|
||||
final boolean mustBeContacts = pageType == PAGE_TYPE_CLOSE_FRIENDS || pageType == PAGE_TYPE_EXCLUDE_CONTACTS;
|
||||
if (participants != null && participants.participants != null) {
|
||||
for (int i = 0; i < participants.participants.size(); ++i) {
|
||||
long userId = participants.participants.get(i).user_id;
|
||||
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(userId);
|
||||
if (user != null && !UserObject.isUserSelf(user) && !user.bot && user.id != 777000 && userId != 0) {
|
||||
groupUsers.add(userId);
|
||||
if (mustBeContacts && !user.contact) {
|
||||
nonContactsUsers.add(userId);
|
||||
} else {
|
||||
groupUsers.add(userId);
|
||||
}
|
||||
selectedUsers.remove(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedUsersByGroup.put(id, groupUsers);
|
||||
updateSpans(true);
|
||||
updateButton(true);
|
||||
updateCheckboxes(true);
|
||||
if (!nonContactsUsers.isEmpty()) {
|
||||
if (groupUsers.isEmpty()) {
|
||||
new AlertDialog.Builder(getContext(), resourcesProvider)
|
||||
.setMessage("All group members are not in your contact list.")
|
||||
.setNegativeButton("Cancel", null)
|
||||
.show();
|
||||
} else {
|
||||
new AlertDialog.Builder(getContext(), resourcesProvider)
|
||||
.setMessage(nonContactsUsers.size() + " members are not in your contact list")
|
||||
.setPositiveButton("Add " + groupUsers.size() + " contacts", (di, a) -> {
|
||||
selectedUsersByGroup.put(id, groupUsers);
|
||||
updateSpans(true);
|
||||
updateButton(true);
|
||||
updateCheckboxes(true);
|
||||
di.dismiss();
|
||||
searchField.scrollToBottom();
|
||||
})
|
||||
.setNegativeButton("Cancel", null)
|
||||
.show();
|
||||
}
|
||||
} else {
|
||||
selectedUsersByGroup.put(id, groupUsers);
|
||||
updateSpans(true);
|
||||
updateButton(true);
|
||||
updateCheckboxes(true);
|
||||
searchField.scrollToBottom();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSpans(boolean animated) {
|
||||
|
@ -726,7 +747,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
continue;
|
||||
}
|
||||
GroupCreateSpan span = new GroupCreateSpan(getContext(), obj, null, true, resourcesProvider);
|
||||
// span.setOnClickListener(this);
|
||||
span.setOnClickListener(this);
|
||||
toAdd.add(span);
|
||||
}
|
||||
}
|
||||
|
@ -883,6 +904,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
updateSpans(false);
|
||||
searchField.setText("");
|
||||
searchField.setVisibility(pageType == PAGE_TYPE_SHARE ? View.GONE : View.VISIBLE);
|
||||
searchField.scrollToBottom();
|
||||
query = null;
|
||||
updateItems(false);
|
||||
updateButton(false);
|
||||
|
@ -1169,7 +1191,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
|
||||
private float getSearchFieldTop() {
|
||||
float top = -Math.max(0, searchField.resultContainerHeight - dp(150));
|
||||
float top = -Math.max(0, Math.min(dp(150), searchField.resultContainerHeight) - dp(150));
|
||||
for (int i = 0; i < listView.getChildCount(); ++i) {
|
||||
View child = listView.getChildAt(i);
|
||||
if (child.getTag() instanceof Integer && (int) child.getTag() == 34) {
|
||||
|
@ -1453,7 +1475,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
contentView.setPadding(0, AndroidUtilities.statusBarHeight + AndroidUtilities.dp(56), 0, 0);
|
||||
if (wasKeyboardVisible != keyboardVisible) {
|
||||
float searchFieldTop = getSearchFieldTop();
|
||||
if (keyboardVisible && searchFieldTop + searchField.resultContainerHeight > listView.getPaddingTop()) {
|
||||
if (keyboardVisible && searchFieldTop + Math.min(dp(150), searchField.resultContainerHeight) > listView.getPaddingTop()) {
|
||||
scrollToTopSmoothly();
|
||||
}
|
||||
if (pageType == PAGE_TYPE_SHARE) {
|
||||
|
@ -1623,7 +1645,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height));
|
||||
} else if (viewType == VIEW_TYPE_SEARCH) {
|
||||
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, searchField.resultContainerHeight));
|
||||
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Math.min(dp(150), searchField.resultContainerHeight)));
|
||||
} else if (viewType == VIEW_TYPE_HEADER2) {
|
||||
((HeaderCell2) holder.itemView).setText(item.text, item.text2);
|
||||
} else if (viewType == VIEW_TYPE_NO_USERS) {
|
||||
|
@ -1640,7 +1662,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
cell.setText(item.text);
|
||||
}
|
||||
} else if (viewType == VIEW_TYPE_CHECK) {
|
||||
((TextCell) holder.itemView).setTextAndCheck(item.text, item.resId == 0 ? allowScreenshots : keepOnMyPage, !divider);
|
||||
((TextCell) holder.itemView).setTextAndCheck(item.text, item.resId == 0 ? allowScreenshots : keepOnMyPage, divider);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2258,7 +2280,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
continue;
|
||||
}
|
||||
int participants_count = getParticipantsCount(chat);
|
||||
if (participants_count > 1 && participants_count <= 20) {
|
||||
if (participants_count > 1) {
|
||||
contains.put(-chat.id, true);
|
||||
users.add(chat);
|
||||
}
|
||||
|
@ -2398,6 +2420,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
subtitleTextView.setTextColor(Theme.getColor(isOnline[0] ? Theme.key_dialogTextBlue2 : Theme.key_dialogTextGray3, resourcesProvider));
|
||||
|
||||
checkBox.setVisibility(View.VISIBLE);
|
||||
checkBox.setAlpha(1f);
|
||||
radioButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
@ -2405,7 +2428,10 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
avatarDrawable.setInfo(chat);
|
||||
imageView.setForUserOrChat(chat, avatarDrawable);
|
||||
|
||||
titleTextView.setText(chat.title);
|
||||
CharSequence text = chat.title;
|
||||
text = Emoji.replaceEmoji(text, titleTextView.getPaint().getFontMetricsInt(), false);
|
||||
titleTextView.setText(text);
|
||||
|
||||
isOnline[0] = false;
|
||||
String subtitle;
|
||||
if (ChatObject.isChannel(chat) && !chat.megagroup) {
|
||||
|
@ -2435,6 +2461,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
subtitleTextView.setTextColor(Theme.getColor(isOnline[0] ? Theme.key_dialogTextBlue2 : Theme.key_dialogTextGray3, resourcesProvider));
|
||||
|
||||
checkBox.setVisibility(View.VISIBLE);
|
||||
checkBox.setAlpha(participants_count > 200 ? .3f : 1f);
|
||||
radioButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
@ -2655,7 +2682,6 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
private Runnable updateHeight;
|
||||
|
||||
private boolean ignoreTextChange;
|
||||
|
||||
private Utilities.Callback<String> onSearchTextChange;
|
||||
|
||||
public SearchUsersCell(Context context, Theme.ResourcesProvider resourcesProvider, Runnable updateHeight) {
|
||||
|
@ -2683,6 +2709,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if (!AndroidUtilities.showKeyboard(this)) {
|
||||
fullScroll(View.FOCUS_DOWN);
|
||||
clearFocus();
|
||||
requestFocus();
|
||||
}
|
||||
|
@ -2758,11 +2785,60 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
});
|
||||
}
|
||||
|
||||
private final AnimatedFloat topGradientAlpha = new AnimatedFloat(this, 0, 300, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
private final LinearGradient topGradient = new LinearGradient(0, 0, 0, dp(8), new int[] { 0xff000000, 0x00000000 }, new float[] { 0, 1 }, Shader.TileMode.CLAMP);
|
||||
private final Paint topGradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Matrix topGradientMatrix = new Matrix();
|
||||
|
||||
private final AnimatedFloat bottomGradientAlpha = new AnimatedFloat(this, 0, 300, CubicBezierInterpolator.EASE_OUT_QUINT);
|
||||
private final LinearGradient bottomGradient = new LinearGradient(0, 0, 0, dp(8), new int[] { 0x00000000, 0xff000000 }, new float[] { 0, 1 }, Shader.TileMode.CLAMP);
|
||||
private final Paint bottomGradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Matrix bottomGradientMatrix = new Matrix();
|
||||
{
|
||||
topGradientPaint.setShader(topGradient);
|
||||
topGradientPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
|
||||
bottomGradientPaint.setShader(bottomGradient);
|
||||
bottomGradientPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
final int y = getScrollY();
|
||||
|
||||
canvas.saveLayerAlpha(0, y, getWidth(), y + getHeight(), 0xFF, Canvas.ALL_SAVE_FLAG);
|
||||
super.dispatchDraw(canvas);
|
||||
|
||||
canvas.save();
|
||||
|
||||
float alpha = topGradientAlpha.set(canScrollVertically(-1));
|
||||
topGradientMatrix.reset();
|
||||
topGradientMatrix.postTranslate(0, y);
|
||||
topGradient.setLocalMatrix(topGradientMatrix);
|
||||
topGradientPaint.setAlpha((int) (0xFF * alpha));
|
||||
canvas.drawRect(0, y, getWidth(), y + dp(8), topGradientPaint);
|
||||
|
||||
alpha = bottomGradientAlpha.set(canScrollVertically(1));
|
||||
bottomGradientMatrix.reset();
|
||||
bottomGradientMatrix.postTranslate(0, y + getHeight() - dp(8));
|
||||
bottomGradient.setLocalMatrix(bottomGradientMatrix);
|
||||
bottomGradientPaint.setAlpha((int) (0xFF * alpha));
|
||||
canvas.drawRect(0, y + getHeight() - dp(8), getWidth(), y + getHeight(), bottomGradientPaint);
|
||||
|
||||
canvas.restore();
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestChildFocus(View child, View focused) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (!AndroidUtilities.findClickableView(this, ev.getX(), ev.getY())) {
|
||||
return false;
|
||||
}
|
||||
// if (!AndroidUtilities.findClickableView(this, ev.getX(), ev.getY())) {
|
||||
// return false;
|
||||
// }
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
|
@ -2797,8 +2873,8 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY),
|
||||
heightMeasureSpec
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(dp(150), MeasureSpec.AT_MOST)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2815,10 +2891,17 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
return animator;
|
||||
}
|
||||
|
||||
private boolean scroll;
|
||||
public void scrollToBottom() {
|
||||
scroll = true;
|
||||
}
|
||||
|
||||
public class SpansContainer extends ViewGroup {
|
||||
|
||||
private AnimatorSet currentAnimation;
|
||||
private boolean animationStarted;
|
||||
private ArrayList<View> animAddingSpans = new ArrayList<>();
|
||||
private ArrayList<View> animRemovingSpans = new ArrayList<>();
|
||||
private ArrayList<Animator> animators = new ArrayList<>();
|
||||
private View addingSpan;
|
||||
private final ArrayList<View> removingSpans = new ArrayList<>();
|
||||
|
@ -2933,6 +3016,10 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
editText.bringPointIntoView(editText.getSelectionStart());
|
||||
}
|
||||
}
|
||||
if (scroll) {
|
||||
fullScroll(View.FOCUS_DOWN);
|
||||
scroll = false;
|
||||
}
|
||||
setMeasuredDimension(width, (int) containerHeight);
|
||||
}
|
||||
|
||||
|
@ -2945,46 +3032,12 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
}
|
||||
|
||||
public void addSpan(final GroupCreateSpan span, boolean animated) {
|
||||
allSpans.add(span);
|
||||
|
||||
if (currentAnimation != null && currentAnimation.isRunning()) {
|
||||
currentAnimation.setupEndValues();
|
||||
currentAnimation.cancel();
|
||||
}
|
||||
animationStarted = false;
|
||||
if (animated) {
|
||||
currentAnimation = new AnimatorSet();
|
||||
currentAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
addingSpan = null;
|
||||
currentAnimation = null;
|
||||
animationStarted = false;
|
||||
editText.setAllowDrawCursor(true);
|
||||
if (updateHeight != null) {
|
||||
updateHeight.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
addingSpan = span;
|
||||
animators.clear();
|
||||
animators.add(ObjectAnimator.ofFloat(addingSpan, View.SCALE_X, 0.01f, 1.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(addingSpan, View.SCALE_Y, 0.01f, 1.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(addingSpan, View.ALPHA, 0.0f, 1.0f));
|
||||
}
|
||||
addView(span);
|
||||
}
|
||||
|
||||
public void removeSpan(final GroupCreateSpan span) {
|
||||
ignoreScrollEvent = true;
|
||||
allSpans.remove(span);
|
||||
span.setOnClickListener(null);
|
||||
|
||||
if (currentAnimation != null) {
|
||||
currentAnimation.setupEndValues();
|
||||
currentAnimation.cancel();
|
||||
}
|
||||
setupEndValues();
|
||||
animationStarted = false;
|
||||
currentAnimation = new AnimatorSet();
|
||||
currentAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
|
@ -3002,6 +3055,9 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
});
|
||||
removingSpans.clear();
|
||||
removingSpans.add(span);
|
||||
animAddingSpans.clear();
|
||||
animRemovingSpans.clear();
|
||||
animAddingSpans.add(span);
|
||||
animators.clear();
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.SCALE_X, 1.0f, 0.01f));
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.SCALE_Y, 1.0f, 0.01f));
|
||||
|
@ -3022,10 +3078,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
toDelete.get(i).setOnClickListener(null);
|
||||
}
|
||||
|
||||
if (currentAnimation != null) {
|
||||
currentAnimation.setupEndValues();
|
||||
currentAnimation.cancel();
|
||||
}
|
||||
setupEndValues();
|
||||
if (animated) {
|
||||
animationStarted = false;
|
||||
currentAnimation = new AnimatorSet();
|
||||
|
@ -3046,14 +3099,18 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
});
|
||||
animators.clear();
|
||||
animAddingSpans.clear();
|
||||
animRemovingSpans.clear();
|
||||
for (int i = 0; i < toDelete.size(); ++i) {
|
||||
GroupCreateSpan span = toDelete.get(i);
|
||||
animRemovingSpans.add(span);
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.SCALE_X, 1.0f, 0.01f));
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.SCALE_Y, 1.0f, 0.01f));
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.ALPHA, 1.0f, 0.0f));
|
||||
}
|
||||
for (int i = 0; i < toAdd.size(); ++i) {
|
||||
GroupCreateSpan addingSpan = toAdd.get(i);
|
||||
animAddingSpans.add(addingSpan);
|
||||
animators.add(ObjectAnimator.ofFloat(addingSpan, View.SCALE_X, 0.01f, 1.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(addingSpan, View.SCALE_Y, 0.01f, 1.0f));
|
||||
animators.add(ObjectAnimator.ofFloat(addingSpan, View.ALPHA, 0.0f, 1.0f));
|
||||
|
@ -3086,10 +3143,7 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
spans.get(i).setOnClickListener(null);
|
||||
}
|
||||
|
||||
if (currentAnimation != null) {
|
||||
currentAnimation.setupEndValues();
|
||||
currentAnimation.cancel();
|
||||
}
|
||||
setupEndValues();
|
||||
if (animated) {
|
||||
animationStarted = false;
|
||||
currentAnimation = new AnimatorSet();
|
||||
|
@ -3109,8 +3163,11 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
});
|
||||
animators.clear();
|
||||
animAddingSpans.clear();
|
||||
animRemovingSpans.clear();
|
||||
for (int i = 0; i < spans.size(); ++i) {
|
||||
GroupCreateSpan span = spans.get(i);
|
||||
animAddingSpans.add(span);
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.SCALE_X, 1.0f, 0.01f));
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.SCALE_Y, 1.0f, 0.01f));
|
||||
animators.add(ObjectAnimator.ofFloat(span, View.ALPHA, 1.0f, 0.0f));
|
||||
|
@ -3126,6 +3183,24 @@ public class StoryPrivacyBottomSheet extends BottomSheet implements Notification
|
|||
}
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
private void setupEndValues() {
|
||||
if (currentAnimation != null) {
|
||||
currentAnimation.cancel();
|
||||
}
|
||||
for (int i = 0; i < animAddingSpans.size(); ++i) {
|
||||
animAddingSpans.get(i).setScaleX(1f);
|
||||
animAddingSpans.get(i).setScaleY(1f);
|
||||
animAddingSpans.get(i).setAlpha(1f);
|
||||
}
|
||||
for (int i = 0; i < animRemovingSpans.size(); ++i) {
|
||||
animRemovingSpans.get(i).setScaleX(0f);
|
||||
animRemovingSpans.get(i).setScaleY(0f);
|
||||
animRemovingSpans.get(i).setAlpha(0f);
|
||||
}
|
||||
animAddingSpans.clear();
|
||||
animRemovingSpans.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1627,9 +1627,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
titleTextView.setRightPadding(AndroidUtilities.dp(96));
|
||||
actionBarContainer.addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 56, Gravity.TOP | Gravity.FILL_HORIZONTAL, 71, 0, 0, 0));
|
||||
|
||||
downloadButton = new DownloadButton(context, () -> {
|
||||
applyFilter();
|
||||
downloadButton = new DownloadButton(context, done -> {
|
||||
applyPaint(true);
|
||||
applyFilter(done);
|
||||
}, currentAccount, windowView, resourcesProvider);
|
||||
actionBarContainer.addView(downloadButton, LayoutHelper.createFrame(56, 56, Gravity.TOP | Gravity.RIGHT));
|
||||
|
||||
|
@ -1766,7 +1766,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
navbarContainer.addView(modeSwitcherView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL));
|
||||
|
||||
hintTextView = new HintTextView(context);
|
||||
navbarContainer.addView(hintTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 32, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 8, 0, 8, 8));
|
||||
navbarContainer.addView(hintTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 32, Gravity.CENTER, 8, 0, 8, 8));
|
||||
|
||||
previewButtons = new PreviewButtons(context);
|
||||
previewButtons.setVisibility(View.GONE);
|
||||
|
@ -1788,6 +1788,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
}
|
||||
if (outputEntry.isEdit) {
|
||||
outputEntry.editedPrivacy = false;
|
||||
applyFilter(null);
|
||||
upload(true);
|
||||
} else {
|
||||
previewView.updatePauseReason(3, true);
|
||||
|
@ -1805,9 +1806,6 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
return;
|
||||
}
|
||||
previewView.updatePauseReason(5, true);
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
outputEntry.privacy = privacy;
|
||||
StoryPrivacySelector.save(currentAccount, outputEntry.privacy);
|
||||
outputEntry.pinned = keepInProfile;
|
||||
|
@ -1815,7 +1813,10 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
outputEntry.privacyRules.clear();
|
||||
outputEntry.privacyRules.addAll(privacy.rules);
|
||||
outputEntry.editedPrivacy = true;
|
||||
upload(true);
|
||||
applyFilter(() -> {
|
||||
whenDone.run();
|
||||
upload(true);
|
||||
});
|
||||
}, false);
|
||||
privacySheet.setOnDismissListener(di -> {
|
||||
previewView.updatePauseReason(3, false);
|
||||
|
@ -1910,7 +1911,6 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
}
|
||||
|
||||
private void upload(boolean asStory) {
|
||||
applyFilter();
|
||||
applyPaint(true);
|
||||
if (outputEntry == null) {
|
||||
close(true);
|
||||
|
@ -2188,26 +2188,35 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
}
|
||||
outputFile = StoryEntry.makeCacheFile(currentAccount, true);
|
||||
CameraController.getInstance().recordVideo(cameraView.getCameraSession(), outputFile, false, (thumbPath, duration) -> {
|
||||
if (recordControl != null) {
|
||||
recordControl.stopRecordingLoading(true);
|
||||
}
|
||||
if (outputFile == null || cameraView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
takingVideo = false;
|
||||
stoppingTakingVideo = false;
|
||||
animateRecording(false, true);
|
||||
|
||||
if (duration <= 800) {
|
||||
animateRecording(false, true);
|
||||
setAwakeLock(false);
|
||||
videoTimerView.setRecording(false, true);
|
||||
if (recordControl != null) {
|
||||
recordControl.stopRecordingLoading(true);
|
||||
}
|
||||
try {
|
||||
outputFile.delete();
|
||||
outputFile = null;
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
try {
|
||||
new File(thumbPath).delete();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
if (thumbPath != null) {
|
||||
try {
|
||||
new File(thumbPath).delete();
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2223,17 +2232,19 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
outputEntry.height = height;
|
||||
outputEntry.setupMatrix();
|
||||
}
|
||||
|
||||
navigateToPreviewWithPlayerAwait(() -> navigateTo(PAGE_PREVIEW, true), 0);
|
||||
navigateToPreviewWithPlayerAwait(() -> {
|
||||
navigateTo(PAGE_PREVIEW, true);
|
||||
}, 0);
|
||||
}, () /* onVideoStart */ -> {
|
||||
whenStarted.run();
|
||||
|
||||
hintTextView.setText(byLongPress ? LocaleController.getString("StoryHintSwipeToZoom", R.string.StoryHintSwipeToZoom) : LocaleController.getString("StoryHintPinchToZoom", R.string.StoryHintPinchToZoom), false);
|
||||
animateRecording(true, true);
|
||||
setAwakeLock(true);
|
||||
|
||||
videoTimerView.setRecording(true, true);
|
||||
showVideoTimer(true, true);
|
||||
}, cameraView);
|
||||
}, cameraView, false);
|
||||
|
||||
if (!isVideo) {
|
||||
isVideo = true;
|
||||
|
@ -2267,8 +2278,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
AndroidUtilities.runOnUIThread(() -> {
|
||||
if (takingVideo && stoppingTakingVideo && cameraView != null) {
|
||||
showZoomControls(false, true);
|
||||
animateRecording(false, true);
|
||||
CameraController.getInstance().stopVideoRecording(cameraView.getCameraSessionRecording(), false);
|
||||
// animateRecording(false, true);
|
||||
// setAwakeLock(false);
|
||||
CameraController.getInstance().stopVideoRecording(cameraView.getCameraSessionRecording(), false, false);
|
||||
}
|
||||
}, byDuration ? 0 : 400);
|
||||
}
|
||||
|
@ -2311,6 +2323,19 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
}
|
||||
};
|
||||
|
||||
private void setAwakeLock(boolean lock) {
|
||||
if (lock) {
|
||||
windowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||
} else {
|
||||
windowLayoutParams.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||
}
|
||||
try {
|
||||
windowManager.updateViewLayout(windowView, windowLayoutParams);
|
||||
} catch (Exception e) {
|
||||
FileLog.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
private AnimatorSet recordingAnimator;
|
||||
private boolean animatedRecording;
|
||||
private void animateRecording(boolean recording, boolean animated) {
|
||||
|
@ -2343,18 +2368,20 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
recordingAnimator = new AnimatorSet();
|
||||
recordingAnimator.playTogether(
|
||||
ObjectAnimator.ofFloat(backButton, View.ALPHA, recording ? 0 : 1),
|
||||
ObjectAnimator.ofFloat(flashButton, View.ALPHA, recording ? 0 : 1),
|
||||
ObjectAnimator.ofFloat(dualButton, View.ALPHA, recording || cameraView == null || !cameraView.dualAvailable() ? 0 : 1),
|
||||
ObjectAnimator.ofFloat(hintTextView, View.ALPHA, recording ? 1 : 0),
|
||||
ObjectAnimator.ofFloat(hintTextView, View.TRANSLATION_Y, recording ? 0 : dp(16)),
|
||||
ObjectAnimator.ofFloat(modeSwitcherView, View.ALPHA, recording ? 0 : 1),
|
||||
ObjectAnimator.ofFloat(modeSwitcherView, View.TRANSLATION_Y, recording ? dp(16) : 0)
|
||||
ObjectAnimator.ofFloat(flashButton, View.ALPHA, recording || currentPage != PAGE_CAMERA ? 0 : 1),
|
||||
ObjectAnimator.ofFloat(dualButton, View.ALPHA, recording || currentPage != PAGE_CAMERA || cameraView == null || !cameraView.dualAvailable() ? 0 : 1),
|
||||
ObjectAnimator.ofFloat(hintTextView, View.ALPHA, recording && currentPage == PAGE_CAMERA ? 1 : 0),
|
||||
ObjectAnimator.ofFloat(hintTextView, View.TRANSLATION_Y, recording || currentPage != PAGE_CAMERA ? 0 : dp(16)),
|
||||
ObjectAnimator.ofFloat(modeSwitcherView, View.ALPHA, recording || currentPage != PAGE_CAMERA ? 0 : 1),
|
||||
ObjectAnimator.ofFloat(modeSwitcherView, View.TRANSLATION_Y, recording || currentPage != PAGE_CAMERA ? dp(16) : 0)
|
||||
);
|
||||
recordingAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (recording) {
|
||||
backButton.setVisibility(View.GONE);
|
||||
}
|
||||
if (recording || currentPage != PAGE_CAMERA) {
|
||||
flashButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
@ -2365,14 +2392,14 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
} else {
|
||||
backButton.setAlpha(recording ? 0 : 1f);
|
||||
backButton.setVisibility(recording ? View.GONE : View.VISIBLE);
|
||||
flashButton.setAlpha(recording ? 0 : 1f);
|
||||
flashButton.setVisibility(recording ? View.GONE : View.VISIBLE);
|
||||
dualButton.setAlpha(recording ? 0 : 1f);
|
||||
dualButton.setVisibility(recording || cameraView == null || !cameraView.dualAvailable() ? View.GONE : View.VISIBLE);
|
||||
hintTextView.setAlpha(recording ? 1f : 0);
|
||||
hintTextView.setTranslationY(recording ? 0 : dp(16));
|
||||
modeSwitcherView.setAlpha(recording ? 0 : 1f);
|
||||
modeSwitcherView.setTranslationY(recording ? dp(16) : 0);
|
||||
flashButton.setAlpha(recording || currentPage != PAGE_CAMERA ? 0 : 1f);
|
||||
flashButton.setVisibility(recording || currentPage != PAGE_CAMERA ? View.GONE : View.VISIBLE);
|
||||
dualButton.setAlpha(recording || currentPage != PAGE_CAMERA ? 0 : 1f);
|
||||
dualButton.setVisibility(recording || currentPage != PAGE_CAMERA || cameraView == null || !cameraView.dualAvailable() ? View.GONE : View.VISIBLE);
|
||||
hintTextView.setAlpha(recording && currentPage == PAGE_CAMERA ? 1f : 0);
|
||||
hintTextView.setTranslationY(recording || currentPage != PAGE_CAMERA ? 0 : dp(16));
|
||||
modeSwitcherView.setAlpha(recording || currentPage != PAGE_CAMERA ? 0 : 1f);
|
||||
modeSwitcherView.setTranslationY(recording || currentPage != PAGE_CAMERA ? dp(16) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2537,6 +2564,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
animators.add(ObjectAnimator.ofFloat(recordControl, View.TRANSLATION_Y, page == PAGE_CAMERA ? 0 : dp(24)));
|
||||
animators.add(ObjectAnimator.ofFloat(modeSwitcherView, View.ALPHA, page == PAGE_CAMERA ? 1 : 0));
|
||||
animators.add(ObjectAnimator.ofFloat(modeSwitcherView, View.TRANSLATION_Y, page == PAGE_CAMERA ? 0 : dp(24)));
|
||||
backButton.setVisibility(View.VISIBLE);
|
||||
animators.add(ObjectAnimator.ofFloat(backButton, View.ALPHA, 1));
|
||||
animators.add(ObjectAnimator.ofFloat(hintTextView, View.ALPHA, page == PAGE_CAMERA && animatedRecording ? 1 : 0));
|
||||
animators.add(ObjectAnimator.ofFloat(captionContainer, View.ALPHA, page == PAGE_PREVIEW ? 1f : 0));
|
||||
animators.add(ObjectAnimator.ofFloat(captionContainer, View.TRANSLATION_Y, page == PAGE_PREVIEW ? 0 : dp(12)));
|
||||
animators.add(ObjectAnimator.ofFloat(titleTextView, View.ALPHA, page == PAGE_PREVIEW ? 1f : 0));
|
||||
|
@ -2572,6 +2602,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
recordControl.setTranslationY(page == PAGE_CAMERA ? 0 : dp(16));
|
||||
modeSwitcherView.setAlpha(page == PAGE_CAMERA ? 1f : 0);
|
||||
modeSwitcherView.setTranslationY(page == PAGE_CAMERA ? 0 : dp(16));
|
||||
backButton.setVisibility(View.VISIBLE);
|
||||
backButton.setAlpha(1f);
|
||||
hintTextView.setAlpha(page == PAGE_CAMERA && animatedRecording ? 1f : 0);
|
||||
captionContainer.setAlpha(page == PAGE_PREVIEW ? 1f : 0);
|
||||
captionContainer.setTranslationY(page == PAGE_PREVIEW ? 0 : dp(12));
|
||||
muteButton.setAlpha(page == PAGE_PREVIEW && isVideo ? 1f : 0);
|
||||
|
@ -2886,6 +2919,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
if (toPage == PAGE_CAMERA) {
|
||||
requestCameraPermission(false);
|
||||
recordControl.setVisibility(View.VISIBLE);
|
||||
if (recordControl != null) {
|
||||
recordControl.stopRecordingLoading(false);
|
||||
}
|
||||
modeSwitcherView.setVisibility(View.VISIBLE);
|
||||
zoomControlView.setVisibility(View.VISIBLE);
|
||||
zoomControlView.setAlpha(0);
|
||||
|
@ -2994,6 +3030,8 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
zoomControlView.setVisibility(View.GONE);
|
||||
modeSwitcherView.setVisibility(View.GONE);
|
||||
dualButton.setVisibility(View.GONE);
|
||||
animateRecording(false, false);
|
||||
setAwakeLock(false);
|
||||
}
|
||||
cameraViewThumb.setClickable(toPage == PAGE_CAMERA);
|
||||
if (fromPage == PAGE_PREVIEW) {
|
||||
|
@ -3397,7 +3435,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
// privacySelectorHint.hide();
|
||||
Bulletin.hideVisible();
|
||||
if (photoFilterView != null && toMode == EDIT_MODE_FILTER) {
|
||||
applyFilter();
|
||||
applyFilter(null);
|
||||
}
|
||||
if (photoFilterEnhanceView != null) {
|
||||
photoFilterEnhanceView.setAllowTouch(false);
|
||||
|
@ -3459,14 +3497,16 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
outputEntry.paintFile = FileLoader.getInstance(currentAccount).getPathToAttach(size, true);
|
||||
}
|
||||
|
||||
private void applyFilter() {
|
||||
private void applyFilter(Runnable whenDone) {
|
||||
if (photoFilterView == null || outputEntry == null) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
outputEntry.editedMedia |= photoFilterView.hasChanges();
|
||||
outputEntry.updateFilter(photoFilterView);
|
||||
outputEntry.filterState = photoFilterView.getSavedFilterState();
|
||||
if (!outputEntry.isVideo) {
|
||||
outputEntry.updateFilter(photoFilterView, whenDone);
|
||||
if (whenDone == null && !outputEntry.isVideo && previewView != null) {
|
||||
previewView.set(outputEntry);
|
||||
}
|
||||
}
|
||||
|
@ -3474,16 +3514,14 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
// private Matrix photoFilterStartMatrix, photoFilterEndMatrix;
|
||||
|
||||
private void createFilterPhotoView() {
|
||||
if (photoFilterView != null) {
|
||||
if (photoFilterView != null || outputEntry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(outputEntry.file.getPath(), opts);
|
||||
StoryEntry.setupScale(opts, outputEntry.resultWidth, outputEntry.resultHeight);
|
||||
opts.inJustDecodeBounds = false;
|
||||
Bitmap photoBitmap = photoFilterBitmap = BitmapFactory.decodeFile(outputEntry.file.getPath(), opts);
|
||||
Bitmap photoBitmap = previewView.getPhotoBitmap();
|
||||
if (photoBitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
photoFilterView = new PhotoFilterView(activity, previewView.getTextureView(), photoBitmap, previewView.getOrientation(), outputEntry == null ? null : outputEntry.filterState, null, 0, false, false, resourcesProvider);
|
||||
containerView.addView(photoFilterView);
|
||||
|
@ -3491,6 +3529,9 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
photoFilterEnhanceView.setFilterView(photoFilterView);
|
||||
}
|
||||
photoFilterViewTextureView = photoFilterView.getMyTextureView();
|
||||
if (photoFilterViewTextureView != null) {
|
||||
photoFilterViewTextureView.setOpaque(false);
|
||||
}
|
||||
previewView.setFilterTextureView(photoFilterViewTextureView);
|
||||
if (photoFilterViewTextureView != null) {
|
||||
photoFilterViewTextureView.setAlpha(0f);
|
||||
|
@ -3508,7 +3549,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
orderPreviewViews();
|
||||
|
||||
photoFilterView.getDoneTextView().setOnClickListener(v -> {
|
||||
applyFilter();
|
||||
applyFilter(null);
|
||||
switchToEditMode(EDIT_MODE_NONE, true);
|
||||
});
|
||||
photoFilterView.getCancelTextView().setOnClickListener(v -> {
|
||||
|
@ -3782,7 +3823,7 @@ public class StoryRecorder implements NotificationCenter.NotificationCenterDeleg
|
|||
return;
|
||||
}
|
||||
showSavedDraftHint = !outputEntry.isDraft;
|
||||
applyFilter();
|
||||
applyFilter(null);
|
||||
applyPaint(false);
|
||||
destroyPhotoFilterView();
|
||||
StoryEntry storyEntry = outputEntry;
|
||||
|
|
|
@ -15,20 +15,46 @@ uniform float blur;
|
|||
float modI(float a,float b) {
|
||||
return floor(a-floor((a+0.5)/b)*b+0.5);
|
||||
}
|
||||
bool eq(float a, float b) {
|
||||
return abs(a - b) < .1;
|
||||
}
|
||||
bool eq(float a, float b, float b2) {
|
||||
return abs(a - b) < .1 || abs(a - b2) < .1;
|
||||
}
|
||||
float box(vec2 position, vec2 halfSize, float cornerRadius) {
|
||||
position = abs(position) - halfSize + cornerRadius;
|
||||
return length(max(position, 0.0)) + min(max(position.x, position.y), 0.0) - cornerRadius;
|
||||
}
|
||||
float star(in vec2 p, in float r) {
|
||||
const vec2 acs = vec2(.9659258, .258819);
|
||||
const vec2 ecs = vec2(.8090169, .5877852);
|
||||
float bn = mod(atan(p.x,p.y),.52359876)-.26179938;
|
||||
p = length(p)*vec2(cos(bn),abs(sin(bn))) - r*acs;
|
||||
p += ecs*clamp( -dot(p,ecs), 0.0, r*acs.y/ecs.y);
|
||||
return length(p)*sign(p.x);
|
||||
}
|
||||
float opSmoothUnion(float d1, float d2, float k) {
|
||||
float h = max(k-abs(d1-d2),0.0);
|
||||
return min(d1, d2) - h*h*0.25/k;
|
||||
}
|
||||
float scene() {
|
||||
vec2 p = (uv - vec2(.5)) * vec2(1., pixelWH.x / pixelWH.y);
|
||||
vec2 r = .5 * vec2(1., pixelWH.x / pixelWH.y) * scale;
|
||||
float R = min(r.x, r.y), rr = roundRadius / pixelWH.y;
|
||||
float a = modI(shapeFrom, 3.), b = modI(shapeTo, 3.);
|
||||
return box(
|
||||
float boxSDF = box(
|
||||
p,
|
||||
mix(abs(a-2.)<.1 ? r : vec2(R), abs(b-2.)<.1 ? r : vec2(R), shapeT),
|
||||
mix(abs(a)<.1 ? R : rr, abs(b)<.1 ? R : rr, shapeT)
|
||||
mix(eq(a, 2.) ? r : vec2(R), eq(b, 2.) ? r : vec2(R), shapeT),
|
||||
mix(eq(a, 0., 3.) ? R : rr, eq(b, 0., 3.) ? R : rr, shapeT)
|
||||
) * pixelWH.x;
|
||||
if (eq(3., a, b)) {
|
||||
float starSDF = opSmoothUnion(box(p, vec2(R * .78), R), star(p, R * .78), .25) * pixelWH.x;
|
||||
float starA = eq(a, 3.) ? 1. - shapeT : 0.;
|
||||
float starB = eq(b, 3.) ? shapeT : 0.;
|
||||
return mix(boxSDF, starSDF, starA + starB);
|
||||
} else {
|
||||
return boxSDF;
|
||||
}
|
||||
}
|
||||
vec4 makeblur() {
|
||||
vec2 S = 4. * vec2(1., pixelWH.x / pixelWH.y);
|
||||
|
|
|
@ -7003,4 +7003,6 @@
|
|||
<string name="StoriesPremiumHint">Posting stories is currently available only to subscribers of **Telegram Premium**.</string>
|
||||
<string name="ArchivePeerStories">Hide Stories</string>
|
||||
<string name="UnarchiveStories">Unhide Stories</string>
|
||||
<string name="GroupTooLarge">Group Too Large</string>
|
||||
<string name="GroupTooLargeMessage">You can select groups that are up to 200 members.</string>
|
||||
</resources>
|
||||
|
|
|
@ -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=3705
|
||||
APP_VERSION_NAME=9.7.2
|
||||
APP_VERSION_CODE=3712
|
||||
APP_VERSION_NAME=9.7.4
|
||||
APP_PACKAGE=org.telegram.messenger
|
||||
RELEASE_KEY_PASSWORD=android
|
||||
RELEASE_KEY_ALIAS=androidkey
|
||||
|
|
Loading…
Reference in a new issue