This commit is contained in:
John Preston 2016-01-01 05:00:47 +08:00
commit 2b4e58b1b9
12 changed files with 459 additions and 271 deletions

View file

@ -901,7 +901,7 @@ StorageImage *getImage(const StorageImageLocation &location, const QByteArray &b
}
WebImage::WebImage(const QString &url) : _url(url), _width(0), _height(0), _size(0) {
WebImage::WebImage(const QString &url) : _url(url), _size(0), _width(0), _height(0) {
}
int32 WebImage::width() const {

View file

@ -5587,6 +5587,207 @@ HistoryWebPage::~HistoryWebPage() {
deleteAndMark(_attach);
}
namespace {
ImageLinkManager manager;
}
void ImageLinkManager::init() {
if (manager) delete manager;
manager = new QNetworkAccessManager();
App::setProxySettings(*manager);
connect(manager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(onFailed(QNetworkReply*)));
connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(onFailed(QNetworkReply*)));
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*)));
if (black) delete black;
QImage b(cIntRetinaFactor(), cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
{
QPainter p(&b);
p.fillRect(QRect(0, 0, cIntRetinaFactor(), cIntRetinaFactor()), st::white->b);
}
QPixmap p = QPixmap::fromImage(b, Qt::ColorOnly);
p.setDevicePixelRatio(cRetinaFactor());
black = new ImagePtr(p, "PNG");
}
void ImageLinkManager::reinit() {
if (manager) App::setProxySettings(*manager);
}
void ImageLinkManager::deinit() {
if (manager) {
delete manager;
manager = 0;
}
if (black) {
delete black;
black = 0;
}
dataLoadings.clear();
imageLoadings.clear();
}
void initImageLinkManager() {
manager.init();
}
void reinitImageLinkManager() {
manager.reinit();
}
void deinitImageLinkManager() {
manager.deinit();
}
void ImageLinkManager::getData(ImageLinkData *data) {
if (!manager) {
DEBUG_LOG(("App Error: getting image link data without manager init!"));
return failed(data);
}
QString url;
switch (data->type) {
case GoogleMapsLink: {
int32 w = st::locationSize.width(), h = st::locationSize.height();
int32 zoom = 13, scale = 1;
if (cScale() == dbisTwo || cRetina()) {
scale = 2;
} else {
w = convertScale(w);
h = convertScale(h);
}
url = qsl("https://maps.googleapis.com/maps/api/staticmap?center=") + data->id.mid(9) + qsl("&zoom=%1&size=%2x%3&maptype=roadmap&scale=%4&markers=color:red|size:big|").arg(zoom).arg(w).arg(h).arg(scale) + data->id.mid(9) + qsl("&sensor=false");
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
imageLoadings[reply] = data;
} break;
default: {
failed(data);
} break;
}
}
void ImageLinkManager::onFinished(QNetworkReply *reply) {
if (!manager) return;
if (reply->error() != QNetworkReply::NoError) return onFailed(reply);
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (statusCode.isValid()) {
int status = statusCode.toInt();
if (status == 301 || status == 302) {
QString loc = reply->header(QNetworkRequest::LocationHeader).toString();
if (!loc.isEmpty()) {
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
if (i != dataLoadings.cend()) {
ImageLinkData *d = i.value();
if (serverRedirects.constFind(d) == serverRedirects.cend()) {
serverRedirects.insert(d, 1);
} else if (++serverRedirects[d] > MaxHttpRedirects) {
DEBUG_LOG(("Network Error: Too many HTTP redirects in onFinished() for image link: %1").arg(loc));
return onFailed(reply);
}
dataLoadings.erase(i);
dataLoadings.insert(manager->get(QNetworkRequest(loc)), d);
return;
} else if ((i = imageLoadings.find(reply)) != imageLoadings.cend()) {
ImageLinkData *d = i.value();
if (serverRedirects.constFind(d) == serverRedirects.cend()) {
serverRedirects.insert(d, 1);
} else if (++serverRedirects[d] > MaxHttpRedirects) {
DEBUG_LOG(("Network Error: Too many HTTP redirects in onFinished() for image link: %1").arg(loc));
return onFailed(reply);
}
imageLoadings.erase(i);
imageLoadings.insert(manager->get(QNetworkRequest(loc)), d);
return;
}
}
}
if (status != 200) {
DEBUG_LOG(("Network Error: Bad HTTP status received in onFinished() for image link: %1").arg(status));
return onFailed(reply);
}
}
ImageLinkData *d = 0;
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
if (i != dataLoadings.cend()) {
d = i.value();
dataLoadings.erase(i);
QJsonParseError e;
QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &e);
if (e.error != QJsonParseError::NoError) {
DEBUG_LOG(("JSON Error: Bad json received in onFinished() for image link"));
return onFailed(reply);
}
switch (d->type) {
case GoogleMapsLink: failed(d); break;
}
if (App::main()) App::main()->update();
} else {
i = imageLoadings.find(reply);
if (i != imageLoadings.cend()) {
d = i.value();
imageLoadings.erase(i);
QPixmap thumb;
QByteArray format;
QByteArray data(reply->readAll());
{
QBuffer buffer(&data);
QImageReader reader(&buffer);
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
reader.setAutoTransform(true);
#endif
thumb = QPixmap::fromImageReader(&reader, Qt::ColorOnly);
format = reader.format();
thumb.setDevicePixelRatio(cRetinaFactor());
if (format.isEmpty()) format = QByteArray("JPG");
}
d->loading = false;
d->thumb = thumb.isNull() ? (*black) : ImagePtr(thumb, format);
serverRedirects.remove(d);
if (App::main()) App::main()->update();
}
}
}
void ImageLinkManager::onFailed(QNetworkReply *reply) {
if (!manager) return;
ImageLinkData *d = 0;
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
if (i != dataLoadings.cend()) {
d = i.value();
dataLoadings.erase(i);
} else {
i = imageLoadings.find(reply);
if (i != imageLoadings.cend()) {
d = i.value();
imageLoadings.erase(i);
}
}
DEBUG_LOG(("Network Error: failed to get data for image link %1, error %2").arg(d ? d->id : 0).arg(reply->errorString()));
if (d) {
failed(d);
}
}
void ImageLinkManager::failed(ImageLinkData *data) {
data->loading = false;
data->thumb = *black;
serverRedirects.remove(data);
}
void ImageLinkData::load() {
if (!thumb->isNull()) return thumb->load(false, false);
if (loading) return;
loading = true;
manager.getData(this);
}
HistoryImageLink::HistoryImageLink(const QString &url, const QString &title, const QString &description) : HistoryMedia(),
_title(st::msgMinWidth),
_description(st::msgMinWidth) {

View file

@ -1859,6 +1859,54 @@ private:
int16 _pixw, _pixh;
};
void initImageLinkManager();
void reinitImageLinkManager();
void deinitImageLinkManager();
enum ImageLinkType {
InvalidImageLink = 0,
GoogleMapsLink
};
struct ImageLinkData {
ImageLinkData(const QString &id) : id(id), type(InvalidImageLink), loading(false) {
}
QString id;
ImagePtr thumb;
ImageLinkType type;
bool loading;
void load();
};
class ImageLinkManager : public QObject {
Q_OBJECT
public:
ImageLinkManager() : manager(0), black(0) {
}
void init();
void reinit();
void deinit();
void getData(ImageLinkData *data);
~ImageLinkManager() {
deinit();
}
public slots:
void onFinished(QNetworkReply *reply);
void onFailed(QNetworkReply *reply);
private:
void failed(ImageLinkData *data);
QNetworkAccessManager *manager;
QMap<QNetworkReply*, ImageLinkData*> dataLoadings, imageLoadings;
QMap<ImageLinkData*, int32> serverRedirects;
ImagePtr *black;
};
class HistoryImageLink : public HistoryMedia {
public:

View file

@ -48,6 +48,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month11" = "November";
"lng_month12" = "Dezember";
"lng_month1_small" = "Jan";
"lng_month2_small" = "Feb";
"lng_month3_small" = "Mär";
"lng_month4_small" = "Apr";
"lng_month5_small" = "Mai";
"lng_month6_small" = "Jun";
"lng_month7_small" = "Jul";
"lng_month8_small" = "Aug";
"lng_month9_small" = "Sept";
"lng_month10_small" = "Okt";
"lng_month11_small" = "Nov";
"lng_month12_small" = "Dez";
"lng_weekday1" = "Mo";
"lng_weekday2" = "Di";
"lng_weekday3" = "Mi";
@ -66,6 +79,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month_day" = "{day}. {month}";
"lng_month_day_year" = "{day} {month}, {year}";
"lng_month_year" = "{month}, {year}";
"lng_box_ok" = "OK";
@ -108,6 +122,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_server_error" = "Interner Serverfehler.";
"lng_flood_error" = "Zu viele Versuche, bitte später erneut probieren.";
"lng_gif_error" = "Ein Fehler ist beim Laden der GIF-Animation aufgetreten :(";
"lng_deleted" = "Gelöschter Kontakt";
"lng_deleted_message" = "Gelöschte Nachricht";
@ -470,8 +485,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_create_channel_crop" = "Sichtbaren Bereich für Bild wählen";
"lng_failed_add_participant" = "Kann Teilnehmer nicht hinzufügen. Später erneut versuchen.";
"lng_failed_add_not_mutual" = "Wenn man eine Gruppe verlässt, kann nur\nein gemeinsamer Kontakt die Person erneut\neinladen (beide Seiten müssen die Nummer\ndes anderen gespeichert haben).";
"lng_failed_add_not_mutual_channel" = "Wenn man einen Kanal verlässt, kann nur\nein gemeinsamer Kontakt die Person erneut\neinladen (beide Seiten müssen die Nummer\ndes anderen gespeichert haben).";
"lng_failed_add_not_mutual" = "Wenn man eine Gruppe verlässt, kann nur ein gemeinsamer Kontakt die Person erneut einladen (beide Seiten müssen die Nummer \ndes anderen gespeichert haben).";
"lng_failed_add_not_mutual_channel" = "Wenn man einen Kanal verlässt, kann nur ein gemeinsamer Kontakt die Person erneut einladen (beide Seiten müssen die Nummer \ndes anderen gespeichert haben).";
"lng_sure_delete_contact" = "Bist du sicher, dass du {contact} von deinen Kontakten löschen willst?";
"lng_sure_delete_history" = "Sicher, dass du den kompletten Verlauf mit {contact} löschen willst?\n\nDas kann man nicht rückgängig machen.";
@ -561,6 +576,14 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_media_video" = "Videodatei";
"lng_media_audio" = "Sprachnachricht";
"lng_media_auto_settings" = "Einstellungen für Mediendownloads";
"lng_media_auto_photo" = "Automatischer Bilder-Download";
"lng_media_auto_audio" = "Automatischer Audio-Download";
"lng_media_auto_gif" = "Automatischer GIF-Download";
"lng_media_auto_private_chats" = "Chats";
"lng_media_auto_groups" = "Gruppen und Kanäle";
"lng_media_auto_play" = "Automatisch Abspielen";
"lng_emoji_category0" = "Häufig genutzt";
"lng_emoji_category1" = "Personen";
"lng_emoji_category2" = "Natur";
@ -571,8 +594,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_emoji_category7" = "Symbole & Flaggen";
"lng_switch_stickers" = "Sticker";
"lng_switch_stickers_gifs" = "GIFs & Sticker";
"lng_switch_emoji" = "Emoji";
"lng_saved_gifs" = "Gespeicherte GIFs";
"lng_inline_bot_results" = "Ergebnisse von {inline_bot}";
"lng_inline_bot_no_results" = "Keine Ergebnisse";
"lng_box_remove" = "Entfernen";
"lng_custom_stickers" = "Eigene Sticker";
@ -664,6 +692,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_save_file" = "Datei speichern";
"lng_save_downloaded" = "{ready} / {total} {mb}";
"lng_duration_and_size" = "{duration}, {size}";
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Bilder auswählen";
"lng_context_view_profile" = "Profil öffnen";
@ -699,6 +729,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_context_delete_file" = "Datei löschen";
"lng_context_close_file" = "Datei schließen";
"lng_context_copy_text" = "Text kopieren";
"lng_context_save_gif" = "GIF speichern";
"lng_context_to_msg" = "Zur Nachricht";
"lng_context_reply_msg" = "Antworten";
"lng_context_forward_msg" = "Nachricht weiterleiten";
@ -801,7 +832,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
"lng_new_version_text" = "— Sticker-Verwaltung: Ändere die Sortierung deiner Sticker-Pakete, Sortierung wird auf all deinen Geräten synchronisiert \n— Sticker gedrückt halten vor dem Versand für eine Vorschau\n— Neues Kontextmenü für Chats in der Chatliste \n— Neue Emoji werden unterstützt\n\nUnseren deutschsprachigen Infokanal findest du hier: https://telegram.me/TelegramDE";
"lng_new_version_text" = "GIF-Revolution: 10x schnelleres Senden und Herunterladen, Autoplay und Speichern von GIFs in einem eigenen Tab im Sticker-Panel.\n\nMehr Infos über GIFs:\n{gifs_link}\n\nInline-Bots: Ein neuer Weg um Bot-Inhalte dem Chat hinzuzufügen. Einfach den Bot-Benutzernamen gefolgt vom Suchbegriff im Eingabefeld eintippen um Echtzeitsuchergebnisse zu erhalten und im Chat zu senden. Probier doch mal \"@gif katze\" im nächsten Chat aus. Beispiel-Bots: @gif, @wiki, @bingpic, @vid.\n\nAusführliche Informationen zu den neuen Inline-Bots: {bot_link}\n\nAußerdem neu: Ein neues niedliches Design für Medien, automatische Download-Einstellungen für Bilder, Sprachnachrichten und GIFs.\n\nPS: Unseren deutschsprachigen Infokanal findest du hier: https://telegram.me/TelegramDE";
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";

View file

@ -48,6 +48,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month11" = "noviembre";
"lng_month12" = "diciembre";
"lng_month1_small" = "ene";
"lng_month2_small" = "feb";
"lng_month3_small" = "mar";
"lng_month4_small" = "abr";
"lng_month5_small" = "may";
"lng_month6_small" = "jun";
"lng_month7_small" = "jul";
"lng_month8_small" = "ago";
"lng_month9_small" = "sep";
"lng_month10_small" = "oct";
"lng_month11_small" = "nov";
"lng_month12_small" = "dic";
"lng_weekday1" = "lun";
"lng_weekday2" = "mar";
"lng_weekday3" = "mié";
@ -66,6 +79,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month_day" = "{day} de {month}";
"lng_month_day_year" = "{day} de {month} de {year}";
"lng_month_year" = "{month}, {year}";
"lng_box_ok" = "OK";
@ -108,6 +122,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_server_error" = "Error interno del servidor.";
"lng_flood_error" = "Muchos intentos. Por favor, reinténtalo más tarde.";
"lng_gif_error" = "Ocurrió un error al leer la animación GIF :(";
"lng_deleted" = "Desconocido";
"lng_deleted_message" = "Mensaje eliminado";
@ -470,8 +485,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_create_channel_crop" = "Selecciona el área para la foto del canal";
"lng_failed_add_participant" = "No se pudo añadir al usuario. Por favor, reinténtalo más tarde.";
"lng_failed_add_not_mutual" = "Lo sentimos, si una persona deja un\ngrupo, sólo un contacto mutuo puede \ntraerlo de vuelta (ellos necesitan tener\ntu número, y tú el suyo).";
"lng_failed_add_not_mutual_channel" = "Lo sentimos, si una persona deja el canal, \nsólo un contacto mutuo puede volver \na invitarlo (necesitan tener tu \nnúmero y tú el de ellos).";
"lng_failed_add_not_mutual" = "Lo sentimos, si una persona deja el grupo, sólo un contacto mutuo puede volver a invitarlo (necesitan tener tu número y tú el suyo).";
"lng_failed_add_not_mutual_channel" = "Lo sentimos, si una persona deja el canal, sólo un contacto mutuo puede volver a invitarlo (necesitan tener tu número y tú el suyo).";
"lng_sure_delete_contact" = "¿Quieres eliminar a {contact} de tu lista de contactos?";
"lng_sure_delete_history" = "¿Quieres borrar todo el historial de mensajes con {contact}?\n\nEsta acción no se puede deshacer.";
@ -561,6 +576,14 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_media_video" = "Vídeo";
"lng_media_audio" = "Mensaje de voz";
"lng_media_auto_settings" = "Ajustes de descarga automática de multimedia";
"lng_media_auto_photo" = "Descarga automática de fotos";
"lng_media_auto_audio" = "Descarga automática de audio";
"lng_media_auto_gif" = "Descarga automática de GIF";
"lng_media_auto_private_chats" = "Chats";
"lng_media_auto_groups" = "Grupos y canales";
"lng_media_auto_play" = "Autorreproducir";
"lng_emoji_category0" = "Uso frecuente";
"lng_emoji_category1" = "Personas";
"lng_emoji_category2" = "Naturaleza";
@ -571,8 +594,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_emoji_category7" = "Símbolos y banderas";
"lng_switch_stickers" = "Stickers";
"lng_switch_stickers_gifs" = "GIF y stickers";
"lng_switch_emoji" = "Emoji";
"lng_saved_gifs" = "GIF guardados";
"lng_inline_bot_results" = "Resultados de {inline_bot}";
"lng_inline_bot_no_results" = "Sin resultados";
"lng_box_remove" = "Eliminar";
"lng_custom_stickers" = "Stickers personalizados";
@ -664,6 +692,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_save_file" = "Guardar archivo";
"lng_save_downloaded" = "{ready} / {total} {mb}";
"lng_duration_and_size" = "{duration}, {size}";
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Elegir imágenes";
"lng_context_view_profile" = "Ver información";
@ -699,6 +729,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_context_delete_file" = "Eliminar archivo";
"lng_context_close_file" = "Cerrar archivo";
"lng_context_copy_text" = "Copiar texto";
"lng_context_save_gif" = "Guardar GIF";
"lng_context_to_msg" = "Ir al mensaje";
"lng_context_reply_msg" = "Responder";
"lng_context_forward_msg" = "Reenviar mensaje";
@ -801,7 +832,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_new_version_wrap" = "Telegram Desktop ha sido actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
"lng_new_version_text" = "— Administra los stickers: ordena manualmente tus packs de stickers. El orden de los packs se sincronizará en todos tus dispositivos \n— Haz clic y mantén en un sticker para ver una vista previa antes de enviar\n— Nuevo menú contextual para los chats en la lista de chats \n— Soporte de todos los emojis existentes";
"lng_new_version_text" = "Revolución del GIF: envío y descarga 10 veces más rápido, reproducción automática, guarda tus GIF favoritos en una pestaña especial en el panel de stickers.\n\nMás sobre los GIF:\n{gifs_link}\n\nBots integrados: una nueva forma para añadir contenidos en los chats. Escribe el alias del bot y tu solicitud, en el campo de escritura, para obtener resultados inmediatamente y enviarlos a tu compañero de chat. Prueba escribiendo \"@gif perro\" en un chat. Algunos ejemplos: @gif, @wiki, @bingpic, @vid.\n\nMás sobre los bots integrados:\n{bots_link}\n\nTambién encontrarás un lindo nuevo diseño para la multimedia y ajustes de descarga automática para fotos, mensajes de voz y GIF.";
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";

View file

@ -48,6 +48,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month11" = "Novembre";
"lng_month12" = "Dicembre";
"lng_month1_small" = "Gen";
"lng_month2_small" = "Feb";
"lng_month3_small" = "Mar";
"lng_month4_small" = "Apr";
"lng_month5_small" = "Mag";
"lng_month6_small" = "Giu";
"lng_month7_small" = "Lug";
"lng_month8_small" = "Ago";
"lng_month9_small" = "Set";
"lng_month10_small" = "Ott";
"lng_month11_small" = "Nov";
"lng_month12_small" = "Dic";
"lng_weekday1" = "Lun";
"lng_weekday2" = "Mar";
"lng_weekday3" = "Mer";
@ -66,6 +79,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month_day" = "{day} {month}";
"lng_month_day_year" = "{day} {month} {year}";
"lng_month_year" = "{month}, {year}";
"lng_box_ok" = "Ok";
@ -108,6 +122,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_server_error" = "Errore interno del server.";
"lng_flood_error" = "Troppi tentativi. Per favore riprova più tardi.";
"lng_gif_error" = "C'è stato un errore nel leggere la GIF :(";
"lng_deleted" = "Sconosciuto";
"lng_deleted_message" = "Messaggio eliminato";
@ -134,7 +149,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_code_ph" = "Codice";
"lng_code_desc" = "Abbiamo inviato un messaggio col codice\ndi attivazione al tuo telefono. Inseriscilo qui";
"lng_code_telegram" = "Per favore inserisci il codice che hai\nappena ricevuto nell'altra app di [b]Telegram[/b].";
"lng_code_no_telegram" = "Invia codice tramite SMS";
"lng_code_no_telegram" = "Invia codice via SMS";
"lng_code_call" = "Telegram ti chiamerà tra {minutes}:{seconds}";
"lng_code_calling" = "Richiedendo una telefonata da Telegram..";
"lng_code_called" = "Telegram ti ha chiamato";
@ -470,8 +485,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_create_channel_crop" = "Seleziona un riquadro per la foto del canale";
"lng_failed_add_participant" = "Impossibile aggiungere l'utente. Riprova più tardi.";
"lng_failed_add_not_mutual" = "Spiacenti, se una persona lascia un gruppo,\nsolo un contatto in comune può reinvitarla\n(chi ti invita deve avere il tuo contatto\nsu Telegram, e viceversa).";
"lng_failed_add_not_mutual_channel" = "Spiacenti, se una persona lascia un canale,\nsolo un contatto in comune può reinvitarla\n(chi ti invita deve avere il tuo contatto\nsu Telegram, e viceversa).";
"lng_failed_add_not_mutual" = "Spiacenti, se una persona lascia un gruppo, solo un contatto in comune può reinvitarla (chi ti invita deve avere il tuo numero, e viceversa).";
"lng_failed_add_not_mutual_channel" = "Spiacenti, se una persona lascia un canale, solo un contatto in comune può reinvitarla (chi ti invita deve avere il tuo numero, e viceversa).";
"lng_sure_delete_contact" = "Sicuro di volere eliminare {contact} dalla tua lista dei contatti?";
"lng_sure_delete_history" = "Sicuro di voler eliminare tutta la cronologia dei messaggi con {contact}?\n\nQuesta azione non può essere annullata.";
@ -496,7 +511,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_action_kick_user" = "{from} ha rimosso {user}";
"lng_action_user_left" = "{from} ha lasciato il gruppo";
"lng_action_user_joined" = "{from} si è unito al gruppo";
"lng_action_user_joined_by_link" = "{from} si è unito al gruppo tramite link di invito";
"lng_action_user_joined_by_link" = "{from} si è unito al gruppo via link di invito";
"lng_action_user_registered" = "{from} si è unito a Telegram";
"lng_action_removed_photo" = "{from} ha rimosso la foto del gruppo";
"lng_action_removed_photo_channel" = "Foto del canale rimossa";
@ -561,6 +576,14 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_media_video" = "Video";
"lng_media_audio" = "Nota vocale";
"lng_media_auto_settings" = "Impostazioni di download automatico";
"lng_media_auto_photo" = "Download automatico foto";
"lng_media_auto_audio" = "Download automatico audio";
"lng_media_auto_gif" = "Download automatico GIF";
"lng_media_auto_private_chats" = "Chat";
"lng_media_auto_groups" = "Gruppi e canali";
"lng_media_auto_play" = "Autoriproduzione";
"lng_emoji_category0" = "Utilizzate di frequente";
"lng_emoji_category1" = "Persone";
"lng_emoji_category2" = "Natura";
@ -571,8 +594,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_emoji_category7" = "Simboli e bandiere";
"lng_switch_stickers" = "Sticker";
"lng_switch_stickers_gifs" = "GIF e Sticker";
"lng_switch_emoji" = "Emoji";
"lng_saved_gifs" = "GIF salvate";
"lng_inline_bot_results" = "Risultati da {inline_bot}";
"lng_inline_bot_no_results" = "Nessun risultato";
"lng_box_remove" = "Rimuovi";
"lng_custom_stickers" = "Sticker personalizzati";
@ -664,6 +692,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_save_file" = "Salva file";
"lng_save_downloaded" = "{ready} / {total} {mb}";
"lng_duration_and_size" = "{duration}, {size}";
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Scegli immagini";
"lng_context_view_profile" = "Visualizza profilo";
@ -699,6 +729,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_context_delete_file" = "Elimina file";
"lng_context_close_file" = "Chiudi file";
"lng_context_copy_text" = "Copia testo";
"lng_context_save_gif" = "Salva GIF";
"lng_context_to_msg" = "Vai al messaggio";
"lng_context_reply_msg" = "Rispondi";
"lng_context_forward_msg" = "Inoltra messaggio";
@ -801,7 +832,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}";
"lng_new_version_minor" = "— Bug fix e altri miglioramenti minori";
"lng_new_version_text" = "— Gestione degli sticker: Riordina manualmente i tuoi set di sticker, ora sono sincronizzati tra i tuoi dispositivi\n— Clicca e tieni premuto su uno sticker per visualizzare l'anteprima prima di inviarlo\n— Nuovo menu contestuale per le chat nella lista chat\n— Tutte le nuove emoji ora sono supportate";
"lng_new_version_text" = "Rivoluzione GIF: L'invio e il download delle GIF sono ora 10 volte più veloci, riproduci automaticamente le GIF e salva le tue GIF preferite in una pagina dedicata nel pannello sticker.\n\nPiù info sulle GIF:\n{gifs_link}\n\n@-Bot: Un nuovo modo di aggiungere contenuto dai bot in qualsiasi chat. Scrivi l'username di un bot e la tua domanda nel campo di scrittura per ricevere risultati immediati e inviarli nella chat. Prova a scrivere “@gif dog” nella tua prossima chat. Bot di esempio: @gif, @wiki, @bingpic, @vid.\n\nPiù info sui @-Bot:\n{bots_link}\n\nInoltre in questa versione: Nuovo design per i media, impostazioni di download automatico per foto, note vocali e GIF.";
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";

