diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2017-10-04 21:10:58 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2017-10-04 22:00:52 +0900 |
commit | 986fa8cd8bdf6110d2aa390a9dcafc4ff19ee6dd (patch) | |
tree | e92964cc05dc18021011fbed2f8f249b7f3ed5b6 /app/src/main/java/net/lacolaco/smileessence/view | |
parent | b471085c2b2d6229bb6fb54a6d444802147a7392 (diff) | |
download | SmileEssence-986fa8cd8bdf6110d2aa390a9dcafc4ff19ee6dd.tar.gz |
worldify (wip)2017-10-04
Diffstat (limited to 'app/src/main/java/net/lacolaco/smileessence/view')
36 files changed, 897 insertions, 1461 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 index 8b623361..33fc05ac 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/ColoredRelativeLayout.java @@ -4,19 +4,17 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; -import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.widget.RelativeLayout; import net.lacolaco.smileessence.R; public class ColoredRelativeLayout extends RelativeLayout { - private int highlightColors[] = new int[4]; + public static final int HIGHLIGHT_NONE = 0; private final Paint paint = new Paint(); + private int highlightColors[] = new int[4]; private boolean showAccent = false; - public static final int HIGHLIGHT_NONE = 0; - public ColoredRelativeLayout(Context context) { this(context, null); } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/Partials.java b/app/src/main/java/net/lacolaco/smileessence/view/Partials.java new file mode 100644 index 00000000..c6f8ffef --- /dev/null +++ b/app/src/main/java/net/lacolaco/smileessence/view/Partials.java @@ -0,0 +1,233 @@ +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(); + ImageCache.getInstance().setImageToView(iconUrl, icon); + 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, () -> { + MessageDetailDialogFragment dialogFragment = new MessageDetailDialogFragment(); + dialogFragment.setMessageID(directMessage.getId()); + DialogHelper.showDialog(activity, dialogFragment); + })); + + 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(); + ImageCache.getInstance().setImageToView(iconUrl, icon); + 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/SettingFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.java index d9891a49..7ed9636b 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.java @@ -24,6 +24,7 @@ package net.lacolaco.smileessence.view; +import android.app.AlertDialog; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; @@ -32,39 +33,30 @@ 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 net.lacolaco.smileessence.activity.ManageAccountsActivity; -import net.lacolaco.smileessence.notification.Notificator; -import net.lacolaco.smileessence.view.dialog.AppInfoDialogFragment; import static android.content.SharedPreferences.OnSharedPreferenceChangeListener; public class SettingFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener, Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { - private static final int TEXT_SIZE_MIN = 8; - private static final int TEXT_SIZE_MAX = 24; - - // --------------------- Interface OnPreferenceChangeListener --------------------- - @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)) { - int newTextSize = Integer.parseInt(newValueStr); - if (TEXT_SIZE_MIN <= newTextSize && newTextSize <= TEXT_SIZE_MAX) { - return true; - } - Notificator.getInstance().alert(R.string.error_setting_text_size_range); + return true; } else { - Notificator.getInstance().alert(R.string.error_setting_text_size_not_number); + Application.toast(R.string.error_setting_text_size_not_number); } return false; } else if (preference.getKey().contentEquals(getString(R.string.key_setting_theme))) { - Notificator.getInstance().publish(R.string.notice_theme_changed); + Application.toast(R.string.notice_theme_changed); } return true; } @@ -76,8 +68,6 @@ public class SettingFragment extends PreferenceFragment implements OnSharedPrefe String key = preference.getKey(); if (key.contentEquals(getString(R.string.key_setting_application_information))) { openAppInfoDialog(); - } else if (key.contentEquals(getString(R.string.key_setting_accounts))) { - openManageAccountsActivity(); } else if (key.contentEquals(getString(R.string.key_setting_licenses))) { openLicenseActivity(); } @@ -97,8 +87,6 @@ public class SettingFragment extends PreferenceFragment implements OnSharedPrefe public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.setting); - Preference manageAccounts = findPreference(R.string.key_setting_accounts); - manageAccounts.setOnPreferenceClickListener(this); EditTextPreference textSizePreference = (EditTextPreference) findPreference(R.string.key_setting_text_size); textSizePreference.setSummary(textSizePreference.getText()); textSizePreference.setOnPreferenceChangeListener(this); @@ -137,14 +125,17 @@ public class SettingFragment extends PreferenceFragment implements OnSharedPrefe getActivity().startActivity(intent); } - private void openManageAccountsActivity() { - Intent intent = new Intent(getActivity(), ManageAccountsActivity.class); - getActivity().startActivity(intent); - } - private void openAppInfoDialog() { - AppInfoDialogFragment dialog = new AppInfoDialogFragment(); - DialogHelper.showDialog(getActivity(), dialog); + 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() { diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java b/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java index 7554e2fb..d5358db5 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.java @@ -43,14 +43,14 @@ public class ThreeStateButton extends Button { 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); } - - public int getState() { - return state; - } } 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 index 802a0dd3..6d7420fb 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java @@ -1,37 +1,20 @@ package net.lacolaco.smileessence.view.adapter; -import android.app.Activity; -import android.view.View; -import android.view.ViewGroup; import android.widget.BaseAdapter; import net.lacolaco.smileessence.util.UIHandler; -import net.lacolaco.smileessence.viewmodel.IViewModel; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -public abstract class CustomListAdapter<T extends IViewModel> extends BaseAdapter { - - // ------------------------------ FIELDS ------------------------------ - - protected boolean isNotifiable = true; +public abstract class CustomListAdapter<T> extends BaseAdapter { + private boolean isNotifiable = true; private List<T> frozenList = new ArrayList<>(); - private Activity activity; - - // --------------------------- CONSTRUCTORS --------------------------- - - CustomListAdapter(Activity activity) { - this.activity = activity; - } - - // --------------------- GETTER / SETTER METHODS --------------------- public final void setNotifiable(boolean notifiable) { isNotifiable = notifiable; } - // --------------------- Interface BaseAdapter --------------------- - @Override public final int getCount() { return frozenList.size(); @@ -48,21 +31,12 @@ public abstract class CustomListAdapter<T extends IViewModel> extends BaseAdapte } @Override - public final View getView(int position, View convertView, ViewGroup parent) { - return getItem(position).getView(activity, activity.getLayoutInflater(), convertView); - } - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override public final void notifyDataSetChanged() { - frozenList = getFrozenList(); + frozenList = Collections.unmodifiableList(getList()); super.notifyDataSetChanged(); } - // -------------------------- OTHER METHODS -------------------------- - - protected abstract List<T> getFrozenList(); + protected abstract List<T> getList(); public void update() { if (isNotifiable) { 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 index 18741e02..2ce0386d 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java @@ -25,13 +25,92 @@ package net.lacolaco.smileessence.view.adapter; import android.app.Activity; -import net.lacolaco.smileessence.viewmodel.EventViewModel; +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; -public class EventListAdapter extends UnorderedCustomListAdapter<EventViewModel> { +import java.lang.ref.WeakReference; +import java.util.List; - // --------------------------- CONSTRUCTORS --------------------------- +public class EventListAdapter extends CustomListAdapter<Event> { + private final World world; + private final Activity activity; - public EventListAdapter(Activity activity) { - super(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(); + ImageCache.getInstance().setImageToView(iconUrl, icon); + + 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/MessageListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java index 114f9e58..c2a53df9 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java @@ -25,23 +25,28 @@ package net.lacolaco.smileessence.view.adapter; import android.app.Activity; -import net.lacolaco.smileessence.viewmodel.MessageViewModel; +import android.view.View; +import android.view.ViewGroup; +import net.lacolaco.smileessence.entity.DirectMessage; +import net.lacolaco.smileessence.view.Partials; -public class MessageListAdapter extends OrderedCustomListAdapter<MessageViewModel> { - - // --------------------------- CONSTRUCTORS --------------------------- +public class MessageListAdapter extends OrderedCustomListAdapter<DirectMessage> { + private final Activity activity; public MessageListAdapter(Activity activity) { - super(activity); + this.activity = activity; } - // --------------------- GETTER / SETTER METHODS --------------------- - public long getLastID() { - return getItem(getCount() - 1).getDirectMessage().getId(); + return getItem(getCount() - 1).getId(); } public long getTopID() { - return getItem(0).getDirectMessage().getId(); + return getItem(0).getId(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + 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 index 43d04b2e..3de58658 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/OrderedCustomListAdapter.java @@ -1,66 +1,31 @@ -/* - * 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 net.lacolaco.smileessence.entity.IdObject; -import net.lacolaco.smileessence.viewmodel.IViewModel; import java.util.*; -public class OrderedCustomListAdapter<T extends IViewModel & IdObject> extends CustomListAdapter<T> { - - // ------------------------------ FIELDS ------------------------------ - +public abstract class OrderedCustomListAdapter<T extends IdObject> extends CustomListAdapter<T> { private final Map<Long, T> treeMap; - // --------------------------- CONSTRUCTORS --------------------------- - - public OrderedCustomListAdapter(Activity activity) { - this(activity, Long::compare); + public OrderedCustomListAdapter() { + this(Long::compare); } - public OrderedCustomListAdapter(Activity activity, Comparator<Long> comparator) { - super(activity); - this.treeMap = new TreeMap<>(Collections.reverseOrder(comparator)); // 降順 + public OrderedCustomListAdapter(Comparator<Long> comparator) { + super(); + this.treeMap = new TreeMap<>(Collections.reverseOrder(comparator)); } - // ------------------------ OVERRIDE METHODS ------------------------ - @Override - protected synchronized List<T> getFrozenList() { - return Collections.unmodifiableList(new ArrayList<>(treeMap.values())); + protected synchronized List<T> getList() { + return new ArrayList<>(treeMap.values()); } - // -------------------------- OTHER METHODS -------------------------- - - public synchronized void addItem(T item) { + public synchronized void add(T item) { treeMap.put(item.getId(), item); } - public synchronized void addItems(List<T> items) { + public synchronized void addAll(Collection<T> items) { for (T item : items) { treeMap.put(item.getId(), item); } @@ -70,16 +35,7 @@ public class OrderedCustomListAdapter<T extends IViewModel & IdObject> extends C treeMap.clear(); } - public synchronized T removeItem(T item) { + public synchronized T remove(T item) { return treeMap.remove(item.getId()); } - - public synchronized int removeItemById(long id) { - T item = treeMap.remove(id); - if (item == null) { - return 0; - } else { - return 1; - } - } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/SearchListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/SearchListAdapter.java deleted file mode 100644 index 48657748..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/SearchListAdapter.java +++ /dev/null @@ -1,65 +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; - -public class SearchListAdapter extends StatusListAdapter { - private String query; - private OnQueryChangeListener listener; - - // --------------------------- CONSTRUCTORS --------------------------- - - public SearchListAdapter(Activity activity) { - super(activity); - } - - // --------------------- GETTER / SETTER METHODS --------------------- - - public String getQuery() { - return query; - } - - public void setOnQueryChangeListener(OnQueryChangeListener listener) { - this.listener = listener; - } - - // -------------------------- OTHER METHODS -------------------------- - - public void initSearch(String query) { - this.query = query; - clear(); - if (listener != null) { - listener.onQueryChange(query); - } - } - - // -------------------------- INNER CLASSES -------------------------- - - public interface OnQueryChangeListener { - - void onQueryChange(String newQuery); - } -} diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/StatusListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/StatusListAdapter.java deleted file mode 100644 index 5fda8d56..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/StatusListAdapter.java +++ /dev/null @@ -1,71 +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 net.lacolaco.smileessence.entity.Tweet; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; - -public class StatusListAdapter extends OrderedCustomListAdapter<StatusViewModel> { - - // --------------------------- CONSTRUCTORS --------------------------- - - public StatusListAdapter(Activity activity) { - super(activity); - } - - // --------------------- GETTER / SETTER METHODS --------------------- - - public long getLastID() { - if (getCount() > 0) { - return getItem(getCount() - 1).getTweet().getId(); - } else { - return -1; - } - } - - public long getTopID() { - if (getCount() > 0) { - return getItem(0).getTweet().getId(); - } else { - return -1; - } - } - - // -------------------------- OTHER METHODS -------------------------- - - @Override - public synchronized int removeItemById(long statusID) { - int count = 0; - count += super.removeItemById(statusID); - Tweet t = Tweet.fetch(statusID); - if (t != null) { - for (long retweetId : t.getRetweets().values()) { - count += super.removeItemById(retweetId); - } - } - return count; - } -} 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 new file mode 100644 index 00000000..0dbe8d53 --- /dev/null +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.java @@ -0,0 +1,39 @@ +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/UnorderedCustomListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/UnorderedCustomListAdapter.java deleted file mode 100644 index 02f90bc2..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/UnorderedCustomListAdapter.java +++ /dev/null @@ -1,88 +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 net.lacolaco.smileessence.viewmodel.IViewModel; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.ListIterator; - -public class UnorderedCustomListAdapter<T extends IViewModel> extends CustomListAdapter<T> { - - // ------------------------------ FIELDS ------------------------------ - - private final List<T> list = new ArrayList<>(); - - // --------------------------- CONSTRUCTORS --------------------------- - - public UnorderedCustomListAdapter(Activity activity) { - super(activity); - } - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - protected synchronized List<T> getFrozenList() { - return Collections.unmodifiableList(new ArrayList<>(list)); - } - - // -------------------------- OTHER METHODS -------------------------- - - public synchronized void addItemToTop(T item) { - if (!list.contains(item)) { - list.add(0, item); - } - } - - public synchronized void addItemsToTop(List<T> items) { - ListIterator<T> iterator = items.listIterator(items.size()); - while (iterator.hasPrevious()) { - addItemToTop(iterator.previous()); - } - } - - public synchronized void addItemToBottom(T item) { - if (!list.contains(item)) { - list.add(item); - } - } - - public synchronized void addItemsToBottom(List<T> items) { - for (T item : items) { - addItemToBottom(item); - } - } - - public synchronized void clear() { - list.clear(); - } - - public synchronized boolean removeItem(T item) { - return list.remove(item); - } -} diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/UserListListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/UserListListAdapter.java deleted file mode 100644 index 81e33d7e..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/UserListListAdapter.java +++ /dev/null @@ -1,50 +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; - -public class UserListListAdapter extends StatusListAdapter { - - // ------------------------------ FIELDS ------------------------------ - - private String listFullName; - - // --------------------------- CONSTRUCTORS --------------------------- - - public UserListListAdapter(Activity activity) { - super(activity); - } - - // --------------------- GETTER / SETTER METHODS --------------------- - - public String getListFullName() { - return listFullName; - } - - public void setListFullName(String listFullName) { - this.listFullName = listFullName; - } -} diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/AppInfoDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/AppInfoDialogFragment.java deleted file mode 100644 index 393bdd06..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/AppInfoDialogFragment.java +++ /dev/null @@ -1,53 +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.LayoutInflater; -import android.view.View; -import android.widget.TextView; -import net.lacolaco.smileessence.BuildConfig; -import net.lacolaco.smileessence.R; - -public class AppInfoDialogFragment extends StackableDialogFragment { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - 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) + ")"); - - return new AlertDialog.Builder(getActivity()) - .setTitle(R.string.dialog_title_about) - .setView(contentView) - .setPositiveButton(R.string.alert_dialog_ok, (dialog, which) -> dialog.dismiss()) - .create(); - } -} 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 index 3ca6e175..8ce25145 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.java @@ -26,12 +26,13 @@ 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 StackableDialogFragment { +public abstract class EditTextDialogFragment extends DialogFragment { // ------------------------------ FIELDS ------------------------------ diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MenuDialogFragment.java deleted file mode 100644 index 57491769..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MenuDialogFragment.java +++ /dev/null @@ -1,81 +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.os.Bundle; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; -import net.lacolaco.smileessence.R; -import net.lacolaco.smileessence.command.Command; -import net.lacolaco.smileessence.command.IConfirmable; -import net.lacolaco.smileessence.view.adapter.UnorderedCustomListAdapter; - -import java.util.List; - -public abstract class MenuDialogFragment extends StackableDialogFragment implements AdapterView.OnItemClickListener { - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - View body = setupView(); - - return new AlertDialog.Builder(getActivity()).setView(body).create(); - } - - protected abstract List<Command> getMenuCommands(); - - protected void executeCommand(Command command) { - dismiss(); - command.execute(); - } - - protected View setupView() { - final Activity activity = getActivity(); - View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null); - ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list); - - final UnorderedCustomListAdapter<Command> adapter = new UnorderedCustomListAdapter<>(activity); - listView.setAdapter(adapter); - listView.setOnItemClickListener(this); - adapter.addItemsToBottom(getMenuCommands()); - adapter.updateForce(); - - return body; - } - - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - final Command command = (Command) parent.getItemAtPosition(position); - if (command != null) { - if (command instanceof IConfirmable) { - ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), () -> executeCommand(command)); - } else { - executeCommand(command); - } - } - } -} 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 index ab140c12..8383363c 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.java @@ -24,46 +24,35 @@ package net.lacolaco.smileessence.view.dialog; -import android.app.Activity; 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 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.DirectMessage; -import net.lacolaco.smileessence.notification.Notificator; 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 net.lacolaco.smileessence.view.adapter.UnorderedCustomListAdapter; -import net.lacolaco.smileessence.viewmodel.MessageViewModel; import java.util.ArrayList; import java.util.List; public class MessageDetailDialogFragment extends StackableDialogFragment implements View.OnClickListener { - - // ------------------------------ FIELDS ------------------------------ - private static final String KEY_MESSAGE_ID = "messageID"; private DirectMessage message; - // --------------------- GETTER / SETTER METHODS --------------------- - - public long getMessageID() { - return getArguments().getLong(KEY_MESSAGE_ID); - } - public void setMessageID(long messageID) { Bundle args = new Bundle(); args.putLong(KEY_MESSAGE_ID, messageID); @@ -96,18 +85,11 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme } } - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - message = DirectMessage.fetch(getMessageID()); - } - @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + message = DirectMessage.fetch(getArguments().getLong(KEY_MESSAGE_ID)); if (message == null) { - Notificator.getInstance().alert(R.string.notice_error_get_messages); + getWorld().notifyError(R.string.notice_error_get_messages); return new DisposeDialog(getActivity()); } @@ -118,17 +100,18 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme // TODO: 効率的な探索どうする DirectMessage replyTo = null; - 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; - } - } + // 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.addItem(new MessageViewModel(replyTo)); + adapter.add(replyTo); adapter.updateForce(); } else { listView.setVisibility(View.GONE); @@ -141,18 +124,16 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme private void deleteMessage() { ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), () -> { - new Messages.DestroyTask(Application.getInstance().getCurrentAccount(), message.getId()) - .onDone(x -> Notificator.getInstance().publish(R.string.notice_message_delete_succeeded)) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_message_delete_failed)) + 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() { - SendMessageDialogFragment dialogFragment = new SendMessageDialogFragment(); - dialogFragment.setScreenName(message.getSender().getScreenName()); - DialogHelper.showDialog(getActivity(), dialogFragment); + DialogHelper.showDialog(getActivity(), SendMessageDialogFragment.newInstance(message.getSender())); } private View getTitleView() { @@ -160,8 +141,7 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme View view = activity.getLayoutInflater().inflate(R.layout.dialog_status_detail, null); - MessageViewModel statusViewModel = new MessageViewModel(message); - View messageHeader = statusViewModel.getView(activity, activity.getLayoutInflater(), view.findViewById(R.id.layout_status_header)); + View messageHeader = Partials.getDirectMessageView(message, activity, view.findViewById(R.id.layout_status_header)); messageHeader.setClickable(false); view.setBackgroundColor(((ColorDrawable) messageHeader.getBackground()).getColor()); @@ -179,19 +159,16 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme } private void updateViewButtons(View view) { - Account account = Application.getInstance().getCurrentAccount(); - //--- 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(account.canDelete(message) ? View.VISIBLE : View.GONE); + delete.setVisibility(View.VISIBLE); } private void updateViewMenu(View view) { - MainActivity activity = ((MainActivity) getActivity()); // -- menu dialog ImageButton menu = (ImageButton) view.findViewById(R.id.button_status_detail_menu); menu.setOnClickListener(this); @@ -203,8 +180,18 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme if (commands.size() > 0) { divider.setVisibility(View.VISIBLE); listView.setVisibility(View.VISIBLE); - final UnorderedCustomListAdapter<Command> adapter = new UnorderedCustomListAdapter<>(activity); - adapter.addItemsToBottom(commands); + final CustomListAdapter<Command> adapter = new CustomListAdapter<Command>() { + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + return null; + } + + @Override + protected List<Command> getList() { + return commands; + } + }; adapter.updateForce(); listView.setAdapter(adapter); listView.setOnItemClickListener((parent, view1, position, id) -> { @@ -218,7 +205,7 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme } private List<Command> getCommands() { - Activity activity = getActivity(); + MainActivity activity = (MainActivity) getActivity(); List<Command> commands = new ArrayList<>(); // Mentions if (message.getSender() != message.getRecipient()) { @@ -241,8 +228,19 @@ public class MessageDetailDialogFragment extends StackableDialogFragment impleme } private void openMenu() { - MessageMenuDialogFragment fragment = new MessageMenuDialogFragment(); - fragment.setMessageID(getMessageID()); - DialogHelper.showDialog(getActivity(), fragment); + 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/MessageMenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageMenuDialogFragment.java deleted file mode 100644 index c3bcbe16..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageMenuDialogFragment.java +++ /dev/null @@ -1,66 +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.os.Bundle; -import net.lacolaco.smileessence.command.Command; -import net.lacolaco.smileessence.entity.DirectMessage; - -import java.util.List; - -public class MessageMenuDialogFragment extends MenuDialogFragment { - - // ------------------------------ FIELDS ------------------------------ - - private static final String KEY_MESSAGE_ID = "messageID"; - private DirectMessage message; - - // --------------------- GETTER / SETTER METHODS --------------------- - - public long getMessageID() { - return getArguments().getLong(KEY_MESSAGE_ID); - } - - public void setMessageID(long messageID) { - Bundle args = new Bundle(); - args.putLong(KEY_MESSAGE_ID, messageID); - setArguments(args); - } - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - message = DirectMessage.fetch(getMessageID()); - } - - @Override - protected List<Command> getMenuCommands() { - Activity activity = getActivity(); - return Command.getMessageCommands(activity, message); - } -} diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SelectSearchQueryDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SelectSearchQueryDialogFragment.java deleted file mode 100644 index 9a897f8f..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SelectSearchQueryDialogFragment.java +++ /dev/null @@ -1,93 +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.os.Bundle; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; -import net.lacolaco.smileessence.Application; -import net.lacolaco.smileessence.R; -import net.lacolaco.smileessence.command.Command; -import net.lacolaco.smileessence.command.CommandOpenSearch; -import net.lacolaco.smileessence.entity.SavedSearch; -import net.lacolaco.smileessence.notification.Notificator; -import net.lacolaco.smileessence.twitter.task.Searches; -import net.lacolaco.smileessence.view.adapter.UnorderedCustomListAdapter; - -import java.util.ArrayList; -import java.util.List; - -public class SelectSearchQueryDialogFragment extends MenuDialogFragment implements AdapterView.OnItemLongClickListener { - - // --------------------- Interface OnItemLongClickListener --------------------- - - @Override - public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { - final CommandOpenSearch command = (CommandOpenSearch) parent.getItemAtPosition(position); - @SuppressWarnings("unchecked") final UnorderedCustomListAdapter<Command> adapter = (UnorderedCustomListAdapter<Command>) parent.getAdapter(); - - ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_delete_query), () -> { - adapter.removeItem(command); - adapter.update(); - new Searches.DestroySavedSearchTask(Application.getInstance().getCurrentAccount(), command.getQuery().getId()) - .onDoneUI(x -> { - Notificator.getInstance().publish(R.string.notice_search_query_deleted); - Application.getInstance().getCurrentAccount().refreshSavedSearches(); - }) - .onFailUI(x -> Notificator.getInstance().publish("unable to delete search query")) - .execute(); - }, false); - - return true; - } - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - protected List<Command> getMenuCommands() { - Activity activity = getActivity(); - List<Command> commands = new ArrayList<>(); - for (SavedSearch query : SavedSearch.cached()) { - commands.add(new CommandOpenSearch(activity, query)); - } - return commands; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - View body = setupView(); - ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list); - listView.setOnItemLongClickListener(this); - - return new AlertDialog.Builder(getActivity()) - .setView(body) - .setTitle(R.string.dialog_title_select_search_query) - .create(); - } -} diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SelectUserListDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SelectUserListDialogFragment.java deleted file mode 100644 index 3d1c276a..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SelectUserListDialogFragment.java +++ /dev/null @@ -1,58 +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.Dialog; -import android.os.Bundle; -import net.lacolaco.smileessence.Application; -import net.lacolaco.smileessence.R; -import net.lacolaco.smileessence.command.Command; -import net.lacolaco.smileessence.command.CommandOpenUserList; - -import java.util.ArrayList; -import java.util.List; - -public class SelectUserListDialogFragment extends MenuDialogFragment { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - protected List<Command> getMenuCommands() { - Activity activity = getActivity(); - List<Command> commands = new ArrayList<>(); - for (String fullName : Application.getInstance().getCurrentAccount().getListSubscriptions()) { - commands.add(new CommandOpenUserList(activity, fullName)); - } - return commands; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - Dialog dialog = super.onCreateDialog(savedInstanceState); - dialog.setTitle(R.string.dialog_title_select_userlist); - return dialog; - } -} 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 index 7f165fea..20917d8f 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.java @@ -39,34 +39,24 @@ import android.widget.TextView; import com.twitter.Validator; import net.lacolaco.smileessence.Application; import net.lacolaco.smileessence.R; -import net.lacolaco.smileessence.data.PostState; -import net.lacolaco.smileessence.notification.Notificator; +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 { - - // ------------------------------ FIELDS ------------------------------ - - private static final String screenNameKey = "screenName"; - private String screenName; + private static final String KEY_RECIPIENT_ID = "KEY_RECIPIENT_ID"; + private User recipient; private EditText editText; private TextView textViewCount; private Button buttonSend; - // --------------------- GETTER / SETTER METHODS --------------------- - - public void setScreenName(String screenName) { + public static SendMessageDialogFragment newInstance(User recipient) { + SendMessageDialogFragment obj = new SendMessageDialogFragment(); Bundle args = new Bundle(); - args.putString(screenNameKey, screenName); - setArguments(args); + args.putLong(KEY_RECIPIENT_ID, recipient.getId()); + obj.setArguments(args); + return obj; } - - // ------------------------ INTERFACE METHODS ------------------------ - - - // --------------------- Interface OnClickListener --------------------- - @Override public void onClick(View v) { int id = v.getId(); @@ -81,8 +71,6 @@ public class SendMessageDialogFragment extends StackableDialogFragment implement } } - // --------------------- Interface TextWatcher --------------------- - @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -92,9 +80,6 @@ public class SendMessageDialogFragment extends StackableDialogFragment implement public void onTextChanged(CharSequence s, int start, int before, int count) { Validator validator = new Validator(); int remainingCount = 140 - validator.getTweetLength(s.toString()); - if (!TextUtils.isEmpty(PostState.getState().getMediaFilePath())) { - remainingCount -= validator.getShortUrlLength(); - } textViewCount.setText(String.valueOf(remainingCount)); if (remainingCount == 140 || remainingCount < 0) { textViewCount.setTextColor(ContextCompat.getColor(getActivity(), R.color.red)); @@ -108,20 +93,12 @@ public class SendMessageDialogFragment extends StackableDialogFragment implement } - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Bundle args = getArguments(); - screenName = args.getString(screenNameKey); - } - @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: @" + screenName); + 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); @@ -142,12 +119,13 @@ public class SendMessageDialogFragment extends StackableDialogFragment implement private void sendMessage() { SystemServiceHelper.hideIM(getActivity(), editText); String text = editText.getText().toString(); - new Messages.CreateTask(Application.getInstance().getCurrentAccount(), screenName, text) + new Messages.CreateTask(getWorld().getAccount(), recipient.getId(), text) .onDoneUI(m -> { - Notificator.getInstance().publish(R.string.notice_message_send_succeeded); + getWorld().addDirectMessage(m); + getWorld().notify(R.string.notice_message_send_succeeded); dismiss(); }) - .onFail(e -> Notificator.getInstance().alert(R.string.notice_message_send_failed, e)) + .onFail(e -> getWorld().notifyError(R.string.notice_message_send_failed, e)) .execute(); } } 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 index 427c4884..848c6465 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StackableDialogFragment.java @@ -1,9 +1,13 @@ package net.lacolaco.smileessence.view.dialog; import android.app.DialogFragment; -import net.lacolaco.smileessence.Application; +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() { @@ -16,4 +20,9 @@ public class StackableDialogFragment extends DialogFragment { 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/StatusDetailDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.java index 7d2e5dbd..5b2ee58c 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.java @@ -24,12 +24,12 @@ package net.lacolaco.smileessence.view.dialog; -import android.app.Activity; 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; @@ -42,18 +42,19 @@ 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.data.PostState; import net.lacolaco.smileessence.entity.RBinding; import net.lacolaco.smileessence.entity.Tweet; -import net.lacolaco.smileessence.notification.Notificator; +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.StatusListAdapter; -import net.lacolaco.smileessence.view.adapter.UnorderedCustomListAdapter; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; +import net.lacolaco.smileessence.view.adapter.CustomListAdapter; +import net.lacolaco.smileessence.view.adapter.TimelineAdapter; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -61,50 +62,117 @@ import java.util.LinkedHashSet; import java.util.List; public class StatusDetailDialogFragment extends StackableDialogFragment implements View.OnClickListener { - - // ------------------------------ FIELDS ------------------------------ - - private static final String KEY_STATUS_ID = "statusID"; + private static final String KEY_STATUS_ID = "status_id"; private Tweet tweet; - // --------------------- GETTER / SETTER METHODS --------------------- - - public long getStatusID() { - return getArguments().getLong(KEY_STATUS_ID); - } - - public void setStatusID(long statusID) { + public static StatusDetailDialogFragment newInstance(Tweet tweet) { + StatusDetailDialogFragment obj = new StatusDetailDialogFragment(); Bundle args = new Bundle(); - args.putLong(KEY_STATUS_ID, statusID); - setArguments(args); + args.putLong(KEY_STATUS_ID, tweet.getId()); + obj.setArguments(args); + return obj; } - // ------------------------ INTERFACE METHODS ------------------------ - - - // --------------------- Interface OnClickListener --------------------- - @Override public void onClick(final View v) { switch (v.getId()) { case R.id.button_status_detail_reply: { - replyToStatus(); + 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: { - toggleRetweet(); + 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: { - toggleFavorite(); + 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: { - deleteStatus(); + 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: { - openMenu(); + 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: { @@ -113,62 +181,25 @@ public class StatusDetailDialogFragment extends StackableDialogFragment implemen } } - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - tweet = Tweet.fetch(getStatusID()); - } - @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + tweet = Tweet.fetch(getArguments().getLong(KEY_STATUS_ID)); if (tweet == null) { // trying to open deleted tweet? - Notificator.getInstance().publish(R.string.notice_error_show_status); + getWorld().notifyError(R.string.notice_error_show_status); return new DisposeDialog(getActivity()); } - Account account = Application.getInstance().getCurrentAccount(); - - View header = getTitleView(); - - ListView listView = (ListView) header.findViewById(R.id.listview_status_detail_reply_to); - final StatusListAdapter adapter = new StatusListAdapter(getActivity()); - listView.setAdapter(adapter); - - View replyDivider = header.findViewById(R.id.detail_dialog_divider_top); - - if (tweet.getInReplyToStatusId() != -1) { - replyDivider.setVisibility(View.VISIBLE); - listView.setVisibility(View.VISIBLE); - Tweet.fetchTask(tweet.getInReplyToStatusId(), account) - .onDoneUI(replyTo -> { - adapter.addItem(new StatusViewModel(replyTo)); - adapter.update(); - }) - .execute(); - } else { - replyDivider.setVisibility(View.GONE); - listView.setVisibility(View.GONE); - } - - return new AlertDialog.Builder(getActivity()).setView(header).create(); - } - - private View getTitleView() { - MainActivity activity = ((MainActivity) getActivity()); - - View view = activity.getLayoutInflater().inflate(R.layout.dialog_status_detail, null); + View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_status_detail, null); UIObserverBundle bundle = new UIObserverBundle(); view.setTag(bundle); - View statusHeader = new StatusViewModel(tweet).getView(activity, activity.getLayoutInflater(), view.findViewById(R.id.layout_status_header)); + 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); - updateViewMenu(view); + setupViewMenu(view); final WeakReference<View> weakView = new WeakReference<>(view); bundle.attach(tweet.getOriginalTweet(), changes -> { @@ -181,11 +212,30 @@ public class StatusDetailDialogFragment extends StackableDialogFragment implemen } }); - return view; + 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) { - //--- favs/RTs count 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) { @@ -210,7 +260,7 @@ public class StatusDetailDialogFragment extends StackableDialogFragment implemen } private void updateViewButtons(View view) { - Account account = Application.getInstance().getCurrentAccount(); + Account account = getWorld().getAccount(); //--- buttons ImageButton reply = (ImageButton) view.findViewById(R.id.button_status_detail_reply); @@ -226,25 +276,37 @@ public class StatusDetailDialogFragment extends StackableDialogFragment implemen ImageButton delete = (ImageButton) view.findViewById(R.id.button_status_detail_delete); delete.setOnClickListener(this); - delete.setVisibility(account.canDelete(tweet) ? View.VISIBLE : View.GONE); - } + delete.setVisibility(tweet.getOriginalTweet().getUser() == account.getUser() ? View.VISIBLE : View.GONE); - private void updateViewMenu(View view) { - MainActivity activity = ((MainActivity) getActivity()); - // -- menu dialog ImageButton menu = (ImageButton) view.findViewById(R.id.button_status_detail_menu); menu.setOnClickListener(this); + } - // -- menu embedded in dialog + 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 UnorderedCustomListAdapter<Command> adapter = new UnorderedCustomListAdapter<>(activity); - adapter.addItemsToBottom(commands); - adapter.updateForce(); + 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); @@ -260,20 +322,8 @@ public class StatusDetailDialogFragment extends StackableDialogFragment implemen ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), onYes); } - private void deleteStatus() { - confirm(() -> { - Account account = Application.getInstance().getCurrentAccount(); - - new Tweets.DestroyTask(account, tweet.getOriginalTweet().getId()) - .onDone(t -> Notificator.getInstance().publish(R.string.notice_status_delete_succeeded)) - .onFail(e -> Notificator.getInstance().alert(R.string.notice_status_delete_failed)) - .execute(); - dismiss(); - }); - } - private List<Command> getCommands() { - Activity activity = getActivity(); + MainActivity activity = (MainActivity) getActivity(); ArrayList<Command> commands = new ArrayList<>(); // Retweeter if (tweet.getRetweetedTweet() != null && tweet.getUser() != tweet.getRetweetedTweet().getUser()) @@ -295,64 +345,4 @@ public class StatusDetailDialogFragment extends StackableDialogFragment implemen } return commands; } - - private void openMenu() { - StatusMenuDialogFragment fragment = new StatusMenuDialogFragment(); - fragment.setStatusID(getStatusID()); - DialogHelper.showDialog(getActivity(), fragment); - } - - private void replyToStatus() { - Account account = Application.getInstance().getCurrentAccount(); - Tweet originalTweet = tweet.getOriginalTweet(); - - StringBuilder builder = new StringBuilder(); - builder.append("@" + originalTweet.getUser().getScreenName() + " "); - - for (String screenName : originalTweet.getMentions()) { - if (!screenName.equals(account.getUser().getScreenName())) - builder.append("@" + screenName + " "); - } - String text = builder.toString(); - int selStart = originalTweet.getUser().getScreenName().length() + 2; // "@" and " " - - PostState.newState().beginTransaction() - .insertText(0, text) - .setInReplyTo(originalTweet) - .setSelection(selStart, text.length()) - .commitWithOpen((MainActivity) getActivity()); - } - - private void toggleFavorite() { - Account account = Application.getInstance().getCurrentAccount(); - if (tweet.isFavoritedBy(account.getUserId())) { - new TweetReactions.UnfavoriteTask(account, tweet.getId()) - .onDone(x -> Notificator.getInstance().publish(R.string.notice_unfavorite_succeeded)) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_unfavorite_failed)) - .execute(); - } else { - new TweetReactions.FavoriteTask(account, tweet.getId()) - .onDone(x -> Notificator.getInstance().publish(R.string.notice_favorite_succeeded)) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_favorite_failed)) - .execute(); - } - } - - private void toggleRetweet() { - Account account = Application.getInstance().getCurrentAccount(); - confirm(() -> { - if (tweet.isRetweetedBy(account.getUserId())) { - new Tweets.DestroyTask(account, tweet.getRetweetIdBy(account.getUserId())) - .onDone(t -> Notificator.getInstance().publish(R.string.notice_status_delete_succeeded)) - .onFail(e -> Notificator.getInstance().alert(R.string.notice_status_delete_failed)) - .execute(); - dismiss(); - } else { - new TweetReactions.RetweetTask(account, tweet.getId()) - .onDone(x -> Notificator.getInstance().publish(R.string.notice_retweet_succeeded)) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_retweet_failed)) - .execute(); - } - }); - } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusMenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusMenuDialogFragment.java deleted file mode 100644 index 58284536..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusMenuDialogFragment.java +++ /dev/null @@ -1,66 +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.os.Bundle; -import net.lacolaco.smileessence.command.Command; -import net.lacolaco.smileessence.entity.Tweet; - -import java.util.List; - -public class StatusMenuDialogFragment extends MenuDialogFragment { - - // ------------------------------ FIELDS ------------------------------ - - private static final String KEY_STATUS_ID = "statusID"; - private Tweet tweet; - - // --------------------- GETTER / SETTER METHODS --------------------- - - public long getStatusID() { - return getArguments().getLong(KEY_STATUS_ID); - } - - public void setStatusID(long statusID) { - Bundle args = new Bundle(); - args.putLong(KEY_STATUS_ID, statusID); - setArguments(args); - } - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - tweet = Tweet.fetch(getStatusID()); - } - - @Override - protected List<Command> getMenuCommands() { - Activity activity = getActivity(); - return Command.getStatusCommands(activity, tweet); - } -} 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 index cc7b2b01..95bbac5c 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.java @@ -28,22 +28,22 @@ 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.adapter.UnorderedCustomListAdapter; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; +import net.lacolaco.smileessence.view.Partials; +import net.lacolaco.smileessence.view.adapter.CustomListAdapter; -public class TalkChainDialogFragment extends StackableDialogFragment { - - // ------------------------------ FIELDS ------------------------------ - - private static final String KEY_STATUS_ID = "statusID"; +import java.util.ArrayList; +import java.util.List; - // --------------------- GETTER / SETTER METHODS --------------------- +public class TalkChainDialogFragment extends StackableDialogFragment { + private static final String KEY_STATUS_ID = "KEY_STATUS_ID"; private long getStatusID() { return getArguments().getLong(KEY_STATUS_ID); @@ -55,24 +55,32 @@ public class TalkChainDialogFragment extends StackableDialogFragment { setArguments(bundle); } - // ------------------------ OVERRIDE METHODS ------------------------ - @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - MainActivity activity = (MainActivity) getActivity(); - Account account = Application.getInstance().getCurrentAccount(); + 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 UnorderedCustomListAdapter<StatusViewModel> adapter = new UnorderedCustomListAdapter<>(getActivity()); + 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 -> { - adapter.addItemToBottom(new StatusViewModel(tweet)); + list.add(tweet); adapter.updateForce(); }).execute(); - return new AlertDialog.Builder(activity) + return new AlertDialog.Builder(getActivity()) .setTitle(R.string.dialog_title_talk_chain) .setView(view) .setCancelable(true) 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 index f7f69947..9e036d32 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.java @@ -31,20 +31,20 @@ import android.text.Html; import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.view.View; -import android.widget.*; +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.Application; import net.lacolaco.smileessence.R; import net.lacolaco.smileessence.activity.MainActivity; -import net.lacolaco.smileessence.command.Command; import net.lacolaco.smileessence.data.Account; import net.lacolaco.smileessence.data.ImageCache; import net.lacolaco.smileessence.entity.RBinding; -import net.lacolaco.smileessence.entity.Tweet; import net.lacolaco.smileessence.entity.User; -import net.lacolaco.smileessence.notification.Notificator; import net.lacolaco.smileessence.twitter.task.Timelines; import net.lacolaco.smileessence.twitter.task.Users; import net.lacolaco.smileessence.util.IntentUtils; @@ -52,9 +52,7 @@ 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.OrderedCustomListAdapter; -import net.lacolaco.smileessence.view.adapter.StatusListAdapter; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; +import net.lacolaco.smileessence.view.adapter.TimelineAdapter; public class UserDetailDialogFragment extends StackableDialogFragment implements View.OnClickListener, PullToRefreshBase.OnRefreshListener2<ListView> { @@ -62,7 +60,7 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements // ------------------------------ FIELDS ------------------------------ private static final String KEY_USER_ID = "userID"; - private StatusListAdapter adapter; + private TimelineAdapter adapter; private TextView textViewScreenName; private TextView textViewName; private TextView textViewURL; @@ -138,15 +136,13 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements @Override public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) { - Account currentAccount = Application.getInstance().getCurrentAccount(); + Account currentAccount = getWorld().getAccount(); new Timelines.UserTimelineTask(currentAccount, getUserID()) .setCount(200) .setSinceId(adapter.getTopID()) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_error_get_user_timeline)) + .onFail(x -> getWorld().notifyError(R.string.notice_error_get_user_timeline)) .onDoneUI(tweets -> { - for (int i = tweets.size() - 1; i >= 0; i--) { - adapter.addItem(new StatusViewModel(tweets.get(i))); - } + adapter.addAll(tweets); updateListView(refreshView.getRefreshableView(), adapter, true); refreshView.onRefreshComplete(); }) @@ -155,15 +151,13 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements @Override public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) { - Account currentAccount = Application.getInstance().getCurrentAccount(); + Account currentAccount = getWorld().getAccount(); new Timelines.UserTimelineTask(currentAccount, getUserID()) .setCount(200) .setMaxId(adapter.getLastID() - 1) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_error_get_user_timeline)) + .onFail(x -> getWorld().notifyError(R.string.notice_error_get_user_timeline)) .onDoneUI(tweets -> { - for (Tweet tweet : tweets) { - adapter.addItem(new StatusViewModel(tweet)); - } + adapter.addAll(tweets); updateListView(refreshView.getRefreshableView(), adapter, false); refreshView.onRefreshComplete(); }) @@ -189,7 +183,7 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements public Dialog onCreateDialog(Bundle savedInstanceState) { MainActivity activity = (MainActivity) getActivity(); if (user == null) { - Notificator.getInstance().publish(R.string.notice_error_show_user); + getWorld().notify(R.string.notice_error_show_user); return new DisposeDialog(activity); } @@ -237,16 +231,14 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements .create(); } - private void executeUserTimelineTask(final StatusListAdapter adapter) { - Account account = Application.getInstance().getCurrentAccount(); + 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 -> Notificator.getInstance().alert(R.string.notice_error_get_user_timeline)) + .onFail(x -> getWorld().notifyError(R.string.notice_error_get_user_timeline)) .onDoneUI(tweets -> { - for (Tweet tweet : tweets) { - adapter.addItem(new StatusViewModel(tweet)); - } + adapter.addAll(tweets); adapter.updateForce(); tabHost.getTabWidget().getChildTabViewAt(1).setVisibility(View.VISIBLE); }) @@ -300,7 +292,7 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements updateUserDataDetail(); MainActivity activity = (MainActivity) getActivity(); - adapter = new StatusListAdapter(activity); + adapter = new TimelineAdapter(activity); listViewTimeline.setAdapter(adapter); executeUserTimelineTask(adapter); updateRelationship(); @@ -316,19 +308,54 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements } private void openUserMenu() { - UserMenuDialogFragment menuFragment = new UserMenuDialogFragment() { - @Override - protected void executeCommand(Command command) { - super.executeCommand(command); - new UIHandler().postDelayed(() -> { - if (UserDetailDialogFragment.this.isAdded()) { - updateRelationship(); + 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(); } - }, 1000); - } - }; - menuFragment.setUserID(user.getId()); - DialogHelper.showDialog(getActivity(), menuFragment); + }); + AlertDialog dialog = builder.create(); + dialog.show(); } private void setFollowButtonState(boolean isFollowing) { @@ -339,30 +366,30 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements } private void toggleFollowing() { - Account account = Application.getInstance().getCurrentAccount(); + 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 -> { - Notificator.getInstance().publish(R.string.notice_unfollow_succeeded); + getWorld().notify(R.string.notice_unfollow_succeeded); updateRelationship(); }) .onFail(x -> - Notificator.getInstance().alert(R.string.notice_unfollow_failed)) + getWorld().notifyError(R.string.notice_unfollow_failed)) .execute(); } else { new Users.FollowTask(account, user.getId()) .onDoneUI(result -> { - Notificator.getInstance().publish(R.string.notice_follow_succeeded); + getWorld().notify(R.string.notice_follow_succeeded); updateRelationship(); }) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_follow_failed)) + .onFail(x -> getWorld().notifyError(R.string.notice_follow_failed)) .execute(); } } - private void updateListView(AbsListView absListView, OrderedCustomListAdapter<?> adapter, boolean addedToTop) { + private void updateListView(AbsListView absListView, TimelineAdapter adapter, boolean addedToTop) { int before = adapter.getCount(); adapter.notifyDataSetChanged(); // synchronized call (not adapter#updateForce()) int after = adapter.getCount(); @@ -379,7 +406,7 @@ public class UserDetailDialogFragment extends StackableDialogFragment implements } private void updateRelationship() { - Account account = Application.getInstance().getCurrentAccount(); + Account account = getWorld().getAccount(); if (user == account.getUser()) { textViewFollowed.setText(R.string.user_detail_followed_is_me); buttonFollow.setVisibility(View.GONE); diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserMenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserMenuDialogFragment.java deleted file mode 100644 index 13d212ee..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserMenuDialogFragment.java +++ /dev/null @@ -1,66 +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.os.Bundle; -import net.lacolaco.smileessence.command.Command; -import net.lacolaco.smileessence.entity.User; - -import java.util.List; - -public class UserMenuDialogFragment extends MenuDialogFragment { - - // ------------------------------ FIELDS ------------------------------ - - private static final String KEY_USER_ID = "userID"; - 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); - } - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - user = User.fetch(getUserID()); - } - - @Override - protected List<Command> getMenuCommands() { - Activity activity = getActivity(); - return Command.getUserCommands(activity, user); - } -} 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 index 12064b3d..0dd24e67 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.java @@ -33,7 +33,8 @@ 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.notification.Notificator; +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, @@ -100,7 +101,6 @@ public abstract class CustomListFragment<T extends CustomListAdapter> extends Pa int after = adapter.getCount(); int increments = after - before; if (increments > 0) { - Notificator.getInstance().publish(R.string.notice_timeline_new, increments); if (addedToTop) { absListView.setSelection(increments + 1); absListView.smoothScrollToPositionFromTop(increments, 0); diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.java index b139575e..5f04114e 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.java @@ -26,40 +26,18 @@ package net.lacolaco.smileessence.view.page; import android.os.Bundle; import com.handmark.pulltorefresh.library.PullToRefreshBase; -import net.lacolaco.smileessence.twitter.StatusFilter; +import net.lacolaco.smileessence.World; import net.lacolaco.smileessence.view.adapter.EventListAdapter; -import net.lacolaco.smileessence.viewmodel.EventViewModel; -/** - * Fragment for notice history - */ public class HistoryFragment extends CustomListFragment<EventListAdapter> { - - // --------------------- GETTER / SETTER METHODS --------------------- - - @Override - protected PullToRefreshBase.Mode getRefreshMode() { - return PullToRefreshBase.Mode.DISABLED; - } - - // ------------------------ INTERFACE METHODS ------------------------ - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - EventListAdapter adapter = new EventListAdapter(getActivity()); - setAdapter(adapter); - - StatusFilter.getInstance().register(this, EventViewModel.class, (EventViewModel vm) -> { - adapter.addItemToTop(vm); - adapter.update(); - }, null); - } - @Override - public void onDestroy() { - super.onDestroy(); - StatusFilter.getInstance().unregister(this); + World world = getWorld(); + final EventListAdapter adapter = new EventListAdapter(world, getActivity()); + setAdapter(adapter); + world.addEventNotifier(this, () -> adapter.update()); // XXX } @Override 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 index 719a5c53..e00f69c6 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.java @@ -32,69 +32,48 @@ 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.notification.Notificator; -import net.lacolaco.smileessence.twitter.StatusFilter; 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.StatusListAdapter; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; - -public class HomeFragment extends CustomListFragment<StatusListAdapter> { - - // --------------------- GETTER / SETTER METHODS --------------------- +import net.lacolaco.smileessence.view.adapter.TimelineAdapter; +public class HomeFragment extends CustomListFragment<TimelineAdapter> { @Override protected PullToRefreshBase.Mode getRefreshMode() { return PullToRefreshBase.Mode.BOTH; } - // ------------------------ INTERFACE METHODS ------------------------ - - @Override // onCreate って Fragment のインスタンスが作られるときは必ず呼ばれるって認識でいいんだよね? + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - StatusListAdapter adapter = new StatusListAdapter(getActivity()); + TimelineAdapter adapter = new TimelineAdapter(getActivity()); setAdapter(adapter); - StatusFilter.getInstance().register(this, Tweet.class, (Tweet tweet) -> { - adapter.addItem(new StatusViewModel(tweet)); + getWorld().addTimeline(this, tweet -> { + adapter.add(tweet); adapter.update(); - }, id -> { - adapter.removeItemById(id); - adapter.updateForce(); }); - if (Application.getInstance().getCurrentAccount() != null) { - Logger.debug(String.format("Current account %s is set; refreshing", Application.getInstance().getCurrentAccount().getUser().getScreenName())); - refresh(); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - StatusFilter.getInstance().unregister(this); + refresh(); } @Override public void refresh() { - runRefreshTask(new Timelines.HomeTimelineTask(Application.getInstance().getCurrentAccount()), () -> getAdapter().updateForce()); + runRefreshTask(new Timelines.HomeTimelineTask(getWorld().getAccount()), () -> getAdapter().updateForce()); } // --------------------- Interface OnRefreshListener2 --------------------- @Override public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) { - final MainActivity activity = (MainActivity) getActivity(); - if (activity.isStreaming()) { + if (getWorld().isStreaming()) { new UIHandler().post(() -> { updateListViewWithNotice(refreshView.getRefreshableView(), true); refreshView.onRefreshComplete(); }); } else { runRefreshTask( - new Timelines.HomeTimelineTask(Application.getInstance().getCurrentAccount()) + new Timelines.HomeTimelineTask(getWorld().getAccount()) .setSinceId(getAdapter().getTopID()), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), true); @@ -106,7 +85,7 @@ public class HomeFragment extends CustomListFragment<StatusListAdapter> { @Override public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) { runRefreshTask( - new Timelines.HomeTimelineTask(Application.getInstance().getCurrentAccount()) + new Timelines.HomeTimelineTask(getWorld().getAccount()) .setMaxId(getAdapter().getLastID() - 1), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), false); @@ -117,12 +96,8 @@ public class HomeFragment extends CustomListFragment<StatusListAdapter> { private void runRefreshTask(TimelineTask<Tweet> task, Runnable onFinish) { task .setCount(200) - .onFail(e -> Notificator.getInstance().alert(R.string.notice_error_get_home)) - .onDoneUI(tweets -> { - for (Tweet tweet : tweets) { - StatusFilter.getInstance().filter(tweet); - } - }) + .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/MentionsFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.java index cfa75d7d..21ae1169 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.java @@ -31,14 +31,12 @@ 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.notification.Notificator; -import net.lacolaco.smileessence.twitter.StatusFilter; +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.StatusListAdapter; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; +import net.lacolaco.smileessence.view.adapter.TimelineAdapter; -public class MentionsFragment extends CustomListFragment<StatusListAdapter> { +public class MentionsFragment extends CustomListFragment<TimelineAdapter> { // --------------------- GETTER / SETTER METHODS --------------------- @@ -51,42 +49,32 @@ public class MentionsFragment extends CustomListFragment<StatusListAdapter> { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - StatusListAdapter adapter = new StatusListAdapter(getActivity()); + + final TimelineAdapter adapter = new TimelineAdapter(getActivity()); setAdapter(adapter); - StatusFilter.getInstance().register(this, Tweet.class, (Tweet tweet) -> { - StatusViewModel vm = new StatusViewModel(tweet); - if (tweet.getMentions().contains(Application.getInstance().getCurrentAccount().getUser().getScreenName())) { - adapter.addItem(vm); + // 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.addItem(vm); + adapter.add(tweet); adapter.update(); - return; } } } - }, id -> { - adapter.removeItemById(id); - adapter.updateForce(); }); - if (Application.getInstance().getCurrentAccount() != null) { - refresh(); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - StatusFilter.getInstance().unregister(this); + refresh(); } @Override public void refresh() { - runRefreshTask(new Timelines.MentionsTimelineTask(Application.getInstance().getCurrentAccount()), () -> getAdapter().updateForce()); + runRefreshTask(new Timelines.MentionsTimelineTask(getWorld().getAccount()), () -> getAdapter().updateForce()); } // --------------------- Interface OnRefreshListener2 --------------------- @@ -94,7 +82,7 @@ public class MentionsFragment extends CustomListFragment<StatusListAdapter> { @Override public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) { runRefreshTask( - new Timelines.MentionsTimelineTask(Application.getInstance().getCurrentAccount()) + new Timelines.MentionsTimelineTask(getWorld().getAccount()) .setSinceId(getAdapter().getTopID()), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), true); @@ -105,7 +93,7 @@ public class MentionsFragment extends CustomListFragment<StatusListAdapter> { @Override public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) { runRefreshTask( - new Timelines.MentionsTimelineTask(Application.getInstance().getCurrentAccount()) + new Timelines.MentionsTimelineTask(getWorld().getAccount()) .setMaxId(getAdapter().getLastID() - 1), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), false); @@ -116,12 +104,8 @@ public class MentionsFragment extends CustomListFragment<StatusListAdapter> { private void runRefreshTask(TimelineTask<Tweet> task, Runnable onFinish) { task .setCount(200) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_error_get_mentions)) - .onDoneUI(tweets -> { - for (Tweet tweet : tweets) { - StatusFilter.getInstance().filter(tweet); - } - }) + .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/MessagesFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.java index e07cf272..291f4cfc 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.java @@ -30,64 +30,40 @@ 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.notification.Notificator; -import net.lacolaco.smileessence.twitter.StatusFilter; import net.lacolaco.smileessence.twitter.task.Messages; import net.lacolaco.smileessence.twitter.task.TimelineTask; import net.lacolaco.smileessence.view.adapter.MessageListAdapter; -import net.lacolaco.smileessence.viewmodel.MessageViewModel; -/** - * Fragment of messages list - */ public class MessagesFragment extends CustomListFragment<MessageListAdapter> { - - // --------------------- GETTER / SETTER METHODS --------------------- - @Override protected PullToRefreshBase.Mode getRefreshMode() { return PullToRefreshBase.Mode.BOTH; } - // ------------------------ INTERFACE METHODS ------------------------ - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MessageListAdapter adapter = new MessageListAdapter(getActivity()); setAdapter(adapter); - StatusFilter.getInstance().register(this, DirectMessage.class, (DirectMessage message) -> { - adapter.addItem(new MessageViewModel(message)); + getWorld().addDirectMessageTimeline(this, message -> { + adapter.add(message); adapter.update(); - }, id -> { - adapter.removeItemById(id); - adapter.updateForce(); }); - if (Application.getInstance().getCurrentAccount() != null) { - refresh(); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - StatusFilter.getInstance().unregister(this); + refresh(); } @Override public void refresh() { - runRefreshTask(new Messages.GetAllReceived(Application.getInstance().getCurrentAccount()), () -> getAdapter().updateForce()); - runRefreshTask(new Messages.GetAllSent(Application.getInstance().getCurrentAccount()), () -> getAdapter().updateForce()); + runRefreshTask(new Messages.GetAllReceived(getWorld().getAccount()), () -> getAdapter().updateForce()); + runRefreshTask(new Messages.GetAllSent(getWorld().getAccount()), () -> getAdapter().updateForce()); } - // --------------------- Interface OnRefreshListener2 --------------------- - @Override public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) { runRefreshTask( - new Messages.GetAllReceived(Application.getInstance().getCurrentAccount()) + new Messages.GetAllReceived(getWorld().getAccount()) .setSinceId(getAdapter().getTopID()), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), true); @@ -98,7 +74,7 @@ public class MessagesFragment extends CustomListFragment<MessageListAdapter> { @Override public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) { runRefreshTask( - new Messages.GetAllReceived(Application.getInstance().getCurrentAccount()) + new Messages.GetAllReceived(getWorld().getAccount()) .setMaxId(getAdapter().getLastID() - 1), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), false); @@ -109,10 +85,10 @@ public class MessagesFragment extends CustomListFragment<MessageListAdapter> { private void runRefreshTask(TimelineTask<DirectMessage> task, Runnable onFinish) { task .setCount(200) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_error_get_messages)) + .onFail(x -> getWorld().notifyError(R.string.notice_error_get_messages)) .onDoneUI(messages -> { for (DirectMessage message : messages) { - StatusFilter.getInstance().filter(message); + getWorld().addDirectMessage(message); } }) .onFinishUI(onFinish) 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 index d9393ccd..c1299298 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.java @@ -1,20 +1,32 @@ 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 T getAdapter() { + protected final T getAdapter() { if (adapter == null) throw new IllegalStateException("adapter is not initialized"); return adapter; } - protected void setAdapter(T _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/PostFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.java index 94fd5ba9..f0c54f6f 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.java @@ -37,20 +37,19 @@ import android.text.method.ArrowKeyMovementMethod; import android.view.*; import android.widget.*; import com.twitter.Validator; -import net.lacolaco.smileessence.Application; 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.notification.Notificator; 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.viewmodel.StatusViewModel; +import net.lacolaco.smileessence.view.Partials; import java.io.File; @@ -135,7 +134,7 @@ public class PostFragment extends PageFragment implements TextWatcher, View.OnFo Tweet tweet = postState.getInReplyTo(); View header = viewGroupReply.findViewById(R.id.layout_post_reply_status); - header = new StatusViewModel(tweet).getView(activity, activity.getLayoutInflater(), header); + header = Partials.getTweetView(tweet, activity, header, true); header.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.transparent)); header.setClickable(false); } else { @@ -168,7 +167,7 @@ public class PostFragment extends PageFragment implements TextWatcher, View.OnFo private void updateTextCount(CharSequence s) { Validator validator = new Validator(); int remainingCount = 140 - validator.getTweetLength(s.toString()); - if (!TextUtils.isEmpty(PostState.getState().getMediaFilePath())) { + if (!TextUtils.isEmpty(getWorld().getPostState().getMediaFilePath())) { remainingCount -= validator.getShortUrlLength(); } textViewCount.setText(String.valueOf(remainingCount)); @@ -202,7 +201,7 @@ public class PostFragment extends PageFragment implements TextWatcher, View.OnFo public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Logger.debug("onCreateView"); - PostState.getState().setListener(this); + getWorld().getPostState().setListener(this); View v = inflater.inflate(R.layout.fragment_post, null); buttonTweet = getTweetButton(v); buttonTweet.setOnClickListener(this); @@ -242,33 +241,33 @@ public class PostFragment extends PageFragment implements TextWatcher, View.OnFo Logger.debug("onDestroyView"); super.onDestroyView(); setStateFromView(); - PostState.getState().removeListener(); + getWorld().getPostState().removeListener(); } @Override public void onViewStateRestored(Bundle savedInstanceState) { Logger.debug("onViewStateRestored"); super.onViewStateRestored(savedInstanceState); - PostState state = PostState.getState(); + PostState state = getWorld().getPostState(); onPostStateChange(state); } private void deletePost() { editText.setText(""); - PostState.getState().beginTransaction().setText("").setCursor(0).commit(); + getWorld().getPostState().beginTransaction().setText("").setCursor(0).commit(); deleteReply(); } private void deleteReply() { viewGroupReply.setVisibility(View.GONE); - PostState.getState().beginTransaction().setInReplyTo(null).commit(); + 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(PostState.getState().getMediaFilePath())), "image/*"); + intent.setDataAndType(Uri.fromFile(new File(getWorld().getPostState().getMediaFilePath())), "image/*"); IntentUtils.startActivityIfFound(getActivity(), intent); } @@ -296,7 +295,7 @@ public class PostFragment extends PageFragment implements TextWatcher, View.OnFo SystemServiceHelper.hideIM(getActivity(), editText); viewGroupMedia.setVisibility(View.GONE); ((ImageView) viewGroupMedia.findViewById(R.id.image_post_media)).setImageBitmap(null); - PostState.getState().beginTransaction().setMediaFilePath("").commit(); + getWorld().getPostState().beginTransaction().setMediaFilePath("").commit(); } private void setImage() { @@ -309,7 +308,7 @@ public class PostFragment extends PageFragment implements TextWatcher, View.OnFo } private void setStateFromView() { - PostState state = PostState.getState(); + PostState state = getWorld().getPostState(); state.removeListener(); state.beginTransaction() .setText(editText.getText().toString()) @@ -321,15 +320,15 @@ public class PostFragment extends PageFragment implements TextWatcher, View.OnFo private void submitPost() { SystemServiceHelper.hideIM(getActivity(), editText); setStateFromView(); - PostState state = PostState.getState(); + PostState state = getWorld().getPostState(); MainActivity mainActivity = (MainActivity) getActivity(); boolean resizeFlag = UserPreferenceHelper.getInstance().get(R.string.key_setting_resize_post_image, false); - new Tweets.CreateTask(Application.getInstance().getCurrentAccount(), state.toStatusUpdate(), state.getMediaFilePath(), resizeFlag) + new Tweets.CreateTask(getWorld().getAccount(), state.toStatusUpdate(), state.getMediaFilePath(), resizeFlag) .onDoneUI(t -> { - Notificator.getInstance().publish(R.string.notice_tweet_succeeded); - PostState.newState().beginTransaction().commit(); + getWorld().notify(R.string.notice_tweet_succeeded); + getWorld().getPostState().beginTransaction().clear().commit(); }) - .onFail(e -> Notificator.getInstance().alert(R.string.notice_tweet_failed, e)) + .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/SearchFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.java index 99173bf6..84d10c21 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.java @@ -24,6 +24,7 @@ package net.lacolaco.smileessence.view.page; +import android.app.AlertDialog; import android.os.Bundle; import android.support.annotation.NonNull; import android.text.Spannable; @@ -40,30 +41,28 @@ 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.command.Command; -import net.lacolaco.smileessence.command.CommandOpenSearch; +import net.lacolaco.smileessence.activity.MainActivity; import net.lacolaco.smileessence.entity.SavedSearch; -import net.lacolaco.smileessence.notification.Notificator; 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.DialogHelper; -import net.lacolaco.smileessence.view.adapter.SearchListAdapter; -import net.lacolaco.smileessence.view.dialog.SelectSearchQueryDialogFragment; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; +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<SearchListAdapter> implements View.OnClickListener, View.OnFocusChangeListener, - SearchListAdapter.OnQueryChangeListener { +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 --------------------- @@ -79,19 +78,19 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); - SearchListAdapter adapter = new SearchListAdapter(getActivity()); + + queryString = InternalPreferenceHelper.getInstance().get(R.string.key_last_used_search_query, ""); + android.app.Activity activity = getActivity(); + adapter = new TimelineAdapter(activity); setAdapter(adapter); - if (Application.getInstance().getCurrentAccount() != null) { - refresh(); - } + refresh(); } @Override public void refresh() { //TODO - String lastUsedSearchQuery = InternalPreferenceHelper.getInstance().get(R.string.key_last_used_search_query, ""); - if (!TextUtils.isEmpty(lastUsedSearchQuery)) { - startSearch(lastUsedSearchQuery); + if (!TextUtils.isEmpty(queryString)) { + startSearch(queryString); } } @@ -114,21 +113,35 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem } } - // --------------------- Interface OnFocusChangeListener --------------------- - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - SystemServiceHelper.hideIM(getActivity(), editText); + 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 OnQueryChangeListener --------------------- + // --------------------- Interface OnFocusChangeListener --------------------- @Override - public void onQueryChange(String newQuery) { - if (editText != null) { - editText.setText(newQuery); + public void onFocusChange(View v, boolean hasFocus) { + if (!hasFocus) { + SystemServiceHelper.hideIM(getActivity(), editText); } } @@ -136,8 +149,6 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem @Override public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) { - final SearchListAdapter adapter = getAdapter(); - String queryString = adapter.getQuery(); if (TextUtils.isEmpty(queryString)) { new UIHandler().post(() -> { notifyTextEmpty(); @@ -160,8 +171,6 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem @Override public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) { - final SearchListAdapter adapter = getAdapter(); - String queryString = adapter.getQuery(); if (TextUtils.isEmpty(queryString)) { new UIHandler().post(() -> { notifyTextEmpty(); @@ -193,7 +202,6 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View page = inflater.inflate(R.layout.fragment_search, container, false); PullToRefreshListView listView = getListView(page); - SearchListAdapter adapter = getAdapter(); listView.setAdapter(adapter); listView.setOnScrollListener(this); listView.setOnRefreshListener(this); @@ -206,7 +214,7 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem buttonSave.setOnClickListener(this); editText = getEditText(page); editText.setOnFocusChangeListener(this); - editText.setText(adapter.getQuery()); + editText.setText(queryString); editText.setOnEditorActionListener((textView, i, keyEvent) -> { if (i == EditorInfo.IME_ACTION_SEARCH || keyEvent != null && @@ -229,7 +237,6 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem return widget.getSelectionStart() == 0 || super.left(widget, buffer); } }); - adapter.setOnQueryChangeListener(this); return page; } @@ -250,32 +257,29 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem } private void notifyTextEmpty() { - Notificator.getInstance().alert(R.string.notice_search_text_empty); + getWorld().notifyError(R.string.notice_search_text_empty); } private void openSearchQueryDialog() { - DialogHelper.showDialog(getActivity(), new SelectSearchQueryDialogFragment() { - @Override - protected void executeCommand(Command command) { - super.executeCommand(command); - SavedSearch ss = ((CommandOpenSearch) command).getQuery(); - editText.setText(ss.getQuery()); - SystemServiceHelper.hideIM(SearchFragment.this.getActivity(), editText); - } + 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)) { - Notificator.getInstance().alert(R.string.notice_query_is_empty); + getWorld().notifyError(R.string.notice_query_is_empty); } else { - new Searches.CreateSavedSearchTask(Application.getInstance().getCurrentAccount(), text).onDoneUI(cb -> { - Notificator.getInstance().publish(R.string.notice_query_saved); - Application.getInstance().getCurrentAccount().refreshSavedSearches(); - }).onFailUI(ex -> { - Notificator.getInstance().publish("Query is not saved"); - }).execute(); + 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(); } } @@ -283,7 +287,7 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem if (editText != null) { String text = editText.getText().toString(); if (TextUtils.isEmpty(text)) { - Notificator.getInstance().alert(R.string.notice_query_is_empty); + getWorld().notifyError(R.string.notice_query_is_empty); } else { startSearch(text); SystemServiceHelper.hideIM(getActivity(), editText); @@ -293,10 +297,12 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem 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 SearchListAdapter adapter = getAdapter(); - adapter.initSearch(queryString); - adapter.updateForce(); final Query query = new Query(); query.setQuery(queryString); query.setCount(200); @@ -306,13 +312,9 @@ public class SearchFragment extends CustomListFragment<SearchListAdapter> implem } private void runRefreshTask(Query query, Runnable onFinish) { - final SearchListAdapter adapter = getAdapter(); - new Searches.SearchTask(Application.getInstance().getCurrentAccount(), query) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_error_search)) - .onDoneUI(tweets -> { - List<StatusViewModel> e = ListUtils.map(ListUtils.filter(tweets, t -> !t.isRetweet()), StatusViewModel::new); - adapter.addItems(e); - }) + 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/UserListFragment.java b/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.java index 2ec98dc2..3d19c5d6 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.java +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.java @@ -24,7 +24,7 @@ package net.lacolaco.smileessence.view.page; -import android.content.DialogInterface; +import android.app.AlertDialog; import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; @@ -37,42 +37,30 @@ 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.notification.Notificator; import net.lacolaco.smileessence.preference.InternalPreferenceHelper; -import net.lacolaco.smileessence.twitter.StatusFilter; 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.DialogHelper; -import net.lacolaco.smileessence.view.adapter.UserListListAdapter; -import net.lacolaco.smileessence.view.dialog.SelectUserListDialogFragment; -import net.lacolaco.smileessence.viewmodel.StatusViewModel; - -public class UserListFragment extends CustomListFragment<UserListListAdapter> implements View.OnClickListener { - - // ------------------------------ FIELDS ------------------------------ +import net.lacolaco.smileessence.view.adapter.TimelineAdapter; +public class UserListFragment extends CustomListFragment<TimelineAdapter> implements View.OnClickListener { private TextView textListName; - - // --------------------- GETTER / SETTER METHODS --------------------- + private String listFullName; @Override protected PullToRefreshBase.Mode getRefreshMode() { return PullToRefreshBase.Mode.BOTH; } - // ------------------------ INTERFACE METHODS ------------------------ - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - UserListListAdapter adapter = new UserListListAdapter(getActivity()); + TimelineAdapter adapter = new TimelineAdapter(getActivity()); setAdapter(adapter); - if (Application.getInstance().getCurrentAccount() != null) { - refresh(); - } + refresh(); } @Override @@ -83,8 +71,6 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im } } - // --------------------- Interface OnClickListener --------------------- - @Override public void onClick(View v) { int id = v.getId(); @@ -96,13 +82,9 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im } } - // --------------------- Interface OnRefreshListener2 --------------------- - @Override public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView) { - final UserListListAdapter adapter = getAdapter(); - String listFullName = adapter.getListFullName(); - if (TextUtils.isEmpty(listFullName)) { + if (listFullName == null) { new UIHandler().post(() -> { notifyTextEmpty(); refreshView.onRefreshComplete(); @@ -110,8 +92,8 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im return; } runRefreshTask( - new Timelines.UserListStatusesTask(Application.getInstance().getCurrentAccount(), listFullName) - .setSinceId(adapter.getTopID()), + new Timelines.UserListStatusesTask(getWorld().getAccount(), listFullName) + .setSinceId(getAdapter().getTopID()), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), true); refreshView.onRefreshComplete(); @@ -120,9 +102,7 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im @Override public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView) { - final UserListListAdapter adapter = getAdapter(); - String listFullName = adapter.getListFullName(); - if (TextUtils.isEmpty(listFullName)) { + if (listFullName == null) { new UIHandler().post(() -> { notifyTextEmpty(); refreshView.onRefreshComplete(); @@ -130,8 +110,8 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im return; } runRefreshTask( - new Timelines.UserListStatusesTask(Application.getInstance().getCurrentAccount(), listFullName) - .setMaxId(adapter.getLastID() - 1), + new Timelines.UserListStatusesTask(getWorld().getAccount(), listFullName) + .setMaxId(getAdapter().getLastID() - 1), () -> { updateListViewWithNotice(refreshView.getRefreshableView(), false); refreshView.onRefreshComplete(); @@ -149,7 +129,7 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View page = inflater.inflate(R.layout.fragment_userlist, container, false); PullToRefreshListView listView = getListView(page); - UserListListAdapter adapter = getAdapter(); + TimelineAdapter adapter = getAdapter(); listView.setAdapter(adapter); listView.setOnScrollListener(this); listView.setOnRefreshListener(this); @@ -157,7 +137,7 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im ImageButton buttonUserLists = getUserListsButton(page); buttonUserLists.setOnClickListener(this); textListName = getTextListName(page); - textListName.setText(adapter.getListFullName()); + textListName.setText(listFullName != null ? listFullName : "<none>"); return page; } @@ -170,40 +150,41 @@ public class UserListFragment extends CustomListFragment<UserListListAdapter> im } private void notifyTextEmpty() { - Notificator.getInstance().alert(R.string.notice_userlist_not_selected); + getWorld().notifyError(R.string.notice_userlist_not_selected); } private void openUserListsDialog() { - DialogHelper.showDialog(getActivity(), new SelectUserListDialogFragment() { - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - textListName.setText(getAdapter().getListFullName()); - } - }); + 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 UserListListAdapter adapter = getAdapter(); - adapter.setListFullName(listFullName); + final TimelineAdapter adapter = getAdapter(); + this.listFullName = listFullName; adapter.clear(); adapter.updateForce(); runRefreshTask( - new Timelines.UserListStatusesTask(Application.getInstance().getCurrentAccount(), listFullName), + new Timelines.UserListStatusesTask(getWorld().getAccount(), listFullName), adapter::updateForce); } private void runRefreshTask(TimelineTask<Tweet> task, Runnable onFinish) { - final UserListListAdapter adapter = getAdapter(); + final TimelineAdapter adapter = getAdapter(); task .setCount(200) - .onFail(x -> Notificator.getInstance().alert(R.string.notice_error_get_list)) + .onFail(x -> getWorld().notifyError(R.string.notice_error_get_list)) .onDoneUI(tweets -> { - for (Tweet tweet : tweets) { - StatusFilter.getInstance().filter(tweet); - adapter.addItem(new StatusViewModel(tweet)); - } + getWorld().addTweetAll(tweets); + adapter.addAll(tweets); }) .onFinishUI(onFinish) .execute(); |