private void retweetOrQuote(AsyncTwitterWrapper twitter, ParcelableStatus status) {
   final Dialog dialog = getDialog();
   if (dialog == null) return;
   final EditText editComment = ((EditText) dialog.findViewById(R.id.edit_comment));
   if (editComment.length() > 0) {
     final Menu menu = mPopupMenu.getMenu();
     final MenuItem quoteOriginalStatus = menu.findItem(R.id.quote_original_status);
     final MenuItem linkToQuotedStatus = menu.findItem(R.id.link_to_quoted_status);
     final Uri statusLink;
     final long inReplyToStatusId;
     if (!status.is_quote || !quoteOriginalStatus.isChecked()) {
       inReplyToStatusId = status.id;
       statusLink = LinkCreator.getTwitterStatusLink(status.user_screen_name, status.id);
     } else {
       inReplyToStatusId = status.quoted_id;
       statusLink =
           LinkCreator.getTwitterStatusLink(status.quoted_user_screen_name, status.quoted_id);
     }
     final String commentText = editComment.getText() + " " + statusLink;
     twitter.updateStatusAsync(
         new long[] {status.account_id},
         commentText,
         null,
         null,
         linkToQuotedStatus.isChecked() ? inReplyToStatusId : -1,
         status.is_possibly_sensitive);
   } else if (isMyRetweet(status)) {
     twitter.cancelRetweetAsync(status.account_id, status.id, status.my_retweet_id);
   } else {
     twitter.retweetStatusAsync(status.account_id, status.id);
   }
 }
 @Override
 public void onClick(final DialogInterface dialog, final int which) {
   switch (which) {
     case DialogInterface.BUTTON_POSITIVE:
       final ParcelableUser user = getUser();
       final AsyncTwitterWrapper twitter = getTwitterWrapper();
       if (user == null || twitter == null) return;
       twitter.createBlockAsync(user.account_id, user.id);
       break;
     default:
       break;
   }
 }
 @Override
 public void onClick(final DialogInterface dialog, final int which) {
   switch (which) {
     case DialogInterface.BUTTON_POSITIVE:
       final ParcelableUserList userList = getUserList();
       final AsyncTwitterWrapper twitter = mTwitterWrapper;
       if (userList == null || twitter == null) return;
       twitter.destroyUserListSubscriptionAsync(userList.account_key, userList.id);
       break;
     default:
       break;
   }
 }
예제 #4
0
 @Override
 protected List<TwitterWrapper.StatusListResponse> doInBackground(final Object... params) {
   final List<TwitterWrapper.StatusListResponse> result = new ArrayList<>();
   if (accountIds == null) return result;
   int idx = 0;
   final SharedPreferencesWrapper preferences = twitterWrapper.getPreferences();
   final Context context = twitterWrapper.getContext();
   final ErrorInfoStore errorInfoStore = twitterWrapper.getErrorInfoStore();
   final int loadItemLimit = preferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
   for (final long accountId : accountIds) {
     final Twitter twitter = TwitterAPIFactory.getTwitterInstance(context, accountId, true);
     if (twitter == null) continue;
     try {
       final Paging paging = new Paging();
       paging.count(loadItemLimit);
       final long maxId, sinceId;
       if (maxIds != null && maxIds[idx] > 0) {
         maxId = maxIds[idx];
         paging.maxId(maxId);
       } else {
         maxId = -1;
       }
       if (sinceIds != null && sinceIds[idx] > 0) {
         sinceId = sinceIds[idx];
         paging.sinceId(sinceId - 1);
         if (maxIds == null || sinceIds[idx] <= 0) {
           paging.setLatestResults(true);
         }
       } else {
         sinceId = -1;
       }
       final List<org.mariotaku.twidere.api.twitter.model.Status> statuses =
           getStatuses(twitter, paging);
       TwitterContentUtils.getStatusesWithQuoteData(twitter, statuses);
       storeStatus(accountId, statuses, sinceId, maxId, true, loadItemLimit);
       publishProgress(new TwitterWrapper.StatusListResponse(accountId, statuses));
       errorInfoStore.remove(getErrorInfoKey(), accountId);
     } catch (final TwitterException e) {
       if (BuildConfig.DEBUG) {
         Log.w(LOGTAG, e);
       }
       if (e.isCausedByNetworkIssue()) {
         errorInfoStore.put(getErrorInfoKey(), accountId, ErrorInfoStore.CODE_NETWORK_ERROR);
       }
       result.add(new TwitterWrapper.StatusListResponse(accountId, e));
     }
     idx++;
   }
   return result;
 }