View file

@ -48,6 +48,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month11" = "11월";
"lng_month12" = "12월";
"lng_month1_small" = "1월";
"lng_month2_small" = "2월";
"lng_month3_small" = "3월";
"lng_month4_small" = "4월";
"lng_month5_small" = "5월";
"lng_month6_small" = "6월";
"lng_month7_small" = "7월";
"lng_month8_small" = "8월";
"lng_month9_small" = "9월";
"lng_month10_small" = "10월";
"lng_month11_small" = "11월";
"lng_month12_small" = "12월";
"lng_weekday1" = "월";
"lng_weekday2" = "화";
"lng_weekday3" = "수";
@ -66,6 +79,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month_day" = "{month} {day}일";
"lng_month_day_year" = "{month} {day}, {year}";
"lng_month_year" = "{month}, {year}";
"lng_box_ok" = "확인";
@ -108,6 +122,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_server_error" = "내부 서버 오류";
"lng_flood_error" = "시도가 너무 많습니다. 나중에 다시 시도해주세요.";
"lng_gif_error" = "GIF 애니메이션을 읽는 동안 에러가 발생하였습니다.";
"lng_deleted" = "알 수 없음";
"lng_deleted_message" = "삭제된 메시지";
@ -470,8 +485,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_create_channel_crop" = "채널프로필 사진으로 사용할 사각영역을 선택하세요";
"lng_failed_add_participant" = "사용자를 추가 하지 못하였습니다. 나중에 다시 시도해주세요";
"lng_failed_add_not_mutual" = "죄송합니다. 그룹방에서 대화상대방이 나갔을 경우, \n상대 전화번호가 있는 분만 초대가 가능합니다. \n(서로 전화번호가 등록되어져 있어야만 가능)";
"lng_failed_add_not_mutual_channel" = "죄송합니다. 채널에서 대화상대방이 나갔을 경우,\n상대 전화번호가 있는 분만 초대가 가능합니다.\n(서로 전화번호가 등록되어져 있어야만 가능)";
"lng_failed_add_not_mutual" = "죄송합니다. 그룹방에서 대화상대방이 나갔을 경우, 상대 전화번호가 있는 분만 초대가 가능합니다. (서로 전화번호가 등록되어져 있어야만 가능)";
"lng_failed_add_not_mutual_channel" = "죄송합니다. 채널에서 대화상대방이 나갔을 경우, 상대 전화번호가 있는 분만 초대가 가능합니다. (서로 전화번호가 등록되어져 있어야만 가능)";
"lng_sure_delete_contact" = "{contact} 님을 주소록에서 \n삭제하시겠습니까?";
"lng_sure_delete_history" = "{contact} 님과 관련된 모든 메시지를 \n삭제하시겠습니까?\n\n삭제 하실 경우 취소가 불가능합니다.";
@ -561,6 +576,14 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_media_video" = "비디오 파일";
"lng_media_audio" = "음성 메시지";
"lng_media_auto_settings" = "미디어 자동 다운로드 설정";
"lng_media_auto_photo" = "사진 자동 다운로드";
"lng_media_auto_audio" = "음성 메시지 자동 다운로드";
"lng_media_auto_gif" = "GIF 자동 다운로드";
"lng_media_auto_private_chats" = "비밀대화";
"lng_media_auto_groups" = "그룹과 채널";
"lng_media_auto_play" = "자동재생";
"lng_emoji_category0" = "자주 사용";
"lng_emoji_category1" = "사람";
"lng_emoji_category2" = "자연";
@ -571,8 +594,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_emoji_category7" = "심볼 및 국기";
"lng_switch_stickers" = "스티커";
"lng_switch_stickers_gifs" = "GIF & 스티커";
"lng_switch_emoji" = "이모티콘";
"lng_saved_gifs" = "저장된 GIF";
"lng_inline_bot_results" = "{inline_bot} 결과";
"lng_inline_bot_no_results" = "결과 없음";
"lng_box_remove" = "삭제";
"lng_custom_stickers" = "커스텀 스티커";
@ -664,6 +692,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_save_file" = "파일 저장";
"lng_save_downloaded" = "{ready} / {total} {mb}";
"lng_duration_and_size" = "{duration}, {size}";
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "이미지 선택";
"lng_context_view_profile" = "프로필 보기";
@ -699,6 +729,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_context_delete_file" = "파일 삭제";
"lng_context_close_file" = "파일 닫기";
"lng_context_copy_text" = "텍스트 복사";
"lng_context_save_gif" = "GIF 저장";
"lng_context_to_msg" = "메시지로 이동";
"lng_context_reply_msg" = "답장";
"lng_context_forward_msg" = "메시지 전달";
@ -801,7 +832,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
"lng_new_version_text" = "— 스티커관리 : 스티커팩을 순서를 수동으로 변경하여, 연결된 모든 기기에 동기화 \n— 스티커를 지속하여 누를 경우 전송전 프리뷰 기능 추가\n— 채팅목록에 채팅관련 메뉴 추가\n— 기존 이모티콘 지원";
"lng_new_version_text" = "GIF 혁명: 10배 빠른 전송, 다운로드 및 자동재생이 가능하며, 스티커 패널에서 즐겨찾는 GIF를 저장가능\n\nGIF에 대한 자세한 정보:\n{gifs_link}\n\n@-봇 : 모든 대화에 봇 기능을 추가 할 수 있습니다. 봇 아이디를 입력란에 같이 입력해주시면 즉시 결과값을 확인 할 수 있습니다.\"@gif dog\"와 같은 명령어를 입력란에 같이 입력해보세요. 예시:@gif, @wiki, @bingpic, @vid.\n\n@-봇에 대한 자세한 정보\n{bots_link}\n\n업데이트 추가사항: 미디어, 사진, 음성메시지 및 GIF 파일 자동다운로드 설정화면 새로운 디자인 적용";
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";

