From f7d3faab5aa9064bc6e705fe990296f172415ac2 Mon Sep 17 00:00:00 2001 From: DrKLO Date: Tue, 30 Sep 2014 02:48:11 +0400 Subject: [PATCH] Service for video encoding, update locales, bug fixes --- TMessagesProj/build.gradle | 2 +- TMessagesProj/src/main/AndroidManifest.xml | 1 + .../telegram/android/AndroidUtilities.java | 20 +- .../org/telegram/android/ImageLoader.java | 109 ++++++---- .../org/telegram/android/MediaController.java | 114 +++++++--- .../org/telegram/android/MessageObject.java | 2 +- .../telegram/android/MessagesController.java | 31 --- .../org/telegram/android/MessagesStorage.java | 18 +- .../telegram/android/NotificationCenter.java | 1 + .../android/NotificationsController.java | 9 +- .../telegram/android/SendMessagesHelper.java | 204 +++++++++--------- .../android/VideoEncodingService.java | 84 ++++++++ .../telegram/android/video/OutputSurface.java | 6 +- .../android/video/TextureRenderer.java | 7 +- .../messenger/ConnectionsManager.java | 25 +++ .../telegram/messenger/FileLoadOperation.java | 38 ++-- .../org/telegram/messenger/FileLoader.java | 147 ++++++------- .../org/telegram/messenger/RPCRequest.java | 2 + .../org/telegram/ui/Cells/ChatMediaCell.java | 20 +- .../java/org/telegram/ui/ChatActivity.java | 85 +++++--- .../telegram/ui/DocumentSelectActivity.java | 55 ++++- .../java/org/telegram/ui/LaunchActivity.java | 60 ++++-- .../org/telegram/ui/MessagesActivity.java | 16 +- .../java/org/telegram/ui/PhotoViewer.java | 27 ++- .../ui/PopupNotificationActivity.java | 2 +- .../org/telegram/ui/VideoEditorActivity.java | 121 +++++++---- .../ui/Views/ActionBar/ActionBarLayout.java | 10 +- .../ui/Views/ChatActivityEnterView.java | 2 - .../telegram/ui/Views/TypingDotsDrawable.java | 3 + .../src/main/res/layout/chat_layout.xml | 4 +- .../main/res/layout/video_editor_layout.xml | 13 +- .../src/main/res/values-ar/strings.xml | 1 + .../src/main/res/values-de/strings.xml | 17 +- .../src/main/res/values-es/strings.xml | 141 ++++++------ .../src/main/res/values-it/strings.xml | 1 + .../src/main/res/values-nl/strings.xml | 33 +-- .../src/main/res/values-pt-rBR/strings.xml | 15 +- .../src/main/res/values-pt-rPT/strings.xml | 1 + TMessagesProj/src/main/res/values/strings.xml | 11 +- 39 files changed, 913 insertions(+), 545 deletions(-) create mode 100644 TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 88d655bfc..ca6704008 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -80,7 +80,7 @@ android { defaultConfig { minSdkVersion 8 targetSdkVersion 19 - versionCode 332 + versionCode 335 versionName "1.9.0" } } diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index d8ee6d5e8..f7bfaaa0c 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -138,6 +138,7 @@ + diff --git a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java index cc8a2439c..9f9431299 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java +++ b/TMessagesProj/src/main/java/org/telegram/android/AndroidUtilities.java @@ -41,8 +41,8 @@ public class AndroidUtilities { public static int statusBarHeight = 0; public static float density = 1; public static Point displaySize = new Point(); + public static Integer photoSize = null; private static Boolean isTablet = null; - private static Boolean isSmallTablet = null; public static int[] arrColors = {0xffee4928, 0xff41a903, 0xffe09602, 0xff0f94ed, 0xff8f3bf7, 0xfffc4380, 0xff00a1c4, 0xffeb7002}; public static int[] arrUsersAvatars = { @@ -277,11 +277,8 @@ public class AndroidUtilities { } public static boolean isSmallTablet() { - if (isSmallTablet == null) { - float minSide = Math.min(displaySize.x, displaySize.y) / density; - isSmallTablet = minSide <= 700; - } - return isSmallTablet; + float minSide = Math.min(displaySize.x, displaySize.y) / density; + return minSide <= 700; } public static int getMinTabletSide() { @@ -354,4 +351,15 @@ public class AndroidUtilities { public static int getBroadcastAvatarForId(int id) { return arrBroadcastAvatars[getColorIndex(-Math.abs(id))]; } + + public static int getPhotoSize() { + if (photoSize == null) { + if (Build.VERSION.SDK_INT >= 16) { + photoSize = 1280; + } else { + photoSize = 800; + } + } + return photoSize; + } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java index 22cc116ab..d1e2b1b99 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/android/ImageLoader.java @@ -64,6 +64,8 @@ public class ImageLoader { private int lastImageNum = 0; private long lastProgressUpdateTime = 0; + private File telegramPath = null; + private class HttpTask extends AsyncTask { private CacheImage cacheImage = null; @@ -548,6 +550,13 @@ public class ImageLoader { AndroidUtilities.RunOnUIThread(new Runnable() { @Override public void run() { + if (location != null) { + if (telegramPath != null && finalFile != null && finalFile.exists() && location.endsWith(".mp4") || location.endsWith(".jpg")) { + if (finalFile.toString().startsWith(telegramPath.toString())) { + Utilities.addMediaToGallery(finalFile.toString()); + } + } + } ImageLoader.this.fileDidLoaded(location, finalFile, tempFile); NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidLoaded, location); } @@ -555,12 +564,12 @@ public class ImageLoader { } @Override - public void fileDidFailedLoad(final String location, final boolean canceled) { + public void fileDidFailedLoad(final String location, final int state) { AndroidUtilities.RunOnUIThread(new Runnable() { @Override public void run() { ImageLoader.this.fileDidFailedLoad(location); - NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidFailedLoad, location, canceled); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidFailedLoad, location, state); } }); } @@ -597,14 +606,14 @@ public class ImageLoader { try { if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { - File telegramPath = new File(Environment.getExternalStorageDirectory(), LocaleController.getString("AppName", R.string.AppName)); + telegramPath = new File(Environment.getExternalStorageDirectory(), LocaleController.getString("AppName", R.string.AppName)); telegramPath.mkdirs(); if (telegramPath.isDirectory()) { try { - File imagePath = new File(telegramPath, "Images"); + File imagePath = new File(telegramPath, LocaleController.getString("AppName", R.string.AppName) + " Images"); imagePath.mkdir(); if (imagePath.isDirectory()) { - new File(imagePath, ".nomedia").createNewFile(); + //new File(imagePath, ".nomedia").delete(); mediaDirs.put(FileLoader.MEDIA_DIR_IMAGE, imagePath); } } catch (Exception e) { @@ -612,10 +621,10 @@ public class ImageLoader { } try { - File videoPath = new File(telegramPath, "Video"); + File videoPath = new File(telegramPath, LocaleController.getString("AppName", R.string.AppName) + " Video"); videoPath.mkdir(); if (videoPath.isDirectory()) { - new File(videoPath, ".nomedia").createNewFile(); + //new File(videoPath, ".nomedia").delete(); mediaDirs.put(FileLoader.MEDIA_DIR_VIDEO, videoPath); } } catch (Exception e) { @@ -623,7 +632,7 @@ public class ImageLoader { } try { - File audioPath = new File(telegramPath, "Audio"); + File audioPath = new File(telegramPath, LocaleController.getString("AppName", R.string.AppName) + " Audio"); audioPath.mkdir(); if (audioPath.isDirectory()) { new File(audioPath, ".nomedia").createNewFile(); @@ -634,7 +643,7 @@ public class ImageLoader { } try { - File documentPath = new File(telegramPath, "Documents"); + File documentPath = new File(telegramPath, LocaleController.getString("AppName", R.string.AppName) + " Documents"); documentPath.mkdir(); if (documentPath.isDirectory()) { new File(documentPath, ".nomedia").createNewFile(); @@ -1041,22 +1050,7 @@ public class ImageLoader { return b; } - public static TLRPC.PhotoSize scaleAndSaveImage(Bitmap bitmap, float maxWidth, float maxHeight, int quality, boolean cache) { - if (bitmap == null) { - return null; - } - float photoW = bitmap.getWidth(); - float photoH = bitmap.getHeight(); - if (photoW == 0 || photoH == 0) { - return null; - } - float scaleFactor = Math.max(photoW / maxWidth, photoH / maxHeight); - int w = (int)(photoW / scaleFactor); - int h = (int)(photoH / scaleFactor); - if (h == 0 || w == 0) { - return null; - } - + private static TLRPC.PhotoSize scaleAndSaveImageInternal(Bitmap bitmap, int w, int h, float photoW, float photoH, float scaleFactor, int quality, boolean cache) throws Exception { Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, w, h, true); TLRPC.TL_fileLocation location = new TLRPC.TL_fileLocation(); @@ -1073,25 +1067,54 @@ public class ImageLoader { size.location = location; size.w = (int)(photoW / scaleFactor); size.h = (int)(photoH / scaleFactor); - try { - if (!cache) { - String fileName = location.volume_id + "_" + location.local_id + ".jpg"; - final File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); - FileOutputStream stream = new FileOutputStream(cacheFile); - scaledBitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream); - size.size = (int)stream.getChannel().size(); - } else { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - scaledBitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream); - size.bytes = stream.toByteArray(); - size.size = size.bytes.length; - } - if (scaledBitmap != bitmap) { - scaledBitmap.recycle(); - } - return size; - } catch (Throwable e) { + + if (!cache) { + String fileName = location.volume_id + "_" + location.local_id + ".jpg"; + final File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); + FileOutputStream stream = new FileOutputStream(cacheFile); + scaledBitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream); + size.size = (int)stream.getChannel().size(); + } else { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + scaledBitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream); + size.bytes = stream.toByteArray(); + size.size = size.bytes.length; + } + if (scaledBitmap != bitmap) { + scaledBitmap.recycle(); + } + + return size; + } + + public static TLRPC.PhotoSize scaleAndSaveImage(Bitmap bitmap, float maxWidth, float maxHeight, int quality, boolean cache) { + if (bitmap == null) { return null; } + float photoW = bitmap.getWidth(); + float photoH = bitmap.getHeight(); + if (photoW == 0 || photoH == 0) { + return null; + } + float scaleFactor = Math.max(photoW / maxWidth, photoH / maxHeight); + int w = (int)(photoW / scaleFactor); + int h = (int)(photoH / scaleFactor); + if (h == 0 || w == 0) { + return null; + } + + try { + return scaleAndSaveImageInternal(bitmap, w, h, photoW, photoH, scaleFactor, quality, cache); + } catch (Throwable e) { + FileLog.e("tmessages", e); + ImageLoader.getInstance().clearMemory(); + System.gc(); + try { + return scaleAndSaveImageInternal(bitmap, w, h, photoW, photoH, scaleFactor, quality, cache); + } catch (Throwable e2) { + FileLog.e("tmessages", e2); + return null; + } + } } } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java index ac698b962..3202d64ab 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MediaController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MediaController.java @@ -148,6 +148,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel private final static int PROCESSOR_TYPE_OTHER = 0; private final static int PROCESSOR_TYPE_QCOM = 1; private final static int PROCESSOR_TYPE_INTEL = 2; + private final static int PROCESSOR_TYPE_MTK = 3; + private final static int PROCESSOR_TYPE_SEC = 4; + private final static int PROCESSOR_TYPE_TI = 5; private final Object videoConvertSync = new Object(); private ArrayList videoConvertQueue = new ArrayList(); @@ -490,6 +493,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel documentDownloadQueue.clear(); videoDownloadQueue.clear(); downloadQueueKeys.clear(); + videoConvertQueue.clear(); + cancelVideoConvert(null); } protected int getAutodownloadMask() { @@ -615,9 +620,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } else if (downloadObject.object instanceof TLRPC.PhotoSize) { FileLoader.getInstance().loadFile((TLRPC.PhotoSize)downloadObject.object, false); } else if (downloadObject.object instanceof TLRPC.Video) { - FileLoader.getInstance().loadFile((TLRPC.Video)downloadObject.object); + FileLoader.getInstance().loadFile((TLRPC.Video)downloadObject.object, false); } else if (downloadObject.object instanceof TLRPC.Document) { - FileLoader.getInstance().loadFile((TLRPC.Document)downloadObject.object); + FileLoader.getInstance().loadFile((TLRPC.Document)downloadObject.object, false); } else { added = false; } @@ -644,12 +649,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } } - private void checkDownloadFinished(String fileName, boolean canceled) { + private void checkDownloadFinished(String fileName, int state) { DownloadObject downloadObject = downloadQueueKeys.get(fileName); if (downloadObject != null) { downloadQueueKeys.remove(fileName); - if (!canceled) { - MessagesStorage.getInstance().removeFromDownloadQueue(downloadObject.id, downloadObject.type); + if (state == 0 || state == 2) { + MessagesStorage.getInstance().removeFromDownloadQueue(downloadObject.id, downloadObject.type, state != 0); } if (downloadObject.type == AUTODOWNLOAD_MASK_PHOTO) { photoDownloadQueue.remove(downloadObject); @@ -907,7 +912,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } listenerInProgress = false; processLaterArrays(); - checkDownloadFinished(fileName, (Boolean)args[1]); + checkDownloadFinished(fileName, (Integer)args[1]); } else if (id == NotificationCenter.FileDidLoaded) { listenerInProgress = true; String fileName = (String)args[0]; @@ -923,7 +928,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } listenerInProgress = false; processLaterArrays(); - checkDownloadFinished(fileName, false); + checkDownloadFinished(fileName, 0); } else if (id == NotificationCenter.FileLoadProgressChanged) { listenerInProgress = true; String fileName = (String)args[0]; @@ -939,7 +944,6 @@ public class MediaController implements NotificationCenter.NotificationCenterDel listenerInProgress = false; processLaterArrays(); } else if (id == NotificationCenter.FileUploadProgressChanged) { - String location = (String)args[0]; listenerInProgress = true; String fileName = (String)args[0]; ArrayList> arrayList = loadingFileObservers.get(fileName); @@ -1523,8 +1527,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel }); } - public static void saveFile(String path, String fullPath, Context context, final int type, final String name) { - if (path == null && fullPath == null) { + public static void saveFile(String fullPath, Context context, final int type, final String name) { + if (fullPath == null) { return; } @@ -1535,8 +1539,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel file = null; } } + if (file == null) { - file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), path); + return; } final File sourceFile = file; @@ -1868,19 +1873,31 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } public void cancelVideoConvert(MessageObject messageObject) { - if (!videoConvertQueue.isEmpty()) { - if (videoConvertQueue.get(0) == messageObject) { - synchronized (videoConvertSync) { - cancelCurrentVideoConversion = true; - } + if (messageObject == null) { + synchronized (videoConvertSync) { + cancelCurrentVideoConversion = true; + } + } else { + if (!videoConvertQueue.isEmpty()) { + if (videoConvertQueue.get(0) == messageObject) { + synchronized (videoConvertSync) { + cancelCurrentVideoConversion = true; + } + } + videoConvertQueue.remove(messageObject); } - videoConvertQueue.remove(messageObject); } } private void startVideoConvertFromQueue() { if (!videoConvertQueue.isEmpty()) { + synchronized (videoConvertSync) { + cancelCurrentVideoConversion = false; + } MessageObject messageObject = videoConvertQueue.get(0); + Intent intent = new Intent(ApplicationLoader.applicationContext, VideoEncodingService.class); + intent.putExtra("path", messageObject.messageOwner.attachPath); + ApplicationLoader.applicationContext.startService(intent); VideoConvertRunnable.runConversion(messageObject); } } @@ -1897,7 +1914,11 @@ public class MediaController implements NotificationCenter.NotificationCenterDel for (String type : types) { if (type.equalsIgnoreCase(mimeType)) { lastCodecInfo = codecInfo; - FileLog.e("tmessages", "available codec = " + codecInfo.getName()); + if (!lastCodecInfo.getName().equals("OMX.SEC.avc.enc")) { + return lastCodecInfo; + } else if (lastCodecInfo.getName().equals("OMX.SEC.AVC.Encoder")) { + return lastCodecInfo; + } } } } @@ -1919,13 +1940,17 @@ public class MediaController implements NotificationCenter.NotificationCenterDel private static int selectColorFormat(MediaCodecInfo codecInfo, String mimeType) { MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType); + int lastColorFormat = 0; for (int i = 0; i < capabilities.colorFormats.length; i++) { int colorFormat = capabilities.colorFormats[i]; if (isRecognizedFormat(colorFormat)) { - return colorFormat; + lastColorFormat = colorFormat; + if (!(codecInfo.getName().equals("OMX.SEC.AVC.Encoder") && colorFormat == 19)) { + return colorFormat; + } } } - return 0; + return lastColorFormat; } @TargetApi(16) @@ -1963,7 +1988,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileNewChunkAvailable, messageObject, file.toString(), finalSize); } - if (finalSize != 0) { + if (error || finalSize != 0) { synchronized (videoConvertSync) { cancelCurrentVideoConversion = false; } @@ -2090,8 +2115,17 @@ public class MediaController implements NotificationCenter.NotificationCenterDel int originalWidth = messageObject.messageOwner.videoEditedInfo.originalWidth; int originalHeight = messageObject.messageOwner.videoEditedInfo.originalHeight; int bitrate = messageObject.messageOwner.videoEditedInfo.bitrate; + int rotateRender = 0; File cacheFile = new File(messageObject.messageOwner.attachPath); + if (Build.VERSION.SDK_INT < 18 && resultHeight > resultWidth && resultWidth != originalWidth && resultHeight != originalHeight) { + int temp = resultHeight; + resultHeight = resultWidth; + resultWidth = temp; + rotationValue = 90; + rotateRender = 270; + } + File inputFile = new File(videoPath); if (!inputFile.canRead()) { return false; @@ -2112,7 +2146,6 @@ public class MediaController implements NotificationCenter.NotificationCenterDel Mp4Movie movie = new Mp4Movie(); movie.setCacheFile(cacheFile); movie.setRotation(rotationValue); - resultHeight = 352; movie.setSize(resultWidth, resultHeight); mediaMuxer = new MP4Builder().createMovie(movie); extractor = new MediaExtractor(); @@ -2142,18 +2175,29 @@ public class MediaController implements NotificationCenter.NotificationCenterDel if (Build.VERSION.SDK_INT < 18) { MediaCodecInfo codecInfo = selectCodec(MIME_TYPE); colorFormat = selectColorFormat(codecInfo, MIME_TYPE); + if (colorFormat == 0) { + throw new RuntimeException("no supported color format"); + } String manufacturer = Build.MANUFACTURER.toLowerCase(); - if (codecInfo.getName().contains("OMX.qcom.")) { + String codecName = codecInfo.getName(); + if (codecName.contains("OMX.qcom.")) { processorType = PROCESSOR_TYPE_QCOM; if (Build.VERSION.SDK_INT == 16) { if (manufacturer.equals("lge") || manufacturer.equals("nokia")) { swapUV = 1; } } - } else if (codecInfo.getName().contains("OMX.Intel.")) { + } else if (codecName.contains("OMX.Intel.")) { processorType = PROCESSOR_TYPE_INTEL; + } else if (codecName.equals("OMX.MTK.VIDEO.ENCODER.AVC")) { + processorType = PROCESSOR_TYPE_MTK; + } else if (codecName.equals("OMX.SEC.AVC.Encoder")) { + processorType = PROCESSOR_TYPE_SEC; + swapUV = 1; + } else if (codecName.equals("OMX.TI.DUCATI1.VIDEO.H264E")) { + processorType = PROCESSOR_TYPE_TI; } - FileLog.e("tmessages", "codec = " + codecInfo.getName() + " manufacturer = " + manufacturer); + FileLog.e("tmessages", "codec = " + codecInfo.getName() + " manufacturer = " + manufacturer + "device = " + Build.MODEL); } else { colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface; } @@ -2174,8 +2218,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel padding = uvoffset - (resultWidth * resultHeight); bufferSize += padding; } - } else if (processorType == PROCESSOR_TYPE_INTEL) { - + } else if (processorType == PROCESSOR_TYPE_TI) { + //resultHeightAligned = 368; + //bufferSize = resultWidth * resultHeightAligned * 3 / 2; + //resultHeightAligned += (16 - (resultHeight % 16)); + //padding = resultWidth * (resultHeightAligned - resultHeight); + //bufferSize += padding * 5 / 4; } extractor.selectTrack(videoIndex); @@ -2192,8 +2240,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25); outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10); if (Build.VERSION.SDK_INT < 18) { - outputFormat.setInteger("stride", resultWidth); - outputFormat.setInteger("slice-height", resultHeightAligned); + outputFormat.setInteger("stride", resultWidth + 32); + outputFormat.setInteger("slice-height", resultHeight); } encoder = MediaCodec.createEncoderByType(MIME_TYPE); @@ -2208,7 +2256,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel if (Build.VERSION.SDK_INT >= 18) { outputSurface = new OutputSurface(); } else { - outputSurface = new OutputSurface(resultWidth, resultHeight); + outputSurface = new OutputSurface(resultWidth, resultHeight, rotateRender); } decoder.configure(inputFormat, outputSurface.getSurface(), null, 0); decoder.start(); @@ -2326,6 +2374,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { MediaFormat newFormat = decoder.getOutputFormat(); + FileLog.e("tmessages", "newFormat = " + newFormat); } else if (decoderStatus < 0) { throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus); } else { @@ -2399,6 +2448,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel } } catch (Exception e) { FileLog.e("tmessages", e); + error = true; } extractor.unselectTrack(videoIndex); @@ -2430,7 +2480,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel videoStartTime = videoTime; } } - readAndWriteTrack(messageObject, extractor, mediaMuxer, info, videoStartTime, endTime, cacheFile, true); + if (!error) { + readAndWriteTrack(messageObject, extractor, mediaMuxer, info, videoStartTime, endTime, cacheFile, true); + } } catch (Exception e) { error = true; FileLog.e("tmessages", e); diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index 67f56dcd3..76869f6f3 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -417,7 +417,7 @@ public class MessageObject { } else if (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { ArrayList sizes = messageOwner.media.photo.sizes; if (sizes.size() > 0) { - TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(sizes, 800, 800); + TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (sizeFull != null) { return FileLoader.getAttachFileName(sizeFull); } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index ee849f557..1860c1d36 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -1645,37 +1645,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } - public TLRPC.TL_photo generatePhotoSizes(String path, Uri imageUri) { - long time = System.currentTimeMillis(); - Bitmap bitmap = ImageLoader.loadBitmap(path, imageUri, 800, 800); - ArrayList sizes = new ArrayList(); - TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, true); - if (size != null) { - size.type = "s"; - sizes.add(size); - } - size = ImageLoader.scaleAndSaveImage(bitmap, 800, 800, 80, false); - if (size != null) { - size.type = "x"; - sizes.add(size); - } - if (bitmap != null) { - bitmap.recycle(); - } - if (sizes.isEmpty()) { - return null; - } else { - UserConfig.saveConfig(false); - TLRPC.TL_photo photo = new TLRPC.TL_photo(); - photo.user_id = UserConfig.getClientUserId(); - photo.date = ConnectionsManager.getInstance().getCurrentTime(); - photo.sizes = sizes; - photo.caption = ""; - photo.geo = new TLRPC.TL_geoPointEmpty(); - return photo; - } - } - public void markDialogAsRead(final long dialog_id, final int max_id, final int max_positive_id, final int offset, final int max_date, final boolean was, final boolean popup) { int lower_part = (int)dialog_id; int high_id = (int)(dialog_id >> 32); diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java index 17e2008e7..07b0e37d2 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesStorage.java @@ -2384,12 +2384,24 @@ public class MessagesStorage { } } - public void removeFromDownloadQueue(final long id, final int type) { + public void removeFromDownloadQueue(final long id, final int type, final boolean move) { storageQueue.postRunnable(new Runnable() { @Override public void run() { try { - database.executeFast(String.format(Locale.US, "DELETE FROM download_queue WHERE uid = %d AND type = %d", id, type)).stepThis().dispose(); + if (move) { + int minDate = -1; + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(date) FROM download_queue WHERE type = %d", type)); + if (cursor.next()) { + minDate = cursor.intValue(0); + } + cursor.dispose(); + if (minDate != -1) { + database.executeFast(String.format(Locale.US, "UPDATE download_queue SET date = %d WHERE uid = %d AND type = %d", minDate - 1, id, type)).stepThis().dispose(); + } + } else { + database.executeFast(String.format(Locale.US, "DELETE FROM download_queue WHERE uid = %d AND type = %d", id, type)).stepThis().dispose(); + } } catch (Exception e) { FileLog.e("tmessages", e); } @@ -2588,7 +2600,7 @@ public class MessagesStorage { } } else if (message.media instanceof TLRPC.TL_messageMediaPhoto) { if ((downloadMask & MediaController.AUTODOWNLOAD_MASK_PHOTO) != 0) { - TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(message.media.photo.sizes, 800, 800); + TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(message.media.photo.sizes, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (photoSize != null) { id = message.media.photo.id; type = MediaController.AUTODOWNLOAD_MASK_PHOTO; diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java index 32003f2dc..87298e130 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationCenter.java @@ -40,6 +40,7 @@ public class NotificationCenter { public static final int blockedUsersDidLoaded = 28; public static final int openedChatChanged = 29; public static final int hideEmojiKeyboard = 30; + public static final int stopEncodingService = 31; public static final int wallpapersDidLoaded = 171; public static final int closeOtherAppActivities = 702; diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java index 10e7c3b61..cc3327a4f 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java @@ -393,7 +393,8 @@ public class NotificationsController { String lastMessageFull = null; if (pushMessages.size() == 1) { String message = lastMessageFull = getStringForMessage(pushMessages.get(0), false); - lastMessage = getStringForMessage(pushMessages.get(0), true); + //lastMessage = getStringForMessage(pushMessages.get(0), true); + lastMessage = lastMessageFull; if (message == null) { return; } @@ -418,7 +419,8 @@ public class NotificationsController { } if (i == 0) { lastMessageFull = message; - lastMessage = getStringForMessage(pushMessages.get(i), true); + //lastMessage = getStringForMessage(pushMessages.get(i), true); + lastMessage = lastMessageFull; } if (pushDialogs.size() == 1) { if (replace) { @@ -444,6 +446,9 @@ public class NotificationsController { if (!notifyDisabled) { if (ApplicationLoader.mainInterfacePaused || inAppPreview) { + if (lastMessage.length() > 100) { + lastMessage = lastMessage.substring(0, 100).replace("\n", " ").trim() + "..."; + } mBuilder.setTicker(lastMessage); } if (choosenSoundPath != null && !choosenSoundPath.equals("NoSound")) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index 43e98c987..adedc4e9e 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -8,6 +8,9 @@ package org.telegram.android; +import android.graphics.Bitmap; +import android.net.Uri; + import org.telegram.messenger.BuffersStorage; import org.telegram.messenger.ByteBufferDesc; import org.telegram.messenger.ConnectionsManager; @@ -198,6 +201,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (message.obj == messageObject) { message.obj.messageOwner.videoEditedInfo = null; message.obj.messageOwner.message = "-1"; + message.obj.messageOwner.media.video.size = (int)finalSize; ArrayList messages = new ArrayList(); messages.add(message.obj.messageOwner); @@ -213,6 +217,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } else if (id == NotificationCenter.FilePreparingFailed) { MessageObject messageObject = (MessageObject)args[0]; String finalPath = (String)args[1]; + stopVideoService(messageObject.messageOwner.attachPath); ArrayList arr = delayedMessages.get(finalPath); if (arr != null) { @@ -949,6 +954,20 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } } + private void stopVideoService(final String path) { + MessagesStorage.getInstance().storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + AndroidUtilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.stopEncodingService, path); + } + }); + } + }); + } + private void performSendMessageRequest(final TLObject req, final MessageObject newMsgObj, final String originalPath) { ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override @@ -957,6 +976,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter final int oldId = newMsgObj.messageOwner.id; final boolean isBroadcast = req instanceof TLRPC.TL_messages_sendBroadcast; final ArrayList sentMessages = new ArrayList(); + final String attachPath = newMsgObj.messageOwner.attachPath; if (response instanceof TLRPC.messages_SentMessage) { TLRPC.messages_SentMessage res = (TLRPC.messages_SentMessage) response; @@ -1009,6 +1029,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter processSentMessage(oldId); } }); + if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { + stopVideoService(attachPath); + } } }); } else { @@ -1019,6 +1042,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id); processSentMessage(newMsgObj.messageOwner.id); + if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { + stopVideoService(newMsgObj.messageOwner.attachPath); + } } }); } @@ -1100,6 +1126,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter public void run(TLObject response, TLRPC.TL_error error) { if (newMsgObj != null) { if (error == null) { + final String attachPath = newMsgObj.messageOwner.attachPath; final TLRPC.messages_SentEncryptedMessage res = (TLRPC.messages_SentEncryptedMessage) response; newMsgObj.messageOwner.date = res.date; if (res.file instanceof TLRPC.TL_encryptedFile) { @@ -1115,6 +1142,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SENT; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageReceivedByServer, newMsgObj.messageOwner.id, newMsgObj.messageOwner.id, newMsgObj); processSentMessage(newMsgObj.messageOwner.id); + if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { + stopVideoService(attachPath); + } } }); } @@ -1127,6 +1157,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsgObj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR; NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, newMsgObj.messageOwner.id); processSentMessage(newMsgObj.messageOwner.id); + if (newMsgObj.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { + stopVideoService(newMsgObj.messageOwner.attachPath); + } } }); } @@ -1185,11 +1218,21 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter size2.location = size.location; } } + sentMessage.message = newMsg.message; - sentMessage.attachPath = newMsg.attachPath; newMsg.media.video.dc_id = sentMessage.media.video.dc_id; newMsg.media.video.id = sentMessage.media.video.id; newMsg.media.video.access_hash = sentMessage.media.video.access_hash; + + if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { + File cacheFile = new File(newMsg.attachPath); + File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.video); + if (!cacheFile.renameTo(cacheFile2)) { + sentMessage.attachPath = newMsg.attachPath; + } + } else { + sentMessage.attachPath = newMsg.attachPath; + } } else if (sentMessage.media instanceof TLRPC.TL_messageMediaDocument && sentMessage.media.document != null && newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) { MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.document, 1); @@ -1206,37 +1249,39 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter size2.location = size.location; } } + + newMsg.media.document.dc_id = sentMessage.media.document.dc_id; + newMsg.media.document.id = sentMessage.media.document.id; + newMsg.media.document.access_hash = sentMessage.media.document.access_hash; + if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { File cacheFile = new File(newMsg.attachPath); File cacheFile2 = FileLoader.getPathToAttach(sentMessage.media.document); - boolean result = cacheFile.renameTo(cacheFile2); - if (result) { - newMsg.attachPath = null; - } else { + if (!cacheFile.renameTo(cacheFile2)) { sentMessage.attachPath = newMsg.attachPath; sentMessage.message = newMsg.message; + } else { + newMsg.attachPath = ""; } } else { sentMessage.attachPath = newMsg.attachPath; sentMessage.message = newMsg.message; } - newMsg.media.document.dc_id = sentMessage.media.document.dc_id; - newMsg.media.document.id = sentMessage.media.document.id; - newMsg.media.document.access_hash = sentMessage.media.document.access_hash; } else if (sentMessage.media instanceof TLRPC.TL_messageMediaAudio && sentMessage.media.audio != null && newMsg.media instanceof TLRPC.TL_messageMediaAudio && newMsg.media.audio != null) { sentMessage.message = newMsg.message; - sentMessage.attachPath = newMsg.attachPath; String fileName = newMsg.media.audio.dc_id + "_" + newMsg.media.audio.id + ".ogg"; + newMsg.media.audio.dc_id = sentMessage.media.audio.dc_id; + newMsg.media.audio.id = sentMessage.media.audio.id; + newMsg.media.audio.access_hash = sentMessage.media.audio.access_hash; String fileName2 = sentMessage.media.audio.dc_id + "_" + sentMessage.media.audio.id + ".ogg"; if (!fileName.equals(fileName2)) { File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); File cacheFile2 = FileLoader.getPathToAttach(sentMessage.media.audio); - cacheFile.renameTo(cacheFile2); + if (!cacheFile.renameTo(cacheFile2)) { + sentMessage.attachPath = newMsg.attachPath; + } } - newMsg.media.audio.dc_id = sentMessage.media.audio.dc_id; - newMsg.media.audio.id = sentMessage.media.audio.id; - newMsg.media.audio.access_hash = sentMessage.media.audio.access_hash; } } else if (file != null) { if (newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) { @@ -1252,7 +1297,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter String fileName2 = size.location.volume_id + "_" + size.location.local_id; File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg"); File cacheFile2 = FileLoader.getPathToAttach(size); - boolean result = cacheFile.renameTo(cacheFile2); + cacheFile.renameTo(cacheFile2); ImageLoader.getInstance().replaceImageInCache(fileName, fileName2); ArrayList arr = new ArrayList(); arr.add(newMsg); @@ -1276,6 +1321,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsg.media.video.key = decryptedMessage.media.key; newMsg.media.video.iv = decryptedMessage.media.iv; newMsg.media.video.mime_type = video.mime_type; + + if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { + File cacheFile = new File(newMsg.attachPath); + File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.video); + if (cacheFile.renameTo(cacheFile2)) { + newMsg.attachPath = ""; + } + } + ArrayList arr = new ArrayList(); arr.add(newMsg); MessagesStorage.getInstance().putMessages(arr, false, true, false, 0); @@ -1299,7 +1353,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) { File cacheFile = new File(newMsg.attachPath); File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.document); - cacheFile.renameTo(cacheFile2); + if (cacheFile.renameTo(cacheFile2)) { + newMsg.attachPath = ""; + } } ArrayList arr = new ArrayList(); @@ -1326,7 +1382,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (!fileName.equals(fileName2)) { File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); File cacheFile2 = FileLoader.getPathToAttach(newMsg.media.audio); - cacheFile.renameTo(cacheFile2); + if (cacheFile.renameTo(cacheFile2)) { + newMsg.attachPath = ""; + } } ArrayList arr = new ArrayList(); @@ -1485,94 +1543,38 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter }); } - /* - private void startConvert() throws Exception { - IsoFile isoFile = new IsoFile(videoPath); - TrackBox trackBox = (TrackBox) Path.getPath(isoFile, "/moov/trak/mdia/minf/stbl/stsd/avc1/../../../../../"); - AvcConfigurationBox avcConfigurationBox = (AvcConfigurationBox) Path.getPath(trackBox, "mdia/minf/stbl/stsd/avc1/avcC"); - avcConfigurationBox.parseDetails(); - - Movie movie = MovieCreator.build(videoPath); - - List tracks = movie.getTracks(); - movie.setTracks(new LinkedList()); - - double startTime = 0; - double endTime = 0; - - for (Track track : tracks) { - if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) { - double duration = (double) track.getDuration() / (double) track.getTrackMetaData().getTimescale(); - startTime = correctTimeToSyncSample(track, videoTimelineView.getLeftProgress() * duration, false); - endTime = videoTimelineView.getRightProgress() * duration; - break; - } + public TLRPC.TL_photo generatePhotoSizes(String path, Uri imageUri) { + long time = System.currentTimeMillis(); + Bitmap bitmap = ImageLoader.loadBitmap(path, imageUri, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); + ArrayList sizes = new ArrayList(); + TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, true); + if (size != null) { + size.type = "s"; + sizes.add(size); } - - for (Track track : tracks) { - long currentSample = 0; - double currentTime = 0; - double lastTime = 0; - long startSample = 0; - long endSample = -1; - - for (int i = 0; i < track.getSampleDurations().length; i++) { - long delta = track.getSampleDurations()[i]; - if (currentTime > lastTime && currentTime <= startTime) { - startSample = currentSample; - } - if (currentTime > lastTime && currentTime <= endTime) { - endSample = currentSample; - } - lastTime = currentTime; - currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale(); - currentSample++; + size = ImageLoader.scaleAndSaveImage(bitmap, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize(), 80, false); + if (size != null) { + if (AndroidUtilities.getPhotoSize() == 800) { + size.type = "x"; + } else { + size.type = "y"; } - movie.addTrack(new CroppedTrack(track, startSample, endSample)); + sizes.add(size); } - Container out = new DefaultMp4Builder().build(movie); - - String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4"; - UserConfig.lastLocalId--; - File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName); - UserConfig.saveConfig(false); - - FileOutputStream fos = new FileOutputStream(cacheFile); - FileChannel fc = fos.getChannel(); - out.writeContainer(fc); - - fc.close(); - fos.close(); - if (delegate != null) { - //delegate.didFinishedVideoConverting(cacheFile.getAbsolutePath()); - finishFragment(); + if (bitmap != null) { + bitmap.recycle(); + } + if (sizes.isEmpty()) { + return null; + } else { + UserConfig.saveConfig(false); + TLRPC.TL_photo photo = new TLRPC.TL_photo(); + photo.user_id = UserConfig.getClientUserId(); + photo.date = ConnectionsManager.getInstance().getCurrentTime(); + photo.sizes = sizes; + photo.caption = ""; + photo.geo = new TLRPC.TL_geoPointEmpty(); + return photo; } } - - private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) { - double[] timeOfSyncSamples = new double[track.getSyncSamples().length]; - long currentSample = 0; - double currentTime = 0; - for (int i = 0; i < track.getSampleDurations().length; i++) { - long delta = track.getSampleDurations()[i]; - if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) { - timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime; - } - currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale(); - currentSample++; - } - double previous = 0; - for (double timeOfSyncSample : timeOfSyncSamples) { - if (timeOfSyncSample > cutHere) { - if (next) { - return timeOfSyncSample; - } else { - return previous; - } - } - previous = timeOfSyncSample; - } - return timeOfSyncSamples[timeOfSyncSamples.length - 1]; - } - */ } diff --git a/TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java b/TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java new file mode 100644 index 000000000..173570535 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/android/VideoEncodingService.java @@ -0,0 +1,84 @@ +/* + * This is the source code of Telegram for Android v. 1.7.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2014. + */ + +package org.telegram.android; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; + +import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; +import org.telegram.ui.ApplicationLoader; + +public class VideoEncodingService extends Service implements NotificationCenter.NotificationCenterDelegate { + + private NotificationCompat.Builder builder = null; + private String path = null; + private int currentProgress = 0; + + public VideoEncodingService() { + super(); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileUploadProgressChanged); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.stopEncodingService); + } + + public IBinder onBind(Intent arg2) { + return null; + } + + public void onDestroy() { + stopForeground(true); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.FileUploadProgressChanged); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.stopEncodingService); + FileLog.e("tmessages", "destroy video service"); + } + + @Override + public void didReceivedNotification(int id, Object... args) { + if (id == NotificationCenter.FileUploadProgressChanged) { + String fileName = (String)args[0]; + if (path.equals(fileName)) { + Float progress = (Float) args[1]; + Boolean enc = (Boolean) args[2]; + currentProgress = (int)(progress * 100); + builder.setProgress(100, currentProgress, currentProgress == 0); + NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build()); + } + } else if (id == NotificationCenter.stopEncodingService) { + String filepath = (String)args[0]; + if (filepath == null || filepath.equals(path)) { + stopSelf(); + } + } + } + + public int onStartCommand(Intent intent, int flags, int startId) { + path = intent.getStringExtra("path"); + if (path == null) { + stopSelf(); + return Service.START_NOT_STICKY; + } + FileLog.e("tmessages", "start video service"); + if (builder == null) { + builder = new NotificationCompat.Builder(ApplicationLoader.applicationContext); + builder.setSmallIcon(android.R.drawable.stat_sys_upload); + builder.setWhen(System.currentTimeMillis()); + builder.setContentTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setTicker(LocaleController.getString("SendingVideo", R.string.SendingVideo)); + builder.setContentText(LocaleController.getString("SendingVideo", R.string.SendingVideo)); + } + currentProgress = 0; + builder.setProgress(100, currentProgress, currentProgress == 0); + startForeground(4, builder.build()); + NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build()); + return Service.START_NOT_STICKY; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java b/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java index d01b7225a..c3e2d5fde 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/OutputSurface.java @@ -46,14 +46,16 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener { private TextureRenderer mTextureRender; private int mWidth; private int mHeight; + private int rotateRender = 0; private ByteBuffer mPixelBuf; - public OutputSurface(int width, int height) { + public OutputSurface(int width, int height, int rotate) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException(); } mWidth = width; mHeight = height; + rotateRender = rotate; mPixelBuf = ByteBuffer.allocateDirect(mWidth * mHeight * 4); mPixelBuf.order(ByteOrder.LITTLE_ENDIAN); eglSetup(width, height); @@ -66,7 +68,7 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener { } private void setup() { - mTextureRender = new TextureRenderer(); + mTextureRender = new TextureRenderer(rotateRender); mTextureRender.surfaceCreated(); mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId()); mSurfaceTexture.setOnFrameAvailableListener(this); diff --git a/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java b/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java index 550ced58c..9b29f40c1 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java +++ b/TMessagesProj/src/main/java/org/telegram/android/video/TextureRenderer.java @@ -69,8 +69,10 @@ public class TextureRenderer { private int muSTMatrixHandle; private int maPositionHandle; private int maTextureHandle; + private int rotationAngle = 0; - public TextureRenderer() { + public TextureRenderer(int rotation) { + rotationAngle = rotation; mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); mTriangleVertices.put(mTriangleVerticesData).position(0); Matrix.setIdentityM(mSTMatrix, 0); @@ -147,6 +149,9 @@ public class TextureRenderer { checkGlError("glTexParameter"); Matrix.setIdentityM(mMVPMatrix, 0); + if (rotationAngle != 0) { + Matrix.rotateM(mMVPMatrix, 0, rotationAngle, 0, 0, 1); + } } public void changeFragmentShader(String fragmentShader) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index e87e5d089..375934581 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -1116,6 +1116,30 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } request.retryCount++; + + if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) { + int retryMax = 10; + if ((request.flags & RPCRequest.RPCRequestClassForceDownload) == 0) { + if (request.wait) { + retryMax = 1; + } else { + retryMax = 3; + } + } + if (request.retryCount >= retryMax) { + FileLog.e("tmessages", "timed out " + request.rawRequest); + TLRPC.TL_error error = new TLRPC.TL_error(); + error.code = -123; + error.text = "RETRY_LIMIT"; + if (request.completionBlock != null) { + request.completionBlock.run(null, error); + } + runningRequests.remove(i); + i--; + continue; + } + } + NetworkMessage networkMessage = new NetworkMessage(); networkMessage.protoMessage = new TLRPC.TL_protoMessage(); @@ -2081,6 +2105,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. waitTime = Math.min(30, waitTime); discardResponse = true; + request.wait = true; request.runningMinStartTime = (int)(System.currentTimeMillis() / 1000 + waitTime); request.confirmed = false; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java index 583466a0a..364e21be2 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java @@ -52,10 +52,11 @@ public class FileLoadOperation { private RandomAccessFile fiv; private File storePath = null; private File tempPath = null; + private boolean isForceRequest = false; public static interface FileLoadOperationDelegate { public abstract void didFinishLoadingFile(FileLoadOperation operation, File finalFile, File tempFile); - public abstract void didFailedLoadingFile(FileLoadOperation operation, boolean canceled); + public abstract void didFailedLoadingFile(FileLoadOperation operation, int state); public abstract void didChangedLoadProgress(FileLoadOperation operation, float progress); } @@ -146,6 +147,14 @@ public class FileLoadOperation { } } + public void setForceRequest(boolean forceRequest) { + isForceRequest = forceRequest; + } + + public boolean isForceRequest() { + return isForceRequest; + } + public void setPaths(File store, File temp) { storePath = store; tempPath = temp; @@ -160,7 +169,7 @@ public class FileLoadOperation { Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } }); return; @@ -180,7 +189,7 @@ public class FileLoadOperation { Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } }); return; @@ -234,7 +243,7 @@ public class FileLoadOperation { Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } }); return; @@ -246,7 +255,7 @@ public class FileLoadOperation { try { onFinishLoadingFile(); } catch (Exception e) { - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } } else { startDownloadRequest(); @@ -257,7 +266,7 @@ public class FileLoadOperation { try { onFinishLoadingFile(); } catch (Exception e) { - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } } } @@ -276,7 +285,7 @@ public class FileLoadOperation { ConnectionsManager.getInstance().cancelRpc(requestInfo.requestToken, true, true); } } - delegate.didFailedLoadingFile(FileLoadOperation.this, true); + delegate.didFailedLoadingFile(FileLoadOperation.this, 1); } }); } @@ -374,7 +383,7 @@ public class FileLoadOperation { } } catch (Exception e) { cleanup(); - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); FileLog.e("tmessages", e); } } else { @@ -390,7 +399,7 @@ public class FileLoadOperation { } if (val == null) { cleanup(); - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } else { datacenter_id = val; nextDownloadOffset = 0; @@ -403,18 +412,21 @@ public class FileLoadOperation { } catch (Exception e) { FileLog.e("tmessages", e); cleanup(); - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } } else { cleanup(); - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } + } else if (error.text.contains("RETRY_LIMIT")) { + cleanup(); + delegate.didFailedLoadingFile(FileLoadOperation.this, 2); } else { if (location != null) { FileLog.e("tmessages", "" + location + " id = " + location.id + " access_hash = " + location.access_hash + " volume_id = " + location.local_id + " secret = " + location.secret); } cleanup(); - delegate.didFailedLoadingFile(FileLoadOperation.this, false); + delegate.didFailedLoadingFile(FileLoadOperation.this, 0); } } } @@ -448,7 +460,7 @@ public class FileLoadOperation { requestInfo.response = (TLRPC.TL_upload_file) response; processRequestResult(requestInfo, error); } - }, null, true, RPCRequest.RPCRequestClassDownloadMedia, datacenter_id, isLast); + }, null, true, RPCRequest.RPCRequestClassDownloadMedia | (isForceRequest ? RPCRequest.RPCRequestClassForceDownload : 0), datacenter_id, isLast); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index d88b48401..615fbc8d8 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -8,6 +8,8 @@ package org.telegram.messenger; +import org.telegram.android.AndroidUtilities; + import java.io.File; import java.util.ArrayList; import java.util.HashMap; @@ -22,7 +24,7 @@ public class FileLoader { public abstract void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile); public abstract void fileDidFailedUpload(String location, boolean isEncrypted); public abstract void fileDidLoaded(String location, File finalFile, File tempFile); - public abstract void fileDidFailedLoad(String location, boolean canceled); + public abstract void fileDidFailedLoad(String location, int state); public abstract void fileLoadProgressChanged(String location, float progress); } @@ -349,16 +351,16 @@ public class FileLoader { return result[0]; } - public void loadFile(TLRPC.Video video) { - loadFile(video, null, null, null, 0, false, video != null && video.key != null); + public void loadFile(TLRPC.Video video, boolean force) { + loadFile(video, null, null, null, 0, force, video != null && video.key != null); } public void loadFile(TLRPC.PhotoSize photo, boolean cacheOnly) { loadFile(null, null, null, photo.location, photo.size, false, cacheOnly || (photo != null && photo.size == 0 || photo.location.key != null)); } - public void loadFile(TLRPC.Document document) { - loadFile(null, document, null, null, 0, false, document != null && document.key != null); + public void loadFile(TLRPC.Document document, boolean force) { + loadFile(null, document, null, null, 0, force, document != null && document.key != null); } public void loadFile(TLRPC.Audio audio, boolean force) { @@ -404,6 +406,7 @@ public class FileLoader { if (index != -1) { downloadQueue.remove(index); downloadQueue.add(0, operation); + operation.setForceRequest(true); } } } @@ -444,80 +447,12 @@ public class FileLoader { if (delegate != null) { delegate.fileDidLoaded(arg1, finalFile, tempFile); } - fileLoaderQueue.postRunnable(new Runnable() { - @Override - public void run() { - loadOperationPaths.remove(arg1); - if (audio != null) { - currentAudioLoadOperationsCount--; - if (currentAudioLoadOperationsCount < 2) { - FileLoadOperation operation = audioLoadOperationQueue.poll(); - if (operation != null) { - currentAudioLoadOperationsCount++; - operation.start(); - } - } - } else if (location != null) { - currentPhotoLoadOperationsCount--; - if (currentPhotoLoadOperationsCount < 2) { - FileLoadOperation operation = photoLoadOperationQueue.poll(); - if (operation != null) { - currentPhotoLoadOperationsCount++; - operation.start(); - } - } - } else { - currentLoadOperationsCount--; - if (currentLoadOperationsCount < 2) { - FileLoadOperation operation = loadOperationQueue.poll(); - if (operation != null) { - currentLoadOperationsCount++; - operation.start(); - } - } - } - } - }); - fileProgresses.remove(arg1); + checkDownloadQueue(audio, location, arg1); } @Override - public void didFailedLoadingFile(FileLoadOperation operation, boolean canceled) { - fileLoaderQueue.postRunnable(new Runnable() { - @Override - public void run() { - loadOperationPaths.remove(arg1); - if (audio != null) { - currentAudioLoadOperationsCount--; - if (currentAudioLoadOperationsCount < 2) { - FileLoadOperation operation = audioLoadOperationQueue.poll(); - if (operation != null) { - currentAudioLoadOperationsCount++; - operation.start(); - } - } - } else if (location != null) { - currentPhotoLoadOperationsCount--; - if (currentPhotoLoadOperationsCount < 2) { - FileLoadOperation operation = photoLoadOperationQueue.poll(); - if (operation != null) { - currentPhotoLoadOperationsCount++; - operation.start(); - } - } - } else { - currentLoadOperationsCount--; - if (currentLoadOperationsCount < 2) { - FileLoadOperation operation = loadOperationQueue.poll(); - if (operation != null) { - currentLoadOperationsCount++; - operation.start(); - } - } - } - } - }); - fileProgresses.remove(arg1); + public void didFailedLoadingFile(FileLoadOperation operation, int canceled) { + checkDownloadQueue(audio, location, arg1); if (delegate != null) { delegate.fileDidFailedLoad(arg1, canceled); } @@ -531,8 +466,9 @@ public class FileLoader { } } }); + int maxCount = force ? 3 : 1; if (audio != null) { - if (currentAudioLoadOperationsCount < 2) { + if (currentAudioLoadOperationsCount < maxCount) { currentAudioLoadOperationsCount++; operation.start(); } else { @@ -543,7 +479,7 @@ public class FileLoader { } } } else if (location != null) { - if (currentPhotoLoadOperationsCount < 2) { + if (currentPhotoLoadOperationsCount < maxCount) { currentPhotoLoadOperationsCount++; operation.start(); } else { @@ -554,7 +490,7 @@ public class FileLoader { } } } else { - if (currentLoadOperationsCount < 2) { + if (currentLoadOperationsCount < maxCount) { currentLoadOperationsCount++; operation.start(); } else { @@ -569,6 +505,57 @@ public class FileLoader { }); } + private void checkDownloadQueue(final TLRPC.Audio audio, final TLRPC.FileLocation location, final String arg1) { + fileLoaderQueue.postRunnable(new Runnable() { + @Override + public void run() { + loadOperationPaths.remove(arg1); + FileLoadOperation operation = null; + if (audio != null) { + currentAudioLoadOperationsCount--; + if (!audioLoadOperationQueue.isEmpty()) { + operation = audioLoadOperationQueue.get(0); + int maxCount = operation.isForceRequest() ? 3 : 1; + if (currentAudioLoadOperationsCount < maxCount) { + operation = audioLoadOperationQueue.poll(); + if (operation != null) { + currentAudioLoadOperationsCount++; + operation.start(); + } + } + } + } else if (location != null) { + currentPhotoLoadOperationsCount--; + if (!photoLoadOperationQueue.isEmpty()) { + operation = photoLoadOperationQueue.get(0); + int maxCount = operation.isForceRequest() ? 3 : 1; + if (currentPhotoLoadOperationsCount < maxCount) { + operation = photoLoadOperationQueue.poll(); + if (operation != null) { + currentPhotoLoadOperationsCount++; + operation.start(); + } + } + } + } else { + currentLoadOperationsCount--; + if (!loadOperationQueue.isEmpty()) { + operation = loadOperationQueue.get(0); + int maxCount = operation.isForceRequest() ? 3 : 1; + if (currentLoadOperationsCount < maxCount) { + operation = loadOperationQueue.poll(); + if (operation != null) { + currentLoadOperationsCount++; + operation.start(); + } + } + } + } + } + }); + fileProgresses.remove(arg1); + } + public void setDelegate(FileLoaderDelegate delegate) { this.delegate = delegate; } @@ -586,7 +573,7 @@ public class FileLoader { } else if (message.media instanceof TLRPC.TL_messageMediaPhoto) { ArrayList sizes = message.media.photo.sizes; if (sizes.size() > 0) { - TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, 800, 800); + TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (sizeFull != null) { return getPathToAttach(sizeFull); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java index 35ef4d115..84fa468cb 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java @@ -27,6 +27,7 @@ public class RPCRequest { public static int RPCRequestClassPush = 64; public static int RPCRequestClassWithoutLogin = 128; public static int RPCRequestClassTryDifferentDc = 256; + public static int RPCRequestClassForceDownload = 512; static int RPCRequestClassTransportMask = (RPCRequestClassGeneric | RPCRequestClassDownloadMedia | RPCRequestClassUploadMedia); @@ -35,6 +36,7 @@ public class RPCRequest { int serverFailureCount; int flags; + boolean wait = false; protected int retryCount = 0; protected int lastResendTime = 0; protected boolean completed = false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java index 8036fec00..cf2dd2f9a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -314,10 +314,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD photoImage.setImage(currentPhotoObject.photoOwner.location, currentPhotoFilter, currentMessageObject.isOut() ? placeholderOutDrawable : placeholderInDrawable, currentPhotoObject.photoOwner.size); } } else if (currentMessageObject.type == 8 || currentMessageObject.type == 9) { - FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document); + FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document, true); lastDownloadedGifMessage = currentMessageObject; } else if (currentMessageObject.type == 3) { - FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.video); + FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.video, true); } progressVisible = true; startAnimation(); @@ -472,7 +472,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD photoWidth = AndroidUtilities.dp(86); photoHeight = AndroidUtilities.dp(86); backgroundWidth = photoWidth + Math.max(nameWidth, infoWidth) + AndroidUtilities.dp(68); - currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, 800, 800); + currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (currentPhotoObject != null) { if (currentPhotoObject.image != null) { photoImage.setImageBitmap(currentPhotoObject.image); @@ -500,14 +500,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } photoHeight = photoWidth + AndroidUtilities.dp(100); - if (photoWidth > 800) { - photoWidth = 800; + if (photoWidth > AndroidUtilities.getPhotoSize()) { + photoWidth = AndroidUtilities.getPhotoSize(); } - if (photoHeight > 800) { - photoHeight = 800; + if (photoHeight > AndroidUtilities.getPhotoSize()) { + photoHeight = AndroidUtilities.getPhotoSize(); } - currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, 800, 800); + currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (currentPhotoObject != null) { boolean noSize = false; if (currentMessageObject.type == 3 || currentMessageObject.type == 8) { @@ -515,6 +515,10 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD } float scale = (float) currentPhotoObject.photoOwner.w / (float) photoWidth; + if (!noSize && currentPhotoObject.photoOwner.size == 0) { + currentPhotoObject.photoOwner.size = -1; + } + int w = (int) (currentPhotoObject.photoOwner.w / scale); int h = (int) (currentPhotoObject.photoOwner.h / scale); if (w == 0) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index a250b4c12..eb617f9c1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -102,9 +102,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private boolean userBlocked = false; private View topPanel; - private View secretChatPlaceholder; private View progressView; - private TextView emptyView; private View bottomOverlay; private ChatAdapter chatAdapter; private ChatActivityEnterView chatActivityEnterView; @@ -115,6 +113,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not private TextView bottomOverlayChatText; private View bottomOverlayChat; private TypingDotsDrawable typingDotsDrawable; + private View emptyViewContainer; private TextView bottomOverlayText; @@ -343,6 +342,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not NotificationCenter.getInstance().addObserver(this, NotificationCenter.audioDidReset); NotificationCenter.getInstance().addObserver(this, NotificationCenter.screenshotTook); NotificationCenter.getInstance().addObserver(this, NotificationCenter.blockedUsersDidLoaded); + NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileNewChunkAvailable); super.onFragmentCreate(); @@ -353,7 +353,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (AndroidUtilities.isTablet()) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, dialog_id); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, false); } typingDotsDrawable = new TypingDotsDrawable(); @@ -387,8 +387,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not NotificationCenter.getInstance().removeObserver(this, NotificationCenter.audioDidReset); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.screenshotTook); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.blockedUsersDidLoaded); + NotificationCenter.getInstance().removeObserver(this, NotificationCenter.FileNewChunkAvailable); if (AndroidUtilities.isTablet()) { - NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, (long)0); + NotificationCenter.getInstance().postNotificationName(NotificationCenter.openedChatChanged, dialog_id, true); } if (currentEncryptedChat != null) { MediaController.getInstance().stopMediaObserver(); @@ -440,7 +441,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); File video = Utilities.generateVideoPath(); if (video != null) { - if (android.os.Build.VERSION.SDK_INT > 16) { + if (android.os.Build.VERSION.SDK_INT >= 18) { takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(video)); } takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long) (1024 * 1024 * 1000)); @@ -623,7 +624,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not fragmentView = inflater.inflate(R.layout.chat_layout, container, false); View contentView = fragmentView.findViewById(R.id.chat_layout); - emptyView = (TextView)fragmentView.findViewById(R.id.searchEmptyView); + TextView emptyView = (TextView) fragmentView.findViewById(R.id.searchEmptyView); + emptyViewContainer = fragmentView.findViewById(R.id.empty_view); + emptyViewContainer.setVisibility(View.GONE); + emptyViewContainer.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + return true; + } + }); emptyView.setText(LocaleController.getString("NoMessages", R.string.NoMessages)); chatListView = (LayoutListView)fragmentView.findViewById(R.id.chat_list_view); chatListView.setAdapter(chatAdapter = new ChatAdapter(getParentActivity())); @@ -680,7 +689,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } if (currentEncryptedChat != null) { - secretChatPlaceholder = contentView.findViewById(R.id.secret_placeholder); + emptyView.setVisibility(View.GONE); + View secretChatPlaceholder = contentView.findViewById(R.id.secret_placeholder); + secretChatPlaceholder.setVisibility(View.VISIBLE); if (isCustomTheme) { secretChatPlaceholder.setBackgroundResource(R.drawable.system_black); } else { @@ -791,11 +802,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not chatListView.setEmptyView(null); } else { progressView.setVisibility(View.GONE); - if (currentEncryptedChat == null) { - chatListView.setEmptyView(emptyView); - } else { - chatListView.setEmptyView(secretChatPlaceholder); - } + chatListView.setEmptyView(emptyViewContainer); } pagedownButton.setOnClickListener(new View.OnClickListener() { @@ -1505,7 +1512,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not photo = (TLRPC.TL_photo)MessagesStorage.getInstance().getSentFile(Utilities.getPath(uri), currentEncryptedChat == null ? 0 : 3); } if (photo == null) { - photo = MessagesController.getInstance().generatePhotoSizes(path, uri); + photo = SendMessagesHelper.getInstance().generatePhotoSizes(path, uri); } if (photo != null) { final String originalPathFinal = originalPath; @@ -1946,11 +1953,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not if (first) { if (chatListView.getEmptyView() == null) { - if (currentEncryptedChat == null) { - chatListView.setEmptyView(emptyView); - } else { - chatListView.setEmptyView(secretChatPlaceholder); - } + chatListView.setEmptyView(emptyViewContainer); } } } else { @@ -2157,7 +2160,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } } else if (id == NotificationCenter.closeChats) { - removeSelfFromStack(); + if (args != null && args.length > 0) { + long did = (Long)args[0]; + if (did == dialog_id) { + finishFragment(); + } + } else { + removeSelfFromStack(); + } } else if (id == NotificationCenter.messagesRead) { ArrayList markAsReadMessages = (ArrayList)args[0]; boolean updated = false; @@ -2313,11 +2323,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not messagesByDays.clear(); messagesDict.clear(); progressView.setVisibility(View.GONE); - if (currentEncryptedChat == null) { - chatListView.setEmptyView(emptyView); - } else { - chatListView.setEmptyView(secretChatPlaceholder); - } + chatListView.setEmptyView(emptyViewContainer); if (currentEncryptedChat == null) { maxMessageId = Integer.MAX_VALUE; minMessageId = Integer.MIN_VALUE; @@ -2341,6 +2347,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateBottomOverlay(); } } + } else if (id == NotificationCenter.FileNewChunkAvailable) { + MessageObject messageObject = (MessageObject)args[0]; + long finalSize = (Long)args[2]; + if (finalSize != 0 && dialog_id == messageObject.getDialogId()) { + MessageObject currentObject = messagesDict.get(messageObject.messageOwner.id); + if (currentObject != null) { + currentObject.messageOwner.media.video.size = (int)finalSize; + updateVisibleRows(); + } + } } } @@ -2551,7 +2567,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } else { actionBarLayer.setSubTitleIcon(0, null, 0); - typingDotsDrawable.stop(); + if (typingDotsDrawable != null) { + typingDotsDrawable.stop(); + } } } @@ -2866,12 +2884,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } } else if (option == 4) { String fileName = selectedObject.getFileName(); + String path = selectedObject.messageOwner.attachPath; + if (path == null || path.length() == 0) { + path = FileLoader.getPathToMessage(selectedObject.messageOwner).toString(); + } if (selectedObject.type == 3) { - MediaController.saveFile(fileName, selectedObject.messageOwner.attachPath, getParentActivity(), 1, null); + MediaController.saveFile(path, getParentActivity(), 1, null); } else if (selectedObject.type == 1) { - MediaController.saveFile(fileName, selectedObject.messageOwner.attachPath, getParentActivity(), 0, null); + MediaController.saveFile(path, getParentActivity(), 0, null); } else if (selectedObject.type == 8 || selectedObject.type == 9) { - MediaController.saveFile(fileName, selectedObject.messageOwner.attachPath, getParentActivity(), 2, selectedObject.messageOwner.media.document.file_name); + MediaController.saveFile(path, getParentActivity(), 2, selectedObject.messageOwner.media.document.file_name); } } else if (option == 5) { File locFile = null; @@ -2967,7 +2989,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } presentFragment(new ChatActivity(args), true); forwardSelectedMessages(did, param); - removeSelfFromStack(); + if (!AndroidUtilities.isTablet()) { + removeSelfFromStack(); + } } else { activity.finishFragment(); } @@ -2976,6 +3000,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not forwardSelectedMessages(did, param); chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop()); scrollToTopOnResume = true; + if (AndroidUtilities.isTablet()) { + actionBarLayer.hideActionMode(); + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java index 784963d5e..d97f49816 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java @@ -80,7 +80,7 @@ public class DocumentSelectActivity extends BaseFragment { Runnable r = new Runnable() { public void run() { try { - if (currentDir == null){ + if (currentDir == null) { listRoots(); } else { listFiles(currentDir); @@ -159,13 +159,22 @@ public class DocumentSelectActivity extends BaseFragment { public void onItemClick(AdapterView adapterView, View view, int i, long l) { ListItem item = items.get(i); File file = item.file; - if (file.isDirectory()) { + if (file == null) { + HistoryEntry he = history.remove(history.size() - 1); + actionBarLayer.setTitle(he.title); + if (he.dir != null) { + listFiles(he.dir); + } else { + listRoots(); + } + listView.setSelectionFromTop(he.scrollItem, he.scrollOffset); + } else if (file.isDirectory()) { HistoryEntry he = new HistoryEntry(); he.scrollItem = listView.getFirstVisiblePosition(); he.scrollOffset = listView.getChildAt(0).getTop(); he.dir = currentDir; he.title = actionBarLayer.getTitle().toString(); - if (!listFiles(file)){ + if (!listFiles(file)) { return; } history.add(he); @@ -212,7 +221,7 @@ public class DocumentSelectActivity extends BaseFragment { @Override public boolean onBackPressed() { - if (history.size() > 0){ + if (history.size() > 0) { HistoryEntry he = history.remove(history.size() - 1); actionBarLayer.setTitle(he.title); if (he.dir != null) { @@ -240,7 +249,7 @@ public class DocumentSelectActivity extends BaseFragment { currentDir = dir; items.clear(); String state = Environment.getExternalStorageState(); - if (Environment.MEDIA_SHARED.equals(state)){ + if (Environment.MEDIA_SHARED.equals(state)) { emptyView.setText(LocaleController.getString("UsbActive", R.string.UsbActive)); } else { emptyView.setText(LocaleController.getString("NotMounted", R.string.NotMounted)); @@ -273,6 +282,15 @@ public class DocumentSelectActivity extends BaseFragment { return lhs.isDirectory() ? -1 : 1; } return lhs.getName().compareToIgnoreCase(rhs.getName()); + /*long lm = lhs.lastModified(); + long rm = lhs.lastModified(); + if (lm == rm) { + return 0; + } else if (lm > rm) { + return -1; + } else { + return 1; + }*/ } }); for (File file : files) { @@ -296,6 +314,12 @@ public class DocumentSelectActivity extends BaseFragment { } items.add(item); } + ListItem item = new ListItem(); + item.title = ".."; + item.subtitle = ""; + item.icon = R.drawable.ic_directory; + item.file = null; + items.add(0, item); listAdapter.notifyDataSetChanged(); return true; } @@ -374,10 +398,25 @@ public class DocumentSelectActivity extends BaseFragment { fs.icon = R.drawable.ic_directory; fs.file = new File("/"); items.add(fs); + + try { + File telegramPath = new File(Environment.getExternalStorageDirectory(), LocaleController.getString("AppName", R.string.AppName)); + if (telegramPath.exists()) { + fs = new ListItem(); + fs.title = LocaleController.getString("AppName", R.string.AppName); + fs.subtitle = telegramPath.toString(); + fs.icon = R.drawable.ic_directory; + fs.file = telegramPath; + items.add(fs); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + listAdapter.notifyDataSetChanged(); } - private String getRootSubtitle(String path){ + private String getRootSubtitle(String path) { StatFs stat = new StatFs(path); long total = (long)stat.getBlockCount() * (long)stat.getBlockSize(); long free = (long)stat.getAvailableBlocks() * (long)stat.getBlockSize(); @@ -409,11 +448,11 @@ public class DocumentSelectActivity extends BaseFragment { return 0; } - public int getViewTypeCount(){ + public int getViewTypeCount() { return 2; } - public int getItemViewType(int pos){ + public int getItemViewType(int pos) { return items.get(pos).subtitle.length() > 0 ? 0 : 1; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index fee454ec2..2802b1b59 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -580,7 +580,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa actionBarLayout.presentFragment(fragment, false, true, true); pushOpened = true; if (PhotoViewer.getInstance().isVisible()) { - PhotoViewer.getInstance().closePhoto(true); + PhotoViewer.getInstance().closePhoto(false); } } if (open_settings != 0) { @@ -648,22 +648,40 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa args.putInt("enc_id", high_id); } ChatActivity fragment = new ChatActivity(args); - actionBarLayout.presentFragment(fragment, true); + if (videoPath != null) { - fragment.processSendingVideo(videoPath, 0, 0, 0, 0, null); - } - if (sendingText != null) { - fragment.processSendingText(sendingText); - } - if (photoPathsArray != null) { - fragment.processSendingPhotos(null, photoPathsArray); - } - if (documentsPathsArray != null) { - fragment.processSendingDocuments(documentsPathsArray, documentsOriginalPathsArray); - } - if (contactsToSend != null && !contactsToSend.isEmpty()) { - for (TLRPC.User user : contactsToSend) { - SendMessagesHelper.getInstance().sendMessage(user, dialog_id); + if(android.os.Build.VERSION.SDK_INT >= 16) { + if (AndroidUtilities.isTablet()) { + actionBarLayout.presentFragment(fragment, false, true, true); + } + + Bundle args2 = new Bundle(); + args2.putString("videoPath", videoPath); + VideoEditorActivity fragment2 = new VideoEditorActivity(args2); + fragment2.setDelegate(fragment); + presentFragment(fragment2, true, true); + if (!AndroidUtilities.isTablet()) { + actionBarLayout.addFragmentToStack(fragment, actionBarLayout.fragmentsStack.size() - 1); + } + } else { + actionBarLayout.presentFragment(fragment, true); + fragment.processSendingVideo(videoPath, 0, 0, 0, 0, null); + } + } else { + actionBarLayout.presentFragment(fragment, true); + if (sendingText != null) { + fragment.processSendingText(sendingText); + } + if (photoPathsArray != null) { + fragment.processSendingPhotos(null, photoPathsArray); + } + if (documentsPathsArray != null) { + fragment.processSendingDocuments(documentsPathsArray, documentsOriginalPathsArray); + } + if (contactsToSend != null && !contactsToSend.isEmpty()) { + for (TLRPC.User user : contactsToSend) { + SendMessagesHelper.getInstance().sendMessage(user, dialog_id); + } } } @@ -1027,7 +1045,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); a--; } - layersActionBarLayout.closeLastFragment(true); + layersActionBarLayout.closeLastFragment(!forceWithoutAnimation); } return false; } else if (tabletFullSize && layout != actionBarLayout) { @@ -1037,7 +1055,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); a--; } - layersActionBarLayout.closeLastFragment(true); + layersActionBarLayout.closeLastFragment(!forceWithoutAnimation); } return false; } else { @@ -1046,7 +1064,11 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa layersActionBarLayout.removeFragmentFromStack(layersActionBarLayout.fragmentsStack.get(0)); a--; } - layersActionBarLayout.closeLastFragment(true); + layersActionBarLayout.closeLastFragment(!forceWithoutAnimation); + } + if (actionBarLayout.fragmentsStack.size() > 1) { + actionBarLayout.presentFragment(fragment, actionBarLayout.fragmentsStack.size() > 1, forceWithoutAnimation, false); + return false; } } } else if (layout != layersActionBarLayout) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java index 16de820dd..552f17527 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -366,6 +366,9 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter public void onClick(DialogInterface dialogInterface, int i) { MessagesController.getInstance().deleteUserFromChat((int) -selectedDialog, MessagesController.getInstance().getUser(UserConfig.getClientUserId()), null); MessagesController.getInstance().deleteDialog(selectedDialog, 0, false); + if (AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats, selectedDialog); + } } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); @@ -387,6 +390,9 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter @Override public void onClick(DialogInterface dialogInterface, int i) { MessagesController.getInstance().deleteDialog(selectedDialog, 0, false); + if (AndroidUtilities.isTablet()) { + NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats, selectedDialog); + } } }); builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); @@ -486,7 +492,15 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter updateVisibleRows(0); } else if (id == NotificationCenter.openedChatChanged) { if (!serverOnly && AndroidUtilities.isTablet()) { - openedDialogId = (Long)args[0]; + boolean close = (Boolean)args[1]; + long dialog_id = (Long)args[0]; + if (close) { + if (dialog_id == openedDialogId) { + openedDialogId = 0; + } + } else { + openedDialogId = dialog_id; + } updateVisibleRows(0); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java index 85df56636..09f3e673a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoViewer.java @@ -509,10 +509,16 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (id == -1) { closePhoto(true); } else if (id == gallery_menu_save) { - if (currentFileName == null) { - return; + File f = null; + if (currentMessageObject != null) { + f = FileLoader.getPathToMessage(currentMessageObject.messageOwner); + } else if (currentFileLocation != null) { + f = FileLoader.getPathToAttach(currentFileLocation); + } + + if (f != null && f.exists()) { + MediaController.saveFile(f.toString(), parentActivity, currentFileName.endsWith("mp4") ? 1 : 0, null); } - MediaController.saveFile(currentFileName, null, parentActivity, currentFileName.endsWith("mp4") ? 1 : 0, null); } else if (id == gallery_menu_showall) { if (opennedFromMedia) { closePhoto(true); @@ -945,7 +951,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (message.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { return message.messageOwner.action.newUserPhoto.photo_big; } else { - TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.action.photo.sizes, 800, 800); + TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.action.photo.sizes, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (sizeFull != null) { size[0] = sizeFull.size; if (size[0] == 0) { @@ -957,7 +963,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } } else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && message.messageOwner.media.photo != null) { - TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.media.photo.sizes, 800, 800); + TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.media.photo.sizes, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (sizeFull != null) { size[0] = sizeFull.size; if (size[0] == 0) { @@ -1008,7 +1014,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat location.secret = sizeFull.secret; return location; } else { - TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.action.photo.sizes, 800, 800); + TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.action.photo.sizes, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (sizeFull != null) { TLRPC.TL_inputFileLocation location = new TLRPC.TL_inputFileLocation(); location.local_id = sizeFull.location.local_id; @@ -1019,7 +1025,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } } } else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { - TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.media.photo.sizes, 800, 800); + TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(message.messageOwner.media.photo.sizes, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); if (sizeFull != null) { TLRPC.TL_inputFileLocation location = new TLRPC.TL_inputFileLocation(); location.local_id = sizeFull.location.local_id; @@ -1370,7 +1376,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (currentThumb != null && imageReceiver == centerImage) { placeHolder = currentThumb; } - int size = (int)(800 / AndroidUtilities.density); + int size = (int)(AndroidUtilities.getPhotoSize() / AndroidUtilities.density); imageReceiver.setImage(photoEntry.path, String.format(Locale.US, "%d_%d", size, size), placeHolder != null ? new BitmapDrawable(null, placeHolder) : null); } else { imageReceiver.setImageBitmap((Bitmap) null); @@ -1405,6 +1411,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat if (currentThumb != null && imageReceiver == centerImage) { placeHolder = currentThumb; } + if (size[0] == 0) { + size[0] = -1; + } imageReceiver.setImage(fileLocation, null, placeHolder != null ? new BitmapDrawable(null, placeHolder) : null, size[0]); } } else { @@ -2306,7 +2315,7 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat } if (loadFile) { if (!FileLoader.getInstance().isLoadingFile(currentFileName)) { - FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.video); + FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.video, true); } else { FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.video); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index 00432144d..c21aea9dc 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -445,7 +445,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC TextView messageText = (TextView)view.findViewById(R.id.message_text); BackupImageView imageView = (BackupImageView) view.findViewById(R.id.message_image); imageView.imageReceiver.setAspectFit(true); - PhotoObject currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, 800, 800); + PhotoObject currentPhotoObject = PhotoObject.getClosestImageWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize(), AndroidUtilities.getPhotoSize()); boolean photoSet = false; if (currentPhotoObject != null) { boolean photoExist = true; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java index 9ba8b869f..539e6646d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java @@ -9,10 +9,11 @@ package org.telegram.ui; import android.annotation.TargetApi; +import android.app.Activity; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.SurfaceTexture; import android.media.MediaPlayer; -import android.os.Build; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; @@ -21,6 +22,8 @@ import android.view.TextureView; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; @@ -52,12 +55,6 @@ import java.util.List; @TargetApi(16) public class VideoEditorActivity extends BaseFragment implements TextureView.SurfaceTextureListener { - private final static int OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100; - private final static int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; - private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03; - private final static int OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002; - private final static int OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m = 0x7FA30C04; - private MediaPlayer videoPlayer = null; private VideoTimelineView videoTimelineView = null; private View videoContainerView = null; @@ -68,6 +65,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur private VideoSeekBarView videoSeekBarView = null; private TextureView textureView = null; private View controlView = null; + private CheckBox compressVideo = null; private boolean playerPrepared = false; private String videoPath = null; @@ -77,7 +75,6 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur private final Object sync = new Object(); private Thread thread = null; - private long createTime = 0; private int rotationValue = 0; private int originalWidth = 0; @@ -92,6 +89,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur private int videoFramesSize = 0; private int estimatedSize = 0; private long esimatedDuration = 0; + private long originalSize = 0; public interface VideoEditorActivityDelegate { public abstract void didFinishEditVideo(String videoPath, long startTime, long endTime, int resultWidth, int resultHeight, int rotationValue, int originalWidth, int originalHeight, int bitrate, long estimatedSize, long estimatedDuration); @@ -225,7 +223,11 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur } } if (delegate != null) { - delegate.didFinishEditVideo(videoPath, startTime, endTime, resultWidth, resultHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); + if (compressVideo.getVisibility() == View.VISIBLE && !compressVideo.isChecked()) { + delegate.didFinishEditVideo(videoPath, startTime, endTime, originalWidth, originalHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); + } else { + delegate.didFinishEditVideo(videoPath, startTime, endTime, resultWidth, resultHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); + } } finishFragment(); } @@ -244,6 +246,21 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur videoContainerView = fragmentView.findViewById(R.id.video_container); textContainerView = fragmentView.findViewById(R.id.info_container); controlView = fragmentView.findViewById(R.id.control_layout); + compressVideo = (CheckBox) fragmentView.findViewById(R.id.compress_video); + compressVideo.setText(LocaleController.getString("CompressVideo", R.string.CompressVideo)); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + compressVideo.setVisibility(originalHeight != resultHeight || originalWidth != resultWidth ? View.VISIBLE : View.GONE); + compressVideo.setChecked(preferences.getBoolean("compress_video", true)); + compressVideo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("compress_video", isChecked); + editor.commit(); + updateVideoEditedInfo(); + } + }); TextView titleTextView = (TextView) fragmentView.findViewById(R.id.original_title); titleTextView.setText(LocaleController.getString("OriginalVideo", R.string.OriginalVideo)); titleTextView = (TextView) fragmentView.findViewById(R.id.edited_title); @@ -297,13 +314,19 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur videoSeekBarView.delegate = new VideoSeekBarView.SeekBarDelegate() { @Override public void onSeekBarDrag(float progress) { + if (progress < videoTimelineView.getLeftProgress()) { + progress = videoTimelineView.getLeftProgress(); + videoSeekBarView.setProgress(progress); + } else if (progress > videoTimelineView.getRightProgress()) { + progress = videoTimelineView.getRightProgress(); + videoSeekBarView.setProgress(progress); + } if (videoPlayer == null || !playerPrepared) { return; } if (videoPlayer.isPlaying()) { try { - float prog = videoTimelineView.getLeftProgress() + (videoTimelineView.getRightProgress() - videoTimelineView.getLeft()) * progress; - videoPlayer.seekTo((int) (videoDuration * prog)); + videoPlayer.seekTo((int) (videoDuration * progress)); lastProgress = progress; } catch (Exception e) { FileLog.e("tmessages", e); @@ -335,7 +358,6 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur } } fixLayoutInternal(); - createTime = System.currentTimeMillis(); return fragmentView; } @@ -402,14 +424,13 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur if (originalSizeTextView == null) { return; } - File file = new File(videoPath); int width = rotationValue == 90 || rotationValue == 270 ? originalHeight : originalWidth; int height = rotationValue == 90 || rotationValue == 270 ? originalWidth : originalHeight; String videoDimension = String.format("%dx%d", width, height); long duration = (long)Math.ceil(videoDuration); int minutes = (int)(duration / 1000 / 60); int seconds = (int) Math.ceil(duration / 1000) - minutes * 60; - String videoTimeSize = String.format("%d:%02d, %s", minutes, seconds, Utilities.formatFileSize(file.length())); + String videoTimeSize = String.format("%d:%02d, %s", minutes, seconds, Utilities.formatFileSize(originalSize)); originalSizeTextView.setText(String.format("%s, %s", videoDimension, videoTimeSize)); } @@ -417,12 +438,21 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur if (editedSizeTextView == null) { return; } - int width = rotationValue == 90 || rotationValue == 270 ? resultHeight : resultWidth; - int height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight; - String videoDimension = String.format("%dx%d", width, height); - esimatedDuration = (long)Math.ceil((videoTimelineView.getRightProgress() - videoTimelineView.getLeftProgress()) * videoDuration); - estimatedSize = calculateEstimatedSize((float)esimatedDuration / videoDuration); + + int width = 0; + int height = 0; + + if (compressVideo.getVisibility() == View.VISIBLE && !compressVideo.isChecked()) { + width = rotationValue == 90 || rotationValue == 270 ? originalHeight : originalWidth; + height = rotationValue == 90 || rotationValue == 270 ? originalWidth : originalHeight; + estimatedSize = (int)(originalSize * ((float)esimatedDuration / videoDuration)); + } else { + width = rotationValue == 90 || rotationValue == 270 ? resultHeight : resultWidth; + height = rotationValue == 90 || rotationValue == 270 ? resultWidth : resultHeight; + estimatedSize = calculateEstimatedSize((float)esimatedDuration / videoDuration); + } + if (videoTimelineView.getLeftProgress() == 0) { startTime = -1; } else { @@ -434,6 +464,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur endTime = (long) (videoTimelineView.getRightProgress() * videoDuration) * 1000; } + String videoDimension = String.format("%dx%d", width, height); int minutes = (int)(esimatedDuration / 1000 / 60); int seconds = (int) Math.ceil(esimatedDuration / 1000) - minutes * 60; String videoTimeSize = String.format("%d:%02d, ~%s", minutes, seconds, Utilities.formatFileSize(estimatedSize)); @@ -459,14 +490,14 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur int height = 0; if (AndroidUtilities.isTablet()) { width = AndroidUtilities.dp(490); - height = viewHeight - AndroidUtilities.dp(276); + height = viewHeight - AndroidUtilities.dp(276 + (compressVideo.getVisibility() == View.VISIBLE ? 20 : 0)); } else { if (getParentActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { width = AndroidUtilities.displaySize.x / 3 - AndroidUtilities.dp(24); height = viewHeight - AndroidUtilities.dp(32); } else { width = AndroidUtilities.displaySize.x; - height = viewHeight - AndroidUtilities.dp(276); + height = viewHeight - AndroidUtilities.dp(276 + (compressVideo.getVisibility() == View.VISIBLE ? 20 : 0)); } } @@ -518,7 +549,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur } else { FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) videoContainerView.getLayoutParams(); layoutParams.topMargin = AndroidUtilities.dp(16); - layoutParams.bottomMargin = AndroidUtilities.dp(260); + layoutParams.bottomMargin = AndroidUtilities.dp(260 + (compressVideo.getVisibility() == View.VISIBLE ? 20 : 0)); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.leftMargin = 0; videoContainerView.setLayoutParams(layoutParams); @@ -526,7 +557,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur layoutParams = (FrameLayout.LayoutParams) controlView.getLayoutParams(); layoutParams.topMargin = 0; layoutParams.leftMargin = 0; - layoutParams.bottomMargin = AndroidUtilities.dp(150); + layoutParams.bottomMargin = AndroidUtilities.dp(150 + (compressVideo.getVisibility() == View.VISIBLE ? 20 : 0)); layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT; layoutParams.gravity = Gravity.BOTTOM; controlView.setLayoutParams(layoutParams); @@ -546,23 +577,16 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur if (originalSizeTextView == null) { return; } - if (createTime < System.currentTimeMillis() - 3000) { - originalSizeTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - if (originalSizeTextView != null) { - if (Build.VERSION.SDK_INT < 16) { - originalSizeTextView.getViewTreeObserver().removeGlobalOnLayoutListener(this); - } else { - originalSizeTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this); - } - } - fixLayoutInternal(); + fragmentView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + fixLayoutInternal(); + if (fragmentView != null) { + fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); } - }); - } else { - fixLayoutInternal(); - } + return true; + } + }); } private void play() { @@ -577,8 +601,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur playButton.setImageDrawable(null); lastProgress = 0; if (needSeek) { - float prog = videoTimelineView.getLeftProgress() + (videoTimelineView.getRightProgress() - videoTimelineView.getLeft()) * videoSeekBarView.getProgress(); - videoPlayer.seekTo((int) (videoDuration * prog)); + videoPlayer.seekTo((int) (videoDuration * videoSeekBarView.getProgress())); needSeek = false; } videoPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() { @@ -614,9 +637,19 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur private boolean processOpenVideo() { try { + File file = new File(videoPath); + originalSize = file.length(); + IsoFile isoFile = new IsoFile(videoPath); List boxes = Path.getPaths(isoFile, "/moov/trak/"); TrackHeaderBox trackHeaderBox = null; + boolean isAvc = true; + + Box avc = Path.getPath(isoFile, "/moov/trak/mdia/minf/stbl/stsd/avc1/"); + if (avc == null) { + isAvc = false; + } + for (Box box : boxes) { TrackBox trackBox = (TrackBox)box; int sampleSizes = 0; @@ -665,10 +698,14 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur resultWidth *= scale; resultHeight *= scale; if (bitrate != 0) { - bitrate *= scale; + bitrate *= Math.max(0.5f, scale); videoFramesSize = (int)(bitrate / 8 * videoDuration); } } + + if (!isAvc && (resultWidth == originalWidth || resultHeight == originalHeight)) { + return false; + } } catch (Exception e) { FileLog.e("tmessages", e); return false; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayout.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayout.java index d65d83fc9..7885959b8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayout.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ActionBar/ActionBarLayout.java @@ -568,11 +568,19 @@ public class ActionBarLayout extends FrameLayout { } public boolean addFragmentToStack(BaseFragment fragment) { + return addFragmentToStack(fragment, -1); + } + + public boolean addFragmentToStack(BaseFragment fragment, int position) { if (delegate != null && !delegate.needAddFragmentToStack(fragment, this) || !fragment.onFragmentCreate()) { return false; } fragment.setParentLayout(this); - fragmentsStack.add(fragment); + if (position == -1) { + fragmentsStack.add(fragment); + } else { + fragmentsStack.add(position, fragment); + } return true; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java index 9d9c65d46..da4c9e4ca 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ChatActivityEnterView.java @@ -45,8 +45,6 @@ import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; import org.telegram.ui.ApplicationLoader; -import java.lang.reflect.Method; - public class ChatActivityEnterView implements NotificationCenter.NotificationCenterDelegate, SizeNotifierRelativeLayout.SizeNotifierRelativeLayoutDelegate { public static interface ChatActivityEnterViewDelegate { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java index b0069496e..ff9d59c4d 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/TypingDotsDrawable.java @@ -39,6 +39,9 @@ public class TypingDotsDrawable extends Drawable { long newTime = System.currentTimeMillis(); long dt = newTime - lastUpdateTime; lastUpdateTime = newTime; + if (dt > 50) { + dt = 50; + } for (int a = 0; a < 3; a++) { elapsedTimes[a] += dt; diff --git a/TMessagesProj/src/main/res/layout/chat_layout.xml b/TMessagesProj/src/main/res/layout/chat_layout.xml index 0253fad0c..e9d9bbb11 100644 --- a/TMessagesProj/src/main/res/layout/chat_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_layout.xml @@ -7,7 +7,8 @@ + android:paddingBottom="48dp" + android:id="@+id/empty_view"> @@ -65,7 +67,6 @@ android:layout_height="wrap_content" android:textColor="#f0f0f0" android:textSize="15dp" - android:layout_marginTop="8dp" android:layout_marginLeft="13dp" android:id="@+id/original_title"/> @@ -92,9 +93,17 @@ android:textColor="#bebebe" android:textSize="15dp" android:layout_marginLeft="13dp" - android:layout_marginBottom="8dp" android:id="@+id/edited_size"/> + + diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index ce03f3f25..c7ea24cc4 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -318,6 +318,7 @@ الفيديو الأصلي تم تحرير الفيديو Sending video... + Compress Video التالي diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 0f044aee8..9d90c64b7 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -11,7 +11,7 @@ Dein Telefon - Bitte bestätige deine Landesvorwahl und deine Telefonnummer. + Bitte Landeskennzahl und\nTelefonnummer bestätigen. Wähle ein Land Falsche Landesvorwahl @@ -42,7 +42,7 @@ gestern Keine Ergebnisse Noch keine Chats… - Beginne Telegram zu nutzen, indem du\neine neue Nachricht erstellst (rechte obere Ecke)\noder deine Kontakte aufrufst. + Tippe rechts oben für deine erste\nChatnachricht, oder auf den Menüknopf\num die restlichen Optionen zu öffnen. Warte auf Netzwerk... Verbinde… Aktualisiere… @@ -219,7 +219,7 @@ 1 Std. 1 Tag 1 Woche - Dieses Bild ist eine Visualisierung des geheimen Schlüssels für den geheimen Chat mit ]]>%1$s]]>.
]]>Wenn dieses Bild auf ]]>%2$s\s]]> Telefon genau so aussieht, ist euer Chat zu 200%% sicher.
]]>Erfahre mehr über die Sicherheit auf telegram.org
+ Das ist eine Darstellung des Schlüssels für den Geheimen Chat mit ]]>%1$s]]>.
]]>Wenn dieses Bild auf ]]>%2$s\s]]>s Telefon genau so aussieht, ist euer Chat zu 200%% sicher.
]]>Erfahre mehr auf telegram.org
Alle Einstellungen für Mitteilungen zurücksetzen @@ -317,7 +317,8 @@ Video bearbeiten Originalvideo Bearbeitetes Video - Sending video... + Sende Video... + Video komprimieren Weiter @@ -405,12 +406,12 @@ Leistungsstark Cloud-Basiert Vertraulich - Willkommen im Zeitalter der sicheren und schnellen Kommunikation. - Telegram]]> stellt Nachrichten schneller zu als andere Anwendungen - Telegram]]> ist für immer kostenlos. Keine Werbung. Keine Abo-Gebühr. + Die schnellste]]> Messaging App der Welt. Kostenlos]]> und sicher]]>. + Telegram]]> stellt Nachrichten schneller zu als alle andere Anwendungen + Telegram]]> ist für immer kostenlos. Keine Werbung. ]]>Keine Abo-Gebühr. Telegram]]> schützt deine Nachrichten vor Hacker-Angriffen Telegram]]> unterstützt unbegrenzt große Chats und Mediendateien - Telegram]]> lässt sich von verschiedenen Geräten gleichzeitig nutzen + Telegram]]> kannst du vom Handy, Tablet oder auch Computer syncronisiert benutzen Telegram]]>-Nachrichten sind stark verschlüsselt und können sich selbst zerstören Jetzt beginnen diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index d7e5704ff..d4f4ed15d 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -11,13 +11,13 @@ Tu teléfono - Por favor, confirma tu código de país\ne introduce tu número. + Por favor, confirma tu código de país\ny pon tu número de teléfono. Elige un país Código de país incorrecto Tu código - Hemos enviado un SMS con un código de activación a tu teléfono + Enviamos un SMS con el código de activación al número Te llamaremos en Llamándote... Código @@ -26,7 +26,7 @@ Tu nombre - Ingresa tu nombre y apellidos + Ingresa tu nombre y apellido Nombre (requerido) Apellido (opcional) @@ -35,14 +35,14 @@ Chats Buscar - Nuevo mensaje + Nuevos mensajes Ajustes Contactos Nuevo grupo ayer Sin resultados - No tienes conversaciones todavía... - Empieza a chatear presionando el\nbotón de Nuevo mensaje en la esquina superior\nderecha o ve a la sección de Contactos. + Aún sin conversaciones... + Envía mensajes pulsando el botón para\nredactar, en la parte superior derecha,\no pulsa el botón menú para más opciones. Esperando red... Conectando... Actualizando... @@ -51,27 +51,27 @@ Chat secreto cancelado Intercambiando claves de cifrado... %s se unió a tu chat secreto. - Te has unido al chat secreto. + Te uniste al chat secreto. Limpiar historial Eliminar y salir Nombre oculto - Selecciona el chat + Elige el chat Lista de difusión - Nueva lista de difusión - Ingresa el nombre de la lista + Nueva difusión + Nombre de la lista Creaste una lista de difusión Añadir destinatario Quitar de la lista de difusión - Seleccionar archivo + Elegir archivo %1$s de %2$s libres Error desconocido Error de acceso - No hay archivos aún... - El tamaño del archivo no debe superar los %1$s + Aún sin archivos... + El archivo no debe superar los %1$s Almacenamiento no montado Transferencia USB activa Almacenamiento Interno @@ -83,18 +83,18 @@ invisible escribiendo... Adjuntar - está escribiendo... - están escribiendo... - ¿Tienes una pregunta\nsobre Telegram? + escribe... + escriben... + ¿Tienes preguntas\nsobre Telegram? Hacer foto Galería Ubicación Vídeo Archivo - No hay mensajes aún... + Aún sin mensajes... Ver foto Ver ubicación - Reproducir vídeo + Ver vídeo Mensaje reenviado De No hay recientes @@ -102,22 +102,22 @@ Escribe un mensaje Descargar Seleccionado: %d - COMPARTIR MI INFORMACIÓN DE CONTACTO + COMPARTIR MI NÚMERO AÑADIR A CONTACTOS - %s te ha invitado a un chat secreto. - Has invitado a %s a un chat secreto. + %s te invitó a un chat secreto. + Invitaste a %s a un chat secreto. Los chats secretos: Usan cifrado end-to-end No dejan rastro en el servidor Tienen autodestrucción de mensajes No permiten reenvíos de mensajes - Te han expulsado de este grupo - Has abandonado este grupo + Te expulsaron de este grupo + Dejaste este grupo Eliminar este grupo Eliminar esta conversación DESLIZA PARA CANCELAR Guardar en descargas - Aplicar archivo de traducción + Aplicar traducción Adjunto no soportado @@ -150,21 +150,21 @@ %1$s envió una ubicación al grupo %2$s %1$s envió un archivo al grupo %2$s %1$s envió un audio al grupo %2$s - %1$s te ha invitado al grupo %2$s + %1$s te invitó al grupo %2$s %1$s cambió el nombre del grupo %2$s %1$s cambió la foto del grupo %2$s %1$s invitó a %3$s al grupo %2$s %1$s expulsó a %3$s del grupo %2$s - %1$s te ha expulsado del grupo %2$s - %1$s abandonó el grupo %2$s + %1$s te expulsó del grupo %2$s + %1$s dejó el grupo %2$s ¡%1$s se unió a Telegram! - %1$s,\nHemos detectado un inicio de sesión en tu cuenta desde un nuevo dispositivo, el %2$s\n\nDispositivo: %3$s\nUbicación: %4$s\n\nSi no eras tú, puedes ir a Ajustes - Cerrar todas las otras sesiones.\n\nAtentamente,\nEl Equipo de Telegram + %1$s,\nDetectamos un inicio de sesión en tu cuenta desde un nuevo dispositivo, el %2$s\n\nDispositivo: %3$s\nUbicación: %4$s\n\nSi no eras tú, puedes ir a Ajustes - Cerrar todas las otras sesiones.\n\nAtentamente,\nEl equipo de Telegram %1$s actualizó su foto de perfil Responder - Seleccionar contacto - No hay contactos aún + Elegir contacto + Aún sin contactos Oye, cambiémonos a Telegram: http://telegram.org/dl2 hoy a las ayer a las @@ -177,13 +177,13 @@ Enviar mensaje a... - El nombre del grupo + Nombre del grupo Nombre del grupo TODOS LOS CONTACTOS %1$d/%2$d miembros - INGRESA EL NOMBRE DEL GRUPO + PON EL NOMBRE DEL GRUPO Fotos y vídeos Información FOTOS Y VÍDEOS @@ -204,22 +204,22 @@ TRABAJO OTRO PRINCIPAL - Información del contacto + Información TELÉFONO Iniciar chat secreto Ocurrió un error. - No podemos crear un chat secreto con %1$s.\n\n%2$s está usando una versión antigua de Telegram y debe actualizarla primero. + No podemos crear un chat secreto con %1$s.\n\n%2$s está usando una versión antigua de Telegram y debe actualizarla. Chat secreto Clave de cifrado Autodestrucción - Apagado + Apagada 2s 5s 1m 1h 1d - 1sem - Esta imagen es una visualización de la clave de cifrado para el chat secreto con ]]>%1$s]]>.
]]>Si esta imagen se visualiza de la misma manera en el teléfono de ]]>%2$s]]>, tu chat es seguro en un 200%%.
]]>Aprende más en telegram.org
+ 1S + Esta imagen es una visualización de la clave de cifrado para el chat secreto con ]]>%1$s]]>.
]]>Si esta imagen se ve igual en el teléfono de ]]>%2$s]]>, tu chat es seguro en un 200%%.
]]>Aprende más en telegram.org
Restablecer todas las notificaciones @@ -227,8 +227,8 @@ Hacer una pregunta Activar animaciones Desbloquear - Mantén pulsado un usuario para desbloquearlo. - No hay usuarios bloqueados + Para desbloquear, mantén pulsado sobre un usuario. + Sin usuarios bloqueados TU NÚMERO DE TELÉFONO NOTIFICACIONES DE MENSAJES Alerta @@ -238,7 +238,7 @@ NOTIFICACIONES EN LA APP Sonidos en la app Vibración en la app - Vibración + Vibraciones Vista previa en la app RESTABLECER Restablecer todas las notificaciones @@ -247,7 +247,7 @@ Usuarios bloqueados Guardar fotos entrantes Cerrar sesión - TU NOMBRE Y APELLIDOS + TU NOMBRE Y APELLIDO Sin sonido Por defecto SOPORTE @@ -259,16 +259,16 @@ Un contacto se unió a Telegram PEBBLE Idioma - Por favor, ten en cuenta que el Soporte de Telegram está hecho por voluntarios. Intentamos responder lo antes posible, pero puede tomar un tiempo.
]]>Por favor, echa un vistazo a las Preguntas Frecuentes de Telegram]]>: tienen importantes soluciones a problemas]]> y respuestas para la mayoría de las preguntas.
+ Por favor, considera que el soporte de Telegram está hecho por voluntarios. Respondemos lo antes posible, pero puede tomar tiempo.
]]>Si quieres, mira las preguntas frecuentes de Telegram]]>: tienen soluciones a problemas]]>, y respuestas para la mayoría de las preguntas.
Preguntar Preguntas frecuentes https://telegram.org/faq/es ¿Eliminar traducción? Archivo de traducción incorrecto - Activado - Desactivado + Activadas + Desactivadas Servicio de notificaciones - Si los Servicios de Google Play son suficientes para que recibas las notificaciones, puedes desactivar el Servicio de notificaciones. Sin embargo, te recomendamos que lo dejes activo para mantener funcionando la aplicación en segundo plano y recibir las notificaciones al instante. + Si tus notificaciones funcionan bien con los Servicios de Google Play, puedes desactivar el Servicio de notificaciones. Sin embargo, recomendamos que lo dejes activo para mantener la app en segundo plano y recibir notificaciones al instante. Ordenar por Importar contactos Sólo vía Wi-Fi @@ -276,15 +276,15 @@ Apellido Color del LED Notificaciones emergentes - Sin notificación emergente - Sólo con pantalla encendida - Sólo con pantalla apagada - Siempre mostrar notificación emergente + Desactivadas + Con pantalla encendida + Con pantalla apagada + Mostrar siempre Globo en el ícono Corto Largo - Por defecto del sistema - Ajustes por defecto + Según el sistema + Según Telegram DESCARGA AUTOMÁTICA DE MULTIMEDIA Con uso de datos móviles Con conexión a Wi-Fi @@ -292,7 +292,7 @@ Ningún contenido multimedia - No hay fotos ni vídeos compartidos aún + Aún no hay fotos ni vídeos Cancelar descarga @@ -310,14 +310,15 @@ Guardar en galería %1$d de %2$d Galería - Todas - No hay fotos aún + Todas las fotos + Sin fotos aún Editar vídeo Vídeo original Vídeo editado - Sending video... + Enviando vídeo... + Comprimir Vídeo Siguiente @@ -349,11 +350,11 @@ un1 cambió el nombre del grupo a un2 un1 creó el grupo Expulsaste a un2 - Abandonaste el grupo + Dejaste el grupo Añadiste a un2 - Quitaste la foto de grupo - Cambiaste la foto de grupo - Cambiaste el nombre de grupo a un2 + Quitaste la foto del grupo + Cambiaste la foto del grupo + Cambiaste el nombre del grupo a un2 Creaste el grupo un1 te expulsó un1 te añadió @@ -371,7 +372,7 @@ Número de teléfono inválido Código expirado. Por favor, vuelve a iniciar sesión. - Demasiados intentos. Por favor, prueba de nuevo más tarde. + Muchos intentos. Por favor, inténtalo más tarde. Código inválido Nombre inválido Apellido inválido @@ -390,7 +391,7 @@ ¿Quieres terminar todas las otras sesiones? ¿Quieres eliminar y dejar el grupo? ¿Quieres eliminar este chat? - ¿Quieres compartir tu información de contacto? + ¿Quieres compartir tu número? ¿Quieres bloquear este contacto? ¿Quieres desbloquear este contacto? ¿Quieres eliminar este contacto? @@ -405,7 +406,7 @@ Poderosa Basada en la nube Privada - Bienvenidos a la era de la mensajería rápida y segura. + La aplicación de mensajería más\nveloz]]> del mundo. Es gratis]]> y segura]]>. Telegram]]> entrega mensajes más rápido que]]>cualquier otra aplicación. Telegram]]> es gratis para siempre. Sin publicidad.]]>Sin cuotas de suscripción. Telegram]]> mantiene tus mensajes]]>a salvo del ataque de hackers. @@ -421,19 +422,19 @@ %1$d miembros %1$d miembros %1$d miembros - y %1$d personas más están escribiendo - y %1$d personas más están escribiendo - y %1$d personas más están escribiendo - y %1$d personas más están escribiendo - y %1$d personas más están escribiendo - y %1$d personas más están escribiendo - no hay mensajes nuevos + y %1$d personas más escriben + y %1$d personas más escriben + y %1$d personas más escriben + y %1$d personas más escriben + y %1$d personas más escriben + y %1$d personas más escriben + Sin mensajes nuevos %1$d nuevo mensaje %1$d nuevos mensajes %1$d nuevos mensajes %1$d nuevos mensajes %1$d nuevos mensajes - no hay mensajes + Sin mensajes %1$d mensaje %1$d mensajes %1$d mensajes diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index 142129a3a..3801d14b4 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -318,6 +318,7 @@ Video originale Video modificato Sending video... + Compress Video Avanti diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index d37ad39f5..6d2cbf965 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -42,7 +42,7 @@ gisteren Geen resultaten Nog geen gesprekken… - Tik op de opstelknop rechtsbovenin\nom een gesprek te beginnen\nof ga naar de contactenlijst. + Begin een gesprek door op de\nopstellen-knop rechtsboven te drukken\nof druk op de menuknop voor meer opties. Wachten op netwerk… Verbinden… Bijwerken… @@ -108,7 +108,7 @@ Je hebt %s uitgenodigd voor een geheime chat. Geheime chat functies: End-to-end encryptie - Ontraceerbaar via onze servers + Geen serveropslag Zelfvernietigingstimers Doorstuurbescherming Je bent verwijderd uit deze groep @@ -171,8 +171,8 @@ om online offline - laatst gez.: - laatst gez.: + gezien + gezien Vrienden uitnodigen @@ -219,7 +219,7 @@ 1u 1d 1w - Dit is een weergave van de encryptiesleutel voor deze geheime chat met ]]>%1$s]]>.
]]>Als deze afbeelding er bij ]]>%2$s]]> hetzelfde uitziet, is jullie gesprek 200%% beveiligd.
]]>Lees meer op telegram.org.
+ Dit is een weergave van de encryptiesleutel voor deze geheime chat met ]]>%1$s]]>.\n\nAls deze afbeelding er bij ]]>%2$s]]> hetzelfde uitziet, is jullie gesprek 200%% beveiligd.\n\nLees meer op telegram.org. Alle meldingsinstellingen herstellen @@ -242,7 +242,7 @@ Voorvertoningen RESETTEN Alle meldingen resetten - Alle aangepaste meldingsinstellingen ongedaan maken voor alle contacten en groepen. + Aangepaste meldingsinstellingen wissen voor contacten en groepen. Meldingen en geluiden Geblokkeerde gebruikers Inkomende foto\'s opslaan @@ -259,7 +259,7 @@ Contact lid van Telegram PEBBLE Taal - Houd er rekening mee dat de ondersteuning van Telegram door vrijwilligers wordt gedaan. We doen ons best om zo snel mogelijk te antwoorden, maar het kan even even duren.
]]>Bekijk ook de veelgestelde vragen]]>: hier staan de antwoorden op de meeste vragen en belangrijke tips voor het oplossen van problemen]]>.
+ Houd er rekening mee dat de ondersteuning van Telegram door vrijwilligers wordt gedaan. We doen ons best om zo snel mogelijk te antwoorden, maar het kan even even duren.\n\nBekijk ook de veelgestelde vragen]]>: hier staan de antwoorden op de meeste vragen en belangrijke tips voor het oplossen van problemen]]>. Vraag een vrijwilliger Veelgestelde vragen https://telegram.org/faq @@ -317,7 +317,8 @@ Video bewerken Originele video Bewerkte video - Sending video... + Video versturen... + Video comprimeren Volgende @@ -387,7 +388,7 @@ Dit gesprek verwijderen? Berichten naar %1$s verzenden? Weet je zeker dat je wilt uitloggen? - Weet je zeker dat je alle andere sessies wilt beëindigen? + Alle apparaten behalve het huidige apparaat uitloggen? Weet je zeker dat je alles wilt verwijderen en de groep wilt verlaten? Weet je zeker dat je dit gesprek wilt verwijderen? Weet je zeker dat je je contactinformatie wilt delen? @@ -405,13 +406,13 @@ Krachtig In de cloud Privé - \'s Werelds snelste]]> berichtendienst.]]>Het is veilig]]> en gratis]]>. - Telegram]]> bezorgt berichten]]>sneller dan elke andere applicatie. - Telegram]]> is altijd gratis. ]]>Geen advertenties.]]>Geen abonnementskosten. - Telegram]]> beveiligt je berichten]]>tegen aanvallen van hackers. - Telegram]]> beperkt je niet]]>in de grootte van je media of gesprekken. - Telegram]]> biedt toegang tot je berichten]]>vanaf meerdere apparaten. - Telegram]]> berichten zijn sterk versleuteld]]>en kunnen zichzelf vernietigen + \'s Werelds snelste]]> berichtendienst.\nHet is veilig]]> en gratis]]>. + Telegram]]> bezorgt berichten\nsneller dan elke andere applicatie. + Telegram]]> is altijd gratis. \nGeen advertenties.\nGeen abonnementskosten. + Telegram]]> beveiligt je berichten\ntegen aanvallen van hackers. + Telegram]]> beperkt je niet\nin de grootte van je media of gesprekken. + Telegram]]> biedt toegang tot je berichten\nvanaf meerdere apparaten. + Telegram]]> berichten zijn sterk versleuteld\nen kunnen zichzelf vernietigen. Begin met chatten diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index f9cad9be0..fa176ac01 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -42,7 +42,7 @@ ontem Nenhum resultado Ainda não há conversas... - Comece a conversar pressionando o\nbotão \'Nova Mensagem\' no canto superior direito\nou vá para a seção \'Contatos\' + Comece a conversar pressionando o\nbotão \'Nova Mensagem\' no canto superior direito\nou vá para a seção \'Contatos\'. Aguardando rede... Conectando... Atualizando... @@ -166,13 +166,13 @@ Selecionar Contato Ainda não há contatos Ei, vamos mudar para o Telegram: http://telegram.org/dl2 - hoje à(s) - ontem à(s) - em + hoje às + ontem às + às online offline - visto pela última vez - visto pela última vez + visto por último + visto por último Convidar Amigos @@ -318,6 +318,7 @@ Vídeo Original Vídeo Editado Sending video... + Compress video Próximo @@ -405,7 +406,7 @@ Poderoso Baseado na nuvem Privado - Bem-vindo à era das mensagens]]> rápidas e seguras + O Mais rápido]]> aplicativo de mensagens\ndo mundo. É grátis]]> e seguro]]>. Telegram]]> envia mensagens mais rapidamente do que qualquer outro aplicativo Telegram]]> será gratuito para sempre. Sem propagandas. Sem mensalidades Telegram]]> mantém suas mensagens seguras contra ataques de hackers diff --git a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml index 2f55edf39..8f4ff0c4d 100644 --- a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml @@ -318,6 +318,7 @@ Original Video Edited Video Sending video... + Compress Video Seguinte diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index 4f2ad1de0..1fa36d948 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -42,7 +42,7 @@ yesterday No results No chats yet... - Start messaging by pressing the\ncompose button in the top right corner\nor go to the Contacts section. + Start messaging by pressing the\ncompose button in the top right corner\nor tap the menu button for more options. Waiting for network... Connecting... Updating... @@ -259,7 +259,7 @@ Contact joined Telegram PEBBLE Language - Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.
]]>Please take a look at the Telegram FAQ]]>: it has answers to most questions and important tips for troubleshooting]]>.
+ Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.
]]>Please take a look at the Telegram FAQ]]>: it has answers to most questions and important tips for troubleshooting]]>.
Ask a volunteer Telegram FAQ https://telegram.org/faq @@ -277,8 +277,8 @@ LED Color Popup Notifications No popup - Only when screen "on" - Only when screen "off" + Only when screen \"on\" + Only when screen \"off\" Always show popup Badge Counter Short @@ -318,6 +318,7 @@ Original Video Edited Video Sending video... + Compress Video Next @@ -405,7 +406,7 @@ Powerful Cloud-Based Private - The world\'s fastets messaging app.\nIt is free and secure. + The world\'s fastest]]> messaging app.\nIt is free]]> and secure]]>. Telegram]]> delivers messages faster than]]>any other application Telegram]]> is free forever. No ads.]]>No subscription fees Telegram]]> keeps your messages safe]]>from hacker attacks