aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/net/lacolaco/smileessence/view/adapter
diff options
context:
space:
mode:
authorlaco0416 <laco0416@gmail.com>2015-04-26 19:03:29 +0900
committerlaco0416 <laco0416@gmail.com>2015-04-26 19:03:31 +0900
commitd2cda779b3dcaad81ad68018270b84636a576c37 (patch)
treecf6b2e2019f0778ef96bb5b2ee7849b6722bee8d /app/src/main/java/net/lacolaco/smileessence/view/adapter
parentae56571e6e1358ce2ae7afb24959d97af0917022 (diff)
downloadSmileEssence-d2cda779b3dcaad81ad68018270b84636a576c37.tar.gz
Reconstruct the project
Diffstat (limited to 'app/src/main/java/net/lacolaco/smileessence/view/adapter')
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java178
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java38
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java107
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java186
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/PostState.java202
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/SearchListAdapter.java83
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/adapter/StatusListAdapter.java113
7 files changed, 907 insertions, 0 deletions
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
new file mode 100644
index 00000000..69c893e5
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/CustomListAdapter.java
@@ -0,0 +1,178 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.Activity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import com.google.common.collect.Iterables;
+
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.viewmodel.IViewModel;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class CustomListAdapter<T extends IViewModel> extends BaseAdapter {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ protected final Object LOCK = new Object();
+ protected Class<T> clss;
+ protected ArrayList<T> list = new ArrayList<>();
+ protected T[] array;
+ protected int count;
+ protected boolean isNotifiable = true;
+ protected Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CustomListAdapter(Activity activity, Class<T> clss) {
+ this.activity = activity;
+ this.clss = clss;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public Activity getActivity() {
+ return activity;
+ }
+
+ @Override
+ public int getCount() {
+ return count;
+ }
+
+ public boolean isNotifiable() {
+ synchronized (LOCK) {
+ return isNotifiable;
+ }
+ }
+
+ public void setNotifiable(boolean notifiable) {
+ synchronized (LOCK) {
+ isNotifiable = notifiable;
+ }
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface Adapter ---------------------
+
+ @Override
+ public Object getItem(int position) {
+ return array[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return ((T) getItem(position)).getView(activity, activity.getLayoutInflater(), convertView);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void notifyDataSetChanged() {
+ sort();
+ array = Iterables.toArray(list, clss);
+ count = array.length;
+ super.notifyDataSetChanged();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void addToBottom(T... items) {
+ synchronized (LOCK) {
+ List<T> buffer = Arrays.asList(items);
+ for (T item : buffer) {
+ if (list.contains(item)) {
+ list.remove(item);
+ }
+ list.add(item);
+ }
+ }
+ }
+
+ public void addToTop(T... items) {
+ synchronized (LOCK) {
+ List<T> buffer = Arrays.asList(items);
+ Collections.reverse(buffer);
+ for (T item : buffer) {
+ if (list.contains(item)) {
+ list.remove(item);
+ }
+ list.add(0, item);
+ }
+ }
+ }
+
+ public void clear() {
+ synchronized (LOCK) {
+ list.clear();
+ }
+ }
+
+ public T removeItem(int position) {
+ synchronized (LOCK) {
+ return list.remove(position);
+ }
+ }
+
+ public boolean removeItem(T item) {
+ synchronized (LOCK) {
+ return list.remove(item);
+ }
+ }
+
+ public void sort() {
+ }
+
+ public void update() {
+ if (isNotifiable) {
+ updateForce();
+ }
+ }
+
+ public void updateForce() {
+ synchronized (LOCK) {
+ new UIHandler() {
+ @Override
+ public void run() {
+ notifyDataSetChanged();
+ }
+ }.post();
+ }
+ }
+}
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
new file mode 100644
index 00000000..94762845
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.java
@@ -0,0 +1,38 @@
+/*
+ * 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.EventViewModel;
+
+public class EventListAdapter extends CustomListAdapter<EventViewModel> {
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public EventListAdapter(Activity activity) {
+ super(activity, EventViewModel.class);
+ }
+}
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
new file mode 100644
index 00000000..7c6b992d
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.java
@@ -0,0 +1,107 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.Activity;
+
+import net.lacolaco.smileessence.viewmodel.MessageViewModel;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+
+public class MessageListAdapter extends CustomListAdapter<MessageViewModel> {
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageListAdapter(Activity activity) {
+ super(activity, MessageViewModel.class);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getLastID() {
+ return ((MessageViewModel) getItem(getCount() - 1)).getID();
+ }
+
+ public long getTopID() {
+ return ((MessageViewModel) getItem(0)).getID();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void addToBottom(MessageViewModel... items) {
+ for (MessageViewModel item : items) {
+ if (!preAdd(item)) {
+ continue;
+ }
+ super.addToBottom(items);
+ }
+ }
+
+ @Override
+ public void addToTop(MessageViewModel... items) {
+ for (MessageViewModel item : items) {
+ if (!preAdd(item)) {
+ continue;
+ }
+ super.addToTop(items);
+ }
+ }
+
+ @Override
+ public void sort() {
+ synchronized (LOCK) {
+ Collections.sort(list, new Comparator<MessageViewModel>() {
+ @Override
+ public int compare(MessageViewModel lhs, MessageViewModel rhs) {
+ return rhs.getCreatedAt().compareTo(lhs.getCreatedAt());
+ }
+ });
+ }
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public MessageViewModel removeByMessageID(long messageID) {
+ synchronized (this.LOCK) {
+ Iterator<MessageViewModel> iterator = this.list.iterator();
+ while (iterator.hasNext()) {
+ MessageViewModel message = iterator.next();
+ if (message.getID() == messageID) {
+ iterator.remove();
+ return message;
+ }
+ }
+ return null;
+ }
+ }
+
+ private boolean preAdd(MessageViewModel item) {
+ removeByMessageID(item.getID());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java
new file mode 100644
index 00000000..7c6cab9a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.java
@@ -0,0 +1,186 @@
+/*
+ * 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.ActionBar;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.v13.app.FragmentStatePagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.widget.ArrayAdapter;
+
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.logging.Logger;
+
+import java.util.ArrayList;
+
+public class PageListAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener,
+ ActionBar.OnNavigationListener {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final MainActivity context;
+ private final ActionBar actionBar;
+ private final ViewPager viewPager;
+ private final ArrayList<PageInfo> pages = new ArrayList<>();
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PageListAdapter(MainActivity activity, ViewPager viewPager) {
+ super(activity.getFragmentManager());
+ this.context = activity;
+ this.actionBar = activity.getActionBar();
+ this.viewPager = viewPager;
+ viewPager.setAdapter(this);
+ viewPager.setOnPageChangeListener(this);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public synchronized int getCount() {
+ return pages.size();
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnNavigationListener ---------------------
+
+ @Override
+ public synchronized boolean onNavigationItemSelected(int itemPosition, long itemId) {
+ viewPager.setCurrentItem(itemPosition, true);
+ return true;
+ }
+
+ // --------------------- Interface OnPageChangeListener ---------------------
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ }
+
+ @Override
+ public synchronized void onPageSelected(int position) {
+ //Synchronize pager and navigation.
+ Logger.debug(String.format("Page selected:%d", position));
+ actionBar.setSelectedNavigationItem(position);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ /**
+ * Add new tab and new page
+ *
+ * @param name Page name
+ * @param clss Fragment class
+ * @param args Bundle for Fragment instantiate
+ * @return True if adding is complete successfully
+ */
+ public synchronized boolean addPage(String name, Class<? extends Fragment> clss, Bundle args) {
+ if (addPageWithoutNotify(name, clss, args)) {
+ refreshListNavigation();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Add new tab and new page without notify.
+ * You must call notifyDataSetChanged after adding tab.
+ *
+ * @param name Page name
+ * @param clss Fragment class
+ * @param args Bundle for Fragment instantiate
+ * @return True if adding is complete successfully
+ */
+ public synchronized boolean addPageWithoutNotify(String name, Class<? extends Fragment> clss, Bundle args) {
+ PageInfo info = new PageInfo(name, clss, args);
+ return pages.add(info);
+ }
+
+ @Override
+ public synchronized Fragment getItem(int position) {
+ PageInfo info = pages.get(position);
+ return Fragment.instantiate(context, info.fragmentClass.getName(), info.args);
+ }
+
+ public synchronized PageInfo getPage(int position) {
+ return pages.get(position);
+ }
+
+ public synchronized void refreshListNavigation() {
+ ArrayList<String> itemList = new ArrayList<>();
+ for (PageInfo page : pages) {
+ itemList.add(page.name);
+ }
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(context, R.layout.navigation_list_item, R.id.navigation_list_item_text, itemList);
+ actionBar.setListNavigationCallbacks(adapter, this);
+ notifyDataSetChanged();
+ }
+
+ public synchronized boolean removePage(int position) {
+ if (removePageWithoutNotify(position)) {
+ refreshListNavigation();
+ return true;
+ }
+ return false;
+ }
+
+ private synchronized boolean removePageWithoutNotify(int position) {
+ return pages.remove(position) != null;
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ public static final class PageInfo {
+
+ private final String name;
+ private final Class<? extends Fragment> fragmentClass;
+ private final Bundle args;
+
+ PageInfo(String name, Class<? extends Fragment> clss, Bundle args) {
+ this.name = name;
+ this.fragmentClass = clss;
+ this.args = args;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Class<? extends Fragment> getFragmentClass() {
+ return fragmentClass;
+ }
+
+ public Bundle getArgs() {
+ return args;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/PostState.java b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PostState.java
new file mode 100644
index 00000000..c3810408
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PostState.java
@@ -0,0 +1,202 @@
+/*
+ * 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 net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+
+import twitter4j.StatusUpdate;
+
+public class PostState {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static PostState instance = new PostState();
+ private String text = "";
+ private long inReplyToStatusID = -1L;
+ private String inReplyToScreenName = "";
+ private String inReplyToText = "";
+ private String mediaFilePath = "";
+ private boolean directMessage = false;
+ private OnPostStateChangeListener listener;
+ private int selectionStart = 0;
+ private int selectionEnd = 0;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private PostState() {
+ }
+
+ public static PostState getState() {
+ return instance;
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static PostState newState() {
+ return instance = new PostState().setListener(instance.listener);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getInReplyToStatusID() {
+ return inReplyToStatusID;
+ }
+
+ public String getMediaFilePath() {
+ return mediaFilePath;
+ }
+
+ public int getSelectionEnd() {
+ if (selectionEnd < 0) {
+ return text.length();
+ }
+ return selectionEnd;
+ }
+
+ public int getSelectionStart() {
+ if (selectionStart < 0) {
+ return text.length();
+ }
+ return selectionStart;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public PostState setListener(OnPostStateChangeListener listener) {
+ this.listener = listener;
+ return this;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public PostStateTransaction beginTransaction() {
+ return new PostStateTransaction(this);
+ }
+
+ public void removeListener() {
+ this.listener = null;
+ }
+
+ /**
+ * Convert to StatusUpdate for tweet.
+ *
+ * @return StatusUpdate
+ */
+ public StatusUpdate toStatusUpdate() {
+ return new StatusUpdate(getText())
+ .inReplyToStatusId(getInReplyToStatusID());
+ }
+
+ private PostState copy(PostState another) {
+ this.text = another.text;
+ this.inReplyToStatusID = another.inReplyToStatusID;
+ this.inReplyToScreenName = another.inReplyToScreenName;
+ this.inReplyToText = another.inReplyToText;
+ this.mediaFilePath = another.mediaFilePath;
+ this.directMessage = another.directMessage;
+ this.selectionStart = another.selectionStart;
+ this.selectionEnd = another.selectionEnd;
+ this.listener = another.listener;
+ return this;
+ }
+
+ private void postStateChange() {
+ if (listener != null) {
+ listener.onPostStateChange(this);
+ }
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ public static interface OnPostStateChangeListener {
+
+ void onPostStateChange(PostState postState);
+ }
+
+ public static class PostStateTransaction {
+
+ private PostState state;
+
+ private PostStateTransaction(PostState state) {
+ this.state = new PostState().copy(state);
+ }
+
+ public PostStateTransaction setText(String text) {
+ state.text = text;
+ return this;
+ }
+
+ public PostStateTransaction appendText(String text) {
+ state.text = state.text + text;
+ return this;
+ }
+
+ public PostStateTransaction insertText(int index, String text) {
+ StringBuilder builder = new StringBuilder(state.text);
+ builder.insert(index, text);
+ state.text = builder.toString();
+ return this;
+ }
+
+ public PostStateTransaction setInReplyToStatusID(long inReplyToStatusID) {
+ state.inReplyToStatusID = inReplyToStatusID;
+ return this;
+ }
+
+ public PostStateTransaction setMediaFilePath(String mediaFilePath) {
+ state.mediaFilePath = mediaFilePath;
+ return this;
+ }
+
+ public PostStateTransaction setCursor(int cursor) {
+ state.selectionStart = state.selectionEnd = cursor;
+ return this;
+ }
+
+ public PostStateTransaction setSelection(int start, int end) {
+ state.selectionStart = start;
+ state.selectionEnd = end;
+ return this;
+ }
+
+ public void commit() {
+ PostState.getState().copy(state).postStateChange();
+ }
+
+ public void commitWithOpen(MainActivity activity) {
+ DialogHelper.closeAll(activity);
+ PostState.getState().copy(state).postStateChange();
+ activity.openPostPage();
+ }
+
+ public PostStateTransaction moveCursor(int length) {
+ int cursor = state.selectionEnd + length;
+ return setCursor(cursor);
+ }
+ }
+}
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
new file mode 100644
index 00000000..20a5971a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/SearchListAdapter.java
@@ -0,0 +1,83 @@
+/*
+ * 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 {
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private long topID;
+ private String query;
+ private OnQueryChangeListener listener;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public SearchListAdapter(Activity activity) {
+ super(activity);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public OnQueryChangeListener getListener() {
+ return listener;
+ }
+
+ public String getQuery() {
+ return query;
+ }
+
+ @Override
+ public long getTopID() {
+ return topID;
+ }
+
+ public void setTopID(long topID) {
+ this.topID = topID;
+ }
+
+ public void setOnQueryChangeListener(OnQueryChangeListener listener) {
+ this.listener = listener;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void initSearch(String query) {
+ this.query = query;
+ topID = 0;
+ if (listener != null) {
+ listener.onQueryChange(query);
+ }
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ public static 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
new file mode 100644
index 00000000..80c60b94
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/StatusListAdapter.java
@@ -0,0 +1,113 @@
+/*
+ * 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.data.UserCache;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+
+public class StatusListAdapter extends CustomListAdapter<StatusViewModel> {
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusListAdapter(Activity activity) {
+ super(activity, StatusViewModel.class);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getLastID() {
+ return ((StatusViewModel) getItem(getCount() - 1)).getID();
+ }
+
+ public long getTopID() {
+ return ((StatusViewModel) getItem(0)).getID();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void addToBottom(StatusViewModel... items) {
+ for (StatusViewModel item : items) {
+ if (!preAdd(item)) {
+ continue;
+ }
+ super.addToBottom(item);
+ }
+ }
+
+ @Override
+ public void addToTop(StatusViewModel... items) {
+ for (StatusViewModel item : items) {
+ if (!preAdd(item)) {
+ continue;
+ }
+ super.addToTop(item);
+ }
+ }
+
+ /**
+ * Sort list by Status#createdAt
+ */
+ @Override
+ public void sort() {
+ synchronized (LOCK) {
+ Collections.sort(list, new Comparator<StatusViewModel>() {
+ @Override
+ public int compare(StatusViewModel lhs, StatusViewModel rhs) {
+ return Long.valueOf(rhs.getID()).compareTo(lhs.getID());
+ }
+ });
+ }
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void removeByStatusID(long statusID) {
+ synchronized (this.LOCK) {
+ Iterator<StatusViewModel> iterator = this.list.iterator();
+ while (iterator.hasNext()) {
+ StatusViewModel statusViewModel = iterator.next();
+ if (statusViewModel.getID() == statusID || statusViewModel.getOriginal().getID() == statusID) {
+ iterator.remove();
+ }
+ }
+ }
+ }
+
+ private boolean isBlockUser(StatusViewModel item) {
+ return UserCache.getInstance().isInvisibleUserID(item.getOriginalUserID());
+ }
+
+ private boolean preAdd(StatusViewModel item) {
+ removeByStatusID(item.getID());
+ return !isBlockUser(item);
+ }
+}