View file

@ -48,6 +48,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month11" = "november";
"lng_month12" = "december";
"lng_month1_small" = "jan";
"lng_month2_small" = "feb";
"lng_month3_small" = "mrt";
"lng_month4_small" = "apr";
"lng_month5_small" = "mei";
"lng_month6_small" = "jun";
"lng_month7_small" = "jul";
"lng_month8_small" = "aug";
"lng_month9_small" = "sep";
"lng_month10_small" = "okt";
"lng_month11_small" = "nov";
"lng_month12_small" = "dec";
"lng_weekday1" = "ma";
"lng_weekday2" = "di";
"lng_weekday3" = "wo";
@ -66,6 +79,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month_day" = "{day} {month}";
"lng_month_day_year" = "{day} {month}, {year}";
"lng_month_year" = "{month}, {year}";
"lng_box_ok" = "Ok";
@ -108,6 +122,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_server_error" = "Interne serverfout.";
"lng_flood_error" = "Teveel pogingen. Probeer het later opnieuw.";
"lng_gif_error" = "Er is iets een fout opgetreden bij het lezen van de GIF :(";
"lng_deleted" = "Onbekend";
"lng_deleted_message" = "Verwijderd bericht";
@ -217,7 +232,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_settings_section_general" = "Algemeen";
"lng_settings_change_lang" = "Taal wijzigen";
"lng_languages" = "Talen";
"lng_sure_save_language" = "Telegram moet herstarten om de taal te wijzigen";
"lng_sure_save_language" = "Opnieuw starten om de taal te wijzen?";
"lng_settings_auto_update" = "Automatisch bijwerken";
"lng_settings_current_version" = "Versie {version}";
"lng_settings_check_now" = "Controleer op updates";
@ -470,8 +485,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_create_channel_crop" = "Kies een vierkant voor de kanaalfoto";
"lng_failed_add_participant" = "Gebruiker toevoegen mislukt. Probeer het later.";
"lng_failed_add_not_mutual" = "Iemand die de groep verlaat kan alleen\nDoor een wederzijds contact \nworden toegevoegd \n(opgeslagen nummers) ";
"lng_failed_add_not_mutual_channel" = "Iemand die het kanaal verlaat kan alleen\nDoor een wederzijds contact \nworden toegevoegd \n(opgeslagen nummers) ";
"lng_failed_add_not_mutual" = "Iemand die de groep verlaat kan alleen door een wederzijds contact worden toegevoegd (opgeslagen nummers)";
"lng_failed_add_not_mutual_channel" = "Iemand die het kanaal verlaat kan alleen door een wederzijds contact worden toegevoegd (opgeslagen nummers)";
"lng_sure_delete_contact" = "{contact} echt verwijderen uit contacten?";
"lng_sure_delete_history" = "Geschiedenis met {contact} echt wissen? \n\nDeze actie kan niet ongedaan worden gemaakt.";
@ -561,6 +576,14 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_media_video" = "Video";
"lng_media_audio" = "Spraakbericht";
"lng_media_auto_settings" = "Instellingen voor media-downloads";
"lng_media_auto_photo" = "Foto's automatisch downloaden";
"lng_media_auto_audio" = "Audio automatisch downloaden";
"lng_media_auto_gif" = "GIF's automatisch downloaden";
"lng_media_auto_private_chats" = "Chats";
"lng_media_auto_groups" = "Groepen en kanalen";
"lng_media_auto_play" = "Automatisch afspelen";
"lng_emoji_category0" = "Veelgebruikt";
"lng_emoji_category1" = "Mensen";
"lng_emoji_category2" = "Natuur";
@ -571,8 +594,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_emoji_category7" = "Symbolen en vlaggen";
"lng_switch_stickers" = "Stickers";
"lng_switch_stickers_gifs" = "GIF's & stickers";
"lng_switch_emoji" = "Emoji";
"lng_saved_gifs" = "Opgeslagen GIF's";
"lng_inline_bot_results" = "Resultaten van {inline_bot}";
"lng_inline_bot_no_results" = "Geen resultaten";
"lng_box_remove" = "Verwijder";
"lng_custom_stickers" = "Aangepaste stickers";
@ -664,6 +692,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_save_file" = "Bestand opslaan";
"lng_save_downloaded" = "{ready} / {total} {mb}";
"lng_duration_and_size" = "{duration}, {size}";
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Afbeeldingen kiezen";
"lng_context_view_profile" = "Profiel weergeven";
@ -699,6 +729,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_context_delete_file" = "Bestand verwijderen";
"lng_context_close_file" = "Bestand sluiten";
"lng_context_copy_text" = "Tekst kopiëren";
"lng_context_save_gif" = "GIF opslaan";
"lng_context_to_msg" = "Naar bericht gaan";
"lng_context_reply_msg" = "Antwoord";
"lng_context_forward_msg" = "Bericht doorsturen";
@ -801,7 +832,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
"lng_new_version_text" = "— Stickerbeheer: Je kunt nu handmatig je stickerbundels sorteren, de volgorde synchroniseren we voor je, over al je apparaten.\n— Klik en hou een sticker vast om een voorbeeld weer te geven voor het versturen.\n— Nieuw contextmenu voor chats in het chats-overzicht\n— Ondersteuning voor alle bestaande emoji";
"lng_new_version_text" = "GIF-revolutie: 10 keer zo snel GIF's sturen en downloaden. Speel ze automatisch af en sla je favorieten op in het stickerpaneel.\n\nmeer over GIFs:\n{gifs_link}\n\nInline-bots: Voeg botcontent toe aan chats op een nieuwe manier! Geef in het invoerveld de naam van een bot en je commando in en stuur de resultaten naar je chatpartner. Probeer het eens met “@gif dog”. Voorbeelden: @gif, @wiki, @bing, @vid.\n\nMeer over inline-bots:\n{bots_link}\n\nIn deze release hebben we nog meer voor je. Een nieuw design voor media en automatische download-instellingen voor foto's, spraakberichten en GIF's.";
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";