예제 #5
0
 @Override
 protected void onPostExecute(List<TwitterWrapper.StatusListResponse> result) {
   super.onPostExecute(result);
   bus.post(
       new GetStatusesTaskEvent(
           getDatabaseUri(), false, AsyncTwitterWrapper.getException(result)));
 }
예제 #6
0
 @SafeVarargs
 @Override
 protected final void onProgressUpdate(
     TwitterWrapper.TwitterListResponse<org.mariotaku.twidere.api.twitter.model.Status>...
         values) {
   AsyncTaskUtils.executeTask(new CacheUsersStatusesTask(twitterWrapper.getContext()), values);
 }
예제 #7
0
 public GetStatusesTask(
     AsyncTwitterWrapper twitterWrapper,
     final long[] accountIds,
     final long[] maxIds,
     final long[] sinceIds,
     final String tag) {
   super(twitterWrapper.getContext(), tag);
   this.twitterWrapper = twitterWrapper;
   this.accountIds = accountIds;
   this.maxIds = maxIds;
   this.sinceIds = sinceIds;
 }
  private void updateStatuses(ParcelableStatusUpdate... statuses) {
    final Builder builder = new Builder(this);
    startForeground(
        NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(this, builder, 0, null));
    for (final ParcelableStatusUpdate item : statuses) {
      mNotificationManager.notify(
          NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(this, builder, 0, item));
      final ContentValues draftValues =
          ContentValuesCreator.createStatusDraft(
              item, ParcelableAccount.getAccountIds(item.accounts));
      final Uri draftUri = mResolver.insert(Drafts.CONTENT_URI, draftValues);
      final long draftId = ParseUtils.parseLong(draftUri.getLastPathSegment(), -1);
      mTwitter.addSendingDraftId(draftId);
      final List<SingleResponse<ParcelableStatus>> result = updateStatus(builder, item);
      boolean failed = false;
      Exception exception = null;
      final Expression where = Expression.equals(Drafts._ID, draftId);
      final List<Long> failedAccountIds =
          ListUtils.fromArray(ParcelableAccount.getAccountIds(item.accounts));

      for (final SingleResponse<ParcelableStatus> response : result) {

        if (response.getData() == null) {
          failed = true;
          if (exception == null) {
            exception = response.getException();
          }
        } else if (response.getData().account_id > 0) {
          failedAccountIds.remove(response.getData().account_id);
          // spice
          if (response.getData().media == null) {
            SpiceProfilingUtil.log(
                response.getData().id
                    + ",Tweet,"
                    + response.getData().account_id
                    + ","
                    + response.getData().in_reply_to_user_id
                    + ","
                    + response.getData().in_reply_to_status_id);
            SpiceProfilingUtil.profile(
                this.getBaseContext(),
                response.getData().account_id,
                response.getData().id
                    + ",Tweet,"
                    + response.getData().account_id
                    + ","
                    + response.getData().in_reply_to_user_id
                    + ","
                    + response.getData().in_reply_to_status_id);
          } else
            for (final ParcelableMedia spiceMedia : response.getData().media) {
              SpiceProfilingUtil.log(
                  response.getData().id
                      + ",Media,"
                      + response.getData().account_id
                      + ","
                      + response.getData().in_reply_to_user_id
                      + ","
                      + response.getData().in_reply_to_status_id
                      + ","
                      + spiceMedia.media_url
                      + ","
                      + TypeMappingUtil.getMediaType(spiceMedia.type));
              SpiceProfilingUtil.profile(
                  this.getBaseContext(),
                  response.getData().account_id,
                  response.getData().id
                      + ",Media,"
                      + response.getData().account_id
                      + ","
                      + response.getData().in_reply_to_user_id
                      + ","
                      + response.getData().in_reply_to_status_id
                      + ","
                      + spiceMedia.media_url
                      + ","
                      + TypeMappingUtil.getMediaType(spiceMedia.type));
            }
          // end
        }
      }

      if (result.isEmpty()) {
        showErrorMessage(
            R.string.action_updating_status, getString(R.string.no_account_selected), false);
      } else if (failed) {
        // If the status is a duplicate, there's no need to save it to
        // drafts.
        if (exception instanceof TwitterException
            && ((TwitterException) exception).getErrorCode()
                == StatusCodeMessageUtils.STATUS_IS_DUPLICATE) {
          showErrorMessage(getString(R.string.status_is_duplicate), false);
        } else {
          final ContentValues accountIdsValues = new ContentValues();
          accountIdsValues.put(
              Drafts.ACCOUNT_IDS, ListUtils.toString(failedAccountIds, ',', false));
          mResolver.update(Drafts.CONTENT_URI, accountIdsValues, where.getSQL(), null);
          showErrorMessage(R.string.action_updating_status, exception, true);
          final ContentValues notifValues = new ContentValues();
          notifValues.put(BaseColumns._ID, draftId);
          mResolver.insert(Drafts.CONTENT_URI_NOTIFICATIONS, notifValues);
        }
      } else {
        showOkMessage(R.string.status_updated, false);
        mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null);
        if (item.media != null) {
          for (final ParcelableMediaUpdate media : item.media) {
            final String path = getImagePathFromUri(this, Uri.parse(media.uri));
            if (path != null) {
              if (!new File(path).delete()) {
                Log.d(LOGTAG, String.format("unable to delete %s", path));
              }
            }
          }
        }
      }
      mTwitter.removeSendingDraftId(draftId);
      if (mPreferences.getBoolean(KEY_REFRESH_AFTER_TWEET, false)) {
        mHandler.post(
            new Runnable() {
              @Override
              public void run() {
                mTwitter.refreshAll();
              }
            });
      }
    }
    stopForeground(false);
    mNotificationManager.cancel(NOTIFICATION_ID_UPDATE_STATUS);
  }
  @Override
  public void displayStatus(
      @NonNull final ParcelableStatus status,
      final boolean displayInReplyTo,
      final boolean shouldDisplayExtraType) {

    final MediaLoaderWrapper loader = adapter.getMediaLoader();
    final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper();
    final TwidereLinkify linkify = adapter.getTwidereLinkify();
    final BidiFormatter formatter = adapter.getBidiFormatter();
    final Context context = adapter.getContext();
    final boolean nameFirst = adapter.isNameFirst();
    final boolean showCardActions = isCardActionsShown();

    actionButtons.setVisibility(showCardActions ? View.VISIBLE : View.GONE);
    itemMenu.setVisibility(showCardActions ? View.VISIBLE : View.GONE);
    if (statusContentLowerSpace != null) {
      statusContentLowerSpace.setVisibility(showCardActions ? View.GONE : View.VISIBLE);
    }

    final long replyCount = status.reply_count;
    final long retweetCount;
    final long favoriteCount;

    if (TwitterCardUtils.isPoll(status)) {
      statusInfoLabel.setText(R.string.label_poll);
      statusInfoIcon.setImageResource(R.drawable.ic_activity_action_poll);
      statusInfoLabel.setVisibility(View.VISIBLE);
      statusInfoIcon.setVisibility(View.VISIBLE);

      if (statusContentUpperSpace != null) {
        statusContentUpperSpace.setVisibility(View.GONE);
      }
    } else if (status.retweet_id != null) {
      final String retweetedBy =
          UserColorNameManager.decideDisplayName(
              status.retweet_user_nickname,
              status.retweeted_by_user_name,
              status.retweeted_by_user_screen_name,
              nameFirst);
      statusInfoLabel.setText(
          context.getString(R.string.name_retweeted, formatter.unicodeWrap(retweetedBy)));
      statusInfoIcon.setImageResource(R.drawable.ic_activity_action_retweet);
      statusInfoLabel.setVisibility(View.VISIBLE);
      statusInfoIcon.setVisibility(View.VISIBLE);

      if (statusContentUpperSpace != null) {
        statusContentUpperSpace.setVisibility(View.GONE);
      }
    } else if (status.in_reply_to_status_id != null
        && status.in_reply_to_user_id != null
        && displayInReplyTo) {
      final String inReplyTo =
          UserColorNameManager.decideDisplayName(
              status.in_reply_to_user_nickname,
              status.in_reply_to_name,
              status.in_reply_to_screen_name,
              nameFirst);
      statusInfoLabel.setText(
          context.getString(R.string.in_reply_to_name, formatter.unicodeWrap(inReplyTo)));
      statusInfoIcon.setImageResource(R.drawable.ic_activity_action_reply);
      statusInfoLabel.setVisibility(View.VISIBLE);
      statusInfoIcon.setVisibility(View.VISIBLE);

      if (statusContentUpperSpace != null) {
        statusContentUpperSpace.setVisibility(View.GONE);
      }
    } else {
      statusInfoLabel.setVisibility(View.GONE);
      statusInfoIcon.setVisibility(View.GONE);

      if (statusContentUpperSpace != null) {
        statusContentUpperSpace.setVisibility(View.VISIBLE);
      }
    }

    boolean skipLinksInText = status.extras != null && status.extras.support_entities;
    if (status.is_quote) {

      quotedNameView.setVisibility(View.VISIBLE);
      quotedTextView.setVisibility(View.VISIBLE);
      quoteIndicator.setVisibility(View.VISIBLE);

      quotedNameView.setName(
          UserColorNameManager.decideNickname(
              status.quoted_user_nickname, status.quoted_user_name));
      quotedNameView.setScreenName("@" + status.quoted_user_screen_name);

      if (adapter.getLinkHighlightingStyle() != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
        final SpannableStringBuilder text =
            SpannableStringBuilder.valueOf(status.quoted_text_unescaped);
        ParcelableStatusUtils.applySpans(text, status.quoted_spans);
        linkify.applyAllLinks(
            text,
            status.account_key,
            getLayoutPosition(),
            status.is_possibly_sensitive,
            adapter.getLinkHighlightingStyle(),
            skipLinksInText);
        quotedTextView.setText(text);
      } else {
        final String text = status.quoted_text_unescaped;
        quotedTextView.setText(text);
      }

      quoteIndicator.setColor(status.quoted_user_color);
      itemContent.drawStart(status.user_color);
    } else {

      quotedNameView.setVisibility(View.GONE);
      quotedTextView.setVisibility(View.GONE);
      quoteIndicator.setVisibility(View.GONE);

      if (status.is_retweet) {
        final int retweetUserColor = status.retweet_user_color;
        final int userColor = status.user_color;
        if (retweetUserColor == 0) {
          itemContent.drawStart(userColor);
        } else if (userColor == 0) {
          itemContent.drawStart(retweetUserColor);
        } else {
          itemContent.drawStart(retweetUserColor, userColor);
        }
      } else {
        itemContent.drawStart(status.user_color);
      }
    }

    if (status.is_retweet) {
      timeView.setTime(status.retweet_timestamp);
    } else {
      timeView.setTime(status.timestamp);
    }
    nameView.setName(UserColorNameManager.decideNickname(status.user_nickname, status.user_name));
    nameView.setScreenName("@" + status.user_screen_name);

    if (statusInfoSpace != null) {
      statusInfoSpace.setVisibility(View.VISIBLE);
    }

    if (adapter.isProfileImageEnabled()) {
      profileImageView.setVisibility(View.VISIBLE);
      if (profileImageSpace != null) {
        profileImageSpace.setVisibility(View.VISIBLE);
      }
      loader.displayProfileImage(profileImageView, status);

      profileTypeView.setImageResource(
          getUserTypeIconRes(status.user_is_verified, status.user_is_protected));
      profileTypeView.setVisibility(View.VISIBLE);
    } else {
      profileTypeView.setVisibility(View.GONE);
      profileImageView.setVisibility(View.GONE);
      if (profileImageSpace != null) {
        profileImageSpace.setVisibility(View.GONE);
      }

      loader.cancelDisplayTask(profileImageView);

      profileTypeView.setImageDrawable(null);
      profileTypeView.setVisibility(View.GONE);
    }

    if (adapter.shouldShowAccountsColor()) {
      itemContent.drawEnd(status.account_color);
    } else {
      itemContent.drawEnd();
    }

    if (adapter.isMediaPreviewEnabled()
        && (adapter.isSensitiveContentEnabled() || !status.is_possibly_sensitive)) {
      mediaPreview.setStyle(adapter.getMediaPreviewStyle());
      quoteMediaPreview.setStyle(adapter.getMediaPreviewStyle());

      final boolean showQuotedMedia = !ArrayUtils.isEmpty(status.quoted_media);
      final boolean showMedia = !showQuotedMedia && !ArrayUtils.isEmpty(status.media);

      mediaPreview.setVisibility(showMedia ? View.VISIBLE : View.GONE);
      if (textMediaSpace != null) {
        textMediaSpace.setVisibility(
            !status.is_quote && (showMedia || showCardActions) ? View.GONE : View.VISIBLE);
      }
      quoteMediaPreview.setVisibility(showQuotedMedia ? View.VISIBLE : View.GONE);
      if (quotedTextMediaSpace != null) {
        quotedTextMediaSpace.setVisibility(
            !status.is_quote || showQuotedMedia ? View.GONE : View.VISIBLE);
      }

      mediaPreview.displayMedia(
          status.media, loader, status.account_key, -1, this, adapter.getMediaLoadingHandler());
      quoteMediaPreview.displayMedia(
          status.quoted_media,
          loader,
          status.account_key,
          -1,
          this,
          adapter.getMediaLoadingHandler());
    } else {
      mediaPreview.setVisibility(View.GONE);
      quoteMediaPreview.setVisibility(View.GONE);
      if (textMediaSpace != null) {
        textMediaSpace.setVisibility(
            showCardActions && !status.is_quote ? View.GONE : View.VISIBLE);
      }
      if (quotedTextMediaSpace != null) {
        quotedTextMediaSpace.setVisibility(status.is_quote ? View.VISIBLE : View.GONE);
      }
    }

    if (adapter.getLinkHighlightingStyle() != VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
      final SpannableStringBuilder text = SpannableStringBuilder.valueOf(status.text_unescaped);
      ParcelableStatusUtils.applySpans(text, status.spans);
      linkify.applyAllLinks(
          text,
          status.account_key,
          getLayoutPosition(),
          status.is_possibly_sensitive,
          adapter.getLinkHighlightingStyle(),
          skipLinksInText);
      textView.setText(text);
    } else {
      textView.setText(status.text_unescaped);
    }

    if (replyCount > 0) {
      replyCountView.setText(UnitConvertUtils.calculateProperCount(replyCount));
      replyCountView.setVisibility(View.VISIBLE);
    } else {
      replyCountView.setText(null);
      replyCountView.setVisibility(View.GONE);
    }

    if (twitter.isDestroyingStatus(status.account_key, status.my_retweet_id)) {
      retweetIconView.setActivated(false);
      retweetCount = Math.max(0, status.retweet_count - 1);
    } else {
      final boolean creatingRetweet = twitter.isCreatingRetweet(status.account_key, status.id);
      retweetIconView.setActivated(
          creatingRetweet
              || status.retweeted
              || Utils.isMyRetweet(
                  status.account_key, status.retweeted_by_user_key, status.my_retweet_id));
      retweetCount = status.retweet_count + (creatingRetweet ? 1 : 0);
    }

    if (retweetCount > 0) {
      retweetCountView.setText(UnitConvertUtils.calculateProperCount(retweetCount));
      retweetCountView.setVisibility(View.VISIBLE);
    } else {
      retweetCountView.setText(null);
      retweetCountView.setVisibility(View.GONE);
    }
    if (twitter.isDestroyingFavorite(status.account_key, status.id)) {
      favoriteIconView.setActivated(false);
      favoriteCount = Math.max(0, status.favorite_count - 1);
    } else {
      final boolean creatingFavorite = twitter.isCreatingFavorite(status.account_key, status.id);
      favoriteIconView.setActivated(creatingFavorite || status.is_favorite);
      favoriteCount = status.favorite_count + (creatingFavorite ? 1 : 0);
    }
    if (favoriteCount > 0) {
      favoriteCountView.setText(UnitConvertUtils.calculateProperCount(favoriteCount));
      favoriteCountView.setVisibility(View.VISIBLE);
    } else {
      favoriteCountView.setText(null);
      favoriteCountView.setVisibility(View.GONE);
    }
    if (shouldDisplayExtraType) {
      displayExtraTypeIcon(
          status.card_name,
          status.media,
          status.location,
          status.place_full_name,
          status.is_possibly_sensitive);
    } else {
      extraTypeView.setVisibility(View.GONE);
    }

    nameView.updateText(formatter);
    quotedNameView.updateText(formatter);
  }
