1
0
mirror of https://github.com/MGislv/NekoX.git synced 2024-07-02 10:33:36 +00:00

Service for video encoding, update locales, bug fixes

This commit is contained in:
DrKLO 2014-09-30 02:48:11 +04:00
parent f83a1b56ff
commit f7d3faab5a
39 changed files with 913 additions and 545 deletions

View File

@ -80,7 +80,7 @@ android {
defaultConfig {
minSdkVersion 8
targetSdkVersion 19
versionCode 332
versionCode 335
versionName "1.9.0"
}
}

View File

@ -138,6 +138,7 @@
<service android:name="org.telegram.android.NotificationsService" android:enabled="true"/>
<service android:name="org.telegram.android.NotificationRepeat" android:exported="false"/>
<service android:name="org.telegram.android.VideoEncodingService" android:enabled="true"/>
<receiver android:name="org.telegram.android.AppStartReceiver" android:enabled="true">
<intent-filter>

View File

@ -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;
}
}

View File

@ -64,6 +64,8 @@ public class ImageLoader {
private int lastImageNum = 0;
private long lastProgressUpdateTime = 0;
private File telegramPath = null;
private class HttpTask extends AsyncTask<Void, Void, Boolean> {
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;
}
}
}
}

View File

@ -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<MessageObject> videoConvertQueue = new ArrayList<MessageObject>();
@ -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<WeakReference<FileDownloadProgressListener>> 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);

View File

@ -417,7 +417,7 @@ public class MessageObject {
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
ArrayList<TLRPC.PhotoSize> 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);
}

View File

@ -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<TLRPC.PhotoSize> sizes = new ArrayList<TLRPC.PhotoSize>();
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);

View File

@ -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;

View File

@ -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;

View File

@ -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")) {

View File

@ -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<TLRPC.Message> messages = new ArrayList<TLRPC.Message>();
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<DelayedMessage> 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<TLRPC.Message> sentMessages = new ArrayList<TLRPC.Message>();
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<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
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<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
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<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
@ -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<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
@ -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<Track> tracks = movie.getTracks();
movie.setTracks(new LinkedList<Track>());
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<TLRPC.PhotoSize> sizes = new ArrayList<TLRPC.PhotoSize>();
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];
}
*/
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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<TLRPC.PhotoSize> 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);
}

View File

@ -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;

View File

@ -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) {

View File

@ -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<Integer> markAsReadMessages = (ArrayList<Integer>)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();
}
}
}
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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<Box> 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;

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;

View File

@ -7,7 +7,8 @@
<org.telegram.ui.Views.FrameLayoutFixed
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:paddingBottom="48dp">
android:paddingBottom="48dp"
android:id="@+id/empty_view">
<TextView
android:layout_width="wrap_content"
@ -20,7 +21,6 @@
android:paddingRight="7dp"
android:textSize="14dp"
android:id="@+id/searchEmptyView"
android:visibility="gone"
android:layout_gravity="center"/>
<include

View File

@ -57,6 +57,8 @@
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:id="@+id/info_container"
android:orientation="vertical">
@ -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"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="6dp"
android:textColor="#f0f0f0"
android:textSize="15dp"
android:id="@+id/compress_video"/>
</LinearLayout>
</FrameLayout>

View File

@ -318,6 +318,7 @@
<string name="OriginalVideo">الفيديو الأصلي</string>
<string name="EditedVideo">تم تحرير الفيديو</string>
<string name="SendingVideo">Sending video...</string>
<string name="CompressVideo">Compress Video</string>
<!--button titles-->
<string name="Next">التالي</string>

View File

@ -11,7 +11,7 @@
<!--signin view-->
<string name="YourPhone">Dein Telefon</string>
<string name="StartText">Bitte bestätige deine Landesvorwahl und deine Telefonnummer.</string>
<string name="StartText">Bitte Landeskennzahl und\nTelefonnummer bestätigen.</string>
<string name="ChooseCountry">Wähle ein Land</string>
<string name="WrongCountry">Falsche Landesvorwahl</string>
@ -42,7 +42,7 @@
<string name="Yesterday">gestern</string>
<string name="NoResult">Keine Ergebnisse</string>
<string name="NoChats">Noch keine Chats…</string>
<string name="NoChatsHelp">Beginne Telegram zu nutzen, indem du\neine neue Nachricht erstellst (rechte obere Ecke)\noder deine Kontakte aufrufst.</string>
<string name="NoChatsHelp">Tippe rechts oben für deine erste\nChatnachricht, oder auf den Menüknopf\num die restlichen Optionen zu öffnen.</string>
<string name="WaitingForNetwork">Warte auf Netzwerk...</string>
<string name="Connecting">Verbinde…</string>
<string name="Updating">Aktualisiere…</string>
@ -219,7 +219,7 @@
<string name="ShortMessageLifetime1h">1 Std.</string>
<string name="ShortMessageLifetime1d">1 Tag</string>
<string name="ShortMessageLifetime1w">1 Woche</string>
<string name="EncryptionKeyDescription">Dieses Bild ist eine Visualisierung des geheimen Schlüssels für den geheimen Chat mit <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Wenn dieses Bild auf <![CDATA[<b>]]>%2$s\s<![CDATA[</b>]]> Telefon genau so aussieht, ist euer Chat zu 200%% sicher.<![CDATA[<br><br>]]>Erfahre mehr über die Sicherheit auf telegram.org</string>
<string name="EncryptionKeyDescription">Das ist eine Darstellung des Schlüssels für den Geheimen Chat mit <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Wenn dieses Bild auf <![CDATA[<b>]]>%2$s\s<![CDATA[</b>]]>s Telefon genau so aussieht, ist euer Chat zu 200%% sicher.<![CDATA[<br><br>]]>Erfahre mehr auf telegram.org</string>
<!--settings view-->
<string name="ResetNotificationsText">Alle Einstellungen für Mitteilungen zurücksetzen</string>
@ -317,7 +317,8 @@
<string name="EditVideo">Video bearbeiten</string>
<string name="OriginalVideo">Originalvideo</string>
<string name="EditedVideo">Bearbeitetes Video</string>
<string name="SendingVideo">Sending video...</string>
<string name="SendingVideo">Sende Video...</string>
<string name="CompressVideo">Video komprimieren</string>
<!--button titles-->
<string name="Next">Weiter</string>
@ -405,12 +406,12 @@
<string name="Page5Title">Leistungsstark</string>
<string name="Page6Title">Cloud-Basiert</string>
<string name="Page7Title">Vertraulich</string>
<string name="Page1Message">Willkommen im Zeitalter der sicheren und schnellen Kommunikation.</string>
<string name="Page2Message"><![CDATA[<b>Telegram</b>]]> stellt Nachrichten schneller zu als andere Anwendungen</string>
<string name="Page3Message"><![CDATA[<b>Telegram</b>]]> ist für immer kostenlos. Keine Werbung. Keine Abo-Gebühr.</string>
<string name="Page1Message">Die <![CDATA[<b>schnellste</b>]]> Messaging App der Welt. <![CDATA[<b>Kostenlos</b>]]> und <![CDATA[<b>sicher</b>]]>.</string>
<string name="Page2Message"><![CDATA[<b>Telegram</b>]]> stellt Nachrichten schneller zu als alle andere Anwendungen</string>
<string name="Page3Message"><![CDATA[<b>Telegram</b>]]> ist für immer kostenlos. Keine Werbung. <![CDATA[<br/>]]>Keine Abo-Gebühr.</string>
<string name="Page4Message"><![CDATA[<b>Telegram</b>]]> schützt deine Nachrichten vor Hacker-Angriffen</string>
<string name="Page5Message"><![CDATA[<b>Telegram</b>]]> unterstützt unbegrenzt große Chats und Mediendateien</string>
<string name="Page6Message"><![CDATA[<b>Telegram</b>]]> lässt sich von verschiedenen Geräten gleichzeitig nutzen</string>
<string name="Page6Message"><![CDATA[<b>Telegram</b>]]> kannst du vom Handy, Tablet oder auch Computer syncronisiert benutzen</string>
<string name="Page7Message"><![CDATA[<b>Telegram</b>]]>-Nachrichten sind stark verschlüsselt und können sich selbst zerstören</string>
<string name="StartMessaging">Jetzt beginnen</string>