View file

@ -48,6 +48,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month11" = "Novembro";
"lng_month12" = "Dezembro";
"lng_month1_small" = "Jan";
"lng_month2_small" = "Fev";
"lng_month3_small" = "Mar";
"lng_month4_small" = "Abr";
"lng_month5_small" = "Mai";
"lng_month6_small" = "Jun";
"lng_month7_small" = "Jul";
"lng_month8_small" = "Ago";
"lng_month9_small" = "Set";
"lng_month10_small" = "Out";
"lng_month11_small" = "Nov";
"lng_month12_small" = "Dez";
"lng_weekday1" = "Seg";
"lng_weekday2" = "Ter";
"lng_weekday3" = "Qua";
@ -66,6 +79,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_month_day" = "{month} {day}";
"lng_month_day_year" = "{day} {month}, {year}";
"lng_month_year" = "{month}, {year}";
"lng_box_ok" = "OK";
@ -108,6 +122,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_server_error" = "Erro interno do servidor.";
"lng_flood_error" = "Muitas tentativas. Por favor, tente novamente mais tarde.";
"lng_gif_error" = "Um erro ocorreu com a animação do GIF :(";
"lng_deleted" = "Desconhecido";
"lng_deleted_message" = "Mensagem apagada";
@ -470,8 +485,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_create_channel_crop" = "Selecione uma área para a foto do canal";
"lng_failed_add_participant" = "Usuário não pôde ser adicionado. Tente novamente mais tarde.";
"lng_failed_add_not_mutual" = "Se uma pessoa deixou o grupo, apenas um\ncontato mútuo pode colocá-la novamente\n(eles precisam do seu número na agenda\ndo telefone e você do número deles).";
"lng_failed_add_not_mutual_channel" = "Se uma pessoa deixou o canal, apenas um\ncontato mútuo pode colocá-la novamente\n(eles precisam do seu número na agenda\ndo telefone e você do número deles).";
"lng_failed_add_not_mutual" = "Se uma pessoa deixou o grupo, apenas um contato mútuo pode colocá-la novamente (eles precisam do seu número na agenda do telefone e você do número deles).";
"lng_failed_add_not_mutual_channel" = "Se uma pessoa deixou o canal, apenas um contato mútuo pode colocá-la novamente (eles precisam do seu número na agenda do telefone e você do número deles).";
"lng_sure_delete_contact" = "Você tem certeza que deseja remover {contact} da sua lista de contatos?";
"lng_sure_delete_history" = "Você tem certeza que deseja apagar todo o seu histórico de mensagens com {contact}?\n\nEssa ação não pode ser desfeita.";
@ -561,6 +576,14 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_media_video" = "Vídeo";
"lng_media_audio" = "Mensagem de voz";
"lng_media_auto_settings" = "Configurações do download automático de mídia";
"lng_media_auto_photo" = "Baixar foto automaticamente";
"lng_media_auto_audio" = "Baixar mensagem de voz automaticamente";
"lng_media_auto_gif" = "Baixar GIF autometicamente";
"lng_media_auto_private_chats" = "Conversas privadas";
"lng_media_auto_groups" = "Grupos e canais";
"lng_media_auto_play" = "Reproduzir automaticamente";
"lng_emoji_category0" = "Frequentemente usado";
"lng_emoji_category1" = "Pessoas";
"lng_emoji_category2" = "Natureza";
@ -571,8 +594,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_emoji_category7" = "Símbolos e Bandeiras";
"lng_switch_stickers" = "Stickers";
"lng_switch_stickers_gifs" = "GIFs e Stickers";
"lng_switch_emoji" = "Emoji";
"lng_saved_gifs" = "GIFs Salvos";
"lng_inline_bot_results" = "Resultados de {inline_bot}";
"lng_inline_bot_no_results" = "Nenhum resultado";
"lng_box_remove" = "Remover";
"lng_custom_stickers" = "Stickers customizados";
@ -664,6 +692,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_save_file" = "Salvar arquivo";
"lng_save_downloaded" = "{ready} / {total} {mb}";
"lng_duration_and_size" = "{duration}, {size}";
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Escolher imagens";
"lng_context_view_profile" = "Ver perfil";
@ -699,6 +729,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_context_delete_file" = "Apagar Arquivo";
"lng_context_close_file" = "Fechar Arquivo";
"lng_context_copy_text" = "Copiar Texto";
"lng_context_save_gif" = "Salvar GIF";
"lng_context_to_msg" = "Ir Para Mensagem";
"lng_context_reply_msg" = "Responder";
"lng_context_forward_msg" = "Encaminhar Mensagem";
@ -801,7 +832,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
"lng_new_version_minor" = "— Resolução de bugs e outras melhorias menores";
"lng_new_version_text" = "— Gerenciamento de stickers: rearranje manualmente seus pacotes de sticker, a ordem dos pacotes agora é sincronizada entre todos os dispositivos\n— Clique e segure sobre um sticker para pré-visualizar antes de enviar\n— Novo menu de contexto para os chats na lista de chats \n— Suporte para todos os emojis existentes";
"lng_new_version_text" = "Revolução dos GIFs: download e envio 10x mais rápido, reprodução automática, salve seus GIFs favoritos em um guia dedicada no painel de stickers.\n\nMais sobre GIFs:\n{gifs_link}\n\nBots integrados: Uma nova maneira de adicionar conteúdo de um bot a qualquer conversa. Digite o nome de usuário do bot seguido do comando no campo de texto para obter resultados imediatos e enviá-los na conversa. Experimente digitar \"@gif cachorro\" na sua próxima conversa. Bots de exemplo: @gif, @wiki, @bing, @vid.\n\nMais sobre bots integrados:\n{bots_link}\n\nTambém nessa versão: Novo design para mídias, configuração de download automático para fotos, mensagens de voz e GIFs.";
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";

