Example #1
0
static void tgp_msg_display (struct tgl_state *TLS, struct tgp_msg_loading *C) {
  connection_data *conn = TLS->ev_base;
  struct tgl_message *M = C->msg;
  char *text = NULL;
  int flags = 0;

  // only display new messages, ignore updates or deletions
  if ((M->flags & (TGLMF_EMPTY | TGLMF_DELETED)) ||
      !(M->flags & TGLMF_CREATED) ||
      !M->message ||
      tgp_outgoing_msg (TLS, M) ||
      !tgl_get_peer_type (M->to_id)) {
    return;
  }

  if (M->flags & TGLMF_SERVICE) {
    text = format_service_msg (TLS, M);
    flags |= PURPLE_MESSAGE_SYSTEM;
  }
  else if (M->media.type == tgl_message_media_document && M->media.document->flags & TGLDF_STICKER) {
#ifdef HAVE_LIBWEBP
    char *filename = C->data;
    int img = p2tgl_imgstore_add_with_id_webp (filename);
    if (img <= 0) { failure ("Cannot display sticker, adding to imgstore failed"); return; }
    used_images_add (conn, img);
    text = format_img_full (img);
    flags |= PURPLE_MESSAGE_IMAGES;
    g_free (filename);
#else
    char *txt_user = p2tgl_strdup_alias (tgl_peer_get (TLS, M->from_id));
    text = g_strdup_printf ("%s sent a sticker", txt_user);
    flags |= PURPLE_MESSAGE_SYSTEM;
    g_free (txt_user);
#endif
  }
  else if (M->media.type == tgl_message_media_photo ||
          (M->media.type == tgl_message_media_document_encr && M->media.encr_document->flags & TGLDF_IMAGE)) {
    char *filename = C->data;
    int img = p2tgl_imgstore_add_with_id (filename);
    if (img <= 0) {
      failure ("Cannot display picture message, adding to imgstore failed.");
      return;
    }
    used_images_add (conn, img);
    text = format_img_full (img);
    flags |= PURPLE_MESSAGE_IMAGES;
    g_free (filename);
  }
  else if (M->media.type == tgl_message_media_document) {
    char *who = p2tgl_strdup_id (M->from_id);
    if (! tgp_our_msg(TLS, M)) {
      tgprpl_recv_file (conn->gc, who, M->media.document);
    }
    g_free (who);
    return;
  }
  else if (M->media.type == tgl_message_media_document_encr) {
    char *who = p2tgl_strdup_id (M->to_id);
    if (! tgp_our_msg(TLS, M)) {
      tgprpl_recv_encr_file (conn->gc, who, M->media.encr_document);
    }
    g_free (who);
    return;
  }
  else {
    text = format_message (M);
    flags |= PURPLE_MESSAGE_RECV;
  }
  
  if (! text || ! *text) {
    warning ("No text to display");
    return;
  }
  switch (tgl_get_peer_type (M->to_id)) {
    case TGL_PEER_CHAT: {
      if (chat_show (conn->gc, tgl_get_peer_id (M->to_id))) {
        p2tgl_got_chat_in (TLS, M->to_id, M->from_id, text, flags, M->date);
      }
      pending_reads_add (conn->pending_reads, M->to_id);
      break;
    }
    case TGL_PEER_ENCR_CHAT: {
      p2tgl_got_im (TLS, M->to_id, text, flags, M->date);
      pending_reads_add (conn->pending_reads, M->to_id);
      break;
    }
    case TGL_PEER_USER: {
      if (tgp_our_msg (TLS, M)) {
        flags |= PURPLE_MESSAGE_SEND;
        flags &= ~PURPLE_MESSAGE_RECV;
        p2tgl_got_im_combo (TLS, M->to_id, text, flags, M->date);
      } else {
        p2tgl_got_im (TLS, M->from_id, text, flags, M->date);
        pending_reads_add (conn->pending_reads, M->from_id);
      }
      break;
    }
  }
  
  if (p2tgl_status_is_present (purple_account_get_active_status (conn->pa)) && p2tgl_send_notifications(conn->pa)) {
    pending_reads_send_all (conn->pending_reads, conn->TLS);
  }
  
  g_free (text);
}
Example #2
0
static void tgp_msg_display (struct tgl_state *TLS, struct tgp_msg_loading *C) {
  connection_data *conn = TLS->ev_base;
  struct tgl_message *M = C->msg;
  char *text = NULL;
  int flags = 0;
  
  if (M->flags & (TGLMF_EMPTY | TGLMF_DELETED)) {
    return;
  }
  if (!(M->flags & TGLMF_CREATED)) {
    return;
  }
  if (!tgl_get_peer_type (M->to_id)) {
    warning ("Bad msg\n");
    return;
  }

  // only display new messages, ignore updates or deletions
  if (!M->message || tgp_outgoing_msg (TLS, M) || !tgl_get_peer_type (M->to_id)) {
    return;
  }
  
  // Mark messages that contain a mention as if they contained our current nick name
  // FIXME: doesn't work in Adium
  if (M->flags & TGLMF_MENTION) {
    flags |= PURPLE_MESSAGE_NICK;
  }
  
  // handle messages that failed to load
  if (C->error) {
    const char *err = C->error_msg;
    if (! err) {
      err = _("failed loading message");
    }
    tgp_msg_err_out (TLS, err, tgp_our_msg (TLS, M) ? M->from_id : M->to_id);
    return;
  }

  // format the message text
  if (M->flags & TGLMF_SERVICE) {
    text = format_service_msg (TLS, M);
    flags |= PURPLE_MESSAGE_SYSTEM;
    
  } else if (M->media.type != tgl_message_media_none) {
    switch (M->media.type) {
  
      case tgl_message_media_photo: {
        if (M->media.photo) {
          g_return_if_fail(C->data != NULL);
          
          text = tgp_msg_photo_display (TLS, C->data, &flags);
          if (str_not_empty (text)) {
            if (str_not_empty (M->media.caption)) {
              char *old = text;
              text = g_strdup_printf ("%s<br>%s", old, M->media.caption);
              g_free (old);
            }
          }
        }
        break;
      }
        
      case tgl_message_media_document:
        if (M->media.document->flags & TGLDF_STICKER) {
          g_return_if_fail(C->data != NULL);
          text = tgp_msg_sticker_display (TLS, M->from_id, C->data, &flags);
        } else if (M->media.document->flags & TGLDF_IMAGE) {
          g_return_if_fail(C->data != NULL);
          text = tgp_msg_photo_display (TLS, C->data, &flags);
        } else {
          if (! tgp_our_msg(TLS, M)) {
            tgprpl_recv_file (conn->gc, tgp_blist_lookup_purple_name (TLS, M->from_id), M);
          }
          return;
        }
        break;
        
      case tgl_message_media_video:
      case tgl_message_media_audio: {
        if (! tgp_our_msg(TLS, M)) {
          tgprpl_recv_file (conn->gc, tgp_blist_lookup_purple_name (TLS, M->from_id), M);
        }
      }
      break;
        
      case tgl_message_media_document_encr:
        if (M->media.encr_document->flags & TGLDF_STICKER) {
          g_return_if_fail(C->data != NULL);
          text = tgp_msg_sticker_display (TLS, M->from_id, C->data, &flags);
        } if (M->media.encr_document->flags & TGLDF_IMAGE) {
          g_return_if_fail(C->data != NULL);
          text = tgp_msg_photo_display (TLS, C->data, &flags);
        } else {
          if (! tgp_our_msg(TLS, M)) {
            tgprpl_recv_file (conn->gc, tgp_blist_lookup_purple_name (TLS, M->to_id), M);
          }
          return;
        }
        break;
      
      case tgl_message_media_contact:
        text = g_strdup_printf ("<b>%s %s</b> %s", M->media.first_name, M->media.last_name, M->media.phone);
        break;
        
      case tgl_message_media_venue: {
        char *address = NULL;
        if (M->media.venue.address && strcmp (M->media.venue.title, M->media.venue.address)) {
          address = g_strdup_printf (" %s", M->media.venue.address);
        }
        char *pos = format_geo_link_osm (M->media.venue.geo.latitude, M->media.geo.longitude);
        text = g_strdup_printf ("<a href=\"%s\">%s</a>%s",
                                pos,
                                M->media.venue.title ? M->media.venue.title : "", address ? address : "");
        if (address) {
          g_free (address);
        }
        g_free (pos);
        break;
      }
        
      case tgl_message_media_geo: {
        char *pos = format_geo_link_osm (M->media.venue.geo.latitude, M->media.geo.longitude);
        text = g_strdup_printf ("<a href=\"%s\">%s</a>", pos, pos);
        g_free (pos);
        break;
      }
        
      case tgl_message_media_webpage: {
        char *msg = g_strdup (M->message);
        text = purple_markup_escape_text (msg, strlen (msg));
        g_free (msg);
        break;
      }
        
      default:
        warning ("received unknown media type: %d", M->media.type);
        break;
    }
    
  } else {
    if (str_not_empty (M->message)) {
      text = purple_markup_escape_text (M->message, strlen (M->message));
    }
    flags |= PURPLE_MESSAGE_RECV;
  }
  
  if (tgl_get_peer_type (M->to_id) != TGL_PEER_ENCR_CHAT && ! (M->flags & TGLMF_UNREAD)) {
    flags |= PURPLE_MESSAGE_DELAYED;
  }
  
  // some service messages (like removing/adding users from chats) might print the message 
  // text through other means and leave the text empty
  if (! str_not_empty (text)) {
    return;
  }
  
  // display the message to the user
  switch (tgl_get_peer_type (M->to_id)) {
    case TGL_PEER_CHAT: {
      tgl_peer_t *P = tgl_peer_get (TLS, M->to_id);
      g_return_if_fail(P != NULL);
      
      if (tgp_chat_show (TLS, &P->chat)) {
        p2tgl_got_chat_in (TLS, M->to_id, M->from_id, text, flags, M->date);
      }
      break;
    }
    case TGL_PEER_ENCR_CHAT: {
      p2tgl_got_im_combo (TLS, M->to_id, text, flags, M->date);
      break;
    }
    case TGL_PEER_USER: {
      if (tgp_our_msg (TLS, M)) {
        flags |= PURPLE_MESSAGE_SEND;
        flags &= ~PURPLE_MESSAGE_RECV;
        p2tgl_got_im_combo (TLS, M->to_id, text, flags, M->date);
      } else {
        p2tgl_got_im_combo (TLS, M->from_id, text, flags, M->date);
      }
      break;
    }
  }
  
  g_free (text);
}