コード例 #1
0
  /**
   * Recursive method to insert comment tree into the mCommentsList, with proper list order and
   * indentation
   */
  int insertNestedComment(
      ThingListing commentThingListing, int indentLevel, int insertedCommentIndex) {
    ThingInfo ci = commentThingListing.getData();
    // First test for moderator distinguished
    if (Constants.DISTINGUISHED_MODERATOR.equalsIgnoreCase(ci.getDistinguished())) {
      SpannableString distSS = new SpannableString(ci.getAuthor() + " [M]");
      distSS.setSpan(
          Util.getModeratorSpan(mActivity.getApplicationContext()),
          0,
          distSS.length(),
          Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      ci.setSSAuthor(distSS);
    } else if (Constants.DISTINGUISHED_ADMIN.equalsIgnoreCase(ci.getDistinguished())) {
      SpannableString distSS = new SpannableString(ci.getAuthor() + " [A]");
      distSS.setSpan(
          Util.getAdminSpan(mActivity.getApplicationContext()),
          0,
          distSS.length(),
          Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      ci.setSSAuthor(distSS);
    } else if (mOpThingInfo != null && mOpThingInfo.getAuthor().equalsIgnoreCase(ci.getAuthor())) {
      if (m_OPSpan == null) {
        m_OPSpan = new SpannableString(mOpThingInfo.getAuthor() + " [S]");
        m_OPSpan.setSpan(
            Util.getOPSpan(mActivity.getApplicationContext(), mSettings.getTheme()),
            0,
            m_OPSpan.length(),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      }
      ci.setSSAuthor(m_OPSpan);
    }
    // Add comment to deferred append/replace list
    if (isInsertingEntireThread()) deferCommentAppend(ci);
    else deferCommentReplacement(ci);

    // Keep track of jump target
    if (isHasJumpTarget()) {
      if (!isFoundJumpTargetComment() && mJumpToCommentId.equals(ci.getId()))
        processJumpTarget(ci, insertedCommentIndex);
    }

    if (isHasJumpTarget()) {
      // if we have found the jump target, then we did the messy stuff already. just append to main
      // processing list.
      if (isFoundJumpTargetComment()) {
        mProcessCommentsTask.addDeferred(new DeferredCommentProcessing(ci, insertedCommentIndex));
      }
      // try to handle the context search, if we want context
      else if (mJumpToCommentContext > 0) {
        // any comment could be in the context; we don't know yet. so append to the high-priority
        // "context" list
        mProcessCommentsTask.addDeferredHighPriority(
            new DeferredCommentProcessing(ci, insertedCommentIndex));

        // we push overflow onto the low priority list, since overflow will end up above the jump
        // target, off the top of the screen.
        // TODO don't use LinkedList.size()
        mProcessCommentsTask.moveHighPriorityOverflowToLowPriority(mJumpToCommentContext);
      }
      // if no context search, then push comments to low priority list until we find the jump target
      // comment
      else {
        mProcessCommentsTask.addDeferredLowPriority(
            new DeferredCommentProcessing(ci, insertedCommentIndex));
      }
    }
    // if there is no jump target, there's just a single deferred-processing list to worry about.
    else {
      mProcessCommentsTask.addDeferred(new DeferredCommentProcessing(ci, insertedCommentIndex));
    }

    // Formatting that applies to all items, both real comments and "more" entries
    ci.setIndent(mIndentation + indentLevel);

    // Handle "more" entry
    if (Constants.MORE_KIND.equals(commentThingListing.getKind())) {
      ci.setLoadMoreCommentsPlaceholder(true);
      if (Constants.LOGGING) Log.v(TAG, "new more position at " + (insertedCommentIndex));
      return insertedCommentIndex;
    }

    // Regular comment

    // Skip things that are not comments, which shouldn't happen
    if (!Constants.COMMENT_KIND.equals(commentThingListing.getKind())) {
      if (Constants.LOGGING)
        Log.e(
            TAG,
            "comment whose kind is \""
                + commentThingListing.getKind()
                + "\" (expected "
                + Constants.COMMENT_KIND
                + ")");
      return insertedCommentIndex;
    }

    // handle the replies
    Listing repliesListing = ci.getReplies();
    if (repliesListing == null) return insertedCommentIndex;
    ListingData repliesListingData = repliesListing.getData();
    if (repliesListingData == null) return insertedCommentIndex;
    ThingListing[] replyThingListings = repliesListingData.getChildren();
    if (replyThingListings == null) return insertedCommentIndex;

    for (ThingListing replyThingListing : replyThingListings) {
      insertedCommentIndex =
          insertNestedComment(replyThingListing, indentLevel + 1, insertedCommentIndex + 1);
    }
    return insertedCommentIndex;
  }
コード例 #2
0
  // XXX: maxComments is unused for now
  public Boolean doInBackground(Integer... maxComments) {
    HttpEntity entity = null;
    try {
      StringBuilder sb = new StringBuilder(Constants.REDDIT_BASE_URL);
      if (mSubreddit != null) {
        sb.append("/r/").append(mSubreddit.trim());
      }
      if (mMoreChildrenId != null && mMoreChildrenId.length() > 0) {
        sb.append("/comments/")
            .append(mThreadId)
            .append("/z/")
            .append(mMoreChildrenId)
            .append("/.json?")
            .append(mSettings.getCommentsSortByUrl());
        // Loading more with context makes no sense
      } else {
        sb.append("/comments/")
            .append(mThreadId)
            .append("/.json?")
            .append(mSettings.getCommentsSortByUrl());
        if (!StringUtils.isEmpty(mJumpToCommentId) && mJumpToCommentContext > 0) {
          sb.append("&comment=")
              .append(mJumpToCommentId)
              .append("&context=")
              .append(mJumpToCommentContext);
        }
      }

      String url = sb.toString();
      if (Constants.LOGGING) Log.d(TAG, "Loading comments from URL: " + url);
      InputStream in = null;
      boolean currentlyUsingCache = false;

      if (Constants.USE_COMMENTS_CACHE) {
        try {
          if (CacheInfo.checkFreshThreadCache(mActivity.getApplicationContext())
              && url.equals(CacheInfo.getCachedThreadUrl(mActivity.getApplicationContext()))) {
            in = mActivity.openFileInput(Constants.FILENAME_THREAD_CACHE);
            mContentLength = mActivity.getFileStreamPath(Constants.FILENAME_THREAD_CACHE).length();
            currentlyUsingCache = true;
            if (Constants.LOGGING) Log.d(TAG, "Using cached thread JSON, length=" + mContentLength);
          }
        } catch (Exception cacheEx) {
          if (Constants.LOGGING) Log.w(TAG, "skip cache", cacheEx);
        }
      }

      // If we couldn't use the cache, then do HTTP request
      if (!currentlyUsingCache) {
        HttpGet request = new HttpGet(url);
        HttpResponse response = mClient.execute(request);

        // Read the header to get Content-Length since entity.getContentLength() returns -1
        Header contentLengthHeader = response.getFirstHeader("Content-Length");
        if (contentLengthHeader != null) {
          mContentLength = Long.valueOf(contentLengthHeader.getValue());
          if (Constants.LOGGING) Log.d(TAG, "Content length: " + mContentLength);
        } else {
          mContentLength = -1;
          if (Constants.LOGGING) Log.d(TAG, "Content length: UNAVAILABLE");
        }

        entity = response.getEntity();
        in = entity.getContent();

        if (Constants.USE_COMMENTS_CACHE) {
          in =
              CacheInfo.writeThenRead(
                  mActivity.getApplicationContext(), in, Constants.FILENAME_THREAD_CACHE);
          try {
            CacheInfo.setCachedThreadUrl(mActivity.getApplicationContext(), url);
          } catch (IOException e) {
            if (Constants.LOGGING) Log.e(TAG, "error on setCachedThreadId", e);
          }
        }
      }

      // setup a special InputStream to report progress
      ProgressInputStream pin = new ProgressInputStream(in, mContentLength);
      pin.addPropertyChangeListener(this);

      parseCommentsJSON(pin);
      if (Constants.LOGGING) Log.d(TAG, "parseCommentsJSON completed");

      pin.close();
      in.close();

      return true;

    } catch (Exception e) {
      if (Constants.LOGGING) Log.e(TAG, "DownloadCommentsTask", e);
    } finally {
      if (entity != null) {
        try {
          entity.consumeContent();
        } catch (Exception e2) {
          if (Constants.LOGGING) Log.e(TAG, "entity.consumeContent()", e2);
        }
      }
    }
    return false;
  }