View file

@ -66,6 +66,8 @@ FileLoader::FileLoader(const QString &toFile, int32 size, LocationType locationT
, _inQueue(false)
, _complete(false)
, _localStatus(LocalNotTried)
, _file(toFile)
, _fname(toFile)
, _fileIsOpen(false)
, _toCache(toCache)
, _fromCloud(fromCloud)

View file

@ -1839,207 +1839,6 @@ WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &u
, pendingTill(pendingTill) {
}
namespace {
ImageLinkManager manager;
}
void ImageLinkManager::init() {
if (manager) delete manager;
manager = new QNetworkAccessManager();
App::setProxySettings(*manager);
connect(manager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(onFailed(QNetworkReply*)));
connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(onFailed(QNetworkReply*)));
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*)));
if (black) delete black;
QImage b(cIntRetinaFactor(), cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
{
QPainter p(&b);
p.fillRect(QRect(0, 0, cIntRetinaFactor(), cIntRetinaFactor()), st::white->b);
}
QPixmap p = QPixmap::fromImage(b, Qt::ColorOnly);
p.setDevicePixelRatio(cRetinaFactor());
black = new ImagePtr(p, "PNG");
}
void ImageLinkManager::reinit() {
if (manager) App::setProxySettings(*manager);
}
void ImageLinkManager::deinit() {
if (manager) {
delete manager;
manager = 0;
}
if (black) {
delete black;
black = 0;
}
dataLoadings.clear();
imageLoadings.clear();
}
void initImageLinkManager() {
manager.init();
}
void reinitImageLinkManager() {
manager.reinit();
}
void deinitImageLinkManager() {
manager.deinit();
}
void ImageLinkManager::getData(ImageLinkData *data) {
if (!manager) {
DEBUG_LOG(("App Error: getting image link data without manager init!"));
return failed(data);
}
QString url;
switch (data->type) {
case GoogleMapsLink: {
int32 w = st::locationSize.width(), h = st::locationSize.height();
int32 zoom = 13, scale = 1;
if (cScale() == dbisTwo || cRetina()) {
scale = 2;
} else {
w = convertScale(w);
h = convertScale(h);
}
url = qsl("https://maps.googleapis.com/maps/api/staticmap?center=") + data->id.mid(9) + qsl("&zoom=%1&size=%2x%3&maptype=roadmap&scale=%4&markers=color:red|size:big|").arg(zoom).arg(w).arg(h).arg(scale) + data->id.mid(9) + qsl("&sensor=false");
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
imageLoadings[reply] = data;
} break;
default: {
failed(data);
} break;
}
}
void ImageLinkManager::onFinished(QNetworkReply *reply) {
if (!manager) return;
if (reply->error() != QNetworkReply::NoError) return onFailed(reply);
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (statusCode.isValid()) {
int status = statusCode.toInt();
if (status == 301 || status == 302) {
QString loc = reply->header(QNetworkRequest::LocationHeader).toString();
if (!loc.isEmpty()) {
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
if (i != dataLoadings.cend()) {
ImageLinkData *d = i.value();
if (serverRedirects.constFind(d) == serverRedirects.cend()) {
serverRedirects.insert(d, 1);
} else if (++serverRedirects[d] > MaxHttpRedirects) {
DEBUG_LOG(("Network Error: Too many HTTP redirects in onFinished() for image link: %1").arg(loc));
return onFailed(reply);
}
dataLoadings.erase(i);
dataLoadings.insert(manager->get(QNetworkRequest(loc)), d);
return;
} else if ((i = imageLoadings.find(reply)) != imageLoadings.cend()) {
ImageLinkData *d = i.value();
if (serverRedirects.constFind(d) == serverRedirects.cend()) {
serverRedirects.insert(d, 1);
} else if (++serverRedirects[d] > MaxHttpRedirects) {
DEBUG_LOG(("Network Error: Too many HTTP redirects in onFinished() for image link: %1").arg(loc));
return onFailed(reply);
}
imageLoadings.erase(i);
imageLoadings.insert(manager->get(QNetworkRequest(loc)), d);
return;
}
}
}
if (status != 200) {
DEBUG_LOG(("Network Error: Bad HTTP status received in onFinished() for image link: %1").arg(status));
return onFailed(reply);
}
}
ImageLinkData *d = 0;
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
if (i != dataLoadings.cend()) {
d = i.value();
dataLoadings.erase(i);
QJsonParseError e;
QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &e);
if (e.error != QJsonParseError::NoError) {
DEBUG_LOG(("JSON Error: Bad json received in onFinished() for image link"));
return onFailed(reply);
}
switch (d->type) {
case GoogleMapsLink: failed(d); break;
}
if (App::main()) App::main()->update();
} else {
i = imageLoadings.find(reply);
if (i != imageLoadings.cend()) {
d = i.value();
imageLoadings.erase(i);
QPixmap thumb;
QByteArray format;
QByteArray data(reply->readAll());
{
QBuffer buffer(&data);
QImageReader reader(&buffer);
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
reader.setAutoTransform(true);
#endif
thumb = QPixmap::fromImageReader(&reader, Qt::ColorOnly);
format = reader.format();
thumb.setDevicePixelRatio(cRetinaFactor());
if (format.isEmpty()) format = QByteArray("JPG");
}
d->loading = false;
d->thumb = thumb.isNull() ? (*black) : ImagePtr(thumb, format);
serverRedirects.remove(d);
if (App::main()) App::main()->update();
}
}
}
void ImageLinkManager::onFailed(QNetworkReply *reply) {
if (!manager) return;
ImageLinkData *d = 0;
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
if (i != dataLoadings.cend()) {
d = i.value();
dataLoadings.erase(i);
} else {
i = imageLoadings.find(reply);
if (i != imageLoadings.cend()) {
d = i.value();
imageLoadings.erase(i);
}
}
DEBUG_LOG(("Network Error: failed to get data for image link %1, error %2").arg(d ? d->id : 0).arg(reply->errorString()));
if (d) {
failed(d);
}
}
void ImageLinkManager::failed(ImageLinkData *data) {
data->loading = false;
data->thumb = *black;
serverRedirects.remove(data);
}
void ImageLinkData::load() {
if (!thumb->isNull()) return thumb->load(false, false);
if (loading) return;
loading = true;
manager.getData(this);
}
void InlineResult::automaticLoadGif() {
if (loaded() || type != qstr("gif") || (content_type != qstr("video/mp4") && content_type != "image/gif")) return;

View file

@ -1289,54 +1289,6 @@ struct WebPageData {
};
void initImageLinkManager();
void reinitImageLinkManager();
void deinitImageLinkManager();
enum ImageLinkType {
InvalidImageLink = 0,
GoogleMapsLink
};
struct ImageLinkData {
ImageLinkData(const QString &id) : id(id), type(InvalidImageLink), loading(false) {
}
QString id;
ImagePtr thumb;
ImageLinkType type;
bool loading;
void load();
};
class ImageLinkManager : public QObject {
Q_OBJECT
public:
ImageLinkManager() : manager(0), black(0) {
}
void init();
void reinit();
void deinit();
void getData(ImageLinkData *data);
~ImageLinkManager() {
deinit();
}
public slots:
void onFinished(QNetworkReply *reply);
void onFailed(QNetworkReply *reply);
private:
void failed(ImageLinkData *data);
QNetworkAccessManager *manager;
QMap<QNetworkReply*, ImageLinkData*> dataLoadings, imageLoadings;
QMap<ImageLinkData*, int32> serverRedirects;
ImagePtr *black;
};
class InlineResult {
public:
InlineResult(uint64 queryId)