diff --git a/global.gradle b/global.gradle
index af4fcfc4a..cbe7c4d80 100644
--- a/global.gradle
+++ b/global.gradle
@@ -22,6 +22,7 @@ android {
lintOptions {
abortOnError false
+ lintConfig rootProject.file('lint.xml')
}
packagingOptions {
diff --git a/lint.xml b/lint.xml
new file mode 100644
index 000000000..650f7796d
--- /dev/null
+++ b/lint.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/twidere/build.gradle b/twidere/build.gradle
index 3bd39d9ed..7ed30ca36 100644
--- a/twidere/build.gradle
+++ b/twidere/build.gradle
@@ -14,7 +14,7 @@ android {
applicationId "org.mariotaku.twidere"
minSdkVersion 14
targetSdkVersion 23
- versionCode 131
+ versionCode 133
versionName "0.3.0"
multiDexEnabled true
}
diff --git a/twidere/src/main/java/edu/tsinghua/hotmobi/HotMobiLogger.java b/twidere/src/main/java/edu/tsinghua/hotmobi/HotMobiLogger.java
index 03523d611..5ecc41247 100644
--- a/twidere/src/main/java/edu/tsinghua/hotmobi/HotMobiLogger.java
+++ b/twidere/src/main/java/edu/tsinghua/hotmobi/HotMobiLogger.java
@@ -27,7 +27,9 @@ import android.content.SharedPreferences;
import android.location.Location;
import android.os.BatteryManager;
import android.text.TextUtils;
+import android.util.Log;
+import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.JsonSerializer;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java
index 13c6bb89b..7972b5e12 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/StatusFragment.java
@@ -56,7 +56,6 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
-import android.text.method.ArrowKeyMovementMethod;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
@@ -859,7 +858,10 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
quotedNameView.setText(manager.getUserNickname(status.quoted_user_id, status.quoted_user_name, false));
quotedScreenNameView.setText("@" + status.quoted_user_screen_name);
- quotedTextView.setText(HtmlSpanBuilder.fromHtml(status.quoted_text_html));
+ final Spanned quotedText = HtmlSpanBuilder.fromHtml(status.quoted_text_html);
+ if (!TextUtils.equals(quotedTextView.getText(), quotedText)) {
+ quotedTextView.setText(quotedText);
+ }
linkify.applyAllLinks(quotedTextView, status.account_id, layoutPosition, status.is_possibly_sensitive);
ThemeUtils.applyParagraphSpacing(quotedTextView, 1.1f);
@@ -910,7 +912,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
}
timeSourceView.setMovementMethod(LinkMovementMethod.getInstance());
- textView.setText(HtmlSpanBuilder.fromHtml(status.text_html));
+ final Spanned text = HtmlSpanBuilder.fromHtml(status.text_html);
+ if (!TextUtils.equals(textView.getText(), text))
+ textView.setText(text);
linkify.applyAllLinks(textView, status.account_id, layoutPosition, status.is_possibly_sensitive);
ThemeUtils.applyParagraphSpacing(textView, 1.1f);
@@ -982,8 +986,8 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
textView.setTextIsSelectable(true);
quotedTextView.setTextIsSelectable(true);
- textView.setMovementMethod(ArrowKeyMovementMethod.getInstance());
- quotedTextView.setMovementMethod(ArrowKeyMovementMethod.getInstance());
+ textView.setMovementMethod(LinkMovementMethod.getInstance());
+ quotedTextView.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
diff --git a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
index 8832c8e24..a50b7f74c 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/fragment/support/UserFragment.java
@@ -509,12 +509,10 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mDescriptionView.setText(user.description_html != null ? HtmlSpanBuilder.fromHtml(user.description_html) : user.description_plain);
final TwidereLinkify linkify = new TwidereLinkify(this);
linkify.applyAllLinks(mDescriptionView, user.account_id, false);
- mDescriptionView.setMovementMethod(null);
mLocationContainer.setVisibility(TextUtils.isEmpty(user.location) ? View.GONE : View.VISIBLE);
mLocationView.setText(user.location);
mURLContainer.setVisibility(TextUtils.isEmpty(user.url) && TextUtils.isEmpty(user.url_expanded) ? View.GONE : View.VISIBLE);
mURLView.setText(TextUtils.isEmpty(user.url_expanded) ? user.url : user.url_expanded);
- mURLView.setMovementMethod(null);
final String createdAt = Utils.formatToLongTimeString(activity, user.created_at);
final float daysSinceCreation = (System.currentTimeMillis() - user.created_at) / 1000 / 60 / 60 / 24;
final int dailyTweets = Math.round(user.statuses_count / Math.max(1, daysSinceCreation));
diff --git a/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java b/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java
index 32160dda2..42835a9bc 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/service/RefreshService.java
@@ -156,7 +156,7 @@ public class RefreshService extends Service implements Constants {
break;
}
case Intent.ACTION_SCREEN_OFF: {
- HotMobiLogger.logScreenEvent(context, ScreenEvent.Action.ON);
+ HotMobiLogger.logScreenEvent(context, ScreenEvent.Action.OFF);
break;
}
}
@@ -173,7 +173,6 @@ public class RefreshService extends Service implements Constants {
super.onCreate();
DaggerGeneralComponent.builder().applicationModule(ApplicationModule.get(this)).build().inject(this);
mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
- final TwidereApplication app = TwidereApplication.getInstance(this);
mPendingRefreshHomeTimelineIntent = PendingIntent.getBroadcast(this, 0, new Intent(
BROADCAST_REFRESH_HOME_TIMELINE), 0);
mPendingRefreshMentionsIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_MENTIONS), 0);
diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereNetwork.java b/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereNetwork.java
index 46637bf2d..02583222a 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereNetwork.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/util/net/TwidereNetwork.java
@@ -30,6 +30,7 @@ import com.squareup.okhttp.internal.Network;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.util.HostsFileParser;
+import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.xbill.DNS.AAAARecord;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.CNAMERecord;
@@ -65,7 +66,7 @@ public class TwidereNetwork implements Constants, Network {
private Resolver mDns;
public TwidereNetwork(final Context context) {
- mHostMapping = context.getSharedPreferences(HOST_MAPPING_PREFERENCES_NAME, Context.MODE_PRIVATE);
+ mHostMapping = SharedPreferencesWrapper.getInstance(context, HOST_MAPPING_PREFERENCES_NAME, Context.MODE_PRIVATE);
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final String address = mPreferences.getString(KEY_DNS_SERVER, DEFAULT_DNS_SERVER_ADDRESS);
mDnsAddress = isValidIpAddress(address) ? address : DEFAULT_DNS_SERVER_ADDRESS;
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/HandleSpanClickTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/HandleSpanClickTextView.java
deleted file mode 100644
index 5aa9c15cb..000000000
--- a/twidere/src/main/java/org/mariotaku/twidere/view/HandleSpanClickTextView.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Twidere - Twitter client for Android
- *
- * Copyright (C) 2012-2014 Mariotaku Lee
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.mariotaku.twidere.view;
-
-import android.content.Context;
-import android.support.annotation.NonNull;
-import android.text.Layout;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.ClickableSpan;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-
-import org.mariotaku.twidere.view.themed.ThemedTextView;
-
-public class HandleSpanClickTextView extends ThemedTextView {
-
- private boolean mLongClickPerformed;
-
- public HandleSpanClickTextView(final Context context) {
- super(context);
- }
-
- public HandleSpanClickTextView(final Context context, final AttributeSet attrs) {
- super(context, attrs);
- }
-
- public HandleSpanClickTextView(final Context context, final AttributeSet attrs, final int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- public boolean onTouchEvent(@NonNull final MotionEvent event) {
- final Spannable buffer = SpannableString.valueOf(getText());
- final int action = event.getAction();
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
- int x = (int) event.getX();
- int y = (int) event.getY();
-
- x -= getTotalPaddingLeft();
- y -= getTotalPaddingTop();
-
- x += getScrollX();
- y += getScrollY();
-
- final Layout layout = getLayout();
- final int line = layout.getLineForVertical(y);
- final int off;
- try {
- off = layout.getOffsetForHorizontal(line, x);
- } catch (IndexOutOfBoundsException e) {
- throw new IndexOutOfBoundsException("Line count " + layout.getLineCount() +
- ", line for y " + y + " is " + line + ", x is " + x);
- }
- final float lineWidth = layout.getLineWidth(line);
-
- final ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
-
- if (links.length != 0 && x <= lineWidth) {
- final ClickableSpan link = links[0];
- if (action == MotionEvent.ACTION_UP) {
- setClickable(false);
- if (!mLongClickPerformed) {
- link.onClick(this);
- }
- return true;
- } else {
- mLongClickPerformed = false;
- setClickable(true);
- }
- } else {
- setClickable(false);
- }
- }
- return super.onTouchEvent(event);
- }
-
-
- @Override
- public boolean performLongClick() {
- final boolean result = super.performLongClick();
- mLongClickPerformed = true;
- return result;
- }
-}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/StatusTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/StatusTextView.java
index 0ffc99ccd..f767725e4 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/view/StatusTextView.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/StatusTextView.java
@@ -1,26 +1,45 @@
package org.mariotaku.twidere.view;
import android.content.Context;
-import android.support.v7.widget.AppCompatTextView;
import android.text.Editable;
import android.text.Spannable;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import org.mariotaku.twidere.text.SafeSpannableString;
import org.mariotaku.twidere.text.SafeSpannableStringBuilder;
+import org.mariotaku.twidere.view.themed.ThemedTextView;
-public class StatusTextView extends HandleSpanClickTextView {
+public class StatusTextView extends ThemedTextView {
public StatusTextView(final Context context) {
- this(context, null);
+ super(context);
+ init();
}
public StatusTextView(final Context context, final AttributeSet attrs) {
- this(context, attrs, 0);
+ super(context, attrs);
+ init();
}
public StatusTextView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
+ init();
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ // FIXME simple workaround to https://code.google.com/p/android/issues/detail?id=191430
+ // Android clears TextView when setText(), so setText before touch
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ final CharSequence text = getText();
+ setText(null);
+ setText(text);
+ }
+ return super.dispatchTouchEvent(event);
+ }
+
+ private void init() {
setEditableFactory(new SafeEditableFactory());
setSpannableFactory(new SafeSpannableFactory());
}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/TimelineContentTextView.java b/twidere/src/main/java/org/mariotaku/twidere/view/TimelineContentTextView.java
new file mode 100644
index 000000000..2bf2a1ed8
--- /dev/null
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/TimelineContentTextView.java
@@ -0,0 +1,87 @@
+/*
+ * Twidere - Twitter client for Android
+ *
+ * Copyright (C) 2012-2015 Mariotaku Lee
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package org.mariotaku.twidere.view;
+
+import android.content.Context;
+import android.text.Layout;
+import android.text.Spannable;
+import android.text.method.LinkMovementMethod;
+import android.text.method.MovementMethod;
+import android.text.style.ClickableSpan;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import org.mariotaku.twidere.view.themed.ThemedTextView;
+
+/**
+ * Returns true when not clicking links
+ * Created by mariotaku on 15/11/20.
+ */
+public class TimelineContentTextView extends ThemedTextView {
+ private boolean mFirstNotLink;
+
+ public TimelineContentTextView(Context context) {
+ super(context);
+ }
+
+ public TimelineContentTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public TimelineContentTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected MovementMethod getDefaultMovementMethod() {
+ return LinkMovementMethod.getInstance();
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN: {
+ Layout layout = getLayout();
+ final float x = event.getX() - getPaddingLeft() + getScrollX();
+ final float y = event.getY() - getPaddingTop() + getScrollY();
+ final int line = layout.getLineForVertical(Math.round(y));
+ int offset = layout.getOffsetForHorizontal(line, x);
+ final CharSequence text = getText();
+ if (text instanceof Spannable) {
+ final ClickableSpan[] spans = ((Spannable) text).getSpans(offset, offset, ClickableSpan.class);
+ mFirstNotLink = spans.length == 0;
+ } else {
+ mFirstNotLink = true;
+ }
+ break;
+ }
+ case MotionEvent.ACTION_UP: {
+ mFirstNotLink = false;
+ break;
+ }
+ }
+ if (mFirstNotLink) {
+ super.onTouchEvent(event);
+ return false;
+ } else {
+ return super.onTouchEvent(event);
+ }
+ }
+}
diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java
index 4e08086a4..2f1a32cb3 100644
--- a/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java
+++ b/twidere/src/main/java/org/mariotaku/twidere/view/holder/StatusViewHolder.java
@@ -124,7 +124,6 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi
} else {
textView.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
}
- textView.setMovementMethod(null);
timeView.setTime(System.currentTimeMillis());
mediaPreview.setVisibility(adapter.isMediaPreviewEnabled() ? View.VISIBLE : View.GONE);
mediaPreview.displayMedia(R.drawable.nyan_stars_background);
@@ -185,7 +184,6 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi
quotedTextView.setText(text);
linkify.applyAllLinks(quotedTextView, status.account_id, getLayoutPosition(),
status.is_possibly_sensitive, adapter.getLinkHighlightingStyle());
- quotedTextView.setMovementMethod(null);
} else {
final String text = status.quoted_text_unescaped;
quotedTextView.setText(text);
@@ -265,7 +263,6 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi
linkify.applyAllLinks(textView, status.account_id, getLayoutPosition(),
status.is_possibly_sensitive,
adapter.getLinkHighlightingStyle());
- textView.setMovementMethod(null);
}
final Locale locale = Locale.getDefault();
diff --git a/twidere/src/main/res/layout/card_item_message_conversation_common.xml b/twidere/src/main/res/layout/card_item_message_conversation_common.xml
index 59fd1f57d..1230140c7 100644
--- a/twidere/src/main/res/layout/card_item_message_conversation_common.xml
+++ b/twidere/src/main/res/layout/card_item_message_conversation_common.xml
@@ -39,7 +39,7 @@
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
-
-
-
-
-
-
-
-
-
-
-
-
- Twitter optimized searches
Use special search terms to improve search results like exclude retweets
I want my stars back!
- Show use favorite (star) instead of like (heart)
+ Use favorite (★) instead of like (♥︎)
Copy link
Link copied to clipboard
Login verification