View File

@ -11,13 +11,13 @@
<!--signin view-->
<string name="YourPhone">Tu teléfono</string>
<string name="StartText">Por favor, confirma tu código de país\ne introduce tu número.</string>
<string name="StartText">Por favor, confirma tu código de país\ny pon tu número de teléfono.</string>
<string name="ChooseCountry">Elige un país</string>
<string name="WrongCountry">Código de país incorrecto</string>
<!--code enter view-->
<string name="YourCode">Tu código</string>
<string name="SentSmsCode">Hemos enviado un SMS con un código de activación a tu teléfono</string>
<string name="SentSmsCode">Enviamos un SMS con el código de activación al número</string>
<string name="CallText">Te llamaremos en</string>
<string name="Calling">Llamándote...</string>
<string name="Code">Código</string>
@ -26,7 +26,7 @@
<!--signup view-->
<string name="YourName">Tu nombre</string>
<string name="RegisterText">Ingresa tu nombre y apellidos</string>
<string name="RegisterText">Ingresa tu nombre y apellido</string>
<!--<string name="RegisterText">Set up your name and picture</string>-->
<string name="FirstName">Nombre (requerido)</string>
<string name="LastName">Apellido (opcional)</string>
@ -35,14 +35,14 @@
<!--chats view-->
<string name="Chats">Chats</string>
<string name="Search">Buscar</string>
<string name="NewMessages">Nuevo mensaje</string>
<string name="NewMessages">Nuevos mensajes</string>
<string name="Settings">Ajustes</string>
<string name="Contacts">Contactos</string>
<string name="NewGroup">Nuevo grupo</string>
<string name="Yesterday">ayer</string>
<string name="NoResult">Sin resultados</string>
<string name="NoChats">No tienes conversaciones todavía...</string>
<string name="NoChatsHelp">Empieza a chatear presionando el\nbotón de Nuevo mensaje en la esquina superior\nderecha o ve a la sección de Contactos.</string>
<string name="NoChats">Aún sin conversaciones...</string>
<string name="NoChatsHelp">Envía mensajes pulsando el botón para\nredactar, en la parte superior derecha,\no pulsa el botón menú para más opciones.</string>
<string name="WaitingForNetwork">Esperando red...</string>
<string name="Connecting">Conectando...</string>
<string name="Updating">Actualizando...</string>
@ -51,27 +51,27 @@
<string name="EncryptionRejected">Chat secreto cancelado</string>
<string name="EncryptionProcessing">Intercambiando claves de cifrado...</string>
<string name="EncryptedChatStartedOutgoing">%s se unió a tu chat secreto.</string>
<string name="EncryptedChatStartedIncoming">Te has unido al chat secreto.</string>
<string name="EncryptedChatStartedIncoming">Te uniste al chat secreto.</string>
<string name="ClearHistory">Limpiar historial</string>
<string name="DeleteChat">Eliminar y salir</string>
<string name="HiddenName">Nombre oculto</string>
<string name="SelectChat">Selecciona el chat</string>
<string name="SelectChat">Elige el chat</string>
<!--broadcasts-->
<string name="BroadcastList">Lista de difusión</string>
<string name="NewBroadcastList">Nueva lista de difusión</string>
<string name="EnterListName">Ingresa el nombre de la lista</string>
<string name="NewBroadcastList">Nueva difusión</string>
<string name="EnterListName">Nombre de la lista</string>
<string name="YouCreatedBroadcastList">Creaste una lista de difusión</string>
<string name="AddRecipient">Añadir destinatario</string>
<string name="KickFromBroadcast">Quitar de la lista de difusión</string>
<!--documents view-->
<string name="SelectFile">Seleccionar archivo</string>
<string name="SelectFile">Elegir archivo</string>
<string name="FreeOfTotal">%1$s de %2$s libres</string>
<string name="UnknownError">Error desconocido</string>
<string name="AccessError">Error de acceso</string>
<string name="NoFiles">No hay archivos aún...</string>
<string name="FileUploadLimit">El tamaño del archivo no debe superar los %1$s</string>
<string name="NoFiles">Aún sin archivos...</string>
<string name="FileUploadLimit">El archivo no debe superar los %1$s</string>
<string name="NotMounted">Almacenamiento no montado</string>
<string name="UsbActive">Transferencia USB activa</string>
<string name="InternalStorage">Almacenamiento Interno</string>
@ -83,18 +83,18 @@
<string name="Invisible">invisible</string>
<string name="Typing">escribiendo...</string>
<string name="Attach">Adjuntar</string>
<string name="IsTyping">está escribiendo...</string>
<string name="AreTyping">están escribiendo...</string>
<string name="GotAQuestion">¿Tienes una pregunta\nsobre Telegram?</string>
<string name="IsTyping">escribe...</string>
<string name="AreTyping">escriben...</string>
<string name="GotAQuestion">¿Tienes preguntas\nsobre Telegram?</string>
<string name="ChatTakePhoto">Hacer foto</string>
<string name="ChatGallery">Galería</string>
<string name="ChatLocation">Ubicación</string>
<string name="ChatVideo">Vídeo</string>
<string name="ChatDocument">Archivo</string>
<string name="NoMessages">No hay mensajes aún...</string>
<string name="NoMessages">Aún sin mensajes...</string>
<string name="ViewPhoto">Ver foto</string>
<string name="ViewLocation">Ver ubicación</string>
<string name="ViewVideo">Reproducir vídeo</string>
<string name="ViewVideo">Ver vídeo</string>
<string name="ForwardedMessage">Mensaje reenviado</string>
<string name="From">De</string>
<string name="NoRecent">No hay recientes</string>
@ -102,22 +102,22 @@
<string name="TypeMessage">Escribe un mensaje</string>
<string name="DOWNLOAD">Descargar</string>
<string name="Selected">Seleccionado: %d</string>
<string name="ShareMyContactInfo">COMPARTIR MI INFORMACIÓN DE CONTACTO</string>
<string name="ShareMyContactInfo">COMPARTIR MI NÚMERO</string>
<string name="AddToContacts">AÑADIR A CONTACTOS</string>
<string name="EncryptedPlaceholderTitleIncoming">%s te ha invitado a un chat secreto.</string>
<string name="EncryptedPlaceholderTitleOutgoing">Has invitado a %s a un chat secreto.</string>
<string name="EncryptedPlaceholderTitleIncoming">%s te invitó a un chat secreto.</string>
<string name="EncryptedPlaceholderTitleOutgoing">Invitaste a %s a un chat secreto.</string>
<string name="EncryptedDescriptionTitle">Los chats secretos:</string>
<string name="EncryptedDescription1">Usan cifrado end-to-end</string>
<string name="EncryptedDescription2">No dejan rastro en el servidor</string>
<string name="EncryptedDescription3">Tienen autodestrucción de mensajes</string>
<string name="EncryptedDescription4">No permiten reenvíos de mensajes</string>
<string name="YouWereKicked">Te han expulsado de este grupo</string>
<string name="YouLeft">Has abandonado este grupo</string>
<string name="YouWereKicked">Te expulsaron de este grupo</string>
<string name="YouLeft">Dejaste este grupo</string>
<string name="DeleteThisGroup">Eliminar este grupo</string>
<string name="DeleteThisChat">Eliminar esta conversación</string>
<string name="SlideToCancel">DESLIZA PARA CANCELAR</string>
<string name="SaveToDownloads">Guardar en descargas</string>
<string name="ApplyLocalizationFile">Aplicar archivo de traducción</string>
<string name="ApplyLocalizationFile">Aplicar traducción</string>
<string name="UnsupportedAttachment">Adjunto no soportado</string>
<!--notification-->
@ -150,21 +150,21 @@
<string name="NotificationMessageGroupMap">%1$s envió una ubicación al grupo %2$s</string>
<string name="NotificationMessageGroupDocument">%1$s envió un archivo al grupo %2$s</string>
<string name="NotificationMessageGroupAudio">%1$s envió un audio al grupo %2$s</string>
<string name="NotificationInvitedToGroup">%1$s te ha invitado al grupo %2$s</string>
<string name="NotificationInvitedToGroup">%1$s te invitó al grupo %2$s</string>
<string name="NotificationEditedGroupName">%1$s cambió el nombre del grupo %2$s</string>
<string name="NotificationEditedGroupPhoto">%1$s cambió la foto del grupo %2$s</string>
<string name="NotificationGroupAddMember">%1$s invitó a %3$s al grupo %2$s</string>
<string name="NotificationGroupKickMember">%1$s expulsó a %3$s del grupo %2$s</string>
<string name="NotificationGroupKickYou">%1$s te ha expulsado del grupo %2$s</string>
<string name="NotificationGroupLeftMember">%1$s abandonó el grupo %2$s</string>
<string name="NotificationGroupKickYou">%1$s te expulsó del grupo %2$s</string>
<string name="NotificationGroupLeftMember">%1$s dejó el grupo %2$s</string>
<string name="NotificationContactJoined">¡%1$s se unió a Telegram!</string>
<string name="NotificationUnrecognizedDevice">%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</string>
<string name="NotificationUnrecognizedDevice">%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</string>
<string name="NotificationContactNewPhoto">%1$s actualizó su foto de perfil</string>
<string name="Reply">Responder</string>
<!--contacts view-->
<string name="SelectContact">Seleccionar contacto</string>
<string name="NoContacts">No hay contactos aún</string>
<string name="SelectContact">Elegir contacto</string>
<string name="NoContacts">Aún sin contactos</string>
<string name="InviteText">Oye, cambiémonos a Telegram: http://telegram.org/dl2</string>
<string name="TodayAt">hoy a las</string>
<string name="YesterdayAt">ayer a las</string>
@ -177,13 +177,13 @@
<!--group create view-->
<string name="SendMessageTo">Enviar mensaje a...</string>
<string name="EnterGroupNamePlaceholder">El nombre del grupo</string>
<string name="EnterGroupNamePlaceholder">Nombre del grupo</string>
<string name="GroupName">Nombre del grupo</string>
<string name="AllContacts">TODOS LOS CONTACTOS</string>
<string name="MembersCount">%1$d/%2$d miembros</string>
<!--group info view-->
<string name="EnterGroupNameTitle">INGRESA EL NOMBRE DEL GRUPO</string>
<string name="EnterGroupNameTitle">PON EL NOMBRE DEL GRUPO</string>
<string name="SharedMedia">Fotos y vídeos</string>
<string name="GroupInfo">Información </string>
<string name="SHAREDMEDIA">FOTOS Y VÍDEOS</string>
@ -204,22 +204,22 @@
<string name="PhoneWork">TRABAJO</string>
<string name="PhoneOther">OTRO</string>
<string name="PhoneMain">PRINCIPAL</string>
<string name="ContactInfo">Información del contacto</string>
<string name="ContactInfo">Información</string>
<string name="PHONE">TELÉFONO</string>
<string name="StartEncryptedChat">Iniciar chat secreto</string>
<string name="CreateEncryptedChatError">Ocurrió un error.</string>
<string name="CreateEncryptedChatOutdatedError">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.</string>
<string name="CreateEncryptedChatOutdatedError">No podemos crear un chat secreto con %1$s.\n\n%2$s está usando una versión antigua de Telegram y debe actualizarla.</string>
<string name="SecretTitle">Chat secreto</string>
<string name="EncryptionKey">Clave de cifrado</string>
<string name="MessageLifetime">Autodestrucción</string>
<string name="ShortMessageLifetimeForever">Apagado</string>
<string name="ShortMessageLifetimeForever">Apagada</string>
<string name="ShortMessageLifetime2s">2s</string>
<string name="ShortMessageLifetime5s">5s</string>
<string name="ShortMessageLifetime1m">1m</string>
<string name="ShortMessageLifetime1h">1h</string>
<string name="ShortMessageLifetime1d">1d</string>
<string name="ShortMessageLifetime1w">1sem</string>
<string name="EncryptionKeyDescription">Esta imagen es una visualización de la clave de cifrado para el chat secreto con <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Si esta imagen se visualiza de la misma manera en el teléfono de <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, tu chat es seguro en un 200%%.<![CDATA[<br><br>]]>Aprende más en telegram.org</string>
<string name="ShortMessageLifetime1w">1S</string>
<string name="EncryptionKeyDescription">Esta imagen es una visualización de la clave de cifrado para el chat secreto con <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Si esta imagen se ve igual en el teléfono de <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, tu chat es seguro en un 200%%.<![CDATA[<br><br>]]>Aprende más en telegram.org</string>
<!--settings view-->
<string name="ResetNotificationsText">Restablecer todas las notificaciones</string>
@ -227,8 +227,8 @@
<string name="AskAQuestion">Hacer una pregunta</string>
<string name="EnableAnimations">Activar animaciones</string>
<string name="Unblock">Desbloquear</string>
<string name="UnblockText">Mantén pulsado un usuario para desbloquearlo.</string>
<string name="NoBlocked">No hay usuarios bloqueados</string>
<string name="UnblockText">Para desbloquear, mantén pulsado sobre un usuario.</string>
<string name="NoBlocked">Sin usuarios bloqueados</string>
<string name="YourPhoneNumber">TU NÚMERO DE TELÉFONO</string>
<string name="MessageNotifications">NOTIFICACIONES DE MENSAJES</string>
<string name="Alert">Alerta</string>
@ -238,7 +238,7 @@
<string name="InAppNotifications">NOTIFICACIONES EN LA APP</string>
<string name="InAppSounds">Sonidos en la app</string>
<string name="InAppVibrate">Vibración en la app</string>
<string name="Vibrate">Vibración</string>
<string name="Vibrate">Vibraciones</string>
<string name="InAppPreview">Vista previa en la app</string>
<string name="Reset">RESTABLECER</string>
<string name="ResetAllNotifications">Restablecer todas las notificaciones</string>
@ -247,7 +247,7 @@
<string name="BlockedUsers">Usuarios bloqueados</string>
<string name="SaveIncomingPhotos">Guardar fotos entrantes</string>
<string name="LogOut">Cerrar sesión</string>
<string name="YourFirstNameAndLastName">TU NOMBRE Y APELLIDOS</string>
<string name="YourFirstNameAndLastName">TU NOMBRE Y APELLIDO</string>
<string name="NoSound">Sin sonido</string>
<string name="Default">Por defecto</string>
<string name="Support">SOPORTE</string>
@ -259,16 +259,16 @@
<string name="ContactJoined">Un contacto se unió a Telegram</string>
<string name="Pebble">PEBBLE</string>
<string name="Language">Idioma</string>
<string name="AskAQuestionInfo">Por favor, ten en cuenta que el Soporte de Telegram está hecho por voluntarios. Intentamos responder lo antes posible, pero puede tomar un tiempo.<![CDATA[<br><br>]]>Por favor, echa un vistazo a las <![CDATA[<a href=“http://telegram.org/faq/es”>Preguntas Frecuentes de Telegram</a>]]>: tienen importantes <![CDATA[<a href=“http://telegram.org/faq/es#solucin-de-problemas”>soluciones a problemas</a>]]> y respuestas para la mayoría de las preguntas.</string>
<string name="AskAQuestionInfo">Por favor, considera que el soporte de Telegram está hecho por voluntarios. Respondemos lo antes posible, pero puede tomar tiempo.<![CDATA[<br><br>]]>Si quieres, mira las <![CDATA[<a href=“http://telegram.org/faq/es”>preguntas frecuentes de Telegram</a>]]>: tienen <![CDATA[<a href=“http://telegram.org/faq/es#solucin-de-problemas”>soluciones a problemas</a>]]>, y respuestas para la mayoría de las preguntas.</string>
<string name="AskButton">Preguntar</string>
<string name="TelegramFaq">Preguntas frecuentes</string>
<string name="TelegramFaqUrl">https://telegram.org/faq/es</string>
<string name="DeleteLocalization">¿Eliminar traducción?</string>
<string name="IncorrectLocalization">Archivo de traducción incorrecto</string>
<string name="Enabled">Activado</string>
<string name="Disabled">Desactivado</string>
<string name="Enabled">Activadas</string>
<string name="Disabled">Desactivadas</string>
<string name="NotificationsService">Servicio de notificaciones</string>
<string name="NotificationsServiceDisableInfo">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.</string>
<string name="NotificationsServiceDisableInfo">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.</string>
<string name="SortBy">Ordenar por</string>
<string name="ImportContacts">Importar contactos</string>
<string name="WiFiOnly">Sólo vía Wi-Fi</string>
@ -276,15 +276,15 @@
<string name="SortLastName">Apellido</string>
<string name="LedColor">Color del LED</string>
<string name="PopupNotification">Notificaciones emergentes</string>
<string name="NoPopup">Sin notificación emergente</string>
<string name="OnlyWhenScreenOn">Sólo con pantalla encendida</string>
<string name="OnlyWhenScreenOff">Sólo con pantalla apagada</string>
<string name="AlwaysShowPopup">Siempre mostrar notificación emergente</string>
<string name="NoPopup">Desactivadas</string>
<string name="OnlyWhenScreenOn">Con pantalla encendida</string>
<string name="OnlyWhenScreenOff">Con pantalla apagada</string>
<string name="AlwaysShowPopup">Mostrar siempre </string>
<string name="BadgeNumber">Globo en el ícono</string>
<string name="Short">Corto</string>
<string name="Long">Largo</string>
<string name="SystemDefault">Por defecto del sistema</string>
<string name="SettingsDefault">Ajustes por defecto</string>
<string name="SystemDefault">Según el sistema</string>
<string name="SettingsDefault">Según Telegram</string>
<string name="AutomaticMediaDownload">DESCARGA AUTOMÁTICA DE MULTIMEDIA</string>
<string name="WhenUsingMobileData">Con uso de datos móviles</string>
<string name="WhenConnectedOnWiFi">Con conexión a Wi-Fi</string>
@ -292,7 +292,7 @@
<string name="NoMediaAutoDownload">Ningún contenido multimedia</string>
<!--media view-->
<string name="NoMedia">No hay fotos ni vídeos compartidos aún</string>
<string name="NoMedia">Aún no hay fotos ni vídeos</string>
<string name="CancelDownload">Cancelar descarga</string>
<!--map view-->
@ -310,14 +310,15 @@
<string name="SaveToGallery">Guardar en galería</string>
<string name="Of">%1$d de %2$d</string>
<string name="Gallery">Galería</string>
<string name="AllPhotos">Todas</string>
<string name="NoPhotos">No hay fotos aún</string>
<string name="AllPhotos">Todas las fotos</string>
<string name="NoPhotos">Sin fotos aún</string>
<!--edit video view-->
<string name="EditVideo">Editar vídeo</string>
<string name="OriginalVideo">Vídeo original</string>
<string name="EditedVideo">Vídeo editado</string>
<string name="SendingVideo">Sending video...</string>
<string name="SendingVideo">Enviando vídeo...</string>
<string name="CompressVideo">Comprimir Vídeo</string>
<!--button titles-->
<string name="Next">Siguiente</string>
@ -349,11 +350,11 @@
<string name="ActionChangedTitle">un1 cambió el nombre del grupo a un2</string>
<string name="ActionCreateGroup">un1 creó el grupo</string>
<string name="ActionYouKickUser">Expulsaste a un2</string>
<string name="ActionYouLeftUser">Abandonaste el grupo</string>
<string name="ActionYouLeftUser">Dejaste el grupo</string>
<string name="ActionYouAddUser">Añadiste a un2</string>
<string name="ActionYouRemovedPhoto">Quitaste la foto de grupo</string>
<string name="ActionYouChangedPhoto">Cambiaste la foto de grupo</string>
<string name="ActionYouChangedTitle">Cambiaste el nombre de grupo a un2</string>
<string name="ActionYouRemovedPhoto">Quitaste la foto del grupo</string>
<string name="ActionYouChangedPhoto">Cambiaste la foto del grupo</string>
<string name="ActionYouChangedTitle">Cambiaste el nombre del grupo a un2</string>
<string name="ActionYouCreateGroup">Creaste el grupo</string>
<string name="ActionKickUserYou">un1 te expulsó</string>
<string name="ActionAddUserYou">un1 te añadió</string>
@ -371,7 +372,7 @@
<!--Alert messages-->
<string name="InvalidPhoneNumber">Número de teléfono inválido</string>
<string name="CodeExpired">Código expirado. Por favor, vuelve a iniciar sesión.</string>
<string name="FloodWait">Demasiados intentos. Por favor, prueba de nuevo más tarde.</string>
<string name="FloodWait">Muchos intentos. Por favor, inténtalo más tarde.</string>
<string name="InvalidCode">Código inválido</string>
<string name="InvalidFirstName">Nombre inválido</string>
<string name="InvalidLastName">Apellido inválido</string>
@ -390,7 +391,7 @@
<string name="AreYouSureSessions">¿Quieres terminar todas las otras sesiones?</string>
<string name="AreYouSureDeleteAndExit">¿Quieres eliminar y dejar el grupo?</string>
<string name="AreYouSureDeleteThisChat">¿Quieres eliminar este chat?</string>
<string name="AreYouSureShareMyContactInfo">¿Quieres compartir tu información de contacto?</string>
<string name="AreYouSureShareMyContactInfo">¿Quieres compartir tu número?</string>
<string name="AreYouSureBlockContact">¿Quieres bloquear este contacto?</string>
<string name="AreYouSureUnblockContact">¿Quieres desbloquear este contacto?</string>
<string name="AreYouSureDeleteContact">¿Quieres eliminar este contacto?</string>
@ -405,7 +406,7 @@
<string name="Page5Title">Poderosa</string>
<string name="Page6Title">Basada en la nube</string>
<string name="Page7Title">Privada</string>
<string name="Page1Message">Bienvenidos a la era de la mensajería rápida y segura.</string>
<string name="Page1Message">La aplicación de mensajería más\n<![CDATA[<b>veloz</b>]]> del mundo. Es <![CDATA[<b>gratis</b>]]> y <![CDATA[<b>segura</b>]]>.</string>
<string name="Page2Message"><![CDATA[<b>Telegram</b>]]> entrega mensajes más rápido que<![CDATA[<br/>]]>cualquier otra aplicación.</string>
<string name="Page3Message"><![CDATA[<b>Telegram</b>]]> es gratis para siempre. Sin publicidad.<![CDATA[<br/>]]>Sin cuotas de suscripción.</string>
<string name="Page4Message"><![CDATA[<b>Telegram</b>]]> mantiene tus mensajes<![CDATA[<br/>]]>a salvo del ataque de hackers.</string>
@ -421,19 +422,19 @@
<string name="Members_few">%1$d miembros</string>
<string name="Members_many">%1$d miembros</string>
<string name="Members_other">%1$d miembros</string>
<string name="AndMoreTyping_zero">y %1$d personas más están escribiendo</string>
<string name="AndMoreTyping_one">y %1$d personas más están escribiendo</string>
<string name="AndMoreTyping_two">y %1$d personas más están escribiendo</string>
<string name="AndMoreTyping_few">y %1$d personas más están escribiendo</string>
<string name="AndMoreTyping_many">y %1$d personas más están escribiendo</string>
<string name="AndMoreTyping_other">y %1$d personas más están escribiendo</string>
<string name="NewMessages_zero">no hay mensajes nuevos</string>
<string name="AndMoreTyping_zero">y %1$d personas más escriben</string>
<string name="AndMoreTyping_one">y %1$d personas más escriben</string>
<string name="AndMoreTyping_two">y %1$d personas más escriben</string>
<string name="AndMoreTyping_few">y %1$d personas más escriben</string>
<string name="AndMoreTyping_many">y %1$d personas más escriben</string>
<string name="AndMoreTyping_other">y %1$d personas más escriben</string>
<string name="NewMessages_zero">Sin mensajes nuevos</string>
<string name="NewMessages_one">%1$d nuevo mensaje</string>
<string name="NewMessages_two">%1$d nuevos mensajes</string>
<string name="NewMessages_few">%1$d nuevos mensajes</string>
<string name="NewMessages_many">%1$d nuevos mensajes</string>
<string name="NewMessages_other">%1$d nuevos mensajes</string>
<string name="messages_zero">no hay mensajes</string>
<string name="messages_zero">Sin mensajes</string>
<string name="messages_one">%1$d mensaje</string>
<string name="messages_two">%1$d mensajes</string>
<string name="messages_few">%1$d mensajes</string>

View File

@ -318,6 +318,7 @@
<string name="OriginalVideo">Video originale</string>
<string name="EditedVideo">Video modificato</string>
<string name="SendingVideo">Sending video...</string>
<string name="CompressVideo">Compress Video</string>
<!--button titles-->
<string name="Next">Avanti</string>

View File

@ -42,7 +42,7 @@
<string name="Yesterday">gisteren</string>
<string name="NoResult">Geen resultaten</string>
<string name="NoChats">Nog geen gesprekken…</string>
<string name="NoChatsHelp">Tik op de opstelknop rechtsbovenin\nom een gesprek te beginnen\nof ga naar de contactenlijst.</string>
<string name="NoChatsHelp">Begin een gesprek door op de\nopstellen-knop rechtsboven te drukken\nof druk op de menuknop voor meer opties.</string>
<string name="WaitingForNetwork">Wachten op netwerk…</string>
<string name="Connecting">Verbinden…</string>
<string name="Updating">Bijwerken…</string>
@ -108,7 +108,7 @@
<string name="EncryptedPlaceholderTitleOutgoing">Je hebt %s uitgenodigd voor een geheime chat.</string>
<string name="EncryptedDescriptionTitle">Geheime chat functies:</string>
<string name="EncryptedDescription1">End-to-end encryptie</string>
<string name="EncryptedDescription2">Ontraceerbaar via onze servers</string>
<string name="EncryptedDescription2">Geen serveropslag</string>
<string name="EncryptedDescription3">Zelfvernietigingstimers</string>
<string name="EncryptedDescription4">Doorstuurbescherming</string>
<string name="YouWereKicked">Je bent verwijderd uit deze groep</string>
@ -171,8 +171,8 @@
<string name="OtherAt">om</string>
<string name="Online">online</string>
<string name="Offline">offline</string>
<string name="LastSeen">laatst gez.:</string>
<string name="LastSeenDate">laatst gez.:</string>
<string name="LastSeen">gezien</string>
<string name="LastSeenDate">gezien</string>
<string name="InviteFriends">Vrienden uitnodigen</string>
<!--group create view-->
@ -219,7 +219,7 @@
<string name="ShortMessageLifetime1h">1u</string>
<string name="ShortMessageLifetime1d">1d</string>
<string name="ShortMessageLifetime1w">1w</string>
<string name="EncryptionKeyDescription">Dit is een weergave van de encryptiesleutel voor deze geheime chat met <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Als deze afbeelding er bij <![CDATA[<b>]]>%2$s<![CDATA[</b>]]> hetzelfde uitziet, is jullie gesprek 200%% beveiligd.<![CDATA[<br><br>]]>Lees meer op telegram.org.</string>
<string name="EncryptionKeyDescription">Dit is een weergave van de encryptiesleutel voor deze geheime chat met <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.\n\nAls deze afbeelding er bij <![CDATA[<b>]]>%2$s<![CDATA[</b>]]> hetzelfde uitziet, is jullie gesprek 200%% beveiligd.\n\nLees meer op telegram.org.</string>
<!--settings view-->
<string name="ResetNotificationsText">Alle meldingsinstellingen herstellen</string>
@ -242,7 +242,7 @@
<string name="InAppPreview">Voorvertoningen</string>
<string name="Reset">RESETTEN</string>
<string name="ResetAllNotifications">Alle meldingen resetten</string>
<string name="UndoAllCustom">Alle aangepaste meldingsinstellingen ongedaan maken voor alle contacten en groepen.</string>
<string name="UndoAllCustom">Aangepaste meldingsinstellingen wissen voor contacten en groepen.</string>
<string name="NotificationsAndSounds">Meldingen en geluiden</string>
<string name="BlockedUsers">Geblokkeerde gebruikers</string>
<string name="SaveIncomingPhotos">Inkomende foto\'s opslaan</string>
@ -259,7 +259,7 @@
<string name="ContactJoined">Contact lid van Telegram</string>
<string name="Pebble">PEBBLE</string>
<string name="Language">Taal</string>
<string name="AskAQuestionInfo">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.<![CDATA[<br><br>]]>Bekijk ook de <![CDATA[<a href=\"http://telegram.org/faq#general\">veelgestelde vragen</a>]]>: hier staan de antwoorden op de meeste vragen en belangrijke tips voor <![CDATA[<a href=\"http://telegram.org/faq#troubleshooting\">het oplossen van problemen</a>]]>.</string>
<string name="AskAQuestionInfo">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 <![CDATA[<a href=\"http://telegram.org/faq#general\">veelgestelde vragen</a>]]>: hier staan de antwoorden op de meeste vragen en belangrijke tips voor <![CDATA[<a href=\"http://telegram.org/faq#troubleshooting\">het oplossen van problemen</a>]]>.</string>
<string name="AskButton">Vraag een vrijwilliger</string>
<string name="TelegramFaq">Veelgestelde vragen</string>
<string name="TelegramFaqUrl">https://telegram.org/faq</string>
@ -317,7 +317,8 @@
<string name="EditVideo">Video bewerken</string>
<string name="OriginalVideo">Originele video</string>
<string name="EditedVideo">Bewerkte video</string>
<string name="SendingVideo">Sending video...</string>
<string name="SendingVideo">Video versturen...</string>
<string name="CompressVideo">Video comprimeren</string>
<!--button titles-->
<string name="Next">Volgende</string>
@ -387,7 +388,7 @@
<string name="DeleteChatQuestion">Dit gesprek verwijderen?</string>
<string name="SendMessagesTo">Berichten naar %1$s verzenden?</string>
<string name="AreYouSureLogout">Weet je zeker dat je wilt uitloggen?</string>
<string name="AreYouSureSessions">Weet je zeker dat je alle andere sessies wilt beëindigen?</string>
<string name="AreYouSureSessions">Alle apparaten behalve het huidige apparaat uitloggen?</string>
<string name="AreYouSureDeleteAndExit">Weet je zeker dat je alles wilt verwijderen en de groep wilt verlaten?</string>
<string name="AreYouSureDeleteThisChat">Weet je zeker dat je dit gesprek wilt verwijderen?</string>
<string name="AreYouSureShareMyContactInfo">Weet je zeker dat je je contactinformatie wilt delen?</string>
@ -405,13 +406,13 @@
<string name="Page5Title">Krachtig</string>
<string name="Page6Title">In de cloud</string>
<string name="Page7Title">Privé</string>
<string name="Page1Message">\'s Werelds <![CDATA[<b>snelste</b>]]> berichtendienst.<![CDATA[<br/>]]>Het is <![CDATA[<b>veilig</b>]]> en <![CDATA[<b>gratis</b>]]>.</string>
<string name="Page2Message"><![CDATA[<b>Telegram</b>]]> bezorgt berichten<![CDATA[<br/>]]>sneller dan elke andere applicatie.</string>
<string name="Page3Message"><![CDATA[<b>Telegram</b>]]> is altijd gratis. <![CDATA[<br/>]]>Geen advertenties.<![CDATA[<br/>]]>Geen abonnementskosten.</string>
<string name="Page4Message"><![CDATA[<b>Telegram</b>]]> beveiligt je berichten<![CDATA[<br/>]]>tegen aanvallen van hackers.</string>
<string name="Page5Message"><![CDATA[<b>Telegram</b>]]> beperkt je niet<![CDATA[<br/>]]>in de grootte van je media of gesprekken.</string>
<string name="Page6Message"><![CDATA[<b>Telegram</b>]]> biedt toegang tot je berichten<![CDATA[<br/>]]>vanaf meerdere apparaten.</string>
<string name="Page7Message"><![CDATA[<b>Telegram</b>]]> berichten zijn sterk versleuteld<![CDATA[<br/>]]>en kunnen zichzelf vernietigen</string>
<string name="Page1Message">\'s Werelds <![CDATA[<b>snelste</b>]]> berichtendienst.\nHet is <![CDATA[<b>veilig</b>]]> en <![CDATA[<b>gratis</b>]]>.</string>
<string name="Page2Message"><![CDATA[<b>Telegram</b>]]> bezorgt berichten\nsneller dan elke andere applicatie.</string>
<string name="Page3Message"><![CDATA[<b>Telegram</b>]]> is altijd gratis. \nGeen advertenties.\nGeen abonnementskosten.</string>
<string name="Page4Message"><![CDATA[<b>Telegram</b>]]> beveiligt je berichten\ntegen aanvallen van hackers.</string>
<string name="Page5Message"><![CDATA[<b>Telegram</b>]]> beperkt je niet\nin de grootte van je media of gesprekken.</string>
<string name="Page6Message"><![CDATA[<b>Telegram</b>]]> biedt toegang tot je berichten\nvanaf meerdere apparaten.</string>
<string name="Page7Message"><![CDATA[<b>Telegram</b>]]> berichten zijn sterk versleuteld\nen kunnen zichzelf vernietigen.</string>
<string name="StartMessaging">Begin met chatten</string>
<!--plurals-->

View File

@ -42,7 +42,7 @@
<string name="Yesterday">ontem</string>
<string name="NoResult">Nenhum resultado</string>
<string name="NoChats">Ainda não há conversas...</string>
<string name="NoChatsHelp">Comece a conversar pressionando o\nbotão \'Nova Mensagem\' no canto superior direito\nou vá para a seção \'Contatos\'</string>
<string name="NoChatsHelp">Comece a conversar pressionando o\nbotão \'Nova Mensagem\' no canto superior direito\nou vá para a seção \'Contatos\'.</string>
<string name="WaitingForNetwork">Aguardando rede...</string>
<string name="Connecting">Conectando...</string>
<string name="Updating">Atualizando...</string>
@ -166,13 +166,13 @@
<string name="SelectContact">Selecionar Contato</string>
<string name="NoContacts">Ainda não há contatos</string>
<string name="InviteText">Ei, vamos mudar para o Telegram: http://telegram.org/dl2</string>
<string name="TodayAt">hoje à(s)</string>
<string name="YesterdayAt">ontem à(s)</string>
<string name="OtherAt">em</string>
<string name="TodayAt">hoje às</string>
<string name="YesterdayAt">ontem às</string>
<string name="OtherAt">às</string>
<string name="Online">online</string>
<string name="Offline">offline</string>
<string name="LastSeen">visto pela última vez</string>
<string name="LastSeenDate">visto pela última vez</string>
<string name="LastSeen">visto por último</string>
<string name="LastSeenDate">visto por último</string>
<string name="InviteFriends">Convidar Amigos</string>
<!--group create view-->
@ -318,6 +318,7 @@
<string name="OriginalVideo">Vídeo Original</string>
<string name="EditedVideo">Vídeo Editado</string>
<string name="SendingVideo">Sending video...</string>
<string name="CompressVideo">Compress video</string>
<!--button titles-->
<string name="Next">Próximo</string>
@ -405,7 +406,7 @@
<string name="Page5Title">Poderoso</string>
<string name="Page6Title">Baseado na nuvem</string>
<string name="Page7Title">Privado</string>
<string name="Page1Message">Bem-vindo à era das mensagens<![CDATA[<br/>]]> rápidas e seguras</string>
<string name="Page1Message">O Mais <![CDATA[<b>rápido</b>]]> aplicativo de mensagens\ndo mundo. É <![CDATA[<b>grátis</b>]]> e <![CDATA[<b>seguro</b>]]>.</string>
<string name="Page2Message"><![CDATA[<b>Telegram</b>]]> envia mensagens mais rapidamente do que qualquer outro aplicativo</string>
<string name="Page3Message"><![CDATA[<b>Telegram</b>]]> será gratuito para sempre. Sem propagandas. Sem mensalidades</string>
<string name="Page4Message"><![CDATA[<b>Telegram</b>]]> mantém suas mensagens seguras contra ataques de hackers</string>

View File

@ -318,6 +318,7 @@
<string name="OriginalVideo">Original Video</string>
<string name="EditedVideo">Edited Video</string>
<string name="SendingVideo">Sending video...</string>
<string name="CompressVideo">Compress Video</string>
<!--button titles-->
<string name="Next">Seguinte</string>

View File

@ -42,7 +42,7 @@
<string name="Yesterday">yesterday</string>
<string name="NoResult">No results</string>
<string name="NoChats">No chats yet...</string>
<string name="NoChatsHelp">Start messaging by pressing the\ncompose button in the top right corner\nor go to the Contacts section.</string>
<string name="NoChatsHelp">Start messaging by pressing the\ncompose button in the top right corner\nor tap the menu button for more options.</string>
<string name="WaitingForNetwork">Waiting for network...</string>
<string name="Connecting">Connecting...</string>
<string name="Updating">Updating...</string>
@ -259,7 +259,7 @@
<string name="ContactJoined">Contact joined Telegram</string>
<string name="Pebble">PEBBLE</string>
<string name="Language">Language</string>
<string name="AskAQuestionInfo">Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.<![CDATA[<br><br>]]>Please take a look at the <![CDATA[<a href="http://telegram.org/faq#general">Telegram FAQ</a>]]>: it has answers to most questions and important tips for <![CDATA[<a href="http://telegram.org/faq#troubleshooting">troubleshooting</a>]]>.</string>
<string name="AskAQuestionInfo">Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.<![CDATA[<br><br>]]>Please take a look at the <![CDATA[<a href=\"http://telegram.org/faq#general\">Telegram FAQ</a>]]>: it has answers to most questions and important tips for <![CDATA[<a href=\"http://telegram.org/faq#troubleshooting\">troubleshooting</a>]]>.</string>
<string name="AskButton">Ask a volunteer</string>
<string name="TelegramFaq">Telegram FAQ</string>
<string name="TelegramFaqUrl">https://telegram.org/faq</string>
@ -277,8 +277,8 @@
<string name="LedColor">LED Color</string>
<string name="PopupNotification">Popup Notifications</string>
<string name="NoPopup">No popup</string>
<string name="OnlyWhenScreenOn">Only when screen "on"</string>
<string name="OnlyWhenScreenOff">Only when screen "off"</string>
<string name="OnlyWhenScreenOn">Only when screen \"on\"</string>
<string name="OnlyWhenScreenOff">Only when screen \"off\"</string>
<string name="AlwaysShowPopup">Always show popup</string>
<string name="BadgeNumber">Badge Counter</string>
<string name="Short">Short</string>
@ -318,6 +318,7 @@
<string name="OriginalVideo">Original Video</string>
<string name="EditedVideo">Edited Video</string>
<string name="SendingVideo">Sending video...</string>
<string name="CompressVideo">Compress Video</string>
<!--button titles-->
<string name="Next">Next</string>
@ -405,7 +406,7 @@
<string name="Page5Title">Powerful</string>
<string name="Page6Title">Cloud-Based</string>
<string name="Page7Title">Private</string>
<string name="Page1Message">The world\'s fastets messaging app.\nIt is free and secure.</string>
<string name="Page1Message">The world\'s <![CDATA[<b>fastest</b>]]> messaging app.\nIt is <![CDATA[<b>free</b>]]> and <![CDATA[<b>secure</b>]]>.</string>
<string name="Page2Message"><![CDATA[<b>Telegram</b>]]> delivers messages faster than<![CDATA[<br/>]]>any other application</string>
<string name="Page3Message"><![CDATA[<b>Telegram</b>]]> is free forever. No ads.<![CDATA[<br/>]]>No subscription fees</string>
<string name="Page4Message"><![CDATA[<b>Telegram</b>]]> keeps your messages safe<![CDATA[<br/>]]>from hacker attacks</string>