예제 #10
0
  private void storeStatus(
      long accountId,
      List<org.mariotaku.twidere.api.twitter.model.Status> statuses,
      long sinceId,
      long maxId,
      boolean notify,
      int loadItemLimit) {
    if (statuses == null || statuses.isEmpty() || accountId <= 0) {
      return;
    }
    final Uri uri = getDatabaseUri();
    final Context context = twitterWrapper.getContext();
    final ContentResolver resolver = context.getContentResolver();
    final boolean noItemsBefore = DataStoreUtils.getStatusCount(context, uri, accountId) <= 0;
    final ContentValues[] values = new ContentValues[statuses.size()];
    final long[] statusIds = new long[statuses.size()];
    long minId = -1;
    int minIdx = -1;
    boolean hasIntersection = false;
    for (int i = 0, j = statuses.size(); i < j; i++) {
      final org.mariotaku.twidere.api.twitter.model.Status status = statuses.get(i);
      values[i] = ContentValuesCreator.createStatus(status, accountId);
      values[i].put(Statuses.INSERTED_DATE, System.currentTimeMillis());
      final long id = status.getId();
      if (sinceId > 0 && id <= sinceId) {
        hasIntersection = true;
      }
      if (minId == -1 || id < minId) {
        minId = id;
        minIdx = i;
      }
      statusIds[i] = id;
    }
    // Delete all rows conflicting before new data inserted.
    final Expression accountWhere = Expression.equals(Statuses.ACCOUNT_ID, accountId);
    final Expression statusWhere =
        Expression.in(new Columns.Column(Statuses.STATUS_ID), new RawItemArray(statusIds));
    final String countWhere = Expression.and(accountWhere, statusWhere).getSQL();
    final String[] projection = {SQLFunctions.COUNT()};
    final int rowsDeleted;
    final Cursor countCur = resolver.query(uri, projection, countWhere, null, null);
    try {
      if (countCur != null && countCur.moveToFirst()) {
        rowsDeleted = countCur.getInt(0);
      } else {
        rowsDeleted = 0;
      }
    } finally {
      Utils.closeSilently(countCur);
    }

    // BEGIN HotMobi
    final RefreshEvent event = RefreshEvent.create(context, statusIds, getTimelineType());
    HotMobiLogger.getInstance(context).log(accountId, event);
    // END HotMobi

    // Insert a gap.
    final boolean deletedOldGap = rowsDeleted > 0 && ArrayUtils.contains(statusIds, maxId);
    final boolean noRowsDeleted = rowsDeleted == 0;
    final boolean insertGap =
        minId > 0 && (noRowsDeleted || deletedOldGap) && !noItemsBefore && !hasIntersection;
    if (insertGap && minIdx != -1) {
      values[minIdx].put(Statuses.IS_GAP, true);
    }
    // Insert previously fetched items.
    final Uri insertUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, notify);
    ContentResolverUtils.bulkInsert(resolver, insertUri, values);
  }