aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/net/lacolaco/smileessence/view
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2017-10-05 15:58:59 +0900
committerKazuki Yamaguchi <k@rhe.jp>2017-10-05 15:58:59 +0900
commit9db537d339faa3ad44dfdcadb23f4c14bd8aceb4 (patch)
tree6b151cdfd0ca7dc44b9a189045b2b2cbc5aefc21 /app/src/main/java/net/lacolaco/smileessence/view
parent52ad6edcb217762154a80990c34ca94772393848 (diff)
downloadSmileEssence-9db537d339faa3ad44dfdcadb23f4c14bd8aceb4.tar.gz
kotlin work part. 1
Diffstat (limited to 'app/src/main/java/net/lacolaco/smileessence/view')
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.java61
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.kt50
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/DialogHelper.kt (renamed from app/src/main/java/net/lacolaco/smileessence/view/DialogHelper.java)42
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.java29
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.kt23
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/Partials.java229
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/Partials.kt220
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.java147
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt140
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java56
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt41
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.java37
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt25
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java50
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.kt45
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java116
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt102
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.kt (renamed from app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.java)29
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.java41
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.kt35
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java140
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt110
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.java39
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt29
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.java119
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt119
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/DisposeDialog.kt (renamed from app/src/main/java/net/lacolaco/smileessence/view/dialog/DisposeDialog.java)18
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.java80
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt81
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.java250
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt246
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.java131
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt127
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.java28
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.kt25
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.java348
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt339
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.java89
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt81
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.java423
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt390
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.kt (renamed from app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.java)47
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.java117
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt107
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.kt (renamed from app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java)34
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.java104
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt97
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.java112
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt102
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.java97
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt90
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.java32
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt25
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.java334
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt304
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.java321
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt299
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.java192
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt179
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.java36
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.kt26
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.java37
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.kt27
63 files changed, 3555 insertions, 3894 deletions
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.java b/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.java
deleted file mode 100644
index 33fc05ac..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package net.lacolaco.smileessence.view;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.widget.RelativeLayout;
-import net.lacolaco.smileessence.R;
-
-
-public class ColoredRelativeLayout extends RelativeLayout {
- public static final int HIGHLIGHT_NONE = 0;
- private final Paint paint = new Paint();
- private int highlightColors[] = new int[4];
- private boolean showAccent = false;
-
- public ColoredRelativeLayout(Context context) {
- this(context, null);
- }
-
- public ColoredRelativeLayout(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public ColoredRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public ColoredRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
-
- setWillNotDraw(false);
-
- TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColoredRelativeLayout);
- highlightColors[0] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_none, R.color.black);
- highlightColors[1] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_type1, R.color.orange);
- highlightColors[2] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_type2, R.color.green);
- highlightColors[3] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_type3, R.color.metro_blue);
- setHighlight(HIGHLIGHT_NONE);
- paint.setColor(ta.getColor(R.styleable.ColoredRelativeLayout_accent_color, R.color.red));
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(3);
- ta.recycle();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- if (showAccent)
- canvas.drawLine(1, 0, 1, getMeasuredHeight(), paint);
- }
-
- public void setAccentVisibility(boolean yes) {
- showAccent = yes;
- }
-
- public void setHighlight(int type) {
- setBackgroundColor(highlightColors[type]);
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.kt b/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.kt
new file mode 100644
index 00000000..0bf69378
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.kt
@@ -0,0 +1,50 @@
+package net.lacolaco.smileessence.view
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.util.AttributeSet
+import android.widget.RelativeLayout
+import net.lacolaco.smileessence.R
+
+
+class ColoredRelativeLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) : RelativeLayout(context, attrs, defStyleAttr, defStyleRes) {
+ private val paint = Paint()
+ private val highlightColors = IntArray(4)
+ private var showAccent = false
+
+ init {
+
+ setWillNotDraw(false)
+
+ val ta = context.obtainStyledAttributes(attrs, R.styleable.ColoredRelativeLayout)
+ highlightColors[0] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_none, R.color.black)
+ highlightColors[1] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_type1, R.color.orange)
+ highlightColors[2] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_type2, R.color.green)
+ highlightColors[3] = ta.getColor(R.styleable.ColoredRelativeLayout_highlight_type3, R.color.metro_blue)
+ setHighlight(HIGHLIGHT_NONE)
+ paint.color = ta.getColor(R.styleable.ColoredRelativeLayout_accent_color, R.color.red)
+ paint.style = Paint.Style.STROKE
+ paint.strokeWidth = 3f
+ ta.recycle()
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+ if (showAccent)
+ canvas.drawLine(1f, 0f, 1f, measuredHeight.toFloat(), paint)
+ }
+
+ fun setAccentVisibility(yes: Boolean) {
+ showAccent = yes
+ }
+
+ fun setHighlight(type: Int) {
+ setBackgroundColor(highlightColors[type])
+ }
+
+ companion object {
+ val HIGHLIGHT_NONE = 0
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/DialogHelper.java b/app/src/main/java/net/lacolaco/smileessence/view/DialogHelper.kt
index 3a0003d6..c9b4a428 100644
--- a/app/src/main/java/net/lacolaco/smileessence/view/DialogHelper.java
+++ b/app/src/main/java/net/lacolaco/smileessence/view/DialogHelper.kt
@@ -22,38 +22,38 @@
* SOFTWARE.
*/
-package net.lacolaco.smileessence.view;
+package net.lacolaco.smileessence.view
-import android.app.Activity;
-import net.lacolaco.smileessence.view.dialog.StackableDialogFragment;
+import android.app.Activity
+import net.lacolaco.smileessence.view.dialog.StackableDialogFragment
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.UUID;
+import java.util.ArrayList
+import java.util.LinkedHashSet
+import java.util.UUID
/**
* DialogFragment のタグの一覧を保持し「全てのダイアログを閉じる」機能を提供するヘルパークラス
*/
-public class DialogHelper {
- private static Set<String> dialogStack = new LinkedHashSet<>();
+object DialogHelper {
+ private val dialogStack = LinkedHashSet<String>()
- public synchronized static void closeAll(Activity activity) {
- for (String tag : new ArrayList<>(dialogStack)) {
- StackableDialogFragment dialogFragment = (StackableDialogFragment) activity.getFragmentManager().findFragmentByTag(tag);
- if (dialogFragment != null) {
- dialogFragment.dismiss();
- }
+ @Synchronized
+ fun closeAll(activity: Activity) {
+ for (tag in ArrayList(dialogStack)) {
+ val dialogFragment = activity.fragmentManager.findFragmentByTag(tag) as StackableDialogFragment?
+ dialogFragment?.dismiss()
}
}
- public synchronized static int showDialog(Activity activity, StackableDialogFragment dialogFragment) {
- String tag = "stackingDialog:" + dialogFragment.getClass().getSimpleName() + ":" + UUID.randomUUID();
- dialogStack.add(tag);
- return dialogFragment.show(activity.getFragmentManager().beginTransaction(), tag);
+ @Synchronized
+ fun showDialog(activity: Activity, dialogFragment: StackableDialogFragment): Int {
+ val tag = "stackingDialog:" + dialogFragment.javaClass.simpleName + ":" + UUID.randomUUID()
+ dialogStack.add(tag)
+ return dialogFragment.show(activity.fragmentManager.beginTransaction(), tag)
}
- public synchronized static void unregisterDialog(String tag) {
- dialogStack.remove(tag);
+ @Synchronized
+ fun unregisterDialog(tag: String) {
+ dialogStack.remove(tag)
}
}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.java b/app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.java
deleted file mode 100644
index e0a4a651..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.lacolaco.smileessence.view;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-import android.widget.ListView;
-
-public class ExpandedListView extends ListView {
- public ExpandedListView(Context context) {
- super(context);
- }
-
- public ExpandedListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public ExpandedListView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
-
- ViewGroup.LayoutParams params = getLayoutParams();
- params.height = getMeasuredHeight();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.kt b/app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.kt
new file mode 100644
index 00000000..288354ba
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/ExpandedListView.kt
@@ -0,0 +1,23 @@
+package net.lacolaco.smileessence.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ListView
+
+class ExpandedListView : ListView {
+ constructor(context: Context) : super(context)
+
+ constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
+
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
+
+ public override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ val expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE shr 2, View.MeasureSpec.AT_MOST)
+ super.onMeasure(widthMeasureSpec, expandSpec)
+
+ val params = layoutParams
+ params.height = measuredHeight
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/Partials.java b/app/src/main/java/net/lacolaco/smileessence/view/Partials.java
deleted file mode 100644
index fc0e35cb..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/Partials.java
+++ /dev/null
@@ -1,229 +0,0 @@
-package net.lacolaco.smileessence.view;
-
-import android.app.Activity;
-import android.text.Html;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import com.android.volley.toolbox.NetworkImageView;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.data.Account;
-import net.lacolaco.smileessence.data.ImageCache;
-import net.lacolaco.smileessence.entity.DirectMessage;
-import net.lacolaco.smileessence.entity.RBinding;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.preference.UserPreferenceHelper;
-import net.lacolaco.smileessence.util.StringUtils;
-import net.lacolaco.smileessence.util.UIObserverBundle;
-import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
-import net.lacolaco.smileessence.view.dialog.MessageDetailDialogFragment;
-import net.lacolaco.smileessence.view.dialog.StatusDetailDialogFragment;
-import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment;
-import net.lacolaco.smileessence.view.listener.ListItemClickListener;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Partials {
- public static View getTweetView(Tweet tweet, Activity activity, View convertView, boolean expandEmbeddedTweets) {
- if (convertView == null) {
- convertView = activity.getLayoutInflater().inflate(R.layout.list_item_status, null);
- }
- UIObserverBundle bundle = (UIObserverBundle) convertView.getTag();
- if (bundle != null) {
- bundle.detachAll();
- } else {
- bundle = new UIObserverBundle();
- convertView.setTag(bundle);
- }
-
- convertView.setOnClickListener(new ListItemClickListener(activity, () -> DialogHelper.showDialog(activity, StatusDetailDialogFragment.newInstance(tweet))));
-
- updateViewUser(tweet, activity, convertView);
- updateViewBody(tweet, activity, convertView);
- updateViewFavorited(tweet, convertView);
- updateViewEmbeddeds(tweet, activity, convertView, expandEmbeddedTweets);
-
- final WeakReference<View> weakView = new WeakReference<>(convertView);
- final WeakReference<Activity> weakActivity = new WeakReference<>(activity);
- bundle.attach(tweet.getOriginalTweet(), changes -> {
- View strongView = weakView.get();
- if (strongView != null && changes.contains(RBinding.FAVORITERS))
- updateViewFavorited(tweet, strongView);
- });
- bundle.attach(tweet.getUser(), changes -> {
- View strongView = weakView.get();
- Activity strongActivity = weakActivity.get();
- if (strongView != null && strongActivity != null && changes.contains(RBinding.BASIC))
- updateViewUser(tweet, strongActivity, strongView);
- });
-
- return convertView;
- }
-
-
- private static void updateViewEmbeddeds(Tweet tweet, Activity activity, View convertView, boolean expandEmbeddedTweets) {
- final ListView embeddedStatus = (ListView) convertView.findViewById(R.id.listview_status_embedded_status);
- if (expandEmbeddedTweets) {
- final List<Tweet> list = new ArrayList<>();
- CustomListAdapter<Tweet> embeddedTweetsAdapter = new CustomListAdapter<Tweet>() {
- @Override
- protected List<Tweet> getList() {
- return list;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return Partials.getTweetView(getItem(position), activity, convertView, false);
- }
- };
-
- Account account = Application.getCurrentWorld().getAccount();
- for (long id : tweet.getEmbeddedStatusIDs()) {
- Tweet.fetchTask(id, account).onDone(t -> list.add(t)).execute();
- }
- embeddedStatus.setAdapter(embeddedTweetsAdapter);
- embeddedStatus.setVisibility(View.VISIBLE);
- } else {
- embeddedStatus.setAdapter(null); // view may be reused, set null explicitly
- embeddedStatus.setVisibility(View.GONE);
- }
- }
-
- private static void updateViewUser(Tweet tweet, Activity activity, View convertView) {
- int textSize = UserPreferenceHelper.getInstance().getTextSize();
-
- NetworkImageView icon = (NetworkImageView) convertView.findViewById(R.id.imageview_status_icon);
- String iconUrl = tweet.getOriginalTweet().getUser().getProfileImageUrlOriginal();
- icon.setImageUrl(iconUrl, ImageCache.getImageLoader());
- icon.setOnClickListener(v -> onIconClick(tweet, activity));
-
- TextView header = (TextView) convertView.findViewById(R.id.textview_status_header);
- header.setTextSize(textSize);
- header.setText(tweet.getOriginalTweet().getUser().getFormattedName());
-
- ((ColoredRelativeLayout) convertView).setAccentVisibility(tweet.getUser() == Application.getCurrentWorld().getAccount().getUser());
- }
-
- private static void updateViewBody(Tweet tweet, Activity activity, View convertView) {
- int textSize = UserPreferenceHelper.getInstance().getTextSize();
-
- TextView content = (TextView) convertView.findViewById(R.id.textview_status_text);
- content.setTextSize(textSize);
- String rawText = tweet.getOriginalTweet().getText();
- content.setText(rawText);
- TextView footer = (TextView) convertView.findViewById(R.id.textview_status_footer);
- footer.setTextSize(textSize - 2);
- footer.setText(getFooterText(tweet));
-
- ColoredRelativeLayout typedView = (ColoredRelativeLayout) convertView;
- if (tweet.isRetweet()) {
- typedView.setHighlight(2);
- } else if (tweet.getOriginalTweet().getMentions().contains(Application.getCurrentWorld().getAccount().getUser().getScreenName())) {
- typedView.setHighlight(1);
- } else {
- typedView.setHighlight(0);
- }
- }
-
- private static void updateViewFavorited(Tweet tweet, View convertView) {
- ImageView favorited = (ImageView) convertView.findViewById(R.id.imageview_status_favorited);
- favorited.setVisibility(tweet.isFavoritedBy(Application.getCurrentWorld().getAccount().getUserId()) ? View.VISIBLE : View.GONE);
- }
-
- private static void onIconClick(Tweet tweet, Activity activity) {
- UserDetailDialogFragment dialogFragment = new UserDetailDialogFragment();
- dialogFragment.setUserID(tweet.getOriginalTweet().getUser().getId());
- DialogHelper.showDialog(activity, dialogFragment);
- }
-
- private static String getFooterText(Tweet tweet) {
- StringBuilder builder = new StringBuilder();
- if (tweet.isRetweet()) {
- builder
- .append("(RT: ")
- .append(tweet.getUser().getScreenName())
- .append(") ");
- }
- builder.append(StringUtils.dateToString(tweet.getOriginalTweet().getCreatedAt()));
- builder.append(" via ");
- builder.append(Html.fromHtml(tweet.getOriginalTweet().getSource()));
- return builder.toString();
- }
-
- public static View getDirectMessageView(DirectMessage directMessage, Activity activity, View convertView) {
- if (convertView == null) {
- convertView = activity.getLayoutInflater().inflate(R.layout.list_item_status, null);
- }
- UIObserverBundle bundle = (UIObserverBundle) convertView.getTag();
- if (bundle != null) {
- bundle.detachAll();
- } else {
- bundle = new UIObserverBundle();
- convertView.setTag(bundle);
- }
-
- convertView.setOnClickListener(new ListItemClickListener(activity, () -> DialogHelper.showDialog(activity, MessageDetailDialogFragment.newInstance(directMessage))));
-
- ImageView favorited = (ImageView) convertView.findViewById(R.id.imageview_status_favorited);
- favorited.setVisibility(View.GONE);
-
- updateViewSender(directMessage, activity, convertView);
- updateViewBody(directMessage, activity, convertView);
-
- final WeakReference<View> weakView = new WeakReference<>(convertView);
- final WeakReference<MainActivity> weakActivity = new WeakReference<>((MainActivity) activity);
- bundle.attach(directMessage.getSender(), changes -> {
- View strongView = weakView.get();
- MainActivity strongActivity = weakActivity.get();
- if (strongView != null && strongActivity != null && changes.contains(RBinding.BASIC))
- updateViewSender(directMessage, strongActivity, strongView);
- });
-
- return convertView;
- }
-
- private static String getFooterText(DirectMessage directMessage, Account account) {
- StringBuilder builder = new StringBuilder();
- builder.append(StringUtils.dateToString(directMessage.getCreatedAt()));
- if (directMessage.getSender().getId() == account.getUserId()) {
- builder.append(" to @").append(directMessage.getRecipient().getScreenName());
- }
- return builder.toString();
- }
-
- private static void updateViewSender(DirectMessage directMessage, Activity activity, View convertView) {
- int textSize = UserPreferenceHelper.getInstance().getTextSize();
-
- NetworkImageView icon = (NetworkImageView) convertView.findViewById(R.id.imageview_status_icon);
- String iconUrl = directMessage.getSender().getProfileImageUrlOriginal();
- icon.setImageUrl(iconUrl, ImageCache.getImageLoader());
- icon.setOnClickListener(v -> {
- UserDetailDialogFragment dialogFragment = new UserDetailDialogFragment();
- dialogFragment.setUserID(directMessage.getSender().getId());
- DialogHelper.showDialog(activity, dialogFragment);
- });
-
- TextView header = (TextView) convertView.findViewById(R.id.textview_status_header);
- header.setTextSize(textSize);
- header.setText(directMessage.getSender().getFormattedName());
-
- ((ColoredRelativeLayout) convertView).setAccentVisibility(directMessage.getSender() == Application.getCurrentWorld().getAccount().getUser());
- }
-
- private static void updateViewBody(DirectMessage directMessage, Activity activity, View convertView) {
- int textSize = UserPreferenceHelper.getInstance().getTextSize();
-
- TextView content = (TextView) convertView.findViewById(R.id.textview_status_text);
- content.setTextSize(textSize);
- content.setText(directMessage.getText());
- TextView footer = (TextView) convertView.findViewById(R.id.textview_status_footer);
- footer.setTextSize(textSize - 2);
- footer.setText(getFooterText(directMessage, Application.getCurrentWorld().getAccount()));
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/Partials.kt b/app/src/main/java/net/lacolaco/smileessence/view/Partials.kt
new file mode 100644
index 00000000..27d8c3cd
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/Partials.kt
@@ -0,0 +1,220 @@
+package net.lacolaco.smileessence.view
+
+import android.app.Activity
+import android.text.Html
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.ListView
+import android.widget.TextView
+import com.android.volley.toolbox.NetworkImageView
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.data.Account
+import net.lacolaco.smileessence.data.ImageCache
+import net.lacolaco.smileessence.entity.DirectMessage
+import net.lacolaco.smileessence.entity.RBinding
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.preference.UserPreferenceHelper
+import net.lacolaco.smileessence.util.StringUtils
+import net.lacolaco.smileessence.util.UIObserverBundle
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter
+import net.lacolaco.smileessence.view.dialog.MessageDetailDialogFragment
+import net.lacolaco.smileessence.view.dialog.StatusDetailDialogFragment
+import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment
+import net.lacolaco.smileessence.view.listener.ListItemClickListener
+
+import java.lang.ref.WeakReference
+import java.util.ArrayList
+
+object Partials {
+ fun getTweetView(tweet: Tweet, activity: Activity, convertView: View?, expandEmbeddedTweets: Boolean): View {
+ var convertView: View = convertView ?: activity.layoutInflater.inflate(R.layout.list_item_status, null)
+ var bundle: UIObserverBundle? = convertView.tag as UIObserverBundle?
+ if (bundle != null) {
+ bundle.detachAll()
+ } else {
+ bundle = UIObserverBundle()
+ convertView.tag = bundle
+ }
+
+ convertView.setOnClickListener(ListItemClickListener(activity) { DialogHelper.showDialog(activity, StatusDetailDialogFragment.newInstance(tweet)) })
+
+ updateViewUser(tweet, activity, convertView)
+ updateViewBody(tweet, activity, convertView)
+ updateViewFavorited(tweet, convertView)
+ updateViewEmbeddeds(tweet, activity, convertView, expandEmbeddedTweets)
+
+ val weakView = WeakReference(convertView)
+ val weakActivity = WeakReference(activity)
+ bundle.attach(tweet.originalTweet) { changes ->
+ val strongView = weakView.get()
+ if (strongView != null && changes.contains(RBinding.FAVORITERS))
+ updateViewFavorited(tweet, strongView)
+ }
+ bundle.attach(tweet.user) { changes ->
+ val strongView = weakView.get()
+ val strongActivity = weakActivity.get()
+ if (strongView != null && strongActivity != null && changes.contains(RBinding.BASIC))
+ updateViewUser(tweet, strongActivity, strongView)
+ }
+
+ return convertView
+ }
+
+
+ private fun updateViewEmbeddeds(tweet: Tweet, activity: Activity, convertView: View, expandEmbeddedTweets: Boolean) {
+ val embeddedStatus = convertView.findViewById(R.id.listview_status_embedded_status) as ListView
+ if (expandEmbeddedTweets) {
+ val list = ArrayList<Tweet>()
+ val embeddedTweetsAdapter = object : CustomListAdapter<Tweet>() {
+ override val list: List<Tweet>
+ get() = list
+
+ override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
+ return Partials.getTweetView(getItem(position), activity, convertView, false)
+ }
+ }
+
+ val account = Application.currentWorld!!.account
+ for (id in tweet.embeddedStatusIDs) {
+ Tweet.fetchTask(id, account).onDone { t -> list.add(t) }.execute()
+ }
+ embeddedStatus.adapter = embeddedTweetsAdapter
+ embeddedStatus.visibility = View.VISIBLE
+ } else {
+ embeddedStatus.adapter = null // view may be reused, set null explicitly
+ embeddedStatus.visibility = View.GONE
+ }
+ }
+
+ private fun updateViewUser(tweet: Tweet, activity: Activity, convertView: View) {
+ val textSize = UserPreferenceHelper.instance.textSize
+
+ val icon = convertView.findViewById(R.id.imageview_status_icon) as NetworkImageView
+ val iconUrl = tweet.originalTweet.user.profileImageUrl
+ icon.setImageUrl(iconUrl, ImageCache.getImageLoader())
+ icon.setOnClickListener { v -> onIconClick(tweet, activity) }
+
+ val header = convertView.findViewById(R.id.textview_status_header) as TextView
+ header.textSize = textSize.toFloat()
+ header.text = tweet.originalTweet.user.formattedName
+
+ (convertView as ColoredRelativeLayout).setAccentVisibility(tweet.user === Application.currentWorld!!.account.user)
+ }
+
+ private fun updateViewBody(tweet: Tweet, activity: Activity, convertView: View) {
+ val textSize = UserPreferenceHelper.instance.textSize
+
+ val content = convertView.findViewById(R.id.textview_status_text) as TextView
+ content.textSize = textSize.toFloat()
+ val rawText = tweet.originalTweet.text
+ content.text = rawText
+ val footer = convertView.findViewById(R.id.textview_status_footer) as TextView
+ footer.textSize = (textSize - 2).toFloat()
+ footer.text = getFooterText(tweet)
+
+ val typedView = convertView as ColoredRelativeLayout
+ if (tweet.isRetweet) {
+ typedView.setHighlight(2)
+ } else if (tweet.originalTweet.mentions.contains(Application.currentWorld!!.account.user.screenName)) {
+ typedView.setHighlight(1)
+ } else {
+ typedView.setHighlight(0)
+ }
+ }
+
+ private fun updateViewFavorited(tweet: Tweet, convertView: View) {
+ val favorited = convertView.findViewById(R.id.imageview_status_favorited) as ImageView
+ favorited.visibility = if (tweet.isFavoritedBy(Application.currentWorld!!.account.userId)) View.VISIBLE else View.GONE
+ }
+
+ private fun onIconClick(tweet: Tweet, activity: Activity) {
+ DialogHelper.showDialog(activity, UserDetailDialogFragment.newInstance(tweet.originalTweet.user))
+ }
+
+ private fun getFooterText(tweet: Tweet): String {
+ val builder = StringBuilder()
+ if (tweet.isRetweet) {
+ builder
+ .append("(RT: ")
+ .append(tweet.user.screenName)
+ .append(") ")
+ }
+ builder.append(StringUtils.dateToString(tweet.originalTweet.createdAt))
+ builder.append(" via ")
+ builder.append(Html.fromHtml(tweet.originalTweet.source))
+ return builder.toString()
+ }
+
+ fun getDirectMessageView(directMessage: DirectMessage, activity: Activity, convertView: View?): View {
+ var convertView = convertView
+ if (convertView == null) {
+ convertView = activity.layoutInflater.inflate(R.layout.list_item_status, null)
+ }
+ var bundle: UIObserverBundle? = convertView!!.tag as UIObserverBundle?
+ if (bundle != null) {
+ bundle.detachAll()
+ } else {
+ bundle = UIObserverBundle()
+ convertView.tag = bundle
+ }
+
+ convertView.setOnClickListener(ListItemClickListener(activity) { DialogHelper.showDialog(activity, MessageDetailDialogFragment.newInstance(directMessage)) })
+
+ val favorited = convertView.findViewById(R.id.imageview_status_favorited) as ImageView
+ favorited.visibility = View.GONE
+
+ updateViewSender(directMessage, activity, convertView)
+ updateViewBody(directMessage, activity, convertView)
+
+ val weakView = WeakReference(convertView)
+ val weakActivity = WeakReference(activity as MainActivity)
+ bundle.attach(directMessage.sender) { changes ->
+ val strongView = weakView.get()
+ val strongActivity = weakActivity.get()
+ if (strongView != null && strongActivity != null && changes.contains(RBinding.BASIC))
+ updateViewSender(directMessage, strongActivity, strongView)
+ }
+
+ return convertView
+ }
+
+ private fun getFooterText(directMessage: DirectMessage, account: Account): String {
+ val builder = StringBuilder()
+ builder.append(StringUtils.dateToString(directMessage.createdAt))
+ if (directMessage.sender.id == account.userId) {
+ builder.append(" to @").append(directMessage.recipient.screenName)
+ }
+ return builder.toString()
+ }
+
+ private fun updateViewSender(directMessage: DirectMessage, activity: Activity, convertView: View) {
+ val textSize = UserPreferenceHelper.instance.textSize
+
+ val icon = convertView.findViewById(R.id.imageview_status_icon) as NetworkImageView
+ val iconUrl = directMessage.sender.profileImageUrl
+ icon.setImageUrl(iconUrl, ImageCache.getImageLoader())
+ icon.setOnClickListener { v ->
+ DialogHelper.showDialog(activity, UserDetailDialogFragment.newInstance(directMessage.sender))
+ }
+
+ val header = convertView.findViewById(R.id.textview_status_header) as TextView
+ header.textSize = textSize.toFloat()
+ header.text = directMessage.sender.formattedName
+
+ (convertView as ColoredRelativeLayout).setAccentVisibility(directMessage.sender === Application.currentWorld!!.account.user)
+ }
+
+ private fun updateViewBody(directMessage: DirectMessage, activity: Activity, convertView: View) {
+ val textSize = UserPreferenceHelper.instance.textSize
+
+ val content = convertView.findViewById(R.id.textview_status_text) as TextView
+ content.textSize = textSize.toFloat()
+ content.text = directMessage.text
+ val footer = convertView.findViewById(R.id.textview_status_footer) as TextView
+ footer.textSize = (textSize - 2).toFloat()
+ footer.text = getFooterText(directMessage, Application.currentWorld!!.account)
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.java
deleted file mode 100644
index 7ed9636b..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view;
-
-import android.app.AlertDialog;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.preference.EditTextPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.BuildConfig;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.LicenseActivity;
-
-import static android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-
-public class SettingFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener,
- Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- String newValueStr = String.valueOf(newValue);
- if (preference.getKey().contentEquals(getString(R.string.key_setting_text_size))) {
- if (TextUtils.isDigitsOnly(newValueStr)) {
- return true;
- } else {
- Application.toast(R.string.error_setting_text_size_not_number);
- }
- return false;
- } else if (preference.getKey().contentEquals(getString(R.string.key_setting_theme))) {
- Application.toast(R.string.notice_theme_changed);
- }
- return true;
- }
-
- // --------------------- Interface OnPreferenceClickListener ---------------------
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- String key = preference.getKey();
- if (key.contentEquals(getString(R.string.key_setting_application_information))) {
- openAppInfoDialog();
- } else if (key.contentEquals(getString(R.string.key_setting_licenses))) {
- openLicenseActivity();
- }
- return true;
- }
-
- // --------------------- Interface OnSharedPreferenceChangeListener ---------------------
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- setSummaryCurrentValue();
- }
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.setting);
- EditTextPreference textSizePreference = (EditTextPreference) findPreference(R.string.key_setting_text_size);
- textSizePreference.setSummary(textSizePreference.getText());
- textSizePreference.setOnPreferenceChangeListener(this);
- ListPreference themePreference = (ListPreference) findPreference(R.string.key_setting_theme);
- themePreference.setSummary(themePreference.getEntry());
- themePreference.setOnPreferenceChangeListener(this);
- Preference appInfoPreference = findPreference(R.string.key_setting_application_information);
- appInfoPreference.setOnPreferenceClickListener(this);
- appInfoPreference.setSummary(BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")");
- Preference license = findPreference(R.string.key_setting_licenses);
- license.setOnPreferenceClickListener(this);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
- sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
- sharedPreferences.registerOnSharedPreferenceChangeListener(this);
- }
-
- // -------------------------- OTHER METHODS --------------------------
-
- public Preference findPreference(int preferenceResID) {
- return findPreference(getString(preferenceResID));
- }
-
- private void openLicenseActivity() {
- Intent intent = new Intent(getActivity(), LicenseActivity.class);
- getActivity().startActivity(intent);
- }
-
- private void openAppInfoDialog() {
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View contentView = inflater.inflate(R.layout.dialog_app_info, null);
- TextView versionTextView = (TextView) contentView.findViewById(R.id.versionTextView);
- versionTextView.setText(BuildConfig.VERSION_NAME + " (rev: " + BuildConfig.VERSION_CODE + "; upstream: " + getString(R.string.app_version_full) + ")");
-
- new AlertDialog.Builder(getActivity())
- .setTitle(R.string.dialog_title_about)
- .setView(contentView)
- .setPositiveButton(R.string.alert_dialog_ok, (dialog, which) -> dialog.dismiss())
- .create().show();
- }
-
- private void setSummaryCurrentValue() {
- EditTextPreference textSizePreference = (EditTextPreference) findPreference(R.string.key_setting_text_size);
- textSizePreference.setSummary(textSizePreference.getText());
- ListPreference themePreference = (ListPreference) findPreference(R.string.key_setting_theme);
- themePreference.setSummary(themePreference.getEntry());
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt
new file mode 100644
index 00000000..05490f97
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt
@@ -0,0 +1,140 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view
+
+import android.app.AlertDialog
+import android.content.Intent
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.preference.EditTextPreference
+import android.preference.ListPreference
+import android.preference.Preference
+import android.preference.PreferenceFragment
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.TextView
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.BuildConfig
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.LicenseActivity
+
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener
+
+class SettingFragment : PreferenceFragment(), OnSharedPreferenceChangeListener, Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener {
+ override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
+ val newValueStr = newValue.toString()
+ if (preference.key.contentEquals(getString(R.string.key_setting_text_size))) {
+ if (TextUtils.isDigitsOnly(newValueStr)) {
+ return true
+ } else {
+ Application.toast(R.string.error_setting_text_size_not_number)
+ }
+ return false
+ } else if (preference.key.contentEquals(getString(R.string.key_setting_theme))) {
+ Application.toast(R.string.notice_theme_changed)
+ }
+ return true
+ }
+
+ // --------------------- Interface OnPreferenceClickListener ---------------------
+
+ override fun onPreferenceClick(preference: Preference): Boolean {
+ val key = preference.key
+ if (key.contentEquals(getString(R.string.key_setting_application_information))) {
+ openAppInfoDialog()
+ } else if (key.contentEquals(getString(R.string.key_setting_licenses))) {
+ openLicenseActivity()
+ }
+ return true
+ }
+
+ // --------------------- Interface OnSharedPreferenceChangeListener ---------------------
+
+ override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
+ setSummaryCurrentValue()
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ addPreferencesFromResource(R.xml.setting)
+ val textSizePreference = findPreference(R.string.key_setting_text_size) as EditTextPreference
+ textSizePreference.summary = textSizePreference.text
+ textSizePreference.onPreferenceChangeListener = this
+ val themePreference = findPreference(R.string.key_setting_theme) as ListPreference
+ themePreference.summary = themePreference.entry
+ themePreference.onPreferenceChangeListener = this
+ val appInfoPreference = findPreference(R.string.key_setting_application_information)
+ appInfoPreference.onPreferenceClickListener = this
+ appInfoPreference.summary = BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")"
+ val license = findPreference(R.string.key_setting_licenses)
+ license.onPreferenceClickListener = this
+ }
+
+ override fun onPause() {
+ super.onPause()
+ val sharedPreferences = preferenceScreen.sharedPreferences
+ sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ val sharedPreferences = preferenceScreen.sharedPreferences
+ sharedPreferences.registerOnSharedPreferenceChangeListener(this)
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ fun findPreference(preferenceResID: Int): Preference {
+ return findPreference(getString(preferenceResID))
+ }
+
+ private fun openLicenseActivity() {
+ val intent = Intent(activity, LicenseActivity::class.java)
+ activity.startActivity(intent)
+ }
+
+ private fun openAppInfoDialog() {
+ val inflater = activity.layoutInflater
+ val contentView = inflater.inflate(R.layout.dialog_app_info, null)
+ val versionTextView = contentView.findViewById(R.id.versionTextView) as TextView
+ versionTextView.text = BuildConfig.VERSION_NAME + " (rev: " + BuildConfig.VERSION_CODE + "; upstream: " + getString(R.string.app_version_full) + ")"
+
+ AlertDialog.Builder(activity)
+ .setTitle(R.string.dialog_title_about)
+ .setView(contentView)
+ .setPositiveButton(R.string.alert_dialog_ok) { dialog, which -> dialog.dismiss() }
+ .create().show()
+ }
+
+ private fun setSummaryCurrentValue() {
+ val textSizePreference = findPreference(R.string.key_setting_text_size) as EditTextPreference
+ textSizePreference.summary = textSizePreference.text
+ val themePreference = findPreference(R.string.key_setting_theme) as ListPreference
+ themePreference.summary = themePreference.entry
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java b/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java
deleted file mode 100644
index d5358db5..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package net.lacolaco.smileessence.view;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.widget.Button;
-import net.lacolaco.smileessence.R;
-
-public class ThreeStateButton extends Button {
- public static final int STATE_OFF = 0;
- public static final int STATE_ON = 1;
- public static final int STATE_LOCKED = 2;
-
- private int state = STATE_OFF;
- private String texts[] = new String[3];
- private Drawable backgrounds[] = new Drawable[3];
-
- public ThreeStateButton(Context context) {
- this(context, null);
- }
-
- public ThreeStateButton(Context context, AttributeSet attrs) {
- this(context, attrs, android.R.attr.buttonStyle);
- }
-
- public ThreeStateButton(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public ThreeStateButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
-
- TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ThreeStateButton);
- texts[STATE_OFF] = ta.getString(R.styleable.ThreeStateButton_off_text);
- texts[STATE_ON] = ta.getString(R.styleable.ThreeStateButton_on_text);
- texts[STATE_LOCKED] = ta.getString(R.styleable.ThreeStateButton_locked_text);
- backgrounds[STATE_OFF] = ta.getDrawable(R.styleable.ThreeStateButton_off_background);
- backgrounds[STATE_ON] = ta.getDrawable(R.styleable.ThreeStateButton_on_background);
- backgrounds[STATE_LOCKED] = ta.getDrawable(R.styleable.ThreeStateButton_locked_background);
- ta.recycle();
-
- setState(STATE_OFF);
- }
-
- public int getState() {
- return state;
- }
-
- public void setState(int s) {
- state = s;
- setText(texts[state]);
- setBackground(backgrounds[state]);
- setEnabled(state != STATE_LOCKED);
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt b/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt
new file mode 100644
index 00000000..547aa84d
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt
@@ -0,0 +1,41 @@
+package net.lacolaco.smileessence.view
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.graphics.drawable.Drawable
+import android.util.AttributeSet
+import android.widget.Button
+import net.lacolaco.smileessence.R
+
+class ThreeStateButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.buttonStyle, defStyleRes: Int = 0) : Button(context, attrs, defStyleAttr, defStyleRes) {
+
+ var state = STATE_OFF
+ set(s) {
+ field = s
+ text = texts[this.state]
+ background = backgrounds[this.state]
+ isEnabled = this.state != STATE_LOCKED
+ }
+ private val texts = arrayOfNulls<String>(3)
+ private val backgrounds = arrayOfNulls<Drawable>(3)
+
+ init {
+
+ val ta = context.obtainStyledAttributes(attrs, R.styleable.ThreeStateButton)
+ texts[STATE_OFF] = ta.getString(R.styleable.ThreeStateButton_off_text)
+ texts[STATE_ON] = ta.getString(R.styleable.ThreeStateButton_on_text)
+ texts[STATE_LOCKED] = ta.getString(R.styleable.ThreeStateButton_locked_text)
+ backgrounds[STATE_OFF] = ta.getDrawable(R.styleable.ThreeStateButton_off_background)
+ backgrounds[STATE_ON] = ta.getDrawable(R.styleable.ThreeStateButton_on_background)
+ backgrounds[STATE_LOCKED] = ta.getDrawable(R.styleable.ThreeStateButton_locked_background)
+ ta.recycle()
+
+ state = STATE_OFF
+ }
+
+ companion object {
+ val STATE_OFF = 0
+ val STATE_ON = 1
+ val STATE_LOCKED = 2
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.java b/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.java
deleted file mode 100644
index b7b2d174..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.lacolaco.smileessence.view;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.widget.ImageButton;
-import net.lacolaco.smileessence.R;
-
-public class ToggleableImageButton extends ImageButton {
- private Drawable onSrc, offSrc;
-
- public ToggleableImageButton(Context context) {
- this(context, null);
- }
-
- public ToggleableImageButton(Context context, AttributeSet attrs) {
- this(context, attrs, android.R.attr.imageButtonStyle);
- }
-
- public ToggleableImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public ToggleableImageButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
-
- TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ToggleableImageButton);
- offSrc = ta.getDrawable(R.styleable.ToggleableImageButton_offSrc);
- onSrc = ta.getDrawable(R.styleable.ToggleableImageButton_onSrc);
- ta.recycle();
- }
-
- public void setState(boolean isOn) {
- setImageDrawable(isOn ? onSrc : offSrc);
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt b/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt
new file mode 100644
index 00000000..47a1821a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt
@@ -0,0 +1,25 @@
+package net.lacolaco.smileessence.view
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.graphics.drawable.Drawable
+import android.util.AttributeSet
+import android.widget.ImageButton
+import net.lacolaco.smileessence.R
+
+class ToggleableImageButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.imageButtonStyle, defStyleRes: Int = 0) : ImageButton(context, attrs, defStyleAttr, defStyleRes) {
+ private val onSrc: Drawable
+ private val offSrc: Drawable
+
+ init {
+
+ val ta = context.obtainStyledAttributes(attrs, R.styleable.ToggleableImageButton)
+ offSrc = ta.getDrawable(R.styleable.ToggleableImageButton_offSrc)
+ onSrc = ta.getDrawable(R.styleable.ToggleableImageButton_onSrc)
+ ta.recycle()
+ }
+
+ fun setState(isOn: Boolean) {
+ setImageDrawable(if (isOn) onSrc else offSrc)
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java
deleted file mode 100644
index 6d7420fb..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package net.lacolaco.smileessence.view.adapter;
-
-import android.widget.BaseAdapter;
-import net.lacolaco.smileessence.util.UIHandler;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public abstract class CustomListAdapter<T> extends BaseAdapter {
- private boolean isNotifiable = true;
- private List<T> frozenList = new ArrayList<>();
-
- public final void setNotifiable(boolean notifiable) {
- isNotifiable = notifiable;
- }
-
- @Override
- public final int getCount() {
- return frozenList.size();
- }
-
- @Override
- public final T getItem(int position) {
- return frozenList.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public final void notifyDataSetChanged() {
- frozenList = Collections.unmodifiableList(getList());
- super.notifyDataSetChanged();
- }
-
- protected abstract List<T> getList();
-
- public void update() {
- if (isNotifiable) {
- updateForce();
- }
- }
-
- public void updateForce() {
- new UIHandler().post(this::notifyDataSetChanged);
- }
-} \ No newline at end of file
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.kt
new file mode 100644
index 00000000..3b022012
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.kt
@@ -0,0 +1,45 @@
+package net.lacolaco.smileessence.view.adapter
+
+import android.widget.BaseAdapter
+import net.lacolaco.smileessence.util.UIHandler
+
+import java.util.ArrayList
+import java.util.Collections
+
+abstract class CustomListAdapter<T> : BaseAdapter() {
+ private var isNotifiable = true
+ private var frozenList: List<T> = ArrayList()
+
+ fun setNotifiable(notifiable: Boolean) {
+ isNotifiable = notifiable
+ }
+
+ override fun getCount(): Int {
+ return frozenList.size
+ }
+
+ override fun getItem(position: Int): T {
+ return frozenList[position]
+ }
+
+ override fun getItemId(position: Int): Long {
+ return position.toLong()
+ }
+
+ override fun notifyDataSetChanged() {
+ frozenList = Collections.unmodifiableList(list)
+ super.notifyDataSetChanged()
+ }
+
+ protected abstract val list: List<T>
+
+ fun update() {
+ if (isNotifiable) {
+ updateForce()
+ }
+ }
+
+ fun updateForce() {
+ UIHandler().post { this.notifyDataSetChanged() }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java
deleted file mode 100644
index 3f98cfaa..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.adapter;
-
-import android.app.Activity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-import com.android.volley.toolbox.NetworkImageView;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.World;
-import net.lacolaco.smileessence.data.ImageCache;
-import net.lacolaco.smileessence.entity.Event;
-import net.lacolaco.smileessence.entity.RBinding;
-import net.lacolaco.smileessence.preference.UserPreferenceHelper;
-import net.lacolaco.smileessence.util.StringUtils;
-import net.lacolaco.smileessence.util.UIObserverBundle;
-import net.lacolaco.smileessence.view.DialogHelper;
-import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment;
-import net.lacolaco.smileessence.view.listener.ListItemClickListener;
-
-import java.lang.ref.WeakReference;
-import java.util.List;
-
-public class EventListAdapter extends CustomListAdapter<Event> {
- private final World world;
- private final Activity activity;
-
- public EventListAdapter(World world, Activity activity) {
- super();
- this.world = world;
- this.activity = activity;
- }
-
- @Override
- protected List<Event> getList() {
- return world.getEvents();
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- Event event = getItem(position);
- if (convertView == null) {
- convertView = activity.getLayoutInflater().inflate(R.layout.list_item_status, null);
- }
- UIObserverBundle bundle = (UIObserverBundle) convertView.getTag();
- if (bundle != null) {
- bundle.detachAll();
- } else {
- bundle = new UIObserverBundle();
- convertView.setTag(bundle);
- }
-
- int textSize = UserPreferenceHelper.getInstance().getTextSize();
-
- TextView header = (TextView) convertView.findViewById(R.id.textview_status_header);
- header.setTextSize(textSize);
-
- updateViewUser(event, convertView);
-
- TextView content = (TextView) convertView.findViewById(R.id.textview_status_text);
- content.setTextSize(textSize);
- content.setText(event.getTargetObject() != null ? event.getTargetObject().getText() : "");
- TextView footer = (TextView) convertView.findViewById(R.id.textview_status_footer);
- footer.setTextSize(textSize - 2);
- footer.setText(StringUtils.dateToString(event.getCreatedAt()));
- ImageView favorited = (ImageView) convertView.findViewById(R.id.imageview_status_favorited);
- favorited.setVisibility(View.GONE);
- convertView.setOnClickListener(new ListItemClickListener(activity, () -> {
- UserDetailDialogFragment fragment = new UserDetailDialogFragment();
- fragment.setUserID(event.getSource().getId());
- DialogHelper.showDialog(activity, fragment);
- }));
-
- final WeakReference<View> weakView = new WeakReference<>(convertView);
- bundle.attach(event.getSource(), changes -> {
- View strongView = weakView.get();
- if (strongView != null && changes.contains(RBinding.BASIC))
- updateViewUser(event, strongView);
- });
-
- return convertView;
- }
-
- private void updateViewUser(Event event, View convertedView) {
- NetworkImageView icon = (NetworkImageView) convertedView.findViewById(R.id.imageview_status_icon);
- String iconUrl = event.getSource().getProfileImageUrlOriginal();
- icon.setImageUrl(iconUrl, ImageCache.getImageLoader());
-
- TextView header = (TextView) convertedView.findViewById(R.id.textview_status_header);
- header.setText(event.getFormattedString());
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt
new file mode 100644
index 00000000..1c19d4ec
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt
@@ -0,0 +1,102 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter
+
+import android.app.Activity
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import com.android.volley.toolbox.NetworkImageView
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.World
+import net.lacolaco.smileessence.data.ImageCache
+import net.lacolaco.smileessence.entity.Event
+import net.lacolaco.smileessence.entity.RBinding
+import net.lacolaco.smileessence.preference.UserPreferenceHelper
+import net.lacolaco.smileessence.util.StringUtils
+import net.lacolaco.smileessence.util.UIObserverBundle
+import net.lacolaco.smileessence.view.DialogHelper
+import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment
+import net.lacolaco.smileessence.view.listener.ListItemClickListener
+
+import java.lang.ref.WeakReference
+
+class EventListAdapter(private val world: World, private val activity: Activity) : CustomListAdapter<Event>() {
+ override val list: List<Event>
+ get() = world.events
+
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ var convertView = convertView
+ val event = getItem(position)
+ if (convertView == null) {
+ convertView = activity.layoutInflater.inflate(R.layout.list_item_status, null)
+ }
+ var bundle: UIObserverBundle? = convertView!!.tag as UIObserverBundle?
+ if (bundle != null) {
+ bundle.detachAll()
+ } else {
+ bundle = UIObserverBundle()
+ convertView.tag = bundle
+ }
+
+ val textSize = UserPreferenceHelper.instance.textSize
+
+ val header = convertView.findViewById(R.id.textview_status_header) as TextView
+ header.textSize = textSize.toFloat()
+
+ updateViewUser(event, convertView)
+
+ val content = convertView.findViewById(R.id.textview_status_text) as TextView
+ content.textSize = textSize.toFloat()
+ content.text = event.targetObject?.text ?: ""
+ val footer = convertView.findViewById(R.id.textview_status_footer) as TextView
+ footer.textSize = (textSize - 2).toFloat()
+ footer.text = StringUtils.dateToString(event.createdAt)
+ val favorited = convertView.findViewById(R.id.imageview_status_favorited) as ImageView
+ favorited.visibility = View.GONE
+ convertView.setOnClickListener(ListItemClickListener(activity) {
+ DialogHelper.showDialog(activity, UserDetailDialogFragment.newInstance(event.source))
+ })
+
+ val weakView = WeakReference(convertView)
+ bundle.attach(event.source) { changes ->
+ val strongView = weakView.get()
+ if (strongView != null && changes.contains(RBinding.BASIC))
+ updateViewUser(event, strongView)
+ }
+
+ return convertView
+ }
+
+ private fun updateViewUser(event: Event, convertedView: View) {
+ val icon = convertedView.findViewById(R.id.imageview_status_icon) as NetworkImageView
+ val iconUrl = event.source.profileImageUrl
+ icon.setImageUrl(iconUrl, ImageCache.getImageLoader())
+
+ val header = convertedView.findViewById(R.id.textview_status_header) as TextView
+ header.text = event.formattedString
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.kt
index 5f04114e..d72ab564 100644
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.java
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.kt
@@ -22,25 +22,22 @@
* SOFTWARE.
*/
-package net.lacolaco.smileessence.view.page;
+package net.lacolaco.smileessence.view.adapter
-import android.os.Bundle;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import net.lacolaco.smileessence.World;
-import net.lacolaco.smileessence.view.adapter.EventListAdapter;
+import android.app.Activity
+import android.view.View
+import android.view.ViewGroup
+import net.lacolaco.smileessence.entity.DirectMessage
+import net.lacolaco.smileessence.view.Partials
-public class HistoryFragment extends CustomListFragment<EventListAdapter> {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+class MessageListAdapter(private val activity: Activity) : OrderedCustomListAdapter<DirectMessage>() {
+ val lastID: Long
+ get() = if (count > 0) getItem(count - 1).id else -1
- World world = getWorld();
- final EventListAdapter adapter = new EventListAdapter(world, getActivity());
- setAdapter(adapter);
- world.addEventNotifier(this, () -> adapter.update()); // XXX
- }
+ val topID: Long
+ get() = if (count > 0) getItem(0).id else -1
- @Override
- public void refresh() {
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ return Partials.getDirectMessageView(getItem(position), activity, convertView)
}
}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.java
deleted file mode 100644
index 3de58658..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package net.lacolaco.smileessence.view.adapter;
-
-import net.lacolaco.smileessence.entity.IdObject;
-
-import java.util.*;
-
-public abstract class OrderedCustomListAdapter<T extends IdObject> extends CustomListAdapter<T> {
- private final Map<Long, T> treeMap;
-
- public OrderedCustomListAdapter() {
- this(Long::compare);
- }
-
- public OrderedCustomListAdapter(Comparator<Long> comparator) {
- super();
- this.treeMap = new TreeMap<>(Collections.reverseOrder(comparator));
- }
-
- @Override
- protected synchronized List<T> getList() {
- return new ArrayList<>(treeMap.values());
- }
-
- public synchronized void add(T item) {
- treeMap.put(item.getId(), item);
- }
-
- public synchronized void addAll(Collection<T> items) {
- for (T item : items) {
- treeMap.put(item.getId(), item);
- }
- }
-
- public synchronized void clear() {
- treeMap.clear();
- }
-
- public synchronized T remove(T item) {
- return treeMap.remove(item.getId());
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.kt
new file mode 100644
index 00000000..53b1c824
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.kt
@@ -0,0 +1,35 @@
+package net.lacolaco.smileessence.view.adapter
+
+import net.lacolaco.smileessence.entity.IdObject
+
+import java.util.*
+
+abstract class OrderedCustomListAdapter<T : IdObject>
+constructor(comparator: Comparator<Long> = Comparator { x, y -> java.lang.Long.compare(x, y) }) : CustomListAdapter<T>() {
+ private val treeMap: MutableMap<Long, T> = TreeMap(Collections.reverseOrder(comparator))
+
+ override val list: List<T>
+ @Synchronized get() = ArrayList(treeMap.values)
+
+ @Synchronized
+ fun add(item: T) {
+ treeMap.put(item.id, item)
+ }
+
+ @Synchronized
+ fun addAll(items: Collection<T>) {
+ for (item in items) {
+ treeMap.put(item.id, item)
+ }
+ }
+
+ @Synchronized
+ fun clear() {
+ treeMap.clear()
+ }
+
+ @Synchronized
+ fun remove(item: T): T {
+ return treeMap.remove(item.id)!!
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java
deleted file mode 100644
index 76e72093..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.adapter;
-
-import android.os.Bundle;
-import android.support.v13.app.FragmentPagerAdapter;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.logging.Logger;
-import net.lacolaco.smileessence.view.page.PageFragment;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class PageListAdapter extends FragmentPagerAdapter {
-
- // ------------------------------ FIELDS ------------------------------
-
- private final List<PageInfo> pages = new ArrayList<>();
- private final Map<Integer, WeakReference<PageFragment>> fragmentCache = new HashMap<>();
-
- // --------------------------- FragmentPagerAdapter ---------------------------
-
- public PageListAdapter(MainActivity _activity) {
- super(_activity.getFragmentManager());
- }
-
- @Override
- public synchronized PageFragment getItem(int position) {
- PageFragment pf;
- PageInfo info = pages.get(position);
- try {
- pf = info.getFragmentClass().newInstance();
- } catch (Exception e) {
- Logger.error("should not happen: fragmentClass is private or Android is broken?");
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- pf.setArguments(info.getArgs());
- fragmentCache.put(position, new WeakReference<>(pf));
- return pf;
- }
-
- public synchronized PageFragment getCachedFragment(int pos) {
- WeakReference<PageFragment> wpf = fragmentCache.get(pos);
- if (wpf == null) {
- return null;
- } else {
- return wpf.get();
- }
- }
-
- @Override
- public synchronized int getCount() {
- return pages.size();
- }
-
- // ------------------------ INTERFACE METHODS ------------------------
-
- // -------------------------- OTHER METHODS --------------------------
-
- public void addPage(Class<? extends PageFragment> klass, String name, Bundle args) {
- this.addPage(klass, name, args, true);
- }
-
- public void addPage(Class<? extends PageFragment> klass, String name, Bundle args, boolean notifyChanged) {
- pages.add(new PageInfo(klass, name, args));
- if (notifyChanged) notifyDataSetChanged();
- }
-
- public synchronized boolean removePage(int position) {
- //if (removePageWithoutNotify(position)) {
- // refreshListNavigation();
- // return true;
- //}
- return pages.remove(position) != null; // TODO
- }
-
- public String getName(int pos) {
- return pages.get(pos).getName();
- }
-
- @Deprecated
- public int getIndex(Class<? extends PageFragment> fragmentClass) {
- for (int i = 0; i < pages.size(); ++i) {
- if (pages.get(i).getFragmentClass() == fragmentClass) {
- return i;
- }
- }
- return -1;
- }
-
- private static final class PageInfo {
- private final Class<? extends PageFragment> fragmentClass;
- private final Bundle args;
- private final String name;
-
- PageInfo(Class<? extends PageFragment> _fragmentClass, String _name, Bundle _args) {
- fragmentClass = _fragmentClass;
- name = _name;
- args = _args;
- }
-
- public Class<? extends PageFragment> getFragmentClass() {
- return fragmentClass;
- }
-
- public String getName() {
- return name;
- }
-
- public Bundle getArgs() {
- return args;
- }
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt
new file mode 100644
index 00000000..34d158f0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt
@@ -0,0 +1,110 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter
+
+import android.os.Bundle
+import android.support.v13.app.FragmentPagerAdapter
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.logging.Logger
+import net.lacolaco.smileessence.view.page.PageFragment
+
+import java.lang.ref.WeakReference
+import java.util.ArrayList
+import java.util.HashMap
+
+class PageListAdapter
+// --------------------------- FragmentPagerAdapter ---------------------------
+
+(_activity: MainActivity) : FragmentPagerAdapter(_activity.fragmentManager) {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private val pages = ArrayList<PageInfo>()
+ private val fragmentCache = HashMap<Int, WeakReference<PageFragment<*>>>()
+
+ @Synchronized override fun getItem(position: Int): PageFragment<*> {
+ val pf: PageFragment<*>
+ val info = pages[position]
+ try {
+ pf = info.fragmentClass.newInstance()
+ } catch (e: Exception) {
+ Logger.error("should not happen: fragmentClass is private or Android is broken?")
+ e.printStackTrace()
+ throw RuntimeException(e)
+ }
+
+ pf.arguments = info.args
+ fragmentCache.put(position, WeakReference(pf))
+ return pf
+ }
+
+ @Synchronized
+ fun getCachedFragment(pos: Int): PageFragment<*>? {
+ val wpf = fragmentCache[pos]
+ return wpf?.get()
+ }
+
+ @Synchronized override fun getCount(): Int {
+ return pages.size
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ fun addPage(klass: Class<out PageFragment<*>>, name: String, args: Bundle) {
+ this.addPage(klass, name, args, true)
+ }
+
+ fun addPage(klass: Class<out PageFragment<*>>, name: String, args: Bundle, notifyChanged: Boolean) {
+ pages.add(PageInfo(klass, name, args))
+ if (notifyChanged) notifyDataSetChanged()
+ }
+
+ @Synchronized
+ fun removePage(position: Int): Boolean {
+ //if (removePageWithoutNotify(position)) {
+ // refreshListNavigation();
+ // return true;
+ //}
+ return pages.removeAt(position) != null // TODO
+ }
+
+ fun getName(pos: Int): String {
+ return pages[pos].name
+ }
+
+ @Deprecated("")
+ fun getIndex(fragmentClass: Class<out PageFragment<*>>): Int {
+ for (i in pages.indices) {
+ if (pages[i].fragmentClass == fragmentClass) {
+ return i
+ }
+ }
+ return -1
+ }
+
+ private class PageInfo internal constructor(val fragmentClass: Class<out PageFragment<*>>, val name: String, val args: Bundle)
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.java
deleted file mode 100644
index 0dbe8d53..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.lacolaco.smileessence.view.adapter;
-
-import android.app.Activity;
-import android.view.View;
-import android.view.ViewGroup;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.view.Partials;
-
-import java.util.*;
-
-public class TimelineAdapter extends OrderedCustomListAdapter<Tweet> {
- private final Activity activity;
-
- public TimelineAdapter(Activity activity) {
- super();
- this.activity = activity;
- }
-
- public long getLastID() {
- if (getCount() > 0) {
- return getItem(getCount() - 1).getId();
- } else {
- return -1;
- }
- }
-
- public long getTopID() {
- if (getCount() > 0) {
- return getItem(0).getId();
- } else {
- return -1;
- }
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return Partials.getTweetView(getItem(position), activity, convertView, true);
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt
new file mode 100644
index 00000000..750b63a0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt
@@ -0,0 +1,29 @@
+package net.lacolaco.smileessence.view.adapter
+
+import android.app.Activity
+import android.view.View
+import android.view.ViewGroup
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.view.Partials
+
+import java.util.*
+
+class TimelineAdapter(private val activity: Activity) : OrderedCustomListAdapter<Tweet>() {
+ val lastID: Long
+ get() = if (count > 0) {
+ getItem(count - 1).id
+ } else {
+ -1
+ }
+
+ val topID: Long
+ get() = if (count > 0) {
+ getItem(0).id
+ } else {
+ -1
+ }
+
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ return Partials.getTweetView(getItem(position), activity, convertView, true)
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.java
deleted file mode 100644
index 74dcc468..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.preference.UserPreferenceHelper;
-import net.lacolaco.smileessence.view.DialogHelper;
-
-public abstract class ConfirmDialogFragment extends StackableDialogFragment {
-
- // ------------------------------ FIELDS ------------------------------
-
- private static final String ARG_TEXT = "text";
- private final DialogInterface.OnClickListener listener = (dialog, which) -> {
- onButtonClick(which);
- dialog.dismiss();
- };
- private String text;
-
- // -------------------------- STATIC METHODS --------------------------
-
- public static void show(Activity activity, String text, final Runnable onYes) {
- show(activity, text, onYes, null, true);
- }
-
- public static void show(Activity activity, String text, final Runnable onYes, boolean ignorable) {
- show(activity, text, onYes, null, ignorable);
- }
-
- public static void show(Activity activity, String text, final Runnable onOK, final Runnable onCancel, boolean ignorable) {
- boolean confirm = UserPreferenceHelper.getInstance().get(R.string.key_setting_show_confirm_dialog, true);
- if (!confirm && ignorable) {
- onOK.run();
- return;
- }
- final ConfirmDialogFragment fragment = new ConfirmDialogFragment() {
- @Override
- public void onButtonClick(int which) {
- switch (which) {
- case DialogInterface.BUTTON_POSITIVE: {
- if (onOK != null) {
- dismiss();
- onOK.run();
- }
- break;
- }
- case DialogInterface.BUTTON_NEGATIVE: {
- if (onCancel != null) {
- dismiss();
- onCancel.run();
- }
- break;
- }
- }
- }
- };
- fragment.setText(text);
- DialogHelper.showDialog(activity, fragment);
- }
-
- // --------------------- GETTER / SETTER METHODS ---------------------
-
- public void setText(String text) {
- Bundle args = new Bundle();
- args.putString(ARG_TEXT, text);
- setArguments(args);
- }
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Bundle args = getArguments();
- if (args != null) {
- text = args.getString(ARG_TEXT);
- }
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- return new AlertDialog.Builder(getActivity()).setTitle(text)
- .setCancelable(false)
- .setPositiveButton(R.string.alert_dialog_ok, listener)
- .setNegativeButton(R.string.alert_dialog_cancel, listener)
- .create();
- }
-
- // -------------------------- OTHER METHODS --------------------------
-
- protected abstract void onButtonClick(int which);
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt
new file mode 100644
index 00000000..094aa18a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt
@@ -0,0 +1,119 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.Activity
+import android.app.AlertDialog
+import android.app.Dialog
+import android.content.DialogInterface
+import android.os.Bundle
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.preference.UserPreferenceHelper
+import net.lacolaco.smileessence.view.DialogHelper
+
+abstract class ConfirmDialogFragment : StackableDialogFragment() {
+ private var text: String? = null
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ fun setText(text: String) {
+ val args = Bundle()
+ args.putString(ARG_TEXT, text)
+ arguments = args
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val args = arguments
+ if (args != null) {
+ text = args.getString(ARG_TEXT)
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return AlertDialog.Builder(activity).setTitle(text)
+ .setCancelable(false)
+ .setPositiveButton(R.string.alert_dialog_ok, { dialog, which ->
+ onButtonClick(which)
+ dialog.dismiss()
+ })
+ .setNegativeButton(R.string.alert_dialog_cancel, { dialog, which ->
+ onButtonClick(which)
+ dialog.dismiss()
+ })
+ .create()
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ protected abstract fun onButtonClick(which: Int)
+
+ companion object {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private val ARG_TEXT = "text"
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ fun show(activity: Activity, text: String, onYes: () -> Unit) {
+ show(activity, text, onYes, null, true)
+ }
+
+ fun show(activity: Activity, text: String, onYes: () -> Unit, ignorable: Boolean) {
+ show(activity, text, onYes, null, ignorable)
+ }
+
+ fun show(activity: Activity, text: String, onOK: (() -> Unit)?, onCancel: (() -> Unit)?, ignorable: Boolean) {
+ val confirm = UserPreferenceHelper.instance.get(R.string.key_setting_show_confirm_dialog, true)
+ if (!confirm && ignorable) {
+ onOK!!()
+ return
+ }
+ val fragment = object : ConfirmDialogFragment() {
+ public override fun onButtonClick(which: Int) {
+ when (which) {
+ DialogInterface.BUTTON_POSITIVE -> {
+ if (onOK != null) {
+ dismiss()
+ onOK()
+ }
+ }
+ DialogInterface.BUTTON_NEGATIVE -> {
+ if (onCancel != null) {
+ dismiss()
+ onCancel()
+ }
+ }
+ }
+ }
+ }
+ fragment.setText(text)
+ DialogHelper.showDialog(activity, fragment)
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/DisposeDialog.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/DisposeDialog.kt
index eb3d3613..3cd486bd 100644
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/DisposeDialog.java
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/DisposeDialog.kt
@@ -22,22 +22,16 @@
* SOFTWARE.
*/
-package net.lacolaco.smileessence.view.dialog;
+package net.lacolaco.smileessence.view.dialog
-import android.app.Dialog;
-import android.content.Context;
+import android.app.Dialog
+import android.content.Context
/**
* Dialog for dispose soon.
*/
-public final class DisposeDialog extends Dialog {
-
- public DisposeDialog(Context context) {
- super(context);
- }
-
- @Override
- public void show() {
- dismiss();
+class DisposeDialog(context: Context) : Dialog(context) {
+ override fun show() {
+ dismiss()
}
}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.java
deleted file mode 100644
index 8ce25145..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.EditText;
-import net.lacolaco.smileessence.R;
-
-public abstract class EditTextDialogFragment extends DialogFragment {
-
- // ------------------------------ FIELDS ------------------------------
-
- private static final String titleKey = "title";
- private static final String textKey = "text";
- private String title;
- private String text;
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Bundle args = getArguments();
- text = args.getString(textKey);
- title = args.getString(titleKey);
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- View view = getActivity().getLayoutInflater().inflate(R.layout.part_edittext, null);
- final EditText editText = (EditText) view.findViewById(R.id.part_edittext);
- editText.setText(text);
- return new AlertDialog.Builder(getActivity())
- .setTitle(title)
- .setView(view)
- .setPositiveButton(R.string.alert_dialog_ok, (dialog, which) -> {
- onTextInput(editText.getText().toString());
- dialog.dismiss();
- })
- .setNegativeButton(R.string.alert_dialog_cancel, (dialog, which) -> dialog.dismiss())
- .create();
- }
-
- // -------------------------- OTHER METHODS --------------------------
-
- public abstract void onTextInput(String text);
-
- public void setParams(String title, String text) {
- Bundle args = new Bundle();
- args.putString(titleKey, title);
- args.putString(textKey, text);
- setArguments(args);
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt
new file mode 100644
index 00000000..399b84ad
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt
@@ -0,0 +1,81 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.app.DialogFragment
+import android.os.Bundle
+import android.view.View
+import android.widget.EditText
+import net.lacolaco.smileessence.R
+
+abstract class EditTextDialogFragment : DialogFragment() {
+ private lateinit var title: String
+ private lateinit var text: String
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val args = arguments
+ text = args.getString(textKey)
+ title = args.getString(titleKey)
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val view = activity.layoutInflater.inflate(R.layout.part_edittext, null)
+ val editText = view.findViewById(R.id.part_edittext) as EditText
+ editText.setText(text)
+ return AlertDialog.Builder(activity)
+ .setTitle(title)
+ .setView(view)
+ .setPositiveButton(R.string.alert_dialog_ok) { dialog, which ->
+ onTextInput(editText.text.toString())
+ dialog.dismiss()
+ }
+ .setNegativeButton(R.string.alert_dialog_cancel) { dialog, which -> dialog.dismiss() }
+ .create()
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ abstract fun onTextInput(text: String)
+
+ fun setParams(title: String, text: String) {
+ val args = Bundle()
+ args.putString(titleKey, title)
+ args.putString(textKey, text)
+ arguments = args
+ }
+
+ companion object {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private val titleKey = "title"
+ private val textKey = "text"
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.java
deleted file mode 100644
index f8a1e2e5..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2015 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-import android.widget.ListView;
-import android.widget.TextView;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.command.Command;
-import net.lacolaco.smileessence.command.CommandAddHashtag;
-import net.lacolaco.smileessence.command.CommandOpenURL;
-import net.lacolaco.smileessence.command.CommandOpenUserDetail;
-import net.lacolaco.smileessence.entity.DirectMessage;
-import net.lacolaco.smileessence.preference.UserPreferenceHelper;
-import net.lacolaco.smileessence.twitter.task.Messages;
-import net.lacolaco.smileessence.util.SystemServiceHelper;
-import net.lacolaco.smileessence.view.DialogHelper;
-import net.lacolaco.smileessence.view.Partials;
-import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
-import net.lacolaco.smileessence.view.adapter.MessageListAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class MessageDetailDialogFragment extends StackableDialogFragment implements View.OnClickListener {
- private static final String KEY_MESSAGE_ID = "message_id";
- private DirectMessage message;
-
- public static MessageDetailDialogFragment newInstance(DirectMessage message) {
- MessageDetailDialogFragment obj = new MessageDetailDialogFragment();
- Bundle args = new Bundle();
- args.putLong(KEY_MESSAGE_ID, message.getId());
- obj.setArguments(args);
- return obj;
- }
-
- @Override
- public void onClick(final View v) {
- switch (v.getId()) {
- case R.id.button_status_detail_reply: {
- openSendMessageDialog();
- break;
- }
- case R.id.button_status_detail_delete: {
- deleteMessage();
- break;
- }
- case R.id.button_status_detail_menu: {
- openMenu();
- break;
- }
- default: {
- dismiss();
- }
- }
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- message = DirectMessage.fetch(getArguments().getLong(KEY_MESSAGE_ID));
- if (message == null) {
- getWorld().notifyError(R.string.notice_error_get_messages);
- return new DisposeDialog(getActivity());
- }
-
- View header = getTitleView();
- ListView listView = (ListView) header.findViewById(R.id.listview_status_detail_reply_to);
- final MessageListAdapter adapter = new MessageListAdapter(getActivity());
- listView.setAdapter(adapter);
-
- // TODO: 効率的な探索どうする
- DirectMessage replyTo = null;
- // FIXME
- // for (DirectMessage mes : DirectMessage.cached()) {
- // if (message.getId() > mes.getId() &&
- // message.getRecipient() == mes.getSender() &&
- // message.getSender() == mes.getRecipient() &&
- // (replyTo == null || replyTo.getId() < mes.getId())) {
- // replyTo = mes;
- // }
- // }
- if (replyTo != null) {
- listView.setVisibility(View.VISIBLE);
- adapter.add(replyTo);
- adapter.updateForce();
- } else {
- listView.setVisibility(View.GONE);
- }
-
- return new AlertDialog.Builder(getActivity()).setView(header).create();
- }
-
- // -------------------------- OTHER METHODS --------------------------
-
- private void deleteMessage() {
- ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), () -> {
- new Messages.DestroyTask(getWorld().getAccount(), message.getId())
- .onDone(x -> getWorld().notify(R.string.notice_message_delete_succeeded))
- .onFail(x -> getWorld().notifyError(R.string.notice_message_delete_failed))
- .execute();
- dismiss();
- });
- }
-
- private void openSendMessageDialog() {
- DialogHelper.showDialog(getActivity(), SendMessageDialogFragment.newInstance(message.getSender()));
- }
-
- private View getTitleView() {
- MainActivity activity = (MainActivity) getActivity();
-
- View view = activity.getLayoutInflater().inflate(R.layout.dialog_status_detail, null);
-
- View messageHeader = Partials.getDirectMessageView(message, activity, view.findViewById(R.id.layout_status_header));
- messageHeader.setClickable(false);
-
- view.setBackgroundColor(((ColorDrawable) messageHeader.getBackground()).getColor());
- updateViewButtons(view);
- updateViewMenu(view);
-
- // status only parts
- view.findViewById(R.id.detail_dialog_divider_top).setVisibility(View.GONE);
- view.findViewById(R.id.button_status_detail_retweet).setVisibility(View.GONE);
- view.findViewById(R.id.button_status_detail_favorite).setVisibility(View.GONE);
- view.findViewById(R.id.image_status_detail_fav_count).setVisibility(View.GONE);
- view.findViewById(R.id.image_status_detail_rt_count).setVisibility(View.GONE);
-
- return view;
- }
-
- private void updateViewButtons(View view) {
- //--- buttons
- ImageButton reply = (ImageButton) view.findViewById(R.id.button_status_detail_reply);
- reply.setOnClickListener(this);
-
- ImageButton delete = (ImageButton) view.findViewById(R.id.button_status_detail_delete);
- delete.setOnClickListener(this);
- delete.setVisibility(View.VISIBLE);
- }
-
- private void updateViewMenu(View view) {
- // -- menu dialog
- ImageButton menu = (ImageButton) view.findViewById(R.id.button_status_detail_menu);
- menu.setOnClickListener(this);
-
- // -- menu embedded in dialog
- View divider = view.findViewById(R.id.detail_dialog_divider_bottom);
- ListView listView = (ListView) view.findViewById(R.id.listview_status_detail_menu);
- List<Command> commands = getCommands();
- if (commands.size() > 0) {
- divider.setVisibility(View.VISIBLE);
- listView.setVisibility(View.VISIBLE);
- final CustomListAdapter<Command> adapter = new CustomListAdapter<Command>() {
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = getActivity().getLayoutInflater().inflate(R.layout.menu_item_simple_text, null);
- }
- TextView textView = (TextView) convertView.findViewById(R.id.list_item_textview);
- textView.setTextSize(UserPreferenceHelper.getInstance().getTextSize());
- textView.setText(getItem(position).getText());
- return convertView;
- }
-
- @Override
- protected List<Command> getList() {
- return commands;
- }
- };
- adapter.update();
- listView.setAdapter(adapter);
- listView.setOnItemClickListener((parent, view1, position, id) -> {
- Command command = (Command) parent.getItemAtPosition(position);
- command.execute();
- });
- } else {
- divider.setVisibility(View.GONE);
- listView.setVisibility(View.GONE);
- }
- }
-
- private List<Command> getCommands() {
- MainActivity activity = (MainActivity) getActivity();
- List<Command> commands = new ArrayList<>();
- // Mentions
- if (message.getSender() != message.getRecipient()) {
- commands.add(new CommandOpenUserDetail(activity, message.getRecipient().getScreenName()));
- }
- for (String screenName : message.getMentions()) {
- commands.add(new CommandOpenUserDetail(activity, screenName));
- }
- for (String hashtag : message.getHashtags()) {
- commands.add(new CommandAddHashtag(activity, hashtag));
- }
- // URL
- for (String url : message.getUrlsExpanded()) {
- commands.add(new CommandOpenURL(activity, url));
- }
- for (String url : message.getMediaUrls()) {
- commands.add(new CommandOpenURL(activity, url));
- }
- return commands;
- }
-
- private void openMenu() {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle("@" + message.getSender().getScreenName() + ": " + message.getText())
- .setItems(R.array.message_commands, (dialog, which) -> {
- switch (which) {
- case 0:
- SystemServiceHelper.copyToClipboard(getActivity(), "message text", message.getText());
- getWorld().notify(R.string.notice_copy_clipboard);
- break;
- default:
- throw new IllegalStateException();
- }
- });
- AlertDialog dialog = builder.create();
- dialog.show();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt
new file mode 100644
index 00000000..36f7584f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt
@@ -0,0 +1,246 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2015 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.graphics.drawable.ColorDrawable
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.ListView
+import android.widget.TextView
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.command.Command
+import net.lacolaco.smileessence.command.CommandAddHashtag
+import net.lacolaco.smileessence.command.CommandOpenURL
+import net.lacolaco.smileessence.command.CommandOpenUserDetail
+import net.lacolaco.smileessence.entity.DirectMessage
+import net.lacolaco.smileessence.preference.UserPreferenceHelper
+import net.lacolaco.smileessence.twitter.task.Messages
+import net.lacolaco.smileessence.util.SystemServiceHelper
+import net.lacolaco.smileessence.view.DialogHelper
+import net.lacolaco.smileessence.view.Partials
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter
+import net.lacolaco.smileessence.view.adapter.MessageListAdapter
+
+import java.util.ArrayList
+
+class MessageDetailDialogFragment : StackableDialogFragment(), View.OnClickListener {
+ private lateinit var message: DirectMessage
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.button_status_detail_reply -> {
+ openSendMessageDialog()
+ }
+ R.id.button_status_detail_delete -> {
+ deleteMessage()
+ }
+ R.id.button_status_detail_menu -> {
+ openMenu()
+ }
+ else -> {
+ dismiss()
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val found = DirectMessage.fetch(arguments.getLong(KEY_MESSAGE_ID))
+ if (found == null) {
+ world.notifyError(R.string.notice_error_get_messages)
+ return DisposeDialog(activity)
+ }
+ message = found
+
+ val header = titleView
+ val listView = header.findViewById(R.id.listview_status_detail_reply_to) as ListView
+ val adapter = MessageListAdapter(activity)
+ listView.adapter = adapter
+
+ // TODO: 効率的な探索どうする
+ val replyTo: DirectMessage? = null
+ // FIXME
+ // for (DirectMessage mes : DirectMessage.cached()) {
+ // if (message.getId() > mes.getId() &&
+ // message.getRecipient() == mes.getSender() &&
+ // message.getSender() == mes.getRecipient() &&
+ // (replyTo == null || replyTo.getId() < mes.getId())) {
+ // replyTo = mes;
+ // }
+ // }
+ if (replyTo != null) {
+ listView.visibility = View.VISIBLE
+ adapter.add(replyTo)
+ adapter.updateForce()
+ } else {
+ listView.visibility = View.GONE
+ }
+
+ return AlertDialog.Builder(activity).setView(header).create()
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ private fun deleteMessage() {
+ ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) {
+ Messages.DestroyTask(world.account, message.id)
+ .onDone { x -> world.notify(R.string.notice_message_delete_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_message_delete_failed) }
+ .execute()
+ dismiss()
+ }
+ }
+
+ private fun openSendMessageDialog() {
+ DialogHelper.showDialog(activity, SendMessageDialogFragment.newInstance(message.sender))
+ }
+
+ private // status only parts
+ val titleView: View
+ get() {
+ val activity = activity as MainActivity
+
+ val view = activity.layoutInflater.inflate(R.layout.dialog_status_detail, null)
+
+ val messageHeader = Partials.getDirectMessageView(message, activity, view.findViewById(R.id.layout_status_header))
+ messageHeader.isClickable = false
+
+ view.setBackgroundColor((messageHeader.background as ColorDrawable).color)
+ updateViewButtons(view)
+ updateViewMenu(view)
+ view.findViewById(R.id.detail_dialog_divider_top).visibility = View.GONE
+ view.findViewById(R.id.button_status_detail_retweet).visibility = View.GONE
+ view.findViewById(R.id.button_status_detail_favorite).visibility = View.GONE
+ view.findViewById(R.id.image_status_detail_fav_count).visibility = View.GONE
+ view.findViewById(R.id.image_status_detail_rt_count).visibility = View.GONE
+
+ return view
+ }
+
+ private fun updateViewButtons(view: View) {
+ //--- buttons
+ val reply = view.findViewById(R.id.button_status_detail_reply) as ImageButton
+ reply.setOnClickListener(this)
+
+ val delete = view.findViewById(R.id.button_status_detail_delete) as ImageButton
+ delete.setOnClickListener(this)
+ delete.visibility = View.VISIBLE
+ }
+
+ private fun updateViewMenu(view: View) {
+ // -- menu dialog
+ val menu = view.findViewById(R.id.button_status_detail_menu) as ImageButton
+ menu.setOnClickListener(this)
+
+ // -- menu embedded in dialog
+ val divider = view.findViewById(R.id.detail_dialog_divider_bottom)
+ val listView = view.findViewById(R.id.listview_status_detail_menu) as ListView
+ val commands = commands
+ if (commands.size > 0) {
+ divider.visibility = View.VISIBLE
+ listView.visibility = View.VISIBLE
+ val adapter = object : CustomListAdapter<Command>() {
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ var convertView = convertView
+ if (convertView == null) {
+ convertView = activity.layoutInflater.inflate(R.layout.menu_item_simple_text, null)
+ }
+ val textView = convertView!!.findViewById(R.id.list_item_textview) as TextView
+ textView.textSize = UserPreferenceHelper.instance.textSize.toFloat()
+ textView.text = getItem(position).text
+ return convertView
+ }
+
+ override val list: List<Command>
+ get() = commands
+ }
+ adapter.update()
+ listView.adapter = adapter
+ listView.setOnItemClickListener { parent, view1, position, id ->
+ val command = parent.getItemAtPosition(position) as Command
+ command.execute()
+ }
+ } else {
+ divider.visibility = View.GONE
+ listView.visibility = View.GONE
+ }
+ }
+
+ private // Mentions
+ // URL
+ val commands: List<Command>
+ get() {
+ val activity = activity as MainActivity
+ val commands = ArrayList<Command>()
+ if (message.sender !== message.recipient) {
+ commands.add(CommandOpenUserDetail(activity, message.recipient.screenName))
+ }
+ for (screenName in message.mentions) {
+ commands.add(CommandOpenUserDetail(activity, screenName))
+ }
+ for (hashtag in message.hashtags) {
+ commands.add(CommandAddHashtag(activity, hashtag))
+ }
+ for (url in message.urlsExpanded) {
+ commands.add(CommandOpenURL(activity, url))
+ }
+ for (url in message.mediaUrls) {
+ commands.add(CommandOpenURL(activity, url))
+ }
+ return commands
+ }
+
+ private fun openMenu() {
+ val builder = AlertDialog.Builder(activity)
+ builder.setTitle("@" + message.sender.screenName + ": " + message.text)
+ .setItems(R.array.message_commands) { dialog, which ->
+ when (which) {
+ 0 -> {
+ SystemServiceHelper.copyToClipboard(activity, "message text", message.text)
+ world.notify(R.string.notice_copy_clipboard)
+ }
+ else -> throw IllegalStateException()
+ }
+ }
+ val dialog = builder.create()
+ dialog.show()
+ }
+
+ companion object {
+ private val KEY_MESSAGE_ID = "message_id"
+
+ fun newInstance(message: DirectMessage): MessageDetailDialogFragment {
+ val obj = MessageDetailDialogFragment()
+ val args = Bundle()
+ args.putLong(KEY_MESSAGE_ID, message.id)
+ obj.arguments = args
+ return obj
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.java
deleted file mode 100644
index 20917d8f..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.os.Bundle;
-import android.support.v4.content.ContextCompat;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.TextView;
-import com.twitter.Validator;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.entity.User;
-import net.lacolaco.smileessence.twitter.task.Messages;
-import net.lacolaco.smileessence.util.SystemServiceHelper;
-
-public class SendMessageDialogFragment extends StackableDialogFragment implements TextWatcher, View.OnClickListener {
- private static final String KEY_RECIPIENT_ID = "KEY_RECIPIENT_ID";
- private User recipient;
- private EditText editText;
- private TextView textViewCount;
- private Button buttonSend;
-
- public static SendMessageDialogFragment newInstance(User recipient) {
- SendMessageDialogFragment obj = new SendMessageDialogFragment();
- Bundle args = new Bundle();
- args.putLong(KEY_RECIPIENT_ID, recipient.getId());
- obj.setArguments(args);
- return obj;
- }
- @Override
- public void onClick(View v) {
- int id = v.getId();
- switch (id) {
- case R.id.button_send_message: {
- sendMessage();
- break;
- }
- case R.id.button_send_message_delete: {
- deleteMessage();
- }
- }
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- Validator validator = new Validator();
- int remainingCount = 140 - validator.getTweetLength(s.toString());
- textViewCount.setText(String.valueOf(remainingCount));
- if (remainingCount == 140 || remainingCount < 0) {
- textViewCount.setTextColor(ContextCompat.getColor(getActivity(), R.color.red));
- } else {
- textViewCount.setTextAppearance(getActivity(), android.R.style.TextAppearance_Widget_TextView);
- }
- }
-
- @Override
- public void afterTextChanged(Editable s) {
-
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- recipient = User.fetch(getArguments().getLong(KEY_RECIPIENT_ID));
- View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_send_message, null);
- TextView textViewName = (TextView) view.findViewById(R.id.textview_send_message_name);
- textViewName.setText("To: @" + recipient.getScreenName());
- textViewCount = (TextView) view.findViewById(R.id.textview_send_message_count);
- editText = (EditText) view.findViewById(R.id.edittext_send_message);
- editText.addTextChangedListener(this);
- buttonSend = (Button) view.findViewById(R.id.button_send_message);
- buttonSend.setOnClickListener(this);
- ImageButton buttonDelete = (ImageButton) view.findViewById(R.id.button_send_message_delete);
- buttonDelete.setOnClickListener(this);
- editText.setText("");
- return new AlertDialog.Builder(getActivity())
- .setView(view)
- .create();
- }
-
- private void deleteMessage() {
- editText.setText("");
- }
-
- private void sendMessage() {
- SystemServiceHelper.hideIM(getActivity(), editText);
- String text = editText.getText().toString();
- new Messages.CreateTask(getWorld().getAccount(), recipient.getId(), text)
- .onDoneUI(m -> {
- getWorld().addDirectMessage(m);
- getWorld().notify(R.string.notice_message_send_succeeded);
- dismiss();
- })
- .onFail(e -> getWorld().notifyError(R.string.notice_message_send_failed, e))
- .execute();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt
new file mode 100644
index 00000000..fb7e9d2f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt
@@ -0,0 +1,127 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.os.Bundle
+import android.support.v4.content.ContextCompat
+import android.text.Editable
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.view.View
+import android.widget.Button
+import android.widget.EditText
+import android.widget.ImageButton
+import android.widget.TextView
+import com.twitter.Validator
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.entity.User
+import net.lacolaco.smileessence.twitter.task.Messages
+import net.lacolaco.smileessence.util.SystemServiceHelper
+
+class SendMessageDialogFragment : StackableDialogFragment(), TextWatcher, View.OnClickListener {
+ private var recipient: User? = null
+ private var editText: EditText? = null
+ private var textViewCount: TextView? = null
+ private var buttonSend: Button? = null
+ override fun onClick(v: View) {
+ val id = v.id
+ when (id) {
+ R.id.button_send_message -> {
+ sendMessage()
+ }
+ R.id.button_send_message_delete -> {
+ deleteMessage()
+ }
+ }
+ }
+
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+
+ }
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+ val validator = Validator()
+ val remainingCount = 140 - validator.getTweetLength(s.toString())
+ textViewCount!!.text = remainingCount.toString()
+ if (remainingCount == 140 || remainingCount < 0) {
+ textViewCount!!.setTextColor(ContextCompat.getColor(activity, R.color.red))
+ } else {
+ textViewCount!!.setTextAppearance(activity, android.R.style.TextAppearance_Widget_TextView)
+ }
+ }
+
+ override fun afterTextChanged(s: Editable) {
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ recipient = User.fetch(arguments.getLong(KEY_RECIPIENT_ID))
+ val view = activity.layoutInflater.inflate(R.layout.dialog_send_message, null)
+ val textViewName = view.findViewById(R.id.textview_send_message_name) as TextView
+ textViewName.text = "To: @" + recipient!!.screenName
+ textViewCount = view.findViewById(R.id.textview_send_message_count) as TextView
+ editText = view.findViewById(R.id.edittext_send_message) as EditText
+ editText!!.addTextChangedListener(this)
+ buttonSend = view.findViewById(R.id.button_send_message) as Button
+ buttonSend!!.setOnClickListener(this)
+ val buttonDelete = view.findViewById(R.id.button_send_message_delete) as ImageButton
+ buttonDelete.setOnClickListener(this)
+ editText!!.setText("")
+ return AlertDialog.Builder(activity)
+ .setView(view)
+ .create()
+ }
+
+ private fun deleteMessage() {
+ editText!!.setText("")
+ }
+
+ private fun sendMessage() {
+ SystemServiceHelper.hideIM(activity, editText)
+ val text = editText!!.text.toString()
+ Messages.CreateTask(world.account, recipient!!.id, text)
+ .onDoneUI { m ->
+ world.addDirectMessage(m)
+ world.notify(R.string.notice_message_send_succeeded)
+ dismiss()
+ }
+ .onFail { e -> world.notifyError(R.string.notice_message_send_failed, e) }
+ .execute()
+ }
+
+ companion object {
+ private val KEY_RECIPIENT_ID = "KEY_RECIPIENT_ID"
+
+ fun newInstance(recipient: User): SendMessageDialogFragment {
+ val obj = SendMessageDialogFragment()
+ val args = Bundle()
+ args.putLong(KEY_RECIPIENT_ID, recipient.id)
+ obj.arguments = args
+ return obj
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.java
deleted file mode 100644
index 848c6465..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.DialogFragment;
-import net.lacolaco.smileessence.World;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.view.DialogHelper;
-
-/**
- * Only used by MainActivity.
- */
-public class StackableDialogFragment extends DialogFragment {
- @Override
- public void dismiss() {
- super.dismiss();
- DialogHelper.unregisterDialog(getTag());
- }
-
- @Override
- public void dismissAllowingStateLoss() {
- super.dismissAllowingStateLoss();
- DialogHelper.unregisterDialog(getTag());
- }
-
- protected World getWorld() {
- final MainActivity activity = (MainActivity) getActivity();
- return activity.getWorld();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.kt
new file mode 100644
index 00000000..7822cfe3
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.kt
@@ -0,0 +1,25 @@
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.DialogFragment
+import net.lacolaco.smileessence.World
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.view.DialogHelper
+
+/**
+ * Only used by MainActivity.
+ */
+open class StackableDialogFragment : DialogFragment() {
+ override fun dismiss() {
+ super.dismiss()
+ DialogHelper.unregisterDialog(tag)
+ }
+
+ override fun dismissAllowingStateLoss() {
+ super.dismissAllowingStateLoss()
+ DialogHelper.unregisterDialog(tag)
+ }
+
+ protected val world: World by lazy {
+ (activity as MainActivity).world
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.java
deleted file mode 100644
index 5b2ee58c..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.command.Command;
-import net.lacolaco.smileessence.command.CommandAddHashtag;
-import net.lacolaco.smileessence.command.CommandOpenURL;
-import net.lacolaco.smileessence.command.CommandOpenUserDetail;
-import net.lacolaco.smileessence.data.Account;
-import net.lacolaco.smileessence.entity.RBinding;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.preference.UserPreferenceHelper;
-import net.lacolaco.smileessence.twitter.task.TweetReactions;
-import net.lacolaco.smileessence.twitter.task.Tweets;
-import net.lacolaco.smileessence.util.IntentUtils;
-import net.lacolaco.smileessence.util.SystemServiceHelper;
-import net.lacolaco.smileessence.util.UIObserverBundle;
-import net.lacolaco.smileessence.view.DialogHelper;
-import net.lacolaco.smileessence.view.Partials;
-import net.lacolaco.smileessence.view.ToggleableImageButton;
-import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
-import net.lacolaco.smileessence.view.adapter.TimelineAdapter;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-
-public class StatusDetailDialogFragment extends StackableDialogFragment implements View.OnClickListener {
- private static final String KEY_STATUS_ID = "status_id";
- private Tweet tweet;
-
- public static StatusDetailDialogFragment newInstance(Tweet tweet) {
- StatusDetailDialogFragment obj = new StatusDetailDialogFragment();
- Bundle args = new Bundle();
- args.putLong(KEY_STATUS_ID, tweet.getId());
- obj.setArguments(args);
- return obj;
- }
-
- @Override
- public void onClick(final View v) {
- switch (v.getId()) {
- case R.id.button_status_detail_reply: {
- Tweet originalTweet = tweet.getOriginalTweet();
-
- StringBuilder builder = new StringBuilder();
- builder.append("@" + originalTweet.getUser().getScreenName() + " ");
-
- for (String screenName : originalTweet.getMentions()) {
- if (!screenName.equals(getWorld().getAccount().getUser().getScreenName()))
- builder.append("@" + screenName + " ");
- }
- String text = builder.toString();
- int selStart = originalTweet.getUser().getScreenName().length() + 2; // "@" and " "
-
- getWorld().getPostState().beginTransaction()
- .clear()
- .insertText(0, text)
- .setInReplyTo(originalTweet)
- .setSelection(selStart, text.length())
- .commitWithOpen((MainActivity) getActivity());
- break;
- }
- case R.id.button_status_detail_retweet: {
- Account account = getWorld().getAccount();
- confirm(() -> {
- if (tweet.isRetweetedBy(account.getUserId())) {
- new Tweets.DestroyTask(account, tweet.getRetweetIdBy(account.getUserId()))
- .onDone(t -> getWorld().notify(R.string.notice_status_delete_succeeded))
- .onFail(e -> getWorld().notifyError(R.string.notice_status_delete_failed))
- .execute();
- dismiss();
- } else {
- new TweetReactions.RetweetTask(account, tweet.getId())
- .onDone(x -> getWorld().notify(R.string.notice_retweet_succeeded))
- .onFail(x -> getWorld().notifyError(R.string.notice_retweet_failed))
- .execute();
- }
- });
- break;
- }
- case R.id.button_status_detail_favorite: {
- Account account = getWorld().getAccount();
- if (tweet.isFavoritedBy(account.getUserId())) {
- new TweetReactions.UnfavoriteTask(account, tweet.getId())
- .onDone(x -> getWorld().notify(R.string.notice_unfavorite_succeeded))
- .onFail(x -> getWorld().notifyError(R.string.notice_unfavorite_failed))
- .execute();
- } else {
- new TweetReactions.FavoriteTask(account, tweet.getId())
- .onDone(x -> getWorld().notify(R.string.notice_favorite_succeeded))
- .onFail(x -> getWorld().notifyError(R.string.notice_favorite_failed))
- .execute();
- }
- break;
- }
- case R.id.button_status_detail_delete: {
- confirm(() -> {
- new Tweets.DestroyTask(getWorld().getAccount(), tweet.getOriginalTweet().getId())
- .onDone(t -> getWorld().notify(R.string.notice_status_delete_succeeded))
- .onFail(e -> getWorld().notifyError(R.string.notice_status_delete_failed))
- .execute();
- dismiss();
- });
- break;
- }
- case R.id.button_status_detail_menu: {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle("@" + tweet.getUser().getScreenName() + ": " + tweet.getText())
- .setItems(R.array.status_commands, (dialog, which) -> {
- switch (which) {
- case 0:
- String text = String.format("@%s ", tweet.getOriginalTweet().getUser().getScreenName());
- getWorld().getPostState().beginTransaction().insertText(0, text).moveCursor(text.length()).commit();
- getWorld().notify(R.string.notice_add_to_reply);
- break;
- case 1:
- TalkChainDialogFragment dialogFragment = new TalkChainDialogFragment();
- dialogFragment.setStatusID(tweet.getOriginalTweet().getId());
- DialogHelper.showDialog(getActivity(), dialogFragment);
- break;
- case 2:
- IntentUtils.openUri(getActivity(), tweet.getOriginalTweet().getTwitterUrl());
- break;
- case 3:
- SystemServiceHelper.copyToClipboard(getActivity(), "tweet text", tweet.getOriginalTweet().getText());
- getWorld().notify(R.string.notice_copy_clipboard);
- break;
- case 4:
- String statusURL = tweet.getOriginalTweet().getTwitterUrl();
- SystemServiceHelper.copyToClipboard(getActivity(), "tweet url", statusURL);
- getWorld().notify(R.string.notice_copy_clipboard);
- break;
- default:
- throw new IllegalStateException();
- }
- });
- AlertDialog dialog = builder.create();
- dialog.show();
- break;
- }
- default: {
- dismiss();
- }
- }
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- tweet = Tweet.fetch(getArguments().getLong(KEY_STATUS_ID));
- if (tweet == null) { // trying to open deleted tweet?
- getWorld().notifyError(R.string.notice_error_show_status);
- return new DisposeDialog(getActivity());
- }
-
- View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_status_detail, null);
- UIObserverBundle bundle = new UIObserverBundle();
- view.setTag(bundle);
-
- View statusHeader = Partials.getTweetView(tweet, getActivity(), view.findViewById(R.id.layout_status_header), true);
- statusHeader.setClickable(false);
-
- view.setBackgroundColor(((ColorDrawable) statusHeader.getBackground()).getColor());
- updateViewReactions(view);
- updateViewButtons(view);
- setupViewMenu(view);
-
- final WeakReference<View> weakView = new WeakReference<>(view);
- bundle.attach(tweet.getOriginalTweet(), changes -> {
- View strongView = weakView.get();
- if (strongView != null && getActivity() != null) {
- if (changes.contains(RBinding.REACTION_COUNT))
- updateViewReactions(strongView);
- if (changes.contains(RBinding.FAVORITERS) || changes.contains(RBinding.RETWEETERS))
- updateViewButtons(strongView);
- }
- });
-
- ListView listView = (ListView) view.findViewById(R.id.listview_status_detail_reply_to);
- final TimelineAdapter adapter = new TimelineAdapter(getActivity());
- listView.setAdapter(adapter);
-
- View replyDivider = view.findViewById(R.id.detail_dialog_divider_top);
-
- if (tweet.getInReplyToStatusId() != -1) {
- replyDivider.setVisibility(View.VISIBLE);
- listView.setVisibility(View.VISIBLE);
- Tweet.fetchTask(tweet.getInReplyToStatusId(), getWorld().getAccount())
- .onDoneUI(replyTo -> {
- adapter.add(replyTo);
- adapter.update();
- })
- .execute();
- } else {
- replyDivider.setVisibility(View.GONE);
- listView.setVisibility(View.GONE);
- }
-
- return new AlertDialog.Builder(getActivity()).setView(view).create();
- }
-
- private void updateViewReactions(View view) {
- ImageView favCountIcon = (ImageView) view.findViewById(R.id.image_status_detail_fav_count);
- TextView favCountText = (TextView) view.findViewById(R.id.textview_status_detail_fav_count);
- if (tweet.getFavoriteCount() > 0) {
- favCountText.setText(Integer.toString(tweet.getFavoriteCount()));
- favCountIcon.setVisibility(View.VISIBLE);
- favCountText.setVisibility(View.VISIBLE);
- } else {
- favCountIcon.setVisibility(View.GONE);
- favCountText.setVisibility(View.GONE);
- }
-
- ImageView rtCountIcon = (ImageView) view.findViewById(R.id.image_status_detail_rt_count);
- TextView rtCountText = (TextView) view.findViewById(R.id.textview_status_detail_rt_count);
- if (tweet.getRetweetCount() > 0) {
- rtCountText.setText(Integer.toString(tweet.getRetweetCount()));
- rtCountIcon.setVisibility(View.VISIBLE);
- rtCountText.setVisibility(View.VISIBLE);
- } else {
- rtCountIcon.setVisibility(View.GONE);
- rtCountText.setVisibility(View.GONE);
- }
- }
-
- private void updateViewButtons(View view) {
- Account account = getWorld().getAccount();
-
- //--- buttons
- ImageButton reply = (ImageButton) view.findViewById(R.id.button_status_detail_reply);
- reply.setOnClickListener(this);
-
- ToggleableImageButton retweet = (ToggleableImageButton) view.findViewById(R.id.button_status_detail_retweet);
- retweet.setOnClickListener(this);
- retweet.setState(tweet.isRetweetedBy(account.getUserId()));
-
- ToggleableImageButton favorite = (ToggleableImageButton) view.findViewById(R.id.button_status_detail_favorite);
- favorite.setOnClickListener(this);
- favorite.setState(tweet.isFavoritedBy(account.getUserId()));
-
- ImageButton delete = (ImageButton) view.findViewById(R.id.button_status_detail_delete);
- delete.setOnClickListener(this);
- delete.setVisibility(tweet.getOriginalTweet().getUser() == account.getUser() ? View.VISIBLE : View.GONE);
-
- ImageButton menu = (ImageButton) view.findViewById(R.id.button_status_detail_menu);
- menu.setOnClickListener(this);
- }
-
- private void setupViewMenu(View view) {
- View divider = view.findViewById(R.id.detail_dialog_divider_bottom);
- ListView listView = (ListView) view.findViewById(R.id.listview_status_detail_menu);
- List<Command> commands = getCommands();
- if (commands.size() > 0) {
- divider.setVisibility(View.VISIBLE);
- listView.setVisibility(View.VISIBLE);
- final CustomListAdapter<Command> adapter = new CustomListAdapter<Command>() {
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = getActivity().getLayoutInflater().inflate(R.layout.menu_item_simple_text, null);
- }
- TextView textView = (TextView) convertView.findViewById(R.id.list_item_textview);
- textView.setTextSize(UserPreferenceHelper.getInstance().getTextSize());
- textView.setText(getItem(position).getText());
- return convertView;
- }
-
- @Override
- protected List<Command> getList() {
- return commands;
- }
- };
- adapter.update();
- listView.setAdapter(adapter);
- listView.setOnItemClickListener((parent, view1, position, id) -> {
- Command command = (Command) parent.getItemAtPosition(position);
- command.execute();
- });
- } else {
- divider.setVisibility(View.GONE);
- listView.setVisibility(View.GONE);
- }
- }
-
- private void confirm(Runnable onYes) {
- ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), onYes);
- }
-
- private List<Command> getCommands() {
- MainActivity activity = (MainActivity) getActivity();
- ArrayList<Command> commands = new ArrayList<>();
- // Retweeter
- if (tweet.getRetweetedTweet() != null && tweet.getUser() != tweet.getRetweetedTweet().getUser())
- commands.add(new CommandOpenUserDetail(activity, tweet.getUser().getScreenName()));
- // Mentions
- for (String screenName : new ArrayList<>(new LinkedHashSet<>(tweet.getMentions()))) { // Array#uniq
- commands.add(new CommandOpenUserDetail(activity, screenName));
- }
- // Hashtags
- for (String hashtag : tweet.getHashtags()) {
- commands.add(new CommandAddHashtag(activity, hashtag));
- }
- // URL
- for (String url : tweet.getUrlsExpanded()) {
- commands.add(new CommandOpenURL(activity, url));
- }
- for (String url : tweet.getMediaUrls()) {
- commands.add(new CommandOpenURL(activity, url));
- }
- return commands;
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt
new file mode 100644
index 00000000..c18b6b4d
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt
@@ -0,0 +1,339 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.graphics.drawable.ColorDrawable
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.ListView
+import android.widget.TextView
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.command.Command
+import net.lacolaco.smileessence.command.CommandAddHashtag
+import net.lacolaco.smileessence.command.CommandOpenURL
+import net.lacolaco.smileessence.command.CommandOpenUserDetail
+import net.lacolaco.smileessence.data.Account
+import net.lacolaco.smileessence.entity.RBinding
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.preference.UserPreferenceHelper
+import net.lacolaco.smileessence.twitter.task.TweetReactions
+import net.lacolaco.smileessence.twitter.task.Tweets
+import net.lacolaco.smileessence.util.IntentUtils
+import net.lacolaco.smileessence.util.SystemServiceHelper
+import net.lacolaco.smileessence.util.UIObserverBundle
+import net.lacolaco.smileessence.view.DialogHelper
+import net.lacolaco.smileessence.view.Partials
+import net.lacolaco.smileessence.view.ToggleableImageButton
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter
+import net.lacolaco.smileessence.view.adapter.TimelineAdapter
+
+import java.lang.ref.WeakReference
+import java.util.ArrayList
+import java.util.LinkedHashSet
+
+class StatusDetailDialogFragment : StackableDialogFragment(), View.OnClickListener {
+ private lateinit var tweet: Tweet
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.button_status_detail_reply -> {
+ val originalTweet = tweet.originalTweet
+
+ val builder = StringBuilder()
+ builder.append("@" + originalTweet.user.screenName + " ")
+
+ for (screenName in originalTweet.mentions) {
+ if (screenName != world.account.user.screenName)
+ builder.append("@$screenName ")
+ }
+ val text = builder.toString()
+ val selStart = originalTweet.user.screenName.length + 2 // "@" and " "
+
+ world.postState.beginTransaction()
+ .clear()
+ .insertText(0, text)
+ .setInReplyTo(originalTweet)
+ .setSelection(selStart, text.length)
+ .commitWithOpen(activity as MainActivity)
+ }
+ R.id.button_status_detail_retweet -> {
+ val account = world.account
+ confirm({
+ if (tweet.isRetweetedBy(account.userId)) {
+ Tweets.DestroyTask(account, tweet.getRetweetIdBy(account.userId))
+ .onDone { t -> world.notify(R.string.notice_status_delete_succeeded) }
+ .onFail { e -> world.notifyError(R.string.notice_status_delete_failed) }
+ .execute()
+ dismiss()
+ } else {
+ TweetReactions.RetweetTask(account, tweet.id)
+ .onDone { x -> world.notify(R.string.notice_retweet_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_retweet_failed) }
+ .execute()
+ }
+ })
+ }
+ R.id.button_status_detail_favorite -> {
+ val account = world.account
+ if (tweet.isFavoritedBy(account.userId)) {
+ TweetReactions.UnfavoriteTask(account, tweet.id)
+ .onDone { x -> world.notify(R.string.notice_unfavorite_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_unfavorite_failed) }
+ .execute()
+ } else {
+ TweetReactions.FavoriteTask(account, tweet.id)
+ .onDone { x -> world.notify(R.string.notice_favorite_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_favorite_failed) }
+ .execute()
+ }
+ }
+ R.id.button_status_detail_delete -> {
+ confirm({
+ Tweets.DestroyTask(world.account, tweet.originalTweet.id)
+ .onDone { t -> world.notify(R.string.notice_status_delete_succeeded) }
+ .onFail { e -> world.notifyError(R.string.notice_status_delete_failed) }
+ .execute()
+ dismiss()
+ })
+ }
+ R.id.button_status_detail_menu -> {
+ val builder = AlertDialog.Builder(activity)
+ builder.setTitle("@" + tweet.user.screenName + ": " + tweet.text)
+ .setItems(R.array.status_commands) { dialog, which ->
+ when (which) {
+ 0 -> {
+ val text = String.format("@%s ", tweet.originalTweet.user.screenName)
+ world.postState.beginTransaction().insertText(0, text).moveCursor(text.length).commit()
+ world.notify(R.string.notice_add_to_reply)
+ }
+ 1 -> {
+ DialogHelper.showDialog(activity, TalkChainDialogFragment.newInstance(tweet))
+ }
+ 2 -> IntentUtils.openUri(activity, tweet.originalTweet.twitterUrl)
+ 3 -> {
+ SystemServiceHelper.copyToClipboard(activity, "tweet text", tweet.originalTweet.text)
+ world.notify(R.string.notice_copy_clipboard)
+ }
+ 4 -> {
+ val statusURL = tweet.originalTweet.twitterUrl
+ SystemServiceHelper.copyToClipboard(activity, "tweet url", statusURL)
+ world.notify(R.string.notice_copy_clipboard)
+ }
+ else -> throw IllegalStateException()
+ }
+ }
+ val dialog = builder.create()
+ dialog.show()
+ }
+ else -> {
+ dismiss()
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val found = Tweet.fetch(arguments.getLong(KEY_STATUS_ID))
+ if (found == null) { // trying to open deleted tweet?
+ world.notifyError(R.string.notice_error_show_status)
+ return DisposeDialog(activity)
+ }
+ tweet = found
+
+ val view = activity.layoutInflater.inflate(R.layout.dialog_status_detail, null)
+ val bundle = UIObserverBundle()
+ view.tag = bundle
+
+ val statusHeader = Partials.getTweetView(tweet, activity, view.findViewById(R.id.layout_status_header), true)
+ statusHeader.isClickable = false
+
+ view.setBackgroundColor((statusHeader.background as ColorDrawable).color)
+ updateViewReactions(view)
+ updateViewButtons(view)
+ setupViewMenu(view)
+
+ val weakView = WeakReference(view)
+ bundle.attach(tweet.originalTweet) { changes ->
+ val strongView = weakView.get()
+ if (strongView != null && activity != null) {
+ if (changes.contains(RBinding.REACTION_COUNT))
+ updateViewReactions(strongView)
+ if (changes.contains(RBinding.FAVORITERS) || changes.contains(RBinding.RETWEETERS))
+ updateViewButtons(strongView)
+ }
+ }
+
+ val listView = view.findViewById(R.id.listview_status_detail_reply_to) as ListView
+ val adapter = TimelineAdapter(activity)
+ listView.adapter = adapter
+
+ val replyDivider = view.findViewById(R.id.detail_dialog_divider_top)
+
+ if (tweet.inReplyToStatusId != -1L) {
+ replyDivider.visibility = View.VISIBLE
+ listView.visibility = View.VISIBLE
+ Tweet.fetchTask(tweet.inReplyToStatusId, world.account)
+ .onDoneUI { replyTo ->
+ adapter.add(replyTo)
+ adapter.update()
+ }
+ .execute()
+ } else {
+ replyDivider.visibility = View.GONE
+ listView.visibility = View.GONE
+ }
+
+ return AlertDialog.Builder(activity).setView(view).create()
+ }
+
+ private fun updateViewReactions(view: View) {
+ val favCountIcon = view.findViewById(R.id.image_status_detail_fav_count) as ImageView
+ val favCountText = view.findViewById(R.id.textview_status_detail_fav_count) as TextView
+ if (tweet.favoriteCount > 0) {
+ favCountText.text = Integer.toString(tweet.favoriteCount)
+ favCountIcon.visibility = View.VISIBLE
+ favCountText.visibility = View.VISIBLE
+ } else {
+ favCountIcon.visibility = View.GONE
+ favCountText.visibility = View.GONE
+ }
+
+ val rtCountIcon = view.findViewById(R.id.image_status_detail_rt_count) as ImageView
+ val rtCountText = view.findViewById(R.id.textview_status_detail_rt_count) as TextView
+ if (tweet.retweetCount > 0) {
+ rtCountText.text = Integer.toString(tweet.retweetCount)
+ rtCountIcon.visibility = View.VISIBLE
+ rtCountText.visibility = View.VISIBLE
+ } else {
+ rtCountIcon.visibility = View.GONE
+ rtCountText.visibility = View.GONE
+ }
+ }
+
+ private fun updateViewButtons(view: View) {
+ val account = world.account
+
+ //--- buttons
+ val reply = view.findViewById(R.id.button_status_detail_reply) as ImageButton
+ reply.setOnClickListener(this)
+
+ val retweet = view.findViewById(R.id.button_status_detail_retweet) as ToggleableImageButton
+ retweet.setOnClickListener(this)
+ retweet.setState(tweet.isRetweetedBy(account.userId))
+
+ val favorite = view.findViewById(R.id.button_status_detail_favorite) as ToggleableImageButton
+ favorite.setOnClickListener(this)
+ favorite.setState(tweet.isFavoritedBy(account.userId))
+
+ val delete = view.findViewById(R.id.button_status_detail_delete) as ImageButton
+ delete.setOnClickListener(this)
+ delete.visibility = if (tweet.originalTweet.user === account.user) View.VISIBLE else View.GONE
+
+ val menu = view.findViewById(R.id.button_status_detail_menu) as ImageButton
+ menu.setOnClickListener(this)
+ }
+
+ private fun setupViewMenu(view: View) {
+ val divider = view.findViewById(R.id.detail_dialog_divider_bottom)
+ val listView = view.findViewById(R.id.listview_status_detail_menu) as ListView
+ val commands = commands
+ if (commands.size > 0) {
+ divider.visibility = View.VISIBLE
+ listView.visibility = View.VISIBLE
+ val adapter = object : CustomListAdapter<Command>() {
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ var convertView = convertView
+ if (convertView == null) {
+ convertView = activity.layoutInflater.inflate(R.layout.menu_item_simple_text, null)
+ }
+ val textView = convertView!!.findViewById(R.id.list_item_textview) as TextView
+ textView.textSize = UserPreferenceHelper.instance.textSize.toFloat()
+ textView.text = getItem(position).text
+ return convertView
+ }
+
+ override val list: List<Command>
+ get() = commands
+ }
+ adapter.update()
+ listView.adapter = adapter
+ listView.setOnItemClickListener { parent, view1, position, id ->
+ val command = parent.getItemAtPosition(position) as Command
+ command.execute()
+ }
+ } else {
+ divider.visibility = View.GONE
+ listView.visibility = View.GONE
+ }
+ }
+
+ private fun confirm(onYes: () -> Unit) {
+ ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands), onYes)
+ }
+
+ private // Retweeter
+ // Mentions
+ // Array#uniq
+ // Hashtags
+ // URL
+ val commands: List<Command>
+ get() {
+ val activity = activity as MainActivity
+ val commands = ArrayList<Command>()
+ if (tweet.retweetedTweet != null && tweet.user !== tweet.retweetedTweet!!.user)
+ commands.add(CommandOpenUserDetail(activity, tweet.user.screenName))
+ for (screenName in ArrayList(LinkedHashSet(tweet.mentions))) {
+ commands.add(CommandOpenUserDetail(activity, screenName))
+ }
+ for (hashtag in tweet.hashtags) {
+ commands.add(CommandAddHashtag(activity, hashtag))
+ }
+ for (url in tweet.urlsExpanded) {
+ commands.add(CommandOpenURL(activity, url))
+ }
+ for (url in tweet.mediaUrls) {
+ commands.add(CommandOpenURL(activity, url))
+ }
+ return commands
+ }
+
+ companion object {
+ private val KEY_STATUS_ID = "status_id"
+
+ fun newInstance(tweet: Tweet): StatusDetailDialogFragment {
+ val obj = StatusDetailDialogFragment()
+ val args = Bundle()
+ args.putLong(KEY_STATUS_ID, tweet.id)
+ obj.arguments = args
+ return obj
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.java
deleted file mode 100644
index 95bbac5c..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.os.Bundle;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.data.Account;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.twitter.task.Tweets;
-import net.lacolaco.smileessence.view.Partials;
-import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TalkChainDialogFragment extends StackableDialogFragment {
- private static final String KEY_STATUS_ID = "KEY_STATUS_ID";
-
- private long getStatusID() {
- return getArguments().getLong(KEY_STATUS_ID);
- }
-
- public void setStatusID(long id) {
- Bundle bundle = new Bundle();
- bundle.putLong(KEY_STATUS_ID, id);
- setArguments(bundle);
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- Account account = getWorld().getAccount();
-
- View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_talk_list, null);
- ListView listView = (ListView) view.findViewById(R.id.listview_dialog_talk_list);
- final List<Tweet> list = new ArrayList<>();
- final CustomListAdapter<Tweet> adapter = new CustomListAdapter<Tweet>() {
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return Partials.getTweetView(getItem(position), getActivity(), convertView, true);
- }
-
- @Override
- protected List<Tweet> getList() {
- return list;
- }
- };
- listView.setAdapter(adapter);
-
- new Tweets.GetTalkTask(account, getStatusID()).onProgressUI(tweet -> {
- list.add(tweet);
- adapter.updateForce();
- }).execute();
-
- return new AlertDialog.Builder(getActivity())
- .setTitle(R.string.dialog_title_talk_chain)
- .setView(view)
- .setCancelable(true)
- .create();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt
new file mode 100644
index 00000000..1b39e50a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt
@@ -0,0 +1,81 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ListView
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.twitter.task.Tweets
+import net.lacolaco.smileessence.view.Partials
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter
+
+import java.util.ArrayList
+
+class TalkChainDialogFragment : StackableDialogFragment() {
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val account = world.account
+
+ val view = activity.layoutInflater.inflate(R.layout.dialog_talk_list, null)
+ val listView = view.findViewById(R.id.listview_dialog_talk_list) as ListView
+ val list = ArrayList<Tweet>()
+ val adapter = object : CustomListAdapter<Tweet>() {
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ return Partials.getTweetView(getItem(position), activity, convertView, true)
+ }
+
+ override val list: List<Tweet>
+ get() = list
+ }
+ listView.adapter = adapter
+
+ Tweets.GetTalkTask(account, arguments.getLong(KEY_STATUS_ID)).onProgressUI { tweet ->
+ list.add(tweet)
+ adapter.updateForce()
+ }.execute()
+
+ return AlertDialog.Builder(activity)
+ .setTitle(R.string.dialog_title_talk_chain)
+ .setView(view)
+ .setCancelable(true)
+ .create()
+ }
+
+ companion object {
+ private val KEY_STATUS_ID = "KEY_STATUS_ID"
+
+ fun newInstance(tweet: Tweet): TalkChainDialogFragment {
+ val obj = TalkChainDialogFragment()
+ val bundle = Bundle()
+ bundle.putLong(KEY_STATUS_ID, tweet.originalTweet.id)
+ obj.arguments = bundle
+ return obj
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.java
deleted file mode 100644
index c8d62fa8..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.dialog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.os.Bundle;
-import android.text.Html;
-import android.text.TextUtils;
-import android.text.method.LinkMovementMethod;
-import android.view.View;
-import android.widget.AbsListView;
-import android.widget.ListView;
-import android.widget.TabHost;
-import android.widget.TextView;
-import com.android.volley.toolbox.NetworkImageView;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import com.handmark.pulltorefresh.library.PullToRefreshListView;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.data.Account;
-import net.lacolaco.smileessence.data.ImageCache;
-import net.lacolaco.smileessence.entity.RBinding;
-import net.lacolaco.smileessence.entity.User;
-import net.lacolaco.smileessence.twitter.task.Timelines;
-import net.lacolaco.smileessence.twitter.task.Users;
-import net.lacolaco.smileessence.util.IntentUtils;
-import net.lacolaco.smileessence.util.UIHandler;
-import net.lacolaco.smileessence.util.UIObserverBundle;
-import net.lacolaco.smileessence.view.DialogHelper;
-import net.lacolaco.smileessence.view.ThreeStateButton;
-import net.lacolaco.smileessence.view.adapter.TimelineAdapter;
-
-public class UserDetailDialogFragment extends StackableDialogFragment implements View.OnClickListener,
- PullToRefreshBase.OnRefreshListener2<ListView> {
-
- // ------------------------------ FIELDS ------------------------------
-
- private static final String KEY_USER_ID = "userID";
- private TimelineAdapter adapter;
- private TextView textViewScreenName;
- private TextView textViewName;
- private TextView textViewURL;
- private TextView textViewLocate;
- private TextView textViewFollowed;
- private TextView textViewProtected;
- private TextView textViewDescription;
- private TextView textViewTweetCount;
- private TextView textViewFriendCount;
- private TextView textViewFollowerCount;
- private TextView textViewFavoriteCount;
- private NetworkImageView imageViewIcon;
- private NetworkImageView imageViewHeader;
- private ThreeStateButton buttonFollow;
- private PullToRefreshListView listViewTimeline;
- private TabHost tabHost;
- private UIObserverBundle observerBundle;
- private User user;
-
- // --------------------- GETTER / SETTER METHODS ---------------------
-
- public long getUserID() {
- return getArguments().getLong(KEY_USER_ID);
- }
-
- public void setUserID(long userID) {
- Bundle args = new Bundle();
- args.putLong(KEY_USER_ID, userID);
- setArguments(args);
- }
-
- // ------------------------ INTERFACE METHODS ------------------------
-
-
- // --------------------- Interface OnClickListener ---------------------
-
- @Override
- public void onClick(final View v) {
- switch (v.getId()) {
- case R.id.imageview_user_detail_menu: {
- openUserMenu();
- break;
- }
- case R.id.imageview_user_detail_icon: {
- IntentUtils.openUri(getActivity(), user.getProfileImageUrlOriginal());
- break;
- }
- case R.id.textview_user_detail_screenname:
- case R.id.textview_user_detail_tweet_count: {
- IntentUtils.openUri(getActivity(), user.getUserHomeURL());
- break;
- }
- case R.id.textview_user_detail_friend_count: {
- IntentUtils.openUri(getActivity(), String.format("%s/following", user.getUserHomeURL()));
- break;
- }
- case R.id.textview_user_detail_follower_count: {
- IntentUtils.openUri(getActivity(), String.format("%s/followers", user.getUserHomeURL()));
- break;
- }
- case R.id.textview_user_detail_favorite_count: {
- IntentUtils.openUri(getActivity(), String.format("%s/favorites", user.getUserHomeURL()));
- break;
- }
- case R.id.button_user_detail_follow: {
- ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), this::toggleFollowing);
- break;
- }
- }
- }
-
- // --------------------- Interface OnRefreshListener2 ---------------------
-
- @Override
- public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) {
- Account currentAccount = getWorld().getAccount();
- new Timelines.UserTimelineTask(currentAccount, getUserID())
- .setCount(200)
- .setSinceId(adapter.getTopID())
- .onFail(x -> getWorld().notifyError(R.string.notice_error_get_user_timeline))
- .onDoneUI(tweets -> {
- adapter.addAll(tweets);
- updateListView(refreshView.getRefreshableView(), adapter, true);
- refreshView.onRefreshComplete();
- })
- .execute();
- }
-
- @Override
- public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) {
- Account currentAccount = getWorld().getAccount();
- new Timelines.UserTimelineTask(currentAccount, getUserID())
- .setCount(200)
- .setMaxId(adapter.getLastID() - 1)
- .onFail(x -> getWorld().notifyError(R.string.notice_error_get_user_timeline))
- .onDoneUI(tweets -> {
- adapter.addAll(tweets);
- updateListView(refreshView.getRefreshableView(), adapter, false);
- refreshView.onRefreshComplete();
- })
- .execute();
- }
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- user = User.fetch(getUserID());
- observerBundle = new UIObserverBundle();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- observerBundle.detachAll();
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- MainActivity activity = (MainActivity) getActivity();
- if (user == null) {
- getWorld().notify(R.string.notice_error_show_user);
- return new DisposeDialog(activity);
- }
-
- View v = activity.getLayoutInflater().inflate(R.layout.dialog_user_detail, null);
- View menu = v.findViewById(R.id.imageview_user_detail_menu);
- menu.setOnClickListener(this);
- textViewScreenName = (TextView) v.findViewById(R.id.textview_user_detail_screenname);
- textViewScreenName.setOnClickListener(this);
- textViewName = (TextView) v.findViewById(R.id.textview_user_detail_name);
- textViewURL = (TextView) v.findViewById(R.id.textview_user_detail_url);
- textViewLocate = (TextView) v.findViewById(R.id.textview_user_detail_locate);
- textViewFollowed = (TextView) v.findViewById(R.id.textview_user_detail_followed);
- textViewProtected = (TextView) v.findViewById(R.id.texttview_user_detail_protected);
- textViewDescription = (TextView) v.findViewById(R.id.textview_user_detail_description);
- textViewDescription.setMovementMethod(LinkMovementMethod.getInstance());
- textViewTweetCount = (TextView) v.findViewById(R.id.textview_user_detail_tweet_count);
- textViewTweetCount.setOnClickListener(this);
- textViewFriendCount = (TextView) v.findViewById(R.id.textview_user_detail_friend_count);
- textViewFriendCount.setOnClickListener(this);
- textViewFollowerCount = (TextView) v.findViewById(R.id.textview_user_detail_follower_count);
- textViewFollowerCount.setOnClickListener(this);
- textViewFavoriteCount = (TextView) v.findViewById(R.id.textview_user_detail_favorite_count);
- textViewFavoriteCount.setOnClickListener(this);
- imageViewIcon = (NetworkImageView) v.findViewById(R.id.imageview_user_detail_icon);
- imageViewIcon.setOnClickListener(this);
- imageViewHeader = (NetworkImageView) v.findViewById(R.id.imageview_user_detail_header);
- buttonFollow = (ThreeStateButton) v.findViewById(R.id.button_user_detail_follow);
- buttonFollow.setOnClickListener(this);
- listViewTimeline = (PullToRefreshListView) v.findViewById(R.id.listview_user_detail_timeline);
- listViewTimeline.setOnRefreshListener(this);
-
- tabHost = (TabHost) v.findViewById(android.R.id.tabhost);
- tabHost.setup();
- TabHost.TabSpec tab1 = tabHost.newTabSpec("tab1").setContent(R.id.tab1).setIndicator(getString(R.string.user_detail_tab_info));
- tabHost.addTab(tab1);
- TabHost.TabSpec tab2 = tabHost.newTabSpec("tab2").setContent(R.id.tab2).setIndicator(getString(R.string.user_detail_tab_timeline));
- tabHost.addTab(tab2);
- tabHost.setCurrentTab(0);
-
- initUserData();
-
- return new AlertDialog.Builder(activity)
- .setView(v)
- .setCancelable(true)
- .create();
- }
-
- private void executeUserTimelineTask(final TimelineAdapter adapter) {
- Account account = getWorld().getAccount();
- tabHost.getTabWidget().getChildTabViewAt(1).setVisibility(View.GONE);
- new Timelines.UserTimelineTask(account, user.getId())
- .setCount(200)
- .onFail(x -> getWorld().notifyError(R.string.notice_error_get_user_timeline))
- .onDoneUI(tweets -> {
- adapter.addAll(tweets);
- adapter.updateForce();
- tabHost.getTabWidget().getChildTabViewAt(1).setVisibility(View.VISIBLE);
- })
- .execute();
- }
-
- private String getHtmlDescription() {
- String description = user.getDescription();
- if (TextUtils.isEmpty(description)) {
- return "";
- }
- String html = description;
- html = html.replaceAll("https?://[\\w/:%#$&?()~.=+-]+", "<a href=\"$0\">$0</a>");
- html = html.replaceAll("@([a-zA-Z0-9_]+)", "<a href=\"https://twitter.com/$1\">$0</a>");
- html = html.replaceAll("\r\n", "<br />");
- return html;
- }
-
- private void updateUserDataBasic() {
- textViewName.setText(user.getName());
- textViewScreenName.setText(user.getScreenName());
- textViewProtected.setVisibility(user.isProtected() ? View.VISIBLE : View.GONE);
- imageViewIcon.setImageUrl(user.getProfileImageUrlOriginal(), ImageCache.getImageLoader());
- }
-
- private void updateUserDataDetail() {
- if (TextUtils.isEmpty(user.getLocation())) {
- textViewLocate.setVisibility(View.GONE);
- } else {
- textViewLocate.setText(user.getLocation());
- textViewLocate.setVisibility(View.VISIBLE);
- }
- if (TextUtils.isEmpty(user.getUrl())) {
- textViewURL.setVisibility(View.GONE);
- } else {
- textViewURL.setText(user.getUrl());
- textViewURL.setVisibility(View.VISIBLE);
- }
- textViewDescription.setText(Html.fromHtml(getHtmlDescription()));
-
- textViewTweetCount.setText(String.valueOf(user.getStatusesCount()));
- textViewFriendCount.setText(String.valueOf(user.getFriendsCount()));
- textViewFollowerCount.setText(String.valueOf(user.getFollowersCount()));
- textViewFavoriteCount.setText(String.valueOf(user.getFavoritesCount()));
-
- imageViewHeader.setImageUrl(user.getProfileBannerUrl(), ImageCache.getImageLoader());
- }
-
- private void initUserData() {
- updateUserDataBasic();
- updateUserDataDetail();
-
- MainActivity activity = (MainActivity) getActivity();
- adapter = new TimelineAdapter(activity);
- listViewTimeline.setAdapter(adapter);
- executeUserTimelineTask(adapter);
- updateRelationship();
-
- observerBundle.attach(user, changes -> {
- if (getActivity() != null) {
- if (changes.contains(RBinding.BASIC))
- updateUserDataBasic();
- if (changes.contains(RBinding.DETAIL))
- updateUserDataDetail();
- }
- });
- }
-
- private void openUserMenu() {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle("@" + user.getScreenName())
- .setItems(R.array.user_commands, (dialog, which) -> {
- // XXX
- new UIHandler().postDelayed(() -> {
- if (UserDetailDialogFragment.this.isAdded()) {
- updateRelationship();
- }
- }, 1000);
- switch (which) {
- case 0:
- String text = String.format("@%s ", user.getScreenName());
- getWorld().getPostState().beginTransaction().insertText(0, text).moveCursor(text.length()).commit();
- getWorld().notify(R.string.notice_add_to_reply);
- break;
- case 1:
- DialogHelper.showDialog(getActivity(), SendMessageDialogFragment.newInstance(user));
- break;
- case 2:
- ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), () ->
- new Users.BlockTask(getWorld().getAccount(), user.getId())
- .onDone(user -> getWorld().notify(R.string.notice_block_succeeded))
- .onFail(ex -> getWorld().notifyError(R.string.notice_block_failed))
- .execute());
- break;
- case 3:
- ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), () ->
- new Users.UnblockTask(getWorld().getAccount(), user.getId())
- .onDone(user -> getWorld().notify(R.string.notice_unblock_succeeded))
- .onFail(x -> getWorld().notifyError(R.string.notice_unblock_failed))
- .execute());
- break;
- case 4:
- ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), () ->
- new Users.ReportForSpamTask(getWorld().getAccount(), user.getId())
- .onDone(user -> getWorld().notify(R.string.notice_r4s_succeeded))
- .onFail(ex -> getWorld().notifyError(R.string.notice_r4s_failed))
- .execute());
- break;
- case 5:
- IntentUtils.openUri(getActivity(), user.getAclogTimelineURL());
- break;
- default:
- throw new IllegalStateException();
- }
- });
- AlertDialog dialog = builder.create();
- dialog.show();
- }
-
- private void setFollowButtonState(boolean isFollowing) {
- MainActivity mainActivity = (MainActivity) getActivity();
- if (mainActivity != null) {
- buttonFollow.setState(isFollowing ? ThreeStateButton.STATE_ON : ThreeStateButton.STATE_OFF);
- }
- }
-
- private void toggleFollowing() {
- Account account = getWorld().getAccount();
- Boolean isFollowing = buttonFollow.getState() == ThreeStateButton.STATE_ON;
- buttonFollow.setState(ThreeStateButton.STATE_LOCKED);
- if (isFollowing) {
- new Users.UnfollowTask(account, user.getId())
- .onDoneUI(result -> {
- getWorld().notify(R.string.notice_unfollow_succeeded);
- updateRelationship();
- })
- .onFail(x ->
- getWorld().notifyError(R.string.notice_unfollow_failed))
- .execute();
- } else {
- new Users.FollowTask(account, user.getId())
- .onDoneUI(result -> {
- getWorld().notify(R.string.notice_follow_succeeded);
- updateRelationship();
- })
- .onFail(x -> getWorld().notifyError(R.string.notice_follow_failed))
- .execute();
- }
- }
-
- private void updateListView(AbsListView absListView, TimelineAdapter adapter, boolean addedToTop) {
- int before = adapter.getCount();
- adapter.notifyDataSetChanged(); // synchronized call (not adapter#updateForce())
- int after = adapter.getCount();
- int increments = after - before;
- if (increments > 0) {
- if (addedToTop) {
- absListView.setSelection(increments + 1);
- absListView.smoothScrollToPositionFromTop(increments, 0);
- absListView.setSelection(increments);
- } else {
- absListView.smoothScrollToPositionFromTop(before, 0);
- }
- }
- }
-
- private void updateRelationship() {
- Account account = getWorld().getAccount();
- if (user == account.getUser()) {
- textViewFollowed.setText(R.string.user_detail_followed_is_me);
- buttonFollow.setVisibility(View.GONE);
- } else {
- buttonFollow.setState(ThreeStateButton.STATE_LOCKED);
- textViewFollowed.setText(R.string.user_detail_loading);
- new Users.ShowFriendshipTask(account, user.getId()).onDoneUI(relationship -> {
- boolean isFollowing = relationship.isSourceFollowingTarget();
- boolean isFollowed = relationship.isSourceFollowedByTarget();
- setFollowButtonState(isFollowing);
- textViewFollowed.setText(isFollowed ? R.string.user_detail_followed : R.string.user_detail_not_followed);
- }).execute();
- }
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt
new file mode 100644
index 00000000..228a000a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt
@@ -0,0 +1,390 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.os.Bundle
+import android.text.Html
+import android.text.TextUtils
+import android.text.method.LinkMovementMethod
+import android.view.View
+import android.widget.AbsListView
+import android.widget.ListView
+import android.widget.TabHost
+import android.widget.TextView
+import com.android.volley.toolbox.NetworkImageView
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import com.handmark.pulltorefresh.library.PullToRefreshListView
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.data.ImageCache
+import net.lacolaco.smileessence.entity.RBinding
+import net.lacolaco.smileessence.entity.User
+import net.lacolaco.smileessence.twitter.task.Timelines
+import net.lacolaco.smileessence.twitter.task.Users
+import net.lacolaco.smileessence.util.IntentUtils
+import net.lacolaco.smileessence.util.UIHandler
+import net.lacolaco.smileessence.util.UIObserverBundle
+import net.lacolaco.smileessence.view.DialogHelper
+import net.lacolaco.smileessence.view.ThreeStateButton
+import net.lacolaco.smileessence.view.adapter.TimelineAdapter
+
+class UserDetailDialogFragment : StackableDialogFragment(), View.OnClickListener, PullToRefreshBase.OnRefreshListener2<ListView> {
+ private lateinit var adapter: TimelineAdapter
+ private lateinit var textViewScreenName: TextView
+ private lateinit var textViewName: TextView
+ private lateinit var textViewURL: TextView
+ private lateinit var textViewLocate: TextView
+ private lateinit var textViewFollowed: TextView
+ private lateinit var textViewProtected: TextView
+ private lateinit var textViewDescription: TextView
+ private lateinit var textViewTweetCount: TextView
+ private lateinit var textViewFriendCount: TextView
+ private lateinit var textViewFollowerCount: TextView
+ private lateinit var textViewFavoriteCount: TextView
+ private lateinit var imageViewIcon: NetworkImageView
+ private lateinit var imageViewHeader: NetworkImageView
+ private lateinit var buttonFollow: ThreeStateButton
+ private lateinit var listViewTimeline: PullToRefreshListView
+ private lateinit var tabHost: TabHost
+ private lateinit var observerBundle: UIObserverBundle
+ private lateinit var user: User
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.imageview_user_detail_menu -> {
+ openUserMenu()
+ }
+ R.id.imageview_user_detail_icon -> {
+ IntentUtils.openUri(activity, user.profileImageUrl!!)
+ }
+ R.id.textview_user_detail_screenname, R.id.textview_user_detail_tweet_count -> {
+ IntentUtils.openUri(activity, user.userHomeURL)
+ }
+ R.id.textview_user_detail_friend_count -> {
+ IntentUtils.openUri(activity, String.format("%s/following", user.userHomeURL))
+ }
+ R.id.textview_user_detail_follower_count -> {
+ IntentUtils.openUri(activity, String.format("%s/followers", user.userHomeURL))
+ }
+ R.id.textview_user_detail_favorite_count -> {
+ IntentUtils.openUri(activity, String.format("%s/favorites", user.userHomeURL))
+ }
+ R.id.button_user_detail_follow -> {
+ ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { this.toggleFollowing() }
+ }
+ }
+ }
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ val currentAccount = world.account
+ Timelines.UserTimelineTask(currentAccount, user.id)
+ .setCount(200)
+ .setSinceId(adapter.topID)
+ .onFail { x -> world.notifyError(R.string.notice_error_get_user_timeline) }
+ .onDoneUI { tweets ->
+ adapter.addAll(tweets)
+ updateListView(refreshView.refreshableView, adapter, true)
+ refreshView.onRefreshComplete()
+ }
+ .execute()
+ }
+
+ override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ val currentAccount = world.account
+ Timelines.UserTimelineTask(currentAccount, user.id)
+ .setCount(200)
+ .setMaxId(adapter.lastID - 1)
+ .onFail { x -> world.notifyError(R.string.notice_error_get_user_timeline) }
+ .onDoneUI { tweets ->
+ adapter.addAll(tweets)
+ updateListView(refreshView.refreshableView, adapter, false)
+ refreshView.onRefreshComplete()
+ }
+ .execute()
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun onCreate(savedInstanceState: Bundle) {
+ super.onCreate(savedInstanceState)
+ observerBundle = UIObserverBundle()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ observerBundle.detachAll()
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val activity = activity as MainActivity
+ val found = User.fetch(arguments.getLong(KEY_USER_ID))
+ if (found == null) {
+ world.notify(R.string.notice_error_show_user)
+ return DisposeDialog(activity)
+ }
+ user = found
+
+ val v = activity.layoutInflater.inflate(R.layout.dialog_user_detail, null)
+ val menu = v.findViewById(R.id.imageview_user_detail_menu)
+ menu.setOnClickListener(this)
+ textViewScreenName = v.findViewById(R.id.textview_user_detail_screenname) as TextView
+ textViewScreenName.setOnClickListener(this)
+ textViewName = v.findViewById(R.id.textview_user_detail_name) as TextView
+ textViewURL = v.findViewById(R.id.textview_user_detail_url) as TextView
+ textViewLocate = v.findViewById(R.id.textview_user_detail_locate) as TextView
+ textViewFollowed = v.findViewById(R.id.textview_user_detail_followed) as TextView
+ textViewProtected = v.findViewById(R.id.texttview_user_detail_protected) as TextView
+ textViewDescription = v.findViewById(R.id.textview_user_detail_description) as TextView
+ textViewDescription.movementMethod = LinkMovementMethod.getInstance()
+ textViewTweetCount = v.findViewById(R.id.textview_user_detail_tweet_count) as TextView
+ textViewTweetCount.setOnClickListener(this)
+ textViewFriendCount = v.findViewById(R.id.textview_user_detail_friend_count) as TextView
+ textViewFriendCount.setOnClickListener(this)
+ textViewFollowerCount = v.findViewById(R.id.textview_user_detail_follower_count) as TextView
+ textViewFollowerCount.setOnClickListener(this)
+ textViewFavoriteCount = v.findViewById(R.id.textview_user_detail_favorite_count) as TextView
+ textViewFavoriteCount.setOnClickListener(this)
+ imageViewIcon = v.findViewById(R.id.imageview_user_detail_icon) as NetworkImageView
+ imageViewIcon.setOnClickListener(this)
+ imageViewHeader = v.findViewById(R.id.imageview_user_detail_header) as NetworkImageView
+ buttonFollow = v.findViewById(R.id.button_user_detail_follow) as ThreeStateButton
+ buttonFollow.setOnClickListener(this)
+ listViewTimeline = v.findViewById(R.id.listview_user_detail_timeline) as PullToRefreshListView
+ listViewTimeline.setOnRefreshListener(this)
+
+ tabHost = v.findViewById(android.R.id.tabhost) as TabHost
+ tabHost.setup()
+ val tab1 = tabHost.newTabSpec("tab1").setContent(R.id.tab1).setIndicator(getString(R.string.user_detail_tab_info))
+ tabHost.addTab(tab1)
+ val tab2 = tabHost.newTabSpec("tab2").setContent(R.id.tab2).setIndicator(getString(R.string.user_detail_tab_timeline))
+ tabHost.addTab(tab2)
+ tabHost.currentTab = 0
+
+ initUserData()
+
+ return AlertDialog.Builder(activity)
+ .setView(v)
+ .setCancelable(true)
+ .create()
+ }
+
+ private fun executeUserTimelineTask(adapter: TimelineAdapter) {
+ val account = world.account
+ tabHost.tabWidget.getChildTabViewAt(1).visibility = View.GONE
+ Timelines.UserTimelineTask(account, user.id)
+ .setCount(200)
+ .onFail { x -> world.notifyError(R.string.notice_error_get_user_timeline) }
+ .onDoneUI { tweets ->
+ adapter.addAll(tweets)
+ adapter.updateForce()
+ tabHost.tabWidget.getChildTabViewAt(1).visibility = View.VISIBLE
+ }
+ .execute()
+ }
+
+ private val htmlDescription: String?
+ get() {
+ val description = user.description
+ if (TextUtils.isEmpty(description)) {
+ return ""
+ }
+ var html = description
+ html = html!!.replace("https?://[\\w/:%#$&?()~.=+-]+".toRegex(), "<a href=\"$0\">$0</a>")
+ html = html.replace("@([a-zA-Z0-9_]+)".toRegex(), "<a href=\"https://twitter.com/$1\">$0</a>")
+ html = html.replace("\r\n".toRegex(), "<br />")
+ return html
+ }
+
+ private fun updateUserDataBasic() {
+ textViewName.text = user.name
+ textViewScreenName.text = user.screenName
+ textViewProtected.visibility = if (user.isProtected) View.VISIBLE else View.GONE
+ imageViewIcon.setImageUrl(user.profileImageUrl, ImageCache.getImageLoader())
+ }
+
+ private fun updateUserDataDetail() {
+ if (TextUtils.isEmpty(user.location)) {
+ textViewLocate.visibility = View.GONE
+ } else {
+ textViewLocate.text = user.location
+ textViewLocate.visibility = View.VISIBLE
+ }
+ if (TextUtils.isEmpty(user.url)) {
+ textViewURL.visibility = View.GONE
+ } else {
+ textViewURL.text = user.url
+ textViewURL.visibility = View.VISIBLE
+ }
+ textViewDescription.text = Html.fromHtml(htmlDescription)
+
+ textViewTweetCount.text = user.statusesCount.toString()
+ textViewFriendCount.text = user.friendsCount.toString()
+ textViewFollowerCount.text = user.followersCount.toString()
+ textViewFavoriteCount.text = user.favoritesCount.toString()
+
+ imageViewHeader.setImageUrl(user.profileBannerUrl, ImageCache.getImageLoader())
+ }
+
+ private fun initUserData() {
+ updateUserDataBasic()
+ updateUserDataDetail()
+
+ val activity = activity as MainActivity
+ adapter = TimelineAdapter(activity)
+ listViewTimeline.setAdapter(adapter)
+ executeUserTimelineTask(adapter)
+ updateRelationship()
+
+ observerBundle.attach(user) { changes ->
+ if (getActivity() != null) {
+ if (changes.contains(RBinding.BASIC))
+ updateUserDataBasic()
+ if (changes.contains(RBinding.DETAIL))
+ updateUserDataDetail()
+ }
+ }
+ }
+
+ private fun openUserMenu() {
+ val builder = AlertDialog.Builder(activity)
+ builder.setTitle("@" + user.screenName)
+ .setItems(R.array.user_commands) { dialog, which ->
+ // XXX
+ UIHandler().postDelayed({
+ if (this@UserDetailDialogFragment.isAdded) {
+ updateRelationship()
+ }
+ }, 1000)
+ when (which) {
+ 0 -> {
+ val text = String.format("@%s ", user.screenName)
+ world.postState.beginTransaction().insertText(0, text).moveCursor(text.length).commit()
+ world.notify(R.string.notice_add_to_reply)
+ }
+ 1 -> DialogHelper.showDialog(activity, SendMessageDialogFragment.newInstance(user))
+ 2 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) {
+ Users.BlockTask(world.account, user.id)
+ .onDone { user -> world.notify(R.string.notice_block_succeeded) }
+ .onFail { ex -> world.notifyError(R.string.notice_block_failed) }
+ .execute()
+ }
+ 3 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) {
+ Users.UnblockTask(world.account, user.id)
+ .onDone { user -> world.notify(R.string.notice_unblock_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_unblock_failed) }
+ .execute()
+ }
+ 4 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) {
+ Users.ReportForSpamTask(world.account, user.id)
+ .onDone { user -> world.notify(R.string.notice_r4s_succeeded) }
+ .onFail { ex -> world.notifyError(R.string.notice_r4s_failed) }
+ .execute()
+ }
+ 5 -> IntentUtils.openUri(activity, user.aclogTimelineURL)
+ else -> throw IllegalStateException()
+ }
+ }
+ val dialog = builder.create()
+ dialog.show()
+ }
+
+ private fun setFollowButtonState(isFollowing: Boolean) {
+ if (activity != null) {
+ buttonFollow.state = if (isFollowing) ThreeStateButton.STATE_ON else ThreeStateButton.STATE_OFF
+ }
+ }
+
+ private fun toggleFollowing() {
+ val account = world.account
+ val isFollowing = buttonFollow.state == ThreeStateButton.STATE_ON
+ buttonFollow.state = ThreeStateButton.STATE_LOCKED
+ if (isFollowing) {
+ Users.UnfollowTask(account, user.id)
+ .onDoneUI { result ->
+ world.notify(R.string.notice_unfollow_succeeded)
+ updateRelationship()
+ }
+ .onFail { x -> world.notifyError(R.string.notice_unfollow_failed) }
+ .execute()
+ } else {
+ Users.FollowTask(account, user.id)
+ .onDoneUI { result ->
+ world.notify(R.string.notice_follow_succeeded)
+ updateRelationship()
+ }
+ .onFail { x -> world.notifyError(R.string.notice_follow_failed) }
+ .execute()
+ }
+ }
+
+ private fun updateListView(absListView: AbsListView, adapter: TimelineAdapter, addedToTop: Boolean) {
+ val before = adapter.count
+ adapter.notifyDataSetChanged() // synchronized call (not adapter#updateForce())
+ val after = adapter.count
+ val increments = after - before
+ if (increments > 0) {
+ if (addedToTop) {
+ absListView.setSelection(increments + 1)
+ absListView.smoothScrollToPositionFromTop(increments, 0)
+ absListView.setSelection(increments)
+ } else {
+ absListView.smoothScrollToPositionFromTop(before, 0)
+ }
+ }
+ }
+
+ private fun updateRelationship() {
+ val account = world.account
+ if (user === account.user) {
+ textViewFollowed.setText(R.string.user_detail_followed_is_me)
+ buttonFollow.visibility = View.GONE
+ } else {
+ buttonFollow.state = ThreeStateButton.STATE_LOCKED
+ textViewFollowed.setText(R.string.user_detail_loading)
+ Users.ShowFriendshipTask(account, user.id).onDoneUI { relationship ->
+ val isFollowing = relationship.isSourceFollowingTarget
+ val isFollowed = relationship.isSourceFollowedByTarget
+ setFollowButtonState(isFollowing)
+ textViewFollowed.setText(if (isFollowed) R.string.user_detail_followed else R.string.user_detail_not_followed)
+ }.execute()
+ }
+ }
+
+ companion object {
+ private val KEY_USER_ID = "userID"
+
+ fun newInstance(user: User): UserDetailDialogFragment {
+ val obj = UserDetailDialogFragment()
+ val bundle = Bundle()
+ bundle.putLong(KEY_USER_ID, user.id)
+ obj.arguments = bundle
+ return obj
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.java b/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.kt
index 22d6180f..20404c63 100644
--- a/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.java
+++ b/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.kt
@@ -22,42 +22,35 @@
* SOFTWARE.
*/
-package net.lacolaco.smileessence.view.listener;
+package net.lacolaco.smileessence.view.listener
-import android.app.Activity;
-import android.graphics.drawable.ColorDrawable;
-import android.support.v4.content.ContextCompat;
-import android.view.View;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.util.UIHandler;
+import android.app.Activity
+import android.graphics.drawable.ColorDrawable
+import android.support.v4.content.ContextCompat
+import android.view.View
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.util.UIHandler
-public class ListItemClickListener implements View.OnClickListener {
+class ListItemClickListener
+// --------------------------- CONSTRUCTORS ---------------------------
- // ------------------------------ FIELDS ------------------------------
+(
+ // ------------------------------ FIELDS ------------------------------
- private final Activity activity;
- private final Runnable callback;
-
- // --------------------------- CONSTRUCTORS ---------------------------
-
- public ListItemClickListener(Activity activity, Runnable callback) {
- this.activity = activity;
- this.callback = callback;
- }
+ private val activity: Activity, private val callback: () -> Unit) : View.OnClickListener {
// ------------------------ INTERFACE METHODS ------------------------
// --------------------- Interface OnClickListener ---------------------
- @Override
- public void onClick(final View v) {
- final int currentBgColor = ((ColorDrawable) v.getBackground()).getColor();
- v.setBackgroundColor(ContextCompat.getColor(activity, R.color.metro_blue));
- v.invalidate();
- new UIHandler().post(() -> {
- v.setBackgroundColor(currentBgColor);
- callback.run();
- });
+ override fun onClick(v: View) {
+ val currentBgColor = (v.background as ColorDrawable).color
+ v.setBackgroundColor(ContextCompat.getColor(activity, R.color.metro_blue))
+ v.invalidate()
+ UIHandler().post {
+ v.setBackgroundColor(currentBgColor)
+ callback()
+ }
}
}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.java
deleted file mode 100644
index 0dd24e67..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.page;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.ListView;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import com.handmark.pulltorefresh.library.PullToRefreshListView;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.World;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
-
-public abstract class CustomListFragment<T extends CustomListAdapter> extends PageFragment<T> implements AbsListView.OnScrollListener,
- PullToRefreshBase.OnRefreshListener2<ListView> {
-
- // --------------------- GETTER / SETTER METHODS ---------------------
-
- protected PullToRefreshBase.Mode getRefreshMode() {
- return PullToRefreshBase.Mode.DISABLED;
- }
-
- // ------------------------ INTERFACE METHODS ------------------------
-
-
- // --------------------- Interface OnRefreshListener2 ---------------------
-
- @Override
- public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
- }
-
- @Override
- public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
- }
-
- // --------------------- Interface OnScrollListener ---------------------
-
- @Override
- public void onScrollStateChanged(AbsListView absListView, int scrollState) {
- T adapter = getAdapter();
- if (scrollState != SCROLL_STATE_TOUCH_SCROLL &&
- absListView.getFirstVisiblePosition() == 0 && (absListView.getChildAt(0) == null || absListView.getChildAt(0).getTop() == 0)) {
- adapter.setNotifiable(true);
- updateListViewWithNotice(absListView, true);
- } else {
- adapter.setNotifiable(false);
- }
- }
-
- @Override
- public void onScroll(AbsListView absListView, int i, int i2, int i3) {
- }
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View page = inflater.inflate(R.layout.fragment_list, container, false);
- PullToRefreshListView listView = getListView(page);
- listView.setAdapter(getAdapter());
- listView.setOnScrollListener(this);
- listView.setOnRefreshListener(this);
- listView.setMode(getRefreshMode());
- return page;
- }
-
- protected PullToRefreshListView getListView(View page) {
- return (PullToRefreshListView) page.findViewById(R.id.fragment_list_listview);
- }
-
- protected void updateListViewWithNotice(AbsListView absListView, boolean addedToTop) {
- T adapter = getAdapter();
- int before = adapter.getCount();
- adapter.notifyDataSetChanged(); // synchronized call (not adapter#updateForce())
- int after = adapter.getCount();
- int increments = after - before;
- if (increments > 0) {
- if (addedToTop) {
- absListView.setSelection(increments + 1);
- absListView.smoothScrollToPositionFromTop(increments, 0);
- absListView.setSelection(increments);
- } else {
- absListView.smoothScrollToPositionFromTop(before, 0);
- }
-
- if (increments > 1) {
- adapter.setNotifiable(false);
- }
- }
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt
new file mode 100644
index 00000000..d8536263
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt
@@ -0,0 +1,107 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.page
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AbsListView
+import android.widget.ListView
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import com.handmark.pulltorefresh.library.PullToRefreshListView
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.World
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter
+
+abstract class CustomListFragment<T : CustomListAdapter<*>> : PageFragment<T>(), AbsListView.OnScrollListener, PullToRefreshBase.OnRefreshListener2<ListView> {
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ protected open val refreshMode: PullToRefreshBase.Mode
+ get() = PullToRefreshBase.Mode.DISABLED
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {}
+
+ override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {}
+
+ // --------------------- Interface OnScrollListener ---------------------
+
+ override fun onScrollStateChanged(absListView: AbsListView, scrollState: Int) {
+ val adapter = adapter
+ if (scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL &&
+ absListView.firstVisiblePosition == 0 && (absListView.getChildAt(0) == null || absListView.getChildAt(0).top == 0)) {
+ adapter.setNotifiable(true)
+ updateListViewWithNotice(absListView, true)
+ } else {
+ adapter.setNotifiable(false)
+ }
+ }
+
+ override fun onScroll(absListView: AbsListView, i: Int, i2: Int, i3: Int) {}
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View {
+ val page = inflater.inflate(R.layout.fragment_list, container, false)
+ val listView = getListView(page)
+ listView.setAdapter(adapter)
+ listView.setOnScrollListener(this)
+ listView.setOnRefreshListener(this)
+ listView.mode = refreshMode
+ return page
+ }
+
+ protected open fun getListView(page: View): PullToRefreshListView {
+ return page.findViewById(R.id.fragment_list_listview) as PullToRefreshListView
+ }
+
+ protected fun updateListViewWithNotice(absListView: AbsListView, addedToTop: Boolean) {
+ val adapter = adapter
+ val before = adapter.count
+ adapter.notifyDataSetChanged() // synchronized call (not adapter#updateForce())
+ val after = adapter.count
+ val increments = after - before
+ if (increments > 0) {
+ if (addedToTop) {
+ absListView.setSelection(increments + 1)
+ absListView.smoothScrollToPositionFromTop(increments, 0)
+ absListView.setSelection(increments)
+ } else {
+ absListView.smoothScrollToPositionFromTop(before, 0)
+ }
+
+ if (increments > 1) {
+ adapter.setNotifiable(false)
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.kt
index 9f8e5039..70cae02f 100644
--- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.kt
@@ -22,32 +22,20 @@
* SOFTWARE.
*/
-package net.lacolaco.smileessence.view.adapter;
+package net.lacolaco.smileessence.view.page
-import android.app.Activity;
-import android.view.View;
-import android.view.ViewGroup;
-import net.lacolaco.smileessence.entity.DirectMessage;
-import net.lacolaco.smileessence.view.Partials;
+import android.os.Bundle
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import net.lacolaco.smileessence.World
+import net.lacolaco.smileessence.view.adapter.EventListAdapter
-public class MessageListAdapter extends OrderedCustomListAdapter<DirectMessage> {
- private final Activity activity;
+class HistoryFragment : CustomListFragment<EventListAdapter>() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
- public MessageListAdapter(Activity activity) {
- super();
- this.activity = activity;
+ adapter = EventListAdapter(world, activity)
+ world.addEventNotifier(this) { adapter.update() } // XXX
}
- public long getLastID() {
- return getCount() > 0 ? getItem(getCount() - 1).getId() : -1;
- }
-
- public long getTopID() {
- return getCount() > 0 ? getItem(0).getId() : -1;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- return Partials.getDirectMessageView(getItem(position), activity, convertView);
- }
+ override fun refresh() {}
}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.java
deleted file mode 100644
index e00f69c6..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.page;
-
-import android.os.Bundle;
-import android.widget.ListView;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.logging.Logger;
-import net.lacolaco.smileessence.twitter.task.TimelineTask;
-import net.lacolaco.smileessence.twitter.task.Timelines;
-import net.lacolaco.smileessence.util.UIHandler;
-import net.lacolaco.smileessence.view.adapter.TimelineAdapter;
-
-public class HomeFragment extends CustomListFragment<TimelineAdapter> {
- @Override
- protected PullToRefreshBase.Mode getRefreshMode() {
- return PullToRefreshBase.Mode.BOTH;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- TimelineAdapter adapter = new TimelineAdapter(getActivity());
- setAdapter(adapter);
-
- getWorld().addTimeline(this, tweet -> {
- adapter.add(tweet);
- adapter.update();
- });
-
- refresh();
- }
-
- @Override
- public void refresh() {
- runRefreshTask(new Timelines.HomeTimelineTask(getWorld().getAccount()), () -> getAdapter().updateForce());
- }
-
- // --------------------- Interface OnRefreshListener2 ---------------------
-
- @Override
- public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) {
- if (getWorld().isStreaming()) {
- new UIHandler().post(() -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), true);
- refreshView.onRefreshComplete();
- });
- } else {
- runRefreshTask(
- new Timelines.HomeTimelineTask(getWorld().getAccount())
- .setSinceId(getAdapter().getTopID()),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), true);
- refreshView.onRefreshComplete();
- });
- }
- }
-
- @Override
- public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) {
- runRefreshTask(
- new Timelines.HomeTimelineTask(getWorld().getAccount())
- .setMaxId(getAdapter().getLastID() - 1),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), false);
- refreshView.onRefreshComplete();
- });
- }
-
- private void runRefreshTask(TimelineTask<Tweet> task, Runnable onFinish) {
- task
- .setCount(200)
- .onFail(e -> getWorld().notifyError(R.string.notice_error_get_home))
- .onDoneUI(tweets -> getWorld().addTweetAll(tweets))
- .onFinishUI(onFinish)
- .execute();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt
new file mode 100644
index 00000000..a9bd8fe4
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt
@@ -0,0 +1,97 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.page
+
+import android.os.Bundle
+import android.widget.ListView
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.logging.Logger
+import net.lacolaco.smileessence.twitter.task.TimelineTask
+import net.lacolaco.smileessence.twitter.task.Timelines
+import net.lacolaco.smileessence.util.UIHandler
+import net.lacolaco.smileessence.view.adapter.TimelineAdapter
+
+class HomeFragment : CustomListFragment<TimelineAdapter>() {
+ override val refreshMode: PullToRefreshBase.Mode
+ get() = PullToRefreshBase.Mode.BOTH
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ adapter = TimelineAdapter(activity)
+
+ world.addTimeline(this) { tweet ->
+ adapter.add(tweet)
+ adapter.update()
+ }
+
+ refresh()
+ }
+
+ override fun refresh() {
+ runRefreshTask(Timelines.HomeTimelineTask(world.account), { adapter.updateForce() })
+ }
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ if (world.isStreaming) {
+ UIHandler().post {
+ updateListViewWithNotice(refreshView.refreshableView, true)
+ refreshView.onRefreshComplete()
+ }
+ } else {
+ runRefreshTask(
+ Timelines.HomeTimelineTask(world.account)
+ .setSinceId(adapter.topID),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, true)
+ refreshView.onRefreshComplete()
+ })
+ }
+ }
+
+ override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ runRefreshTask(
+ Timelines.HomeTimelineTask(world.account)
+ .setMaxId(adapter.lastID - 1),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, false)
+ refreshView.onRefreshComplete()
+ })
+ }
+
+ private fun runRefreshTask(task: TimelineTask<Tweet>, onFinish: () -> Unit) {
+ task
+ .setCount(200)
+ .onFail { e -> world.notifyError(R.string.notice_error_get_home) }
+ .onDoneUI { tweets -> world.addTweetAll(tweets) }
+ .onFinishUI(onFinish)
+ .execute()
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.java
deleted file mode 100644
index 21ae1169..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.page;
-
-import android.os.Bundle;
-import android.widget.ListView;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.data.ExtractionWord;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.entity.User;
-import net.lacolaco.smileessence.twitter.task.TimelineTask;
-import net.lacolaco.smileessence.twitter.task.Timelines;
-import net.lacolaco.smileessence.view.adapter.TimelineAdapter;
-
-public class MentionsFragment extends CustomListFragment<TimelineAdapter> {
-
- // --------------------- GETTER / SETTER METHODS ---------------------
-
- @Override
- protected PullToRefreshBase.Mode getRefreshMode() {
- return PullToRefreshBase.Mode.BOTH;
- }
-
- // ------------------------ INTERFACE METHODS ------------------------
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- final TimelineAdapter adapter = new TimelineAdapter(getActivity());
- setAdapter(adapter);
-
- // Prevent calling getWorld() on null
- final User self = getWorld().getAccount().getUser();
- getWorld().addTimeline(this, tweet -> {
- if (tweet.getMentions().contains(self.getScreenName())) {
- adapter.add(tweet);
- adapter.update();
- } else {
- for (ExtractionWord word : ExtractionWord.cached()) {
- if (word.getPattern().matcher(tweet.getOriginalTweet().getText()).find()) {
- adapter.add(tweet);
- adapter.update();
- }
- }
- }
- });
-
- refresh();
- }
-
- @Override
- public void refresh() {
- runRefreshTask(new Timelines.MentionsTimelineTask(getWorld().getAccount()), () -> getAdapter().updateForce());
- }
-
- // --------------------- Interface OnRefreshListener2 ---------------------
-
- @Override
- public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) {
- runRefreshTask(
- new Timelines.MentionsTimelineTask(getWorld().getAccount())
- .setSinceId(getAdapter().getTopID()),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), true);
- refreshView.onRefreshComplete();
- });
- }
-
- @Override
- public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) {
- runRefreshTask(
- new Timelines.MentionsTimelineTask(getWorld().getAccount())
- .setMaxId(getAdapter().getLastID() - 1),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), false);
- refreshView.onRefreshComplete();
- });
- }
-
- private void runRefreshTask(TimelineTask<Tweet> task, Runnable onFinish) {
- task
- .setCount(200)
- .onFail(x -> getWorld().notifyError(R.string.notice_error_get_mentions))
- .onDoneUI(tweets -> getWorld().addTweetAll(tweets))
- .onFinishUI(onFinish)
- .execute();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt
new file mode 100644
index 00000000..d8442ac7
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt
@@ -0,0 +1,102 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.page
+
+import android.os.Bundle
+import android.widget.ListView
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.data.ExtractionWord
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.entity.User
+import net.lacolaco.smileessence.twitter.task.TimelineTask
+import net.lacolaco.smileessence.twitter.task.Timelines
+import net.lacolaco.smileessence.view.adapter.TimelineAdapter
+
+class MentionsFragment : CustomListFragment<TimelineAdapter>() {
+ override val refreshMode: PullToRefreshBase.Mode
+ get() = PullToRefreshBase.Mode.BOTH
+
+ // ------------------------ INTERFACE METHODS ------------------------
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ adapter = TimelineAdapter(activity)
+
+ // Prevent calling getWorld() on null
+ val self = world.account.user
+ world.addTimeline(this) { tweet ->
+ if (tweet.mentions.contains(self.screenName)) {
+ adapter.add(tweet)
+ adapter.update()
+ } else {
+ for (word in ExtractionWord.cached()) {
+ if (word.pattern.matcher(tweet.originalTweet.text).find()) {
+ adapter.add(tweet)
+ adapter.update()
+ }
+ }
+ }
+ }
+
+ refresh()
+ }
+
+ override fun refresh() {
+ runRefreshTask(Timelines.MentionsTimelineTask(world.account), { adapter.updateForce() })
+ }
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ runRefreshTask(
+ Timelines.MentionsTimelineTask(world.account)
+ .setSinceId(adapter.topID),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, true)
+ refreshView.onRefreshComplete()
+ })
+ }
+
+ override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ runRefreshTask(
+ Timelines.MentionsTimelineTask(world.account)
+ .setMaxId(adapter.lastID - 1),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, false)
+ refreshView.onRefreshComplete()
+ })
+ }
+
+ private fun runRefreshTask(task: TimelineTask<Tweet>, onFinish: () -> Unit) {
+ task
+ .setCount(200)
+ .onFail { x -> world.notifyError(R.string.notice_error_get_mentions) }
+ .onDoneUI { tweets -> world.addTweetAll(tweets) }
+ .onFinishUI(onFinish)
+ .execute()
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.java
deleted file mode 100644
index 291f4cfc..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.page;
-
-import android.os.Bundle;
-import android.widget.ListView;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.entity.DirectMessage;
-import net.lacolaco.smileessence.twitter.task.Messages;
-import net.lacolaco.smileessence.twitter.task.TimelineTask;
-import net.lacolaco.smileessence.view.adapter.MessageListAdapter;
-
-public class MessagesFragment extends CustomListFragment<MessageListAdapter> {
- @Override
- protected PullToRefreshBase.Mode getRefreshMode() {
- return PullToRefreshBase.Mode.BOTH;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- MessageListAdapter adapter = new MessageListAdapter(getActivity());
- setAdapter(adapter);
-
- getWorld().addDirectMessageTimeline(this, message -> {
- adapter.add(message);
- adapter.update();
- });
-
- refresh();
- }
-
- @Override
- public void refresh() {
- runRefreshTask(new Messages.GetAllReceived(getWorld().getAccount()), () -> getAdapter().updateForce());
- runRefreshTask(new Messages.GetAllSent(getWorld().getAccount()), () -> getAdapter().updateForce());
- }
-
- @Override
- public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) {
- runRefreshTask(
- new Messages.GetAllReceived(getWorld().getAccount())
- .setSinceId(getAdapter().getTopID()),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), true);
- refreshView.onRefreshComplete();
- }); // TODO: sent?
- }
-
- @Override
- public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) {
- runRefreshTask(
- new Messages.GetAllReceived(getWorld().getAccount())
- .setMaxId(getAdapter().getLastID() - 1),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), false);
- refreshView.onRefreshComplete();
- }); // TODO: sent?
- }
-
- private void runRefreshTask(TimelineTask<DirectMessage> task, Runnable onFinish) {
- task
- .setCount(200)
- .onFail(x -> getWorld().notifyError(R.string.notice_error_get_messages))
- .onDoneUI(messages -> {
- for (DirectMessage message : messages) {
- getWorld().addDirectMessage(message);
- }
- })
- .onFinishUI(onFinish)
- .execute();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt
new file mode 100644
index 00000000..ea756d09
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt
@@ -0,0 +1,90 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.page
+
+import android.os.Bundle
+import android.widget.ListView
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.entity.DirectMessage
+import net.lacolaco.smileessence.twitter.task.Messages
+import net.lacolaco.smileessence.twitter.task.TimelineTask
+import net.lacolaco.smileessence.view.adapter.MessageListAdapter
+
+class MessagesFragment : CustomListFragment<MessageListAdapter>() {
+ override val refreshMode: PullToRefreshBase.Mode
+ get() = PullToRefreshBase.Mode.BOTH
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ adapter = MessageListAdapter(activity)
+
+ world.addDirectMessageTimeline(this) { message ->
+ adapter.add(message)
+ adapter.update()
+ }
+
+ refresh()
+ }
+
+ override fun refresh() {
+ runRefreshTask(Messages.GetAllReceived(world.account), { adapter.updateForce() })
+ runRefreshTask(Messages.GetAllSent(world.account), { adapter.updateForce() })
+ }
+
+ override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ runRefreshTask(
+ Messages.GetAllReceived(world.account)
+ .setSinceId(adapter.topID),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, true)
+ refreshView.onRefreshComplete()
+ }) // TODO: sent?
+ }
+
+ override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ runRefreshTask(
+ Messages.GetAllReceived(world.account)
+ .setMaxId(adapter.lastID - 1),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, false)
+ refreshView.onRefreshComplete()
+ }) // TODO: sent?
+ }
+
+ private fun runRefreshTask(task: TimelineTask<DirectMessage>, onFinish: () -> Unit) {
+ task
+ .setCount(200)
+ .onFail { x -> world.notifyError(R.string.notice_error_get_messages) }
+ .onDoneUI { messages ->
+ for (message in messages) {
+ world.addDirectMessage(message)
+ }
+ }
+ .onFinishUI(onFinish)
+ .execute()
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.java
deleted file mode 100644
index c1299298..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package net.lacolaco.smileessence.view.page;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.widget.Adapter;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.World;
-import net.lacolaco.smileessence.activity.MainActivity;
-
-public abstract class PageFragment<T extends Adapter> extends Fragment {
- public static final String KEY_USER_ID = "KEY_USER_ID";
- private T adapter;
- private World world;
-
- protected final T getAdapter() {
- if (adapter == null) throw new IllegalStateException("adapter is not initialized");
- return adapter;
- }
-
- protected final void setAdapter(T _adapter) {
- adapter = _adapter;
- }
-
- public abstract void refresh();
-
- protected final World getWorld() {
- if (world == null) {
- world = Application.getWorld(getArguments().getLong(KEY_USER_ID));
- }
- return world;
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt
new file mode 100644
index 00000000..596f4107
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt
@@ -0,0 +1,25 @@
+package net.lacolaco.smileessence.view.page
+
+import android.app.Fragment
+import android.os.Bundle
+import android.widget.Adapter
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.World
+import net.lacolaco.smileessence.activity.MainActivity
+
+abstract class PageFragment<T : Adapter> : Fragment() {
+ private var _adapter: T? = null
+ protected var adapter: T
+ get() = _adapter ?: throw IllegalStateException("adapter is not initialized")
+ set(value) { _adapter = value }
+
+ protected val world: World by lazy {
+ Application.getWorld(arguments.getLong(KEY_USER_ID))
+ }
+
+ abstract fun refresh()
+
+ companion object {
+ val KEY_USER_ID = "KEY_USER_ID"
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.java
deleted file mode 100644
index c8426383..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.page;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.text.Editable;
-import android.text.Spannable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.method.ArrowKeyMovementMethod;
-import android.view.*;
-import android.widget.*;
-import com.twitter.Validator;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.World;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.data.PostState;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.logging.Logger;
-import net.lacolaco.smileessence.preference.UserPreferenceHelper;
-import net.lacolaco.smileessence.twitter.task.Tweets;
-import net.lacolaco.smileessence.util.BitmapThumbnailTask;
-import net.lacolaco.smileessence.util.IntentUtils;
-import net.lacolaco.smileessence.util.SystemServiceHelper;
-import net.lacolaco.smileessence.util.UIHandler;
-import net.lacolaco.smileessence.view.Partials;
-
-import java.io.File;
-
-public class PostFragment extends PageFragment implements TextWatcher, View.OnFocusChangeListener, View.OnClickListener,
- PostState.OnPostStateChangeListener {
- // ------------------------------ FIELDS ------------------------------
-
- private EditText editText;
- private TextView textViewCount;
- private Button buttonTweet;
- private ViewGroup viewGroupReply;
- private ViewGroup viewGroupMedia;
-
- @Override
- public void refresh() {
- }
-
- // --------------------- Interface OnClickListener ---------------------
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.button_post_delete: {
- deletePost();
- break;
- }
- case R.id.button_post_media: {
- setImage();
- break;
- }
- case R.id.button_post_tweet: {
- submitPost();
- break;
- }
- case R.id.button_post_reply_delete: {
- deleteReply();
- break;
- }
- case R.id.button_post_media_delete: {
- removeImage();
- break;
- }
- case R.id.image_post_media: {
- displayImage();
- break;
- }
- }
- }
-
- // --------------------- Interface OnFocusChangeListener ---------------------
-
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus) {
- SystemServiceHelper.showIM(getActivity(), editText);
- } else {
- SystemServiceHelper.hideIM(getActivity(), editText);
- }
- }
-
- // --------------------- Interface OnPostStateChangeListener ---------------------
-
-
- @Override
- public void onPostStateChange(final PostState postState) {
- Logger.debug("onPostStateChange");
- final MainActivity activity = (MainActivity) getActivity();
- if (editText != null) {
- final int start = postState.getSelectionStart();
- final int end = postState.getSelectionEnd();
- editText.removeTextChangedListener(this);
- editText.setTextKeepState(postState.getText());
- editText.addTextChangedListener(this);
- updateTextCount(editText.getText());
- new UIHandler().postAtFrontOfQueue(() -> editText.setSelection(start, end));
- }
- if (viewGroupReply != null) {
- if (postState.getInReplyTo() != null) {
- viewGroupReply.setVisibility(View.VISIBLE);
- ImageButton imageButtonDeleteReply = (ImageButton) viewGroupReply.findViewById(R.id.button_post_reply_delete);
- imageButtonDeleteReply.setOnClickListener(this);
-
- Tweet tweet = postState.getInReplyTo();
- View header = viewGroupReply.findViewById(R.id.layout_post_reply_status);
- header = Partials.getTweetView(tweet, activity, header, true);
- header.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.transparent));
- header.setClickable(false);
- } else {
- viewGroupReply.setVisibility(View.GONE);
- }
- }
- if (viewGroupMedia != null) {
- ImageView imageViewMedia = (ImageView) viewGroupMedia.findViewById(R.id.image_post_media);
- if (TextUtils.isEmpty(postState.getMediaFilePath())) {
- viewGroupMedia.setVisibility(View.GONE);
- } else {
- viewGroupMedia.setVisibility(View.VISIBLE);
-
- }
- new BitmapThumbnailTask(postState.getMediaFilePath(), imageViewMedia).execute();
- }
- }
-
- // --------------------- Interface TextWatcher ---------------------
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- updateTextCount(s);
- }
-
- private void updateTextCount(CharSequence s) {
- Validator validator = new Validator();
- int remainingCount = 140 - validator.getTweetLength(s.toString());
- if (!TextUtils.isEmpty(getWorld().getPostState().getMediaFilePath())) {
- remainingCount -= validator.getShortUrlLength();
- }
- textViewCount.setText(String.valueOf(remainingCount));
- if (remainingCount == 140 || remainingCount < 0) {
- textViewCount.setTextColor(ContextCompat.getColor(getActivity(), R.color.red));
- } else {
- textViewCount.setTextAppearance(getActivity(), android.R.style.TextAppearance_Widget_TextView);
- }
- setStateFromView();
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- }
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Logger.debug("onCreate");
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- SystemServiceHelper.showIM(getActivity(), editText);
- }
-
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- Logger.debug("onCreateView");
- getWorld().getPostState().setListener(this);
- View v = inflater.inflate(R.layout.fragment_post, null);
- buttonTweet = getTweetButton(v);
- buttonTweet.setOnClickListener(this);
- editText = getEditText(v);
- textViewCount = getCountTextView(v);
- int textSize = UserPreferenceHelper.getInstance().getTextSize();
- editText.addTextChangedListener(this);
- editText.setOnFocusChangeListener(this);
- editText.setTextSize(textSize + 4);
- editText.setMovementMethod(new ArrowKeyMovementMethod() {
- @Override
- protected boolean right(@NonNull TextView widget, Spannable buffer) {
- //Don't back to Home
- return widget.getSelectionEnd() == widget.length() || super.right(widget, buffer);
- }
- });
- ImageButton imageButtonDeleteText = (ImageButton) v.findViewById(R.id.button_post_delete);
- imageButtonDeleteText.setOnClickListener(this);
- ImageButton imageButtonMedia = (ImageButton) v.findViewById(R.id.button_post_media);
- imageButtonMedia.setOnClickListener(this);
- //Reply view
- viewGroupReply = getReplyViewGroup(v);
- ImageButton imageButtonDeleteReply = (ImageButton) viewGroupReply.findViewById(R.id.button_post_reply_delete);
- imageButtonDeleteReply.setOnClickListener(this);
- //Media view
- viewGroupMedia = getMediaViewGroup(v);
- ImageView imageViewMedia = (ImageView) viewGroupMedia.findViewById(R.id.image_post_media);
- ImageButton imageButtonDeleteMedia = (ImageButton) viewGroupMedia.findViewById(R.id.button_post_media_delete);
- imageViewMedia.setOnClickListener(this);
- imageButtonDeleteMedia.setOnClickListener(this);
- editText.requestFocus();
- return v;
- }
-
- @Override
- public void onDestroyView() {
- Logger.debug("onDestroyView");
- super.onDestroyView();
- setStateFromView();
- getWorld().getPostState().removeListener();
- }
-
- @Override
- public void onViewStateRestored(Bundle savedInstanceState) {
- Logger.debug("onViewStateRestored");
- super.onViewStateRestored(savedInstanceState);
- PostState state = getWorld().getPostState();
- onPostStateChange(state);
- }
-
- private void deletePost() {
- editText.setText("");
- getWorld().getPostState().beginTransaction().setText("").setCursor(0).commit();
- deleteReply();
- }
-
- private void deleteReply() {
- viewGroupReply.setVisibility(View.GONE);
- getWorld().getPostState().beginTransaction().setInReplyTo(null).commit();
- }
-
- private void displayImage() {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_VIEW);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- intent.setDataAndType(Uri.fromFile(new File(getWorld().getPostState().getMediaFilePath())), "image/*");
- IntentUtils.startActivityIfFound(getActivity(), intent);
- }
-
- private TextView getCountTextView(View v) {
- return (TextView) v.findViewById(R.id.post_text_count);
- }
-
- private EditText getEditText(View v) {
- return (EditText) v.findViewById(R.id.post_edit_text);
- }
-
- private ViewGroup getMediaViewGroup(View v) {
- return (ViewGroup) v.findViewById(R.id.post_media_parent);
- }
-
- private ViewGroup getReplyViewGroup(View v) {
- return (ViewGroup) v.findViewById(R.id.post_inreplyto_parent);
- }
-
- private Button getTweetButton(View v) {
- return (Button) v.findViewById(R.id.button_post_tweet);
- }
-
- private void removeImage() {
- SystemServiceHelper.hideIM(getActivity(), editText);
- viewGroupMedia.setVisibility(View.GONE);
- ((ImageView) viewGroupMedia.findViewById(R.id.image_post_media)).setImageBitmap(null);
- getWorld().getPostState().beginTransaction().setMediaFilePath("").commit();
- }
-
- private void setImage() {
- setStateFromView();
- SystemServiceHelper.hideIM(getActivity(), editText);
-
- Intent intent = new Intent(Intent.ACTION_PICK);
- intent.setType("image/*");
- IntentUtils.startActivityForResultIfFound(getActivity(), intent, MainActivity.REQUEST_GET_PICTURE_FROM_GALLERY);
- }
-
- private void setStateFromView() {
- PostState state = getWorld().getPostState();
- state.removeListener();
- state.beginTransaction()
- .setText(editText.getText().toString())
- .setSelection(editText.getSelectionStart(), editText.getSelectionEnd())
- .commit();
- state.setListener(this);
- }
-
- private void submitPost() {
- SystemServiceHelper.hideIM(getActivity(), editText);
- setStateFromView();
- PostState state = getWorld().getPostState();
- MainActivity mainActivity = (MainActivity) getActivity();
- boolean resizeFlag = UserPreferenceHelper.getInstance().get(R.string.key_setting_resize_post_image, false);
- new Tweets.CreateTask(getWorld().getAccount(), state.toStatusUpdate(), state.getMediaFilePath(), resizeFlag)
- .onDoneUI(t -> {
- getWorld().notify(R.string.notice_tweet_succeeded);
- getWorld().getPostState().beginTransaction().clear().commit();
- })
- .onFail(e -> getWorld().notifyError(R.string.notice_tweet_failed, e))
- .execute();
- mainActivity.openHomePage();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt
new file mode 100644
index 00000000..8afeadd1
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt
@@ -0,0 +1,304 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.page
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.support.v4.content.ContextCompat
+import android.text.Editable
+import android.text.Spannable
+import android.text.TextUtils
+import android.text.TextWatcher
+import android.text.method.ArrowKeyMovementMethod
+import android.view.*
+import android.widget.*
+import com.twitter.Validator
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.World
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.data.PostState
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.logging.Logger
+import net.lacolaco.smileessence.preference.UserPreferenceHelper
+import net.lacolaco.smileessence.twitter.task.Tweets
+import net.lacolaco.smileessence.util.BitmapThumbnailTask
+import net.lacolaco.smileessence.util.IntentUtils
+import net.lacolaco.smileessence.util.SystemServiceHelper
+import net.lacolaco.smileessence.util.UIHandler
+import net.lacolaco.smileessence.view.Partials
+
+import java.io.File
+
+class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChangeListener, View.OnClickListener, PostState.OnPostStateChangeListener {
+ private var editText: EditText? = null
+ private var textViewCount: TextView? = null
+ private var buttonTweet: Button? = null
+ private var viewGroupReply: ViewGroup? = null
+ private var viewGroupMedia: ViewGroup? = null
+
+ override fun refresh() {}
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.button_post_delete -> {
+ deletePost()
+ }
+ R.id.button_post_media -> {
+ setImage()
+ }
+ R.id.button_post_tweet -> {
+ submitPost()
+ }
+ R.id.button_post_reply_delete -> {
+ deleteReply()
+ }
+ R.id.button_post_media_delete -> {
+ removeImage()
+ }
+ R.id.image_post_media -> {
+ displayImage()
+ }
+ }
+ }
+
+ // --------------------- Interface OnFocusChangeListener ---------------------
+
+ override fun onFocusChange(v: View, hasFocus: Boolean) {
+ if (hasFocus) {
+ SystemServiceHelper.showIM(activity, editText)
+ } else {
+ SystemServiceHelper.hideIM(activity, editText)
+ }
+ }
+
+ // --------------------- Interface OnPostStateChangeListener ---------------------
+
+
+ override fun onPostStateChange(postState: PostState) {
+ Logger.debug("onPostStateChange")
+ val activity = activity as MainActivity
+ if (editText != null) {
+ val start = postState.selectionStart
+ val end = postState.selectionEnd
+ editText!!.removeTextChangedListener(this)
+ editText!!.setTextKeepState(postState.text)
+ editText!!.addTextChangedListener(this)
+ updateTextCount(editText!!.text)
+ UIHandler().postAtFrontOfQueue { editText!!.setSelection(start, end) }
+ }
+ if (viewGroupReply != null) {
+ if (postState.inReplyTo != null) {
+ viewGroupReply!!.visibility = View.VISIBLE
+ val imageButtonDeleteReply = viewGroupReply!!.findViewById(R.id.button_post_reply_delete) as ImageButton
+ imageButtonDeleteReply.setOnClickListener(this)
+
+ val tweet = postState.inReplyTo
+ var header = viewGroupReply!!.findViewById(R.id.layout_post_reply_status)
+ header = Partials.getTweetView(tweet!!, activity, header, true)
+ header.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.transparent))
+ header.isClickable = false
+ } else {
+ viewGroupReply!!.visibility = View.GONE
+ }
+ }
+ if (viewGroupMedia != null) {
+ val imageViewMedia = viewGroupMedia!!.findViewById(R.id.image_post_media) as ImageView
+ if (TextUtils.isEmpty(postState.mediaFilePath)) {
+ viewGroupMedia!!.visibility = View.GONE
+ } else {
+ viewGroupMedia!!.visibility = View.VISIBLE
+
+ }
+ BitmapThumbnailTask(postState.mediaFilePath, imageViewMedia).execute()
+ }
+ }
+
+ // --------------------- Interface TextWatcher ---------------------
+
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+ updateTextCount(s)
+ }
+
+ private fun updateTextCount(s: CharSequence) {
+ val validator = Validator()
+ var remainingCount = 140 - validator.getTweetLength(s.toString())
+ if (!TextUtils.isEmpty(world.postState.mediaFilePath)) {
+ remainingCount -= validator.shortUrlLength
+ }
+ textViewCount!!.text = remainingCount.toString()
+ if (remainingCount == 140 || remainingCount < 0) {
+ textViewCount!!.setTextColor(ContextCompat.getColor(activity, R.color.red))
+ } else {
+ textViewCount!!.setTextAppearance(activity, android.R.style.TextAppearance_Widget_TextView)
+ }
+ setStateFromView()
+ }
+
+ override fun afterTextChanged(s: Editable) {}
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ SystemServiceHelper.showIM(activity, editText)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
+ Logger.debug("onCreateView")
+ setHasOptionsMenu(true)
+ world.postState.setListener(this)
+ val v = inflater.inflate(R.layout.fragment_post, container, false)
+ buttonTweet = getTweetButton(v)
+ buttonTweet!!.setOnClickListener(this)
+ editText = getEditText(v)
+ textViewCount = getCountTextView(v)
+ val textSize = UserPreferenceHelper.instance.textSize
+ editText!!.addTextChangedListener(this)
+ editText!!.onFocusChangeListener = this
+ editText!!.textSize = (textSize + 4).toFloat()
+ editText!!.movementMethod = object : ArrowKeyMovementMethod() {
+ override fun right(widget: TextView, buffer: Spannable): Boolean {
+ //Don't back to Home
+ return widget.selectionEnd == widget.length() || super.right(widget, buffer)
+ }
+ }
+ val imageButtonDeleteText = v.findViewById(R.id.button_post_delete) as ImageButton
+ imageButtonDeleteText.setOnClickListener(this)
+ val imageButtonMedia = v.findViewById(R.id.button_post_media) as ImageButton
+ imageButtonMedia.setOnClickListener(this)
+ //Reply view
+ viewGroupReply = getReplyViewGroup(v)
+ val imageButtonDeleteReply = viewGroupReply!!.findViewById(R.id.button_post_reply_delete) as ImageButton
+ imageButtonDeleteReply.setOnClickListener(this)
+ //Media view
+ viewGroupMedia = getMediaViewGroup(v)
+ val imageViewMedia = viewGroupMedia!!.findViewById(R.id.image_post_media) as ImageView
+ val imageButtonDeleteMedia = viewGroupMedia!!.findViewById(R.id.button_post_media_delete) as ImageButton
+ imageViewMedia.setOnClickListener(this)
+ imageButtonDeleteMedia.setOnClickListener(this)
+ editText!!.requestFocus()
+ return v
+ }
+
+ override fun onDestroyView() {
+ Logger.debug("onDestroyView")
+ super.onDestroyView()
+ setStateFromView()
+ world.postState.removeListener()
+ }
+
+ override fun onViewStateRestored(savedInstanceState: Bundle?) {
+ Logger.debug("onViewStateRestored")
+ super.onViewStateRestored(savedInstanceState)
+ val state = world.postState
+ onPostStateChange(state)
+ }
+
+ private fun deletePost() {
+ editText!!.setText("")
+ world.postState.beginTransaction().setText("").setCursor(0).commit()
+ deleteReply()
+ }
+
+ private fun deleteReply() {
+ viewGroupReply!!.visibility = View.GONE
+ world.postState.beginTransaction().setInReplyTo(null).commit()
+ }
+
+ private fun displayImage() {
+ val intent = Intent()
+ intent.action = Intent.ACTION_VIEW
+ intent.addCategory(Intent.CATEGORY_DEFAULT)
+ intent.setDataAndType(Uri.fromFile(File(world.postState.mediaFilePath)), "image/*")
+ IntentUtils.startActivityIfFound(activity, intent)
+ }
+
+ private fun getCountTextView(v: View): TextView {
+ return v.findViewById(R.id.post_text_count) as TextView
+ }
+
+ private fun getEditText(v: View): EditText {
+ return v.findViewById(R.id.post_edit_text) as EditText
+ }
+
+ private fun getMediaViewGroup(v: View): ViewGroup {
+ return v.findViewById(R.id.post_media_parent) as ViewGroup
+ }
+
+ private fun getReplyViewGroup(v: View): ViewGroup {
+ return v.findViewById(R.id.post_inreplyto_parent) as ViewGroup
+ }
+
+ private fun getTweetButton(v: View): Button {
+ return v.findViewById(R.id.button_post_tweet) as Button
+ }
+
+ private fun removeImage() {
+ SystemServiceHelper.hideIM(activity, editText)
+ viewGroupMedia!!.visibility = View.GONE
+ (viewGroupMedia!!.findViewById(R.id.image_post_media) as ImageView).setImageBitmap(null)
+ world.postState.beginTransaction().setMediaFilePath("").commit()
+ }
+
+ private fun setImage() {
+ setStateFromView()
+ SystemServiceHelper.hideIM(activity, editText)
+
+ val intent = Intent(Intent.ACTION_PICK)
+ intent.type = "image/*"
+ IntentUtils.startActivityForResultIfFound(activity, intent, MainActivity.REQUEST_GET_PICTURE_FROM_GALLERY)
+ }
+
+ private fun setStateFromView() {
+ val state = world.postState
+ state.removeListener()
+ state.beginTransaction()
+ .setText(editText!!.text.toString())
+ .setSelection(editText!!.selectionStart, editText!!.selectionEnd)
+ .commit()
+ state.setListener(this)
+ }
+
+ private fun submitPost() {
+ SystemServiceHelper.hideIM(activity, editText)
+ setStateFromView()
+ val state = world.postState
+ val mainActivity = activity as MainActivity
+ val resizeFlag = UserPreferenceHelper.instance.get(R.string.key_setting_resize_post_image, false)
+ Tweets.CreateTask(world.account, state.toStatusUpdate(), state.mediaFilePath, resizeFlag)
+ .onDoneUI { t ->
+ world.notify(R.string.notice_tweet_succeeded)
+ world.postState.beginTransaction().clear().commit()
+ }
+ .onFail { e -> world.notifyError(R.string.notice_tweet_failed, e) }
+ .execute()
+ mainActivity.openHomePage()
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.java
deleted file mode 100644
index 84d10c21..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.page;
-
-import android.app.AlertDialog;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.text.Spannable;
-import android.text.TextUtils;
-import android.text.method.ArrowKeyMovementMethod;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.ListView;
-import android.widget.TextView;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import com.handmark.pulltorefresh.library.PullToRefreshListView;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.entity.SavedSearch;
-import net.lacolaco.smileessence.preference.InternalPreferenceHelper;
-import net.lacolaco.smileessence.twitter.task.Searches;
-import net.lacolaco.smileessence.util.ListUtils;
-import net.lacolaco.smileessence.util.SystemServiceHelper;
-import net.lacolaco.smileessence.util.UIHandler;
-import net.lacolaco.smileessence.view.adapter.TimelineAdapter;
-import net.lacolaco.smileessence.view.dialog.ConfirmDialogFragment;
-import twitter4j.Query;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SearchFragment extends CustomListFragment<TimelineAdapter> implements View.OnClickListener, View.OnLongClickListener,
- View.OnFocusChangeListener {
-
- // ------------------------------ FIELDS ------------------------------
-
- private String queryString;
- private TimelineAdapter adapter;
- private EditText editText;
-
- // --------------------- GETTER / SETTER METHODS ---------------------
-
- @Override
- protected PullToRefreshBase.Mode getRefreshMode() {
- return PullToRefreshBase.Mode.BOTH;
- }
-
- // ------------------------ INTERFACE METHODS ------------------------
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
-
- queryString = InternalPreferenceHelper.getInstance().get(R.string.key_last_used_search_query, "");
- android.app.Activity activity = getActivity();
- adapter = new TimelineAdapter(activity);
- setAdapter(adapter);
-
- refresh();
- }
-
- @Override
- public void refresh() { //TODO
- if (!TextUtils.isEmpty(queryString)) {
- startSearch(queryString);
- }
- }
-
- // --------------------- Interface OnClickListener ---------------------
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.button_search_queries: {
- openSearchQueryDialog();
- break;
- }
- case R.id.button_search_execute: {
- search();
- break;
- }
- case R.id.button_search_save: {
- saveQuery();
- }
- }
- }
-
- @Override
- public boolean onLongClick(View v) {
- switch (v.getId()) {
- case R.id.button_search_save: {
- String text = editText.getText().toString();
- for (SavedSearch ss : getWorld().getSavedSearches()) {
- if (ss.getQuery().equals(text)) {
- ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_delete_query), () -> new Searches.DestroySavedSearchTask(getWorld().getAccount(), ss.getId())
- .onDoneUI(x -> {
- getWorld().notify(R.string.notice_search_query_deleted);
- getWorld().refreshSavedSearches();
- })
- .onFailUI(x -> getWorld().notify("unable to delete search query"))
- .execute(), false);
- break;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // --------------------- Interface OnFocusChangeListener ---------------------
-
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (!hasFocus) {
- SystemServiceHelper.hideIM(getActivity(), editText);
- }
- }
-
- // --------------------- Interface OnRefreshListener2 ---------------------
-
- @Override
- public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) {
- if (TextUtils.isEmpty(queryString)) {
- new UIHandler().post(() -> {
- notifyTextEmpty();
- refreshView.onRefreshComplete();
- });
- return;
- }
- final Query query = new Query();
- query.setQuery(queryString);
- query.setCount(200);
- query.setResultType(Query.RECENT);
- if (adapter.getCount() > 0) {
- query.setSinceId(adapter.getTopID());
- }
- runRefreshTask(query, () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), true);
- refreshView.onRefreshComplete();
- });
- }
-
- @Override
- public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) {
- if (TextUtils.isEmpty(queryString)) {
- new UIHandler().post(() -> {
- notifyTextEmpty();
- refreshView.onRefreshComplete();
- });
- return;
- }
- final Query query = new Query();
- query.setQuery(queryString);
- query.setCount(200);
- query.setResultType(Query.RECENT);
- if (adapter.getCount() > 0) {
- query.setMaxId(adapter.getLastID() - 1);
- }
- runRefreshTask(query, () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), false);
- refreshView.onRefreshComplete();
- });
- }
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- protected PullToRefreshListView getListView(View page) {
- return (PullToRefreshListView) page.findViewById(R.id.listview_search);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View page = inflater.inflate(R.layout.fragment_search, container, false);
- PullToRefreshListView listView = getListView(page);
- listView.setAdapter(adapter);
- listView.setOnScrollListener(this);
- listView.setOnRefreshListener(this);
- listView.setMode(getRefreshMode());
- ImageButton buttonQueries = getQueriesButton(page);
- buttonQueries.setOnClickListener(this);
- ImageButton buttonExecute = getExecuteButton(page);
- buttonExecute.setOnClickListener(this);
- ImageButton buttonSave = getSaveButton(page);
- buttonSave.setOnClickListener(this);
- editText = getEditText(page);
- editText.setOnFocusChangeListener(this);
- editText.setText(queryString);
- editText.setOnEditorActionListener((textView, i, keyEvent) -> {
- if (i == EditorInfo.IME_ACTION_SEARCH ||
- keyEvent != null &&
- keyEvent.getAction() == KeyEvent.ACTION_DOWN &&
- keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
- search();
- }
- return true;
- });
- editText.setMovementMethod(new ArrowKeyMovementMethod() {
- @Override
- protected boolean right(@NonNull TextView widget, Spannable buffer) {
- //Don't move page
- return widget.getSelectionEnd() == widget.length() || super.right(widget, buffer);
- }
-
- @Override
- protected boolean left(@NonNull TextView widget, Spannable buffer) {
- //Don't move page
- return widget.getSelectionStart() == 0 || super.left(widget, buffer);
- }
- });
- return page;
- }
-
- private EditText getEditText(View page) {
- return (EditText) page.findViewById(R.id.edittext_search);
- }
-
- private ImageButton getExecuteButton(View page) {
- return (ImageButton) page.findViewById(R.id.button_search_execute);
- }
-
- private ImageButton getQueriesButton(View page) {
- return (ImageButton) page.findViewById(R.id.button_search_queries);
- }
-
- private ImageButton getSaveButton(View page) {
- return (ImageButton) page.findViewById(R.id.button_search_save);
- }
-
- private void notifyTextEmpty() {
- getWorld().notifyError(R.string.notice_search_text_empty);
- }
-
- private void openSearchQueryDialog() {
- List<SavedSearch> sss = new ArrayList<>(getWorld().getSavedSearches());
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setItems(ListUtils.map(sss, SavedSearch::getQuery).toArray(new String[]{}), (dialog, which) -> {
- SavedSearch ss = sss.get(which);
- ((MainActivity) getActivity()).openSearchPage(ss.getQuery());
- });
- AlertDialog dialog = builder.create();
- dialog.show();
- }
-
- private void saveQuery() {
- String text = editText.getText().toString();
- if (TextUtils.isEmpty(text)) {
- getWorld().notifyError(R.string.notice_query_is_empty);
- } else {
- new Searches.CreateSavedSearchTask(getWorld().getAccount(), text).onDoneUI(cb -> {
- getWorld().notify(R.string.notice_query_saved);
- getWorld().refreshSavedSearches();
- }).onFailUI(ex -> getWorld().notifyError("Query is not saved")).execute();
- }
- }
-
- private void search() {
- if (editText != null) {
- String text = editText.getText().toString();
- if (TextUtils.isEmpty(text)) {
- getWorld().notifyError(R.string.notice_query_is_empty);
- } else {
- startSearch(text);
- SystemServiceHelper.hideIM(getActivity(), editText);
- }
- }
- }
-
- public void startSearch(final String queryString) {
- InternalPreferenceHelper.getInstance().set(R.string.key_last_used_search_query, queryString);
- if (editText != null)
- editText.setText(queryString);
- this.queryString = queryString;
- adapter.clear();
- adapter.updateForce();
- if (!TextUtils.isEmpty(queryString)) {
- final Query query = new Query();
- query.setQuery(queryString);
- query.setCount(200);
- query.setResultType(Query.RECENT);
- runRefreshTask(query, adapter::updateForce);
- }
- }
-
- private void runRefreshTask(Query query, Runnable onFinish) {
- new Searches.SearchTask(getWorld().getAccount(), query)
- .onFail(x -> getWorld().notifyError(R.string.notice_error_search))
- .onDoneUI(tweets -> adapter.addAll(ListUtils.filter(tweets, t -> !t.isRetweet())))
- .onFinishUI(onFinish)
- .execute();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt
new file mode 100644
index 00000000..de06a133
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt
@@ -0,0 +1,299 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.page
+
+import android.app.AlertDialog
+import android.os.Bundle
+import android.text.Spannable
+import android.text.TextUtils
+import android.text.method.ArrowKeyMovementMethod
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.inputmethod.EditorInfo
+import android.widget.EditText
+import android.widget.ImageButton
+import android.widget.ListView
+import android.widget.TextView
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import com.handmark.pulltorefresh.library.PullToRefreshListView
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.preference.InternalPreferenceHelper
+import net.lacolaco.smileessence.twitter.task.Searches
+import net.lacolaco.smileessence.util.SystemServiceHelper
+import net.lacolaco.smileessence.util.UIHandler
+import net.lacolaco.smileessence.view.adapter.TimelineAdapter
+import net.lacolaco.smileessence.view.dialog.ConfirmDialogFragment
+import twitter4j.Query
+
+import java.util.ArrayList
+
+class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListener, View.OnLongClickListener, View.OnFocusChangeListener {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private lateinit var queryString: String
+ private var editText: EditText? = null
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ override val refreshMode: PullToRefreshBase.Mode
+ get() = PullToRefreshBase.Mode.BOTH
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setHasOptionsMenu(true)
+
+ queryString = InternalPreferenceHelper.instance.get(R.string.key_last_used_search_query, "")
+ adapter = TimelineAdapter(activity)
+
+ refresh()
+ }
+
+ override fun refresh() { //TODO
+ if (!TextUtils.isEmpty(queryString)) {
+ startSearch(queryString)
+ }
+ }
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.button_search_queries -> {
+ openSearchQueryDialog()
+ }
+ R.id.button_search_execute -> {
+ search()
+ }
+ R.id.button_search_save -> {
+ saveQuery()
+ }
+ }
+ }
+
+ override fun onLongClick(v: View): Boolean {
+ when (v.id) {
+ R.id.button_search_save -> {
+ val text = editText!!.text.toString()
+ for (ss in world.savedSearches.values) {
+ if (ss.query == text) {
+ ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_delete_query), {
+ Searches.DestroySavedSearchTask(world.account, ss.id)
+ .onDoneUI { x ->
+ world.notify(R.string.notice_search_query_deleted)
+ world.refreshSavedSearches()
+ }
+ .onFailUI { x -> world.notify("unable to delete search query") }
+ .execute()
+ }, false)
+ break
+ }
+ }
+ return true
+ }
+ }
+ return false
+ }
+
+ // --------------------- Interface OnFocusChangeListener ---------------------
+
+ override fun onFocusChange(v: View, hasFocus: Boolean) {
+ if (!hasFocus) {
+ SystemServiceHelper.hideIM(activity, editText)
+ }
+ }
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ if (TextUtils.isEmpty(queryString)) {
+ UIHandler().post {
+ notifyTextEmpty()
+ refreshView.onRefreshComplete()
+ }
+ return
+ }
+ val query = Query()
+ query.query = queryString
+ query.count = 200
+ query.resultType = Query.RECENT
+ if (adapter.count > 0) {
+ query.sinceId = adapter.topID
+ }
+ runRefreshTask(query, {
+ updateListViewWithNotice(refreshView.refreshableView, true)
+ refreshView.onRefreshComplete()
+ })
+ }
+
+ override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ if (TextUtils.isEmpty(queryString)) {
+ UIHandler().post {
+ notifyTextEmpty()
+ refreshView.onRefreshComplete()
+ }
+ return
+ }
+ val query = Query()
+ query.query = queryString
+ query.count = 200
+ query.resultType = Query.RECENT
+ if (adapter.count > 0) {
+ query.maxId = adapter.lastID - 1
+ }
+ runRefreshTask(query, {
+ updateListViewWithNotice(refreshView.refreshableView, false)
+ refreshView.onRefreshComplete()
+ })
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun getListView(page: View): PullToRefreshListView {
+ return page.findViewById(R.id.listview_search) as PullToRefreshListView
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View {
+ val page = inflater.inflate(R.layout.fragment_search, container, false)
+ val listView = getListView(page)
+ listView.setAdapter(adapter)
+ listView.setOnScrollListener(this)
+ listView.setOnRefreshListener(this)
+ listView.mode = refreshMode
+ val buttonQueries = getQueriesButton(page)
+ buttonQueries.setOnClickListener(this)
+ val buttonExecute = getExecuteButton(page)
+ buttonExecute.setOnClickListener(this)
+ val buttonSave = getSaveButton(page)
+ buttonSave.setOnClickListener(this)
+ editText = getEditText(page)
+ editText!!.onFocusChangeListener = this
+ editText!!.setText(queryString)
+ editText!!.setOnEditorActionListener { textView, i, keyEvent ->
+ if (i == EditorInfo.IME_ACTION_SEARCH || keyEvent != null &&
+ keyEvent.action == KeyEvent.ACTION_DOWN &&
+ keyEvent.keyCode == KeyEvent.KEYCODE_ENTER) {
+ search()
+ }
+ true
+ }
+ editText!!.movementMethod = object : ArrowKeyMovementMethod() {
+ override fun right(widget: TextView, buffer: Spannable): Boolean {
+ //Don't move page
+ return widget.selectionEnd == widget.length() || super.right(widget, buffer)
+ }
+
+ override fun left(widget: TextView, buffer: Spannable): Boolean {
+ //Don't move page
+ return widget.selectionStart == 0 || super.left(widget, buffer)
+ }
+ }
+ return page
+ }
+
+ private fun getEditText(page: View): EditText {
+ return page.findViewById(R.id.edittext_search) as EditText
+ }
+
+ private fun getExecuteButton(page: View): ImageButton {
+ return page.findViewById(R.id.button_search_execute) as ImageButton
+ }
+
+ private fun getQueriesButton(page: View): ImageButton {
+ return page.findViewById(R.id.button_search_queries) as ImageButton
+ }
+
+ private fun getSaveButton(page: View): ImageButton {
+ return page.findViewById(R.id.button_search_save) as ImageButton
+ }
+
+ private fun notifyTextEmpty() {
+ world.notifyError(R.string.notice_search_text_empty)
+ }
+
+ private fun openSearchQueryDialog() {
+ val sss = ArrayList(world.savedSearches.values)
+ val builder = AlertDialog.Builder(activity)
+ builder.setItems(sss.map { it.query }.toTypedArray()) { dialog, which ->
+ val ss = sss[which]
+ (activity as MainActivity).openSearchPage(ss.query)
+ }
+ val dialog = builder.create()
+ dialog.show()
+ }
+
+ private fun saveQuery() {
+ val text = editText!!.text.toString()
+ if (TextUtils.isEmpty(text)) {
+ world.notifyError(R.string.notice_query_is_empty)
+ } else {
+ Searches.CreateSavedSearchTask(world.account, text).onDoneUI { cb ->
+ world.notify(R.string.notice_query_saved)
+ world.refreshSavedSearches()
+ }.onFailUI { ex -> world.notifyError("Query is not saved") }.execute()
+ }
+ }
+
+ private fun search() {
+ if (editText != null) {
+ val text = editText!!.text.toString()
+ if (TextUtils.isEmpty(text)) {
+ world.notifyError(R.string.notice_query_is_empty)
+ } else {
+ startSearch(text)
+ SystemServiceHelper.hideIM(activity, editText)
+ }
+ }
+ }
+
+ fun startSearch(queryString: String) {
+ InternalPreferenceHelper.instance.set(R.string.key_last_used_search_query, queryString)
+ if (editText != null)
+ editText!!.setText(queryString)
+ this.queryString = queryString
+ adapter.clear()
+ adapter.updateForce()
+ if (!TextUtils.isEmpty(queryString)) {
+ val query = Query()
+ query.query = queryString
+ query.count = 200
+ query.resultType = Query.RECENT
+ runRefreshTask(query) { adapter.updateForce() }
+ }
+ }
+
+ private fun runRefreshTask(query: Query, onFinish: () -> Unit) {
+ Searches.SearchTask(world.account, query)
+ .onFail { x -> world.notifyError(R.string.notice_error_search) }
+ .onDoneUI { tweets -> adapter.addAll(tweets.filter { t -> !t.isRetweet }) }
+ .onFinishUI(onFinish)
+ .execute()
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.java
deleted file mode 100644
index 3d19c5d6..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2012-2014 lacolaco.net
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.lacolaco.smileessence.view.page;
-
-import android.app.AlertDialog;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-import android.widget.ListView;
-import android.widget.TextView;
-import com.handmark.pulltorefresh.library.PullToRefreshBase;
-import com.handmark.pulltorefresh.library.PullToRefreshListView;
-import net.lacolaco.smileessence.Application;
-import net.lacolaco.smileessence.R;
-import net.lacolaco.smileessence.activity.MainActivity;
-import net.lacolaco.smileessence.entity.Tweet;
-import net.lacolaco.smileessence.preference.InternalPreferenceHelper;
-import net.lacolaco.smileessence.twitter.task.TimelineTask;
-import net.lacolaco.smileessence.twitter.task.Timelines;
-import net.lacolaco.smileessence.util.UIHandler;
-import net.lacolaco.smileessence.view.adapter.TimelineAdapter;
-
-public class UserListFragment extends CustomListFragment<TimelineAdapter> implements View.OnClickListener {
- private TextView textListName;
- private String listFullName;
-
- @Override
- protected PullToRefreshBase.Mode getRefreshMode() {
- return PullToRefreshBase.Mode.BOTH;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- TimelineAdapter adapter = new TimelineAdapter(getActivity());
- setAdapter(adapter);
-
- refresh();
- }
-
- @Override
- public void refresh() {//TODO
- String lastUserList = InternalPreferenceHelper.getInstance().get(R.string.key_last_used_user_list, "");
- if (!TextUtils.isEmpty(lastUserList)) {
- startUserList(lastUserList);
- }
- }
-
- @Override
- public void onClick(View v) {
- int id = v.getId();
- switch (id) {
- case R.id.button_userlist_lists: {
- openUserListsDialog();
- break;
- }
- }
- }
-
- @Override
- public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) {
- if (listFullName == null) {
- new UIHandler().post(() -> {
- notifyTextEmpty();
- refreshView.onRefreshComplete();
- });
- return;
- }
- runRefreshTask(
- new Timelines.UserListStatusesTask(getWorld().getAccount(), listFullName)
- .setSinceId(getAdapter().getTopID()),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), true);
- refreshView.onRefreshComplete();
- });
- }
-
- @Override
- public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) {
- if (listFullName == null) {
- new UIHandler().post(() -> {
- notifyTextEmpty();
- refreshView.onRefreshComplete();
- });
- return;
- }
- runRefreshTask(
- new Timelines.UserListStatusesTask(getWorld().getAccount(), listFullName)
- .setMaxId(getAdapter().getLastID() - 1),
- () -> {
- updateListViewWithNotice(refreshView.getRefreshableView(), false);
- refreshView.onRefreshComplete();
- });
- }
-
- // ------------------------ OVERRIDE METHODS ------------------------
-
- @Override
- protected PullToRefreshListView getListView(View page) {
- return (PullToRefreshListView) page.findViewById(R.id.listview_userlist);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View page = inflater.inflate(R.layout.fragment_userlist, container, false);
- PullToRefreshListView listView = getListView(page);
- TimelineAdapter adapter = getAdapter();
- listView.setAdapter(adapter);
- listView.setOnScrollListener(this);
- listView.setOnRefreshListener(this);
- listView.setMode(getRefreshMode());
- ImageButton buttonUserLists = getUserListsButton(page);
- buttonUserLists.setOnClickListener(this);
- textListName = getTextListName(page);
- textListName.setText(listFullName != null ? listFullName : "<none>");
- return page;
- }
-
- private TextView getTextListName(View page) {
- return (TextView) page.findViewById(R.id.textview_userlist_name);
- }
-
- private ImageButton getUserListsButton(View page) {
- return (ImageButton) page.findViewById(R.id.button_userlist_lists);
- }
-
- private void notifyTextEmpty() {
- getWorld().notifyError(R.string.notice_userlist_not_selected);
- }
-
- private void openUserListsDialog() {
- final String[] ary = getWorld().getListSubscriptions().toArray(new String[]{});
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle(R.string.dialog_title_select_userlist)
- .setItems(ary, (dialog, which) -> {
- MainActivity activity = (MainActivity) getActivity();
- activity.openUserListPage(ary[which]);
- textListName.setText(ary[which]);
- });
- AlertDialog dialog = builder.create();
- dialog.show();
- }
-
- public void startUserList(String listFullName) {
- InternalPreferenceHelper.getInstance().set(R.string.key_last_used_user_list, listFullName);
- final TimelineAdapter adapter = getAdapter();
- this.listFullName = listFullName;
- adapter.clear();
- adapter.updateForce();
- runRefreshTask(
- new Timelines.UserListStatusesTask(getWorld().getAccount(), listFullName),
- adapter::updateForce);
- }
-
- private void runRefreshTask(TimelineTask<Tweet> task, Runnable onFinish) {
- final TimelineAdapter adapter = getAdapter();
- task
- .setCount(200)
- .onFail(x -> getWorld().notifyError(R.string.notice_error_get_list))
- .onDoneUI(tweets -> {
- getWorld().addTweetAll(tweets);
- adapter.addAll(tweets);
- })
- .onFinishUI(onFinish)
- .execute();
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt
new file mode 100644
index 00000000..3fb7ef49
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt
@@ -0,0 +1,179 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.page
+
+import android.app.AlertDialog
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.ListView
+import android.widget.TextView
+import com.handmark.pulltorefresh.library.PullToRefreshBase
+import com.handmark.pulltorefresh.library.PullToRefreshListView
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.preference.InternalPreferenceHelper
+import net.lacolaco.smileessence.twitter.task.TimelineTask
+import net.lacolaco.smileessence.twitter.task.Timelines
+import net.lacolaco.smileessence.util.UIHandler
+import net.lacolaco.smileessence.view.adapter.TimelineAdapter
+
+class UserListFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListener {
+ private var textListName: TextView? = null
+ private var listFullName: String? = null
+
+ override val refreshMode: PullToRefreshBase.Mode
+ get() = PullToRefreshBase.Mode.BOTH
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ adapter = TimelineAdapter(activity)
+
+ refresh()
+ }
+
+ override fun refresh() {//TODO
+ val lastUserList = InternalPreferenceHelper.instance.get(R.string.key_last_used_user_list, "")
+ if (!TextUtils.isEmpty(lastUserList)) {
+ startUserList(lastUserList)
+ }
+ }
+
+ override fun onClick(v: View) {
+ val id = v.id
+ when (id) {
+ R.id.button_userlist_lists -> {
+ openUserListsDialog()
+ }
+ }
+ }
+
+ override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ if (listFullName == null) {
+ UIHandler().post {
+ notifyTextEmpty()
+ refreshView.onRefreshComplete()
+ }
+ return
+ }
+ runRefreshTask(
+ Timelines.UserListStatusesTask(world.account, listFullName!!)
+ .setSinceId(adapter.topID),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, true)
+ refreshView.onRefreshComplete()
+ })
+ }
+
+ override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {
+ if (listFullName == null) {
+ UIHandler().post {
+ notifyTextEmpty()
+ refreshView.onRefreshComplete()
+ }
+ return
+ }
+ runRefreshTask(
+ Timelines.UserListStatusesTask(world.account, listFullName!!)
+ .setMaxId(adapter.lastID - 1),
+ {
+ updateListViewWithNotice(refreshView.refreshableView, false)
+ refreshView.onRefreshComplete()
+ })
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ override fun getListView(page: View): PullToRefreshListView {
+ return page.findViewById(R.id.listview_userlist) as PullToRefreshListView
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View {
+ val page = inflater.inflate(R.layout.fragment_userlist, container, false)
+ val listView = getListView(page)
+ val adapter = adapter
+ listView.setAdapter(adapter)
+ listView.setOnScrollListener(this)
+ listView.setOnRefreshListener(this)
+ listView.mode = refreshMode
+ val buttonUserLists = getUserListsButton(page)
+ buttonUserLists.setOnClickListener(this)
+ textListName = getTextListName(page)
+ textListName!!.text = if (listFullName != null) listFullName else "<none>"
+ return page
+ }
+
+ private fun getTextListName(page: View): TextView {
+ return page.findViewById(R.id.textview_userlist_name) as TextView
+ }
+
+ private fun getUserListsButton(page: View): ImageButton {
+ return page.findViewById(R.id.button_userlist_lists) as ImageButton
+ }
+
+ private fun notifyTextEmpty() {
+ world.notifyError(R.string.notice_userlist_not_selected)
+ }
+
+ private fun openUserListsDialog() {
+ val ary = world.listSubscriptions.toTypedArray<String>()
+ val builder = AlertDialog.Builder(activity)
+ builder.setTitle(R.string.dialog_title_select_userlist)
+ .setItems(ary) { dialog, which ->
+ val activity = activity as MainActivity
+ activity.openUserListPage(ary[which])
+ textListName!!.text = ary[which]
+ }
+ val dialog = builder.create()
+ dialog.show()
+ }
+
+ fun startUserList(listFullName: String) {
+ InternalPreferenceHelper.instance.set(R.string.key_last_used_user_list, listFullName)
+ val adapter = adapter
+ this.listFullName = listFullName
+ adapter.clear()
+ adapter.updateForce()
+ runRefreshTask(Timelines.UserListStatusesTask(world.account, listFullName)) { adapter.updateForce() }
+ }
+
+ private fun runRefreshTask(task: TimelineTask<Tweet>, onFinish: () -> Unit) {
+ val adapter = adapter
+ task
+ .setCount(200)
+ .onFail { x -> world.notifyError(R.string.notice_error_get_list) }
+ .onDoneUI { tweets ->
+ world.addTweetAll(tweets)
+ adapter.addAll(tweets)
+ }
+ .onFinishUI(onFinish)
+ .execute()
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.java b/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.java
deleted file mode 100644
index 88ad0879..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.lacolaco.smileessence.view.preference;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.preference.EditTextPreference;
-import android.util.AttributeSet;
-
-public class IntegerEditTextPreference extends EditTextPreference {
- public IntegerEditTextPreference(Context context) {
- super(context);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public IntegerEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- public IntegerEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public IntegerEditTextPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected boolean persistString(String value) {
- return persistInt(Integer.valueOf(value));
- }
-
- @Override
- protected String getPersistedString(String defaultReturnValue) {
- return String.valueOf(getPersistedInt(-1));
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.kt b/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.kt
new file mode 100644
index 00000000..e6a23696
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerEditTextPreference.kt
@@ -0,0 +1,26 @@
+package net.lacolaco.smileessence.view.preference
+
+import android.annotation.TargetApi
+import android.content.Context
+import android.os.Build
+import android.preference.EditTextPreference
+import android.util.AttributeSet
+
+class IntegerEditTextPreference : EditTextPreference {
+ constructor(context: Context) : super(context)
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
+
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
+
+ constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
+
+ override fun persistString(value: String): Boolean {
+ return persistInt(Integer.valueOf(value)!!)
+ }
+
+ override fun getPersistedString(defaultReturnValue: String?): String {
+ return getPersistedInt(-1).toString()
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.java b/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.java
deleted file mode 100644
index f04a3b89..00000000
--- a/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.lacolaco.smileessence.view.preference;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.preference.ListPreference;
-import android.util.AttributeSet;
-
-public class IntegerListPreference extends ListPreference {
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public IntegerListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public IntegerListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public IntegerListPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public IntegerListPreference(Context context) {
- super(context);
- }
-
- @Override
- protected boolean persistString(String value) {
- return persistInt(Integer.valueOf(value));
- }
-
- @Override
- protected String getPersistedString(String defaultReturnValue) {
- return String.valueOf(getPersistedInt(-1));
- }
-}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.kt b/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.kt
new file mode 100644
index 00000000..7dbe3297
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/preference/IntegerListPreference.kt
@@ -0,0 +1,27 @@
+package net.lacolaco.smileessence.view.preference
+
+import android.annotation.TargetApi
+import android.content.Context
+import android.os.Build
+import android.preference.ListPreference
+import android.util.AttributeSet
+
+class IntegerListPreference : ListPreference {
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
+
+ constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
+
+ constructor(context: Context) : super(context)
+
+ override fun persistString(value: String): Boolean {
+ return persistInt(Integer.valueOf(value)!!)
+ }
+
+ override fun getPersistedString(defaultReturnValue: String?): String {
+ return getPersistedInt(-1).toString()
+ }
+}