From 0d06c2931146e1545e40728783539d3e9af3aa44 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Mon, 18 Apr 2016 17:23:23 +0800 Subject: [PATCH 01/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8DMessage=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=B8=ADcreate=5Fat=E5=AD=97=E6=AE=B5=E7=9A=84?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnodejs/android/md/model/entity/Message.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/model/entity/Message.java b/app/src/main/java/org/cnodejs/android/md/model/entity/Message.java index 14382620..ac30d0f8 100644 --- a/app/src/main/java/org/cnodejs/android/md/model/entity/Message.java +++ b/app/src/main/java/org/cnodejs/android/md/model/entity/Message.java @@ -27,7 +27,7 @@ public enum Type { private Reply reply; // 这里不含Author字段,注意 @SerializedName("create_at") - private DateTime createAt; // TODO 这个字段目前不存在,需要服务端补全 + private DateTime createAt; public String getId() { return id; @@ -78,15 +78,8 @@ public void setReply(Reply reply) { this.reply = reply; } - public DateTime getCreateAt() { // TODO 这里做兼容处理 - //return createAt; - if (createAt != null) { - return createAt; - } else if (getReply() != null && getReply().getCreateAt() != null) { - return getReply().getCreateAt(); - } else { - return getTopic().getLastReplyAt(); - } + public DateTime getCreateAt() { + return createAt; } public void setCreateAt(DateTime createAt) { From 4576c5b11e72e0b3ec84d8c133444f6b8a1a01f1 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Mon, 18 Apr 2016 17:43:10 +0800 Subject: [PATCH 02/89] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_user_detail.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/activity_user_detail.xml b/app/src/main/res/layout/activity_user_detail.xml index 4965b36d..850a672d 100644 --- a/app/src/main/res/layout/activity_user_detail.xml +++ b/app/src/main/res/layout/activity_user_detail.xml @@ -54,7 +54,7 @@ android:layout_height="wrap_content" android:padding="4dp" android:textColor="@color/text_color_light" - android:textSize="16sp" + android:textSize="14sp" tools:text="TakWolf@github.com" /> Date: Mon, 18 Apr 2016 17:56:07 +0800 Subject: [PATCH 03/89] =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_login.xml | 12 +++++++++++- app/src/main/res/values/strings.xml | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 32f79674..1532c05e 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -4,7 +4,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="?attr/widgetBackground" - android:orientation="vertical"> + android:orientation="vertical" + android:gravity="center_horizontal"> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3acf4fdd..358990f3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -64,6 +64,7 @@ 扫描二维码 无法打开相机 将二维码放入扫描框内 + 如何获取Access Token? 当前版本 项目开源主页 From 68fcda0f07ac2993cbad32f57741a98f67443cb3 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Mon, 18 Apr 2016 18:06:16 +0800 Subject: [PATCH 04/89] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/md/display/activity/LoginActivity.java | 8 ++++++++ app/src/main/res/values/strings.xml | 1 + 2 files changed, 9 insertions(+) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java index 1a0b46ec..e237a790 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java @@ -138,4 +138,12 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } } + @OnClick(R.id.login_btn_login_tip) + protected void onBtnLoginTipClick() { + DialogUtils.createAlertDialogBuilder(this) + .setMessage(R.string.how_to_get_access_token_tip_content) + .setPositiveButton(R.string.confirm, null) + .show(); + } + } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 358990f3..165871ef 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -65,6 +65,7 @@ 无法打开相机 将二维码放入扫描框内 如何获取Access Token? + 在cnodejs网站端登录你的账户,然后在右上角找到[设置]按钮,点击进入后将页面滑动到最底部,就能看到你的Access Token啦~ 当前版本 项目开源主页 From a60bac45cb8b942640e853fd7f39d28f5e7cb1f5 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Wed, 20 Apr 2016 03:08:49 +0800 Subject: [PATCH 05/89] =?UTF-8?q?=E6=B7=BB=E5=8A=A0header=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../viewholder/TopicHeaderViewHolder.java | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java new file mode 100644 index 00000000..b39416ef --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java @@ -0,0 +1,163 @@ +package org.cnodejs.android.md.display.viewholder; + +import android.app.Activity; +import android.graphics.Color; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; + +import org.cnodejs.android.md.R; +import org.cnodejs.android.md.display.activity.LoginActivity; +import org.cnodejs.android.md.display.activity.UserDetailActivity; +import org.cnodejs.android.md.display.widget.CNodeWebView; +import org.cnodejs.android.md.display.widget.ThemeUtils; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.Topic; +import org.cnodejs.android.md.model.entity.TopicWithReply; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.util.FormatUtils; + +import butterknife.Bind; +import butterknife.ButterKnife; +import butterknife.OnClick; +import retrofit2.Call; +import retrofit2.Response; + +public class TopicHeaderViewHolder { + + @Bind(R.id.topic_item_header_layout_content) + protected ViewGroup layoutContent; + + @Bind(R.id.topic_item_header_icon_good) + protected View iconGood; + + @Bind(R.id.topic_item_header_tv_title) + protected TextView tvTitle; + + @Bind(R.id.topic_item_header_img_avatar) + protected ImageView imgAvatar; + + @Bind(R.id.topic_item_header_tv_tab) + protected TextView tvTab; + + @Bind(R.id.topic_item_header_tv_login_name) + protected TextView tvLoginName; + + @Bind(R.id.topic_item_header_tv_create_time) + protected TextView tvCreateTime; + + @Bind(R.id.topic_item_header_tv_visit_count) + protected TextView tvVisitCount; + + @Bind(R.id.topic_item_header_btn_favorite) + protected ImageView btnFavorite; + + @Bind(R.id.topic_item_header_web_content) + protected CNodeWebView webContent; + + @Bind(R.id.topic_item_header_layout_no_reply) + protected ViewGroup layoutNoReply; + + private final Activity activity; + private Topic topic; + private boolean isCollect; + + public TopicHeaderViewHolder(@NonNull Activity activity, @NonNull ListView listView) { + this.activity = activity; + LayoutInflater inflater = LayoutInflater.from(activity); + View headerView = inflater.inflate(R.layout.activity_topic_item_header, listView, false); + ButterKnife.bind(this, headerView); + listView.addHeaderView(headerView, null, false); + } + + public void update(@Nullable Topic topic, boolean isCollect, int replyCount) { + this.topic = topic; + this.isCollect = isCollect; + if (topic != null) { + layoutContent.setVisibility(View.VISIBLE); + iconGood.setVisibility(topic.isGood() ? View.VISIBLE : View.GONE); + + tvTitle.setText(topic.getTitle()); + Glide.with(activity).load(topic.getAuthor().getAvatarUrl()).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); + tvTab.setText(topic.isTop() ? R.string.tab_top : topic.getTab().getNameId()); + tvTab.setBackgroundDrawable(ThemeUtils.getThemeAttrDrawable(activity, topic.isTop() ? R.attr.referenceBackgroundAccent : R.attr.referenceBackgroundNormal)); + tvTab.setTextColor(topic.isTop() ? Color.WHITE : ThemeUtils.getThemeAttrColor(activity, android.R.attr.textColorSecondary)); + tvLoginName.setText(topic.getAuthor().getLoginName()); + tvCreateTime.setText(FormatUtils.getRecentlyTimeText(topic.getCreateAt()) + "创建"); + tvVisitCount.setText(topic.getVisitCount() + "次浏览"); + btnFavorite.setImageResource(isCollect ? R.drawable.ic_favorite_theme_24dp : R.drawable.ic_favorite_outline_grey600_24dp); + + // 这里直接使用WebView,有性能问题 + webContent.loadRenderedContent(topic.getHandleContent()); + + layoutNoReply.setVisibility(replyCount > 0 ? View.GONE : View.VISIBLE); + } else { + layoutContent.setVisibility(View.GONE); + iconGood.setVisibility(View.GONE); + } + } + + public void update(@NonNull TopicWithReply topic) { + update(topic, topic.isCollect(), topic.getReplyList().size()); + } + + @OnClick(R.id.topic_item_header_img_avatar) + protected void onBtnAvatarClick() { + UserDetailActivity.startWithTransitionAnimation(activity, topic.getAuthor().getLoginName(), imgAvatar, topic.getAuthor().getAvatarUrl()); + } + + @OnClick(R.id.topic_item_header_btn_favorite) + protected void onBtnFavoriteClick() { + if (topic != null) { + if (LoginActivity.startForResultWithAccessTokenCheck(activity)) { + if (isCollect) { + decollectTopicAsyncTask(); + } else { + collectTopicAsyncTask(); + } + } + } + } + + private void collectTopicAsyncTask() { + Call call = ApiClient.service.collectTopic(LoginShared.getAccessToken(activity), topic.getId()); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result result) { + if (!activity.isFinishing()) { + isCollect = true; + btnFavorite.setImageResource(R.drawable.ic_favorite_theme_24dp); + } + return false; + } + + }); + } + + private void decollectTopicAsyncTask() { + Call call = ApiClient.service.decollectTopic(LoginShared.getAccessToken(activity), topic.getId()); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result result) { + if (!activity.isFinishing()) { + isCollect = false; + btnFavorite.setImageResource(R.drawable.ic_favorite_outline_grey600_24dp); + } + return false; + } + + }); + } + +} From 9d3ee19ca6cf55b8f1c7e71df8b53531bdd44804 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Wed, 20 Apr 2016 03:10:25 +0800 Subject: [PATCH 06/89] =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=88=B0listview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/TopicActivity.java | 28 ++- .../md/display/adapter/TopicAdapter.java | 178 +++--------------- app/src/main/res/layout/activity_topic.xml | 9 +- .../res/layout/activity_topic_item_header.xml | 1 + 4 files changed, 41 insertions(+), 175 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index 3d214ebb..8e4d4b86 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -7,8 +7,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.Gravity; import android.view.LayoutInflater; @@ -16,6 +14,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.EditText; +import android.widget.ListView; import android.widget.PopupWindow; import com.melnykov.fab.FloatingActionButton; @@ -26,6 +25,7 @@ import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.viewholder.TopicHeaderViewHolder; import org.cnodejs.android.md.display.widget.EditorBarHandler; import org.cnodejs.android.md.display.widget.RefreshLayoutUtils; import org.cnodejs.android.md.display.widget.ThemeUtils; @@ -76,8 +76,8 @@ public static void start(@NonNull Context context, String topicId) { @Bind(R.id.topic_refresh_layout) protected SwipeRefreshLayout refreshLayout; - @Bind(R.id.topic_recycler_view) - protected RecyclerView recyclerView; + @Bind(R.id.topic_list_view) + protected ListView listView; @Bind(R.id.topic_icon_no_data) protected View iconNoData; @@ -93,6 +93,7 @@ public static void start(@NonNull Context context, String topicId) { private String topicId; private TopicWithReply topic; + private TopicHeaderViewHolder headerViewHolder; private TopicAdapter adapter; @Override @@ -108,11 +109,12 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.inflateMenu(R.menu.topic); toolbar.setOnMenuItemClickListener(this); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); + headerViewHolder = new TopicHeaderViewHolder(this, listView); + headerViewHolder.update(null, false, 0); // TODO adapter = new TopicAdapter(this, this); - recyclerView.setAdapter(adapter); + listView.setAdapter(adapter); - fabReply.attachToRecyclerView(recyclerView); + fabReply.attachToListView(listView); // 创建回复窗口 LayoutInflater inflater = LayoutInflater.from(this); @@ -154,7 +156,8 @@ public void onRefresh() { public boolean onResultOk(Response> response, Result.Data result) { if (!isFinishing()) { topic = result.getData(); - adapter.setTopic(result.getData()); + headerViewHolder.update(topic); + adapter.update(topic); adapter.notifyDataSetChanged(); iconNoData.setVisibility(View.GONE); } @@ -249,13 +252,8 @@ public boolean onResultOk(Response response, Result.ReplyTopi topic.getReplyList().add(reply); // 更新adapter并让recyclerView滑动到最底部 replyWindow.dismiss(); - if (topic.getReplyList().size() == 1) { // 需要全刷新 - adapter.notifyDataSetChanged(); - } else { // 插入刷新 - adapter.notifyItemChanged(topic.getReplyList().size() - 1); - adapter.notifyItemInserted(topic.getReplyList().size()); - } - recyclerView.smoothScrollToPosition(topic.getReplyList().size()); + adapter.notifyDataSetChanged(); + listView.smoothScrollToPosition(topic.getReplyList().size()); // 清空回复框内容 edtContent.setText(null); // 提示 diff --git a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java index 1310d8a8..09d2c453 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java +++ b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java @@ -1,12 +1,12 @@ package org.cnodejs.android.md.display.adapter; import android.app.Activity; -import android.graphics.Color; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; @@ -16,13 +16,11 @@ import org.cnodejs.android.md.display.activity.LoginActivity; import org.cnodejs.android.md.display.activity.UserDetailActivity; import org.cnodejs.android.md.display.widget.CNodeWebView; -import org.cnodejs.android.md.display.widget.ThemeUtils; import org.cnodejs.android.md.display.widget.ToastUtils; import org.cnodejs.android.md.model.api.ApiClient; import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Reply; import org.cnodejs.android.md.model.entity.Result; -import org.cnodejs.android.md.model.entity.Topic; import org.cnodejs.android.md.model.entity.TopicWithReply; import org.cnodejs.android.md.model.storage.LoginShared; import org.cnodejs.android.md.util.FormatUtils; @@ -33,17 +31,12 @@ import retrofit2.Call; import retrofit2.Response; -public class TopicAdapter extends RecyclerView.Adapter { - - private static final int TYPE_HEADER = 0; - private static final int TYPE_REPLY = 1; +public class TopicAdapter extends BaseAdapter { private final Activity activity; private final LayoutInflater inflater; private TopicWithReply topic; - private boolean isHeaderShow = false; // 当false时,渲染header,其他时间不渲染 - public interface OnAtClickListener { void onAt(String loginName); @@ -58,170 +51,41 @@ public TopicAdapter(@NonNull Activity activity, @NonNull OnAtClickListener onAtC this.onAtClickListener = onAtClickListener; } - public void setTopic(TopicWithReply topic) { + public void update(TopicWithReply topic) { this.topic = topic; - isHeaderShow = false; } @Override - public int getItemCount() { - return topic == null ? 0 : topic.getReplyList().size() + 1; + public int getCount() { + return topic == null ? 0 : topic.getReplyList().size(); } @Override - public int getItemViewType(int position) { - if (topic != null && position != 0) { - return TYPE_REPLY; - } else { - return TYPE_HEADER; - } + public Object getItem(int position) { + return topic.getReplyList().get(position); } @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - switch (viewType) { - case TYPE_HEADER: - return new HeaderViewHolder(inflater.inflate(R.layout.activity_topic_item_header, parent, false)); - default: // TYPE_REPLY - return new ReplyViewHolder(inflater.inflate(R.layout.activity_topic_item_reply, parent, false)); - } + public long getItemId(int position) { + return position; } @Override - public void onBindViewHolder(ViewHolder holder, int position) { - switch (getItemViewType(position)) { - case TYPE_HEADER: - holder.update(position); - break; - default: // TYPE_REPLY - holder.update(position - 1); - break; + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.activity_topic_item_reply, parent, false); + holder = new ViewHolder(convertView); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); } + holder.update(position); + return convertView; } public class ViewHolder extends RecyclerView.ViewHolder { - protected ViewHolder(View itemView) { - super(itemView); - } - - protected void update(int position) {} - - } - - public class HeaderViewHolder extends ViewHolder { - - @Bind(R.id.topic_item_header_tv_title) - protected TextView tvTitle; - - @Bind(R.id.topic_item_header_icon_good) - protected View iconGood; - - @Bind(R.id.topic_item_header_img_avatar) - protected ImageView imgAvatar; - - @Bind(R.id.topic_item_header_tv_tab) - protected TextView tvTab; - - @Bind(R.id.topic_item_header_tv_login_name) - protected TextView tvLoginName; - - @Bind(R.id.topic_item_header_tv_create_time) - protected TextView tvCreateTime; - - @Bind(R.id.topic_item_header_tv_visit_count) - protected TextView tvVisitCount; - - @Bind(R.id.topic_item_header_btn_favorite) - protected ImageView btnFavorite; - - @Bind(R.id.topic_item_header_web_content) - protected CNodeWebView webContent; - - @Bind(R.id.topic_item_header_layout_no_reply) - protected ViewGroup layoutNoReply; - - public HeaderViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - - public void update(int position) { - if (!isHeaderShow) { - tvTitle.setText(topic.getTitle()); - iconGood.setVisibility(topic.isGood() ? View.VISIBLE : View.GONE); - Glide.with(activity).load(topic.getAuthor().getAvatarUrl()).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); - tvTab.setText(topic.isTop() ? R.string.tab_top : topic.getTab().getNameId()); - tvTab.setBackgroundDrawable(ThemeUtils.getThemeAttrDrawable(activity, topic.isTop() ? R.attr.referenceBackgroundAccent : R.attr.referenceBackgroundNormal)); - tvTab.setTextColor(topic.isTop() ? Color.WHITE : ThemeUtils.getThemeAttrColor(activity, android.R.attr.textColorSecondary)); - tvLoginName.setText(topic.getAuthor().getLoginName()); - tvCreateTime.setText(FormatUtils.getRecentlyTimeText(topic.getCreateAt()) + "创建"); - tvVisitCount.setText(topic.getVisitCount() + "次浏览"); - btnFavorite.setImageResource(topic.isCollect() ? R.drawable.ic_favorite_theme_24dp : R.drawable.ic_favorite_outline_grey600_24dp); - - // 这里直接使用WebView,有性能问题 - webContent.loadRenderedContent(topic.getHandleContent()); - - isHeaderShow = true; - } - - layoutNoReply.setVisibility(topic.getReplyList().size() > 0 ? View.GONE : View.VISIBLE); - } - - @OnClick(R.id.topic_item_header_img_avatar) - protected void onBtnAvatarClick() { - UserDetailActivity.startWithTransitionAnimation(activity, topic.getAuthor().getLoginName(), imgAvatar, topic.getAuthor().getAvatarUrl()); - } - - @OnClick(R.id.topic_item_header_btn_favorite) - protected void onBtnFavoriteClick() { - if (topic != null) { - if (LoginActivity.startForResultWithAccessTokenCheck(activity)) { - if (topic.isCollect()) { - decollectTopicAsyncTask(topic, btnFavorite); - } else { - collectTopicAsyncTask(topic, btnFavorite); - } - } - } - } - - } - - private void collectTopicAsyncTask(@NonNull final TopicWithReply topic, @NonNull final ImageView btnFavorite) { - Call call = ApiClient.service.collectTopic(LoginShared.getAccessToken(activity), topic.getId()); - call.enqueue(new DefaultToastCallback(activity) { - - @Override - public boolean onResultOk(Response response, Result result) { - if (!activity.isFinishing()) { - topic.setCollect(true); - btnFavorite.setImageResource(R.drawable.ic_favorite_theme_24dp); - } - return false; - } - - }); - } - - private void decollectTopicAsyncTask(@NonNull final TopicWithReply topic, @NonNull final ImageView btnFavorite) { - Call call = ApiClient.service.decollectTopic(LoginShared.getAccessToken(activity), topic.getId()); - call.enqueue(new DefaultToastCallback(activity) { - - @Override - public boolean onResultOk(Response response, Result result) { - if (!activity.isFinishing()) { - topic.setCollect(false); - btnFavorite.setImageResource(R.drawable.ic_favorite_outline_grey600_24dp); - } - return false; - } - - }); - } - - public class ReplyViewHolder extends ViewHolder { - @Bind(R.id.topic_item_reply_img_avatar) protected ImageView imgAvatar; @@ -249,7 +113,7 @@ public class ReplyViewHolder extends ViewHolder { private Reply reply; private int position = -1; - public ReplyViewHolder(View itemView) { + public ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } @@ -296,7 +160,7 @@ protected void onBtnAtClick() { } - private void upReplyAsyncTask(final ReplyViewHolder holder) { + private void upReplyAsyncTask(final ViewHolder holder) { final int position = holder.position; // 标记当时的位置信息 final Reply reply = holder.reply; // 保存当时的回复对象 Call call = ApiClient.service.upReply(holder.reply.getId(), LoginShared.getAccessToken(activity)); diff --git a/app/src/main/res/layout/activity_topic.xml b/app/src/main/res/layout/activity_topic.xml index 82480778..77f40fb8 100644 --- a/app/src/main/res/layout/activity_topic.xml +++ b/app/src/main/res/layout/activity_topic.xml @@ -38,10 +38,13 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:listSelector="@android:color/transparent" + android:cacheColorHint="@android:color/transparent" + android:divider="@android:color/transparent" /> diff --git a/app/src/main/res/layout/activity_topic_item_header.xml b/app/src/main/res/layout/activity_topic_item_header.xml index f67844a1..a8457115 100644 --- a/app/src/main/res/layout/activity_topic_item_header.xml +++ b/app/src/main/res/layout/activity_topic_item_header.xml @@ -5,6 +5,7 @@ android:layout_height="wrap_content"> From 3463b9e6ca9d420165d5aad62bce5603569cdc54 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Wed, 20 Apr 2016 03:43:09 +0800 Subject: [PATCH 07/89] =?UTF-8?q?=E4=B8=BB=E9=A2=98=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8A=A0=E8=BD=BD=E7=AD=96=E7=95=A5=E5=8F=98?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/TopicActivity.java | 33 +++++++++++++++---- .../md/display/adapter/MainAdapter.java | 2 +- .../md/display/adapter/TopicAdapter.java | 27 +++++++-------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index 8e4d4b86..6d4cfa80 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -8,6 +8,7 @@ import android.support.annotation.NonNull; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.Toolbar; +import android.text.TextUtils; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuItem; @@ -35,14 +36,17 @@ import org.cnodejs.android.md.model.entity.Author; import org.cnodejs.android.md.model.entity.Reply; import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.Topic; import org.cnodejs.android.md.model.entity.TopicWithReply; import org.cnodejs.android.md.model.storage.LoginShared; import org.cnodejs.android.md.model.storage.SettingShared; +import org.cnodejs.android.md.model.util.EntityUtils; import org.cnodejs.android.md.util.FormatUtils; import org.cnodejs.android.md.util.ShipUtils; import org.joda.time.DateTime; import java.util.ArrayList; +import java.util.List; import butterknife.Bind; import butterknife.ButterKnife; @@ -53,6 +57,14 @@ public class TopicActivity extends StatusBarActivity implements SwipeRefreshLayout.OnRefreshListener, TopicAdapter.OnAtClickListener, Toolbar.OnMenuItemClickListener { private static final String EXTRA_TOPIC_ID = "topicId"; + private static final String EXTRA_TOPIC = "topic"; + + public static void start(@NonNull Activity activity, @NonNull Topic topic) { + Intent intent = new Intent(activity, TopicActivity.class); + intent.putExtra(EXTRA_TOPIC_ID, topic.getId()); + intent.putExtra(EXTRA_TOPIC, EntityUtils.gson.toJson(topic)); + activity.startActivity(intent); + } public static void start(@NonNull Activity activity, String topicId) { Intent intent = new Intent(activity, TopicActivity.class); @@ -91,7 +103,8 @@ public static void start(@NonNull Context context, String topicId) { private ProgressDialog progressDialog; private String topicId; - private TopicWithReply topic; + private Topic topic; + private final List replyList = new ArrayList<>(); private TopicHeaderViewHolder headerViewHolder; private TopicAdapter adapter; @@ -104,16 +117,21 @@ protected void onCreate(Bundle savedInstanceState) { ButterKnife.bind(this); topicId = getIntent().getStringExtra(EXTRA_TOPIC_ID); + if (!TextUtils.isEmpty(getIntent().getStringExtra(EXTRA_TOPIC))) { + topic = EntityUtils.gson.fromJson(getIntent().getStringExtra(EXTRA_TOPIC), Topic.class); + } toolbar.setNavigationOnClickListener(new NavigationFinishClickListener(this)); toolbar.inflateMenu(R.menu.topic); toolbar.setOnMenuItemClickListener(this); headerViewHolder = new TopicHeaderViewHolder(this, listView); - headerViewHolder.update(null, false, 0); // TODO - adapter = new TopicAdapter(this, this); + headerViewHolder.update(topic, false, 0); + adapter = new TopicAdapter(this, replyList, this); listView.setAdapter(adapter); + iconNoData.setVisibility(topic == null ? View.VISIBLE : View.GONE); + fabReply.attachToListView(listView); // 创建回复窗口 @@ -156,8 +174,9 @@ public void onRefresh() { public boolean onResultOk(Response> response, Result.Data result) { if (!isFinishing()) { topic = result.getData(); - headerViewHolder.update(topic); - adapter.update(topic); + headerViewHolder.update(result.getData()); + replyList.clear(); + replyList.addAll(result.getData().getReplyList()); adapter.notifyDataSetChanged(); iconNoData.setVisibility(View.GONE); } @@ -249,11 +268,11 @@ public boolean onResultOk(Response response, Result.ReplyTopi reply.setHandleContent(FormatUtils.renderMarkdown(content)); // 本地要做预渲染处理 reply.setCreateAt(new DateTime()); reply.setUpList(new ArrayList()); - topic.getReplyList().add(reply); + replyList.add(reply); // 更新adapter并让recyclerView滑动到最底部 replyWindow.dismiss(); adapter.notifyDataSetChanged(); - listView.smoothScrollToPosition(topic.getReplyList().size()); + listView.smoothScrollToPosition(replyList.size()); // 清空回复框内容 edtContent.setText(null); // 提示 diff --git a/app/src/main/java/org/cnodejs/android/md/display/adapter/MainAdapter.java b/app/src/main/java/org/cnodejs/android/md/display/adapter/MainAdapter.java index 9bb319bb..8966f9f2 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/adapter/MainAdapter.java +++ b/app/src/main/java/org/cnodejs/android/md/display/adapter/MainAdapter.java @@ -170,7 +170,7 @@ protected void onBtnAvatarClick() { @OnClick(R.id.main_item_btn_item) protected void onBtnItemClick() { - TopicActivity.start(activity, topic.getId()); + TopicActivity.start(activity, topic); } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java index 09d2c453..36504a3e 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java +++ b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java @@ -21,10 +21,11 @@ import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Reply; import org.cnodejs.android.md.model.entity.Result; -import org.cnodejs.android.md.model.entity.TopicWithReply; import org.cnodejs.android.md.model.storage.LoginShared; import org.cnodejs.android.md.util.FormatUtils; +import java.util.List; + import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; @@ -33,36 +34,32 @@ public class TopicAdapter extends BaseAdapter { - private final Activity activity; - private final LayoutInflater inflater; - private TopicWithReply topic; - public interface OnAtClickListener { void onAt(String loginName); } + private final Activity activity; + private final LayoutInflater inflater; + private final List replyList; private final OnAtClickListener onAtClickListener; - public TopicAdapter(@NonNull Activity activity, @NonNull OnAtClickListener onAtClickListener) { + public TopicAdapter(@NonNull Activity activity, @NonNull List replyList, @NonNull OnAtClickListener onAtClickListener) { this.activity = activity; inflater = LayoutInflater.from(activity); + this.replyList = replyList; this.onAtClickListener = onAtClickListener; } - public void update(TopicWithReply topic) { - this.topic = topic; - } - @Override public int getCount() { - return topic == null ? 0 : topic.getReplyList().size(); + return replyList.size(); } @Override public Object getItem(int position) { - return topic.getReplyList().get(position); + return replyList.get(position); } @Override @@ -120,7 +117,7 @@ public ViewHolder(View itemView) { public void update(int position) { this.position = position; - reply = topic.getReplyList().get(position); + reply = replyList.get(position); Glide.with(activity).load(reply.getAuthor().getAvatarUrl()).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); tvLoginName.setText(reply.getAuthor().getLoginName()); @@ -128,8 +125,8 @@ public void update(int position) { tvCreateTime.setText(FormatUtils.getRecentlyTimeText(reply.getCreateAt())); btnUps.setText(String.valueOf(reply.getUpList().size())); btnUps.setCompoundDrawablesWithIntrinsicBounds(reply.getUpList().contains(LoginShared.getId(activity)) ? R.drawable.ic_thumb_up_theme_24dp : R.drawable.ic_thumb_up_grey600_24dp, 0, 0, 0); - iconDeepLine.setVisibility(position == topic.getReplyList().size() - 1 ? View.GONE : View.VISIBLE); - iconShadowGap.setVisibility(position == topic.getReplyList().size() - 1 ? View.VISIBLE : View.GONE); + iconDeepLine.setVisibility(position == replyList.size() - 1 ? View.GONE : View.VISIBLE); + iconShadowGap.setVisibility(position == replyList.size() - 1 ? View.VISIBLE : View.GONE); // 这里直接使用WebView,有性能问题 webContent.loadRenderedContent(reply.getHandleContent()); From 760e00495468ba65f6fb0ea8a774891b348b9b0f Mon Sep 17 00:00:00 2001 From: TakWolf Date: Wed, 20 Apr 2016 04:14:29 +0800 Subject: [PATCH 08/89] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e8572899..e19c5778 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,7 +18,7 @@ android { minSdkVersion 9 targetSdkVersion 22 versionCode Integer.parseInt(time) - versionName "1.1.0" + versionName "1.1.1-beta.1" manifestPlaceholders = [ UMENG_CHANNEL: "CNodeJS", From 2c4e7a55adcd5df8103e70403621d8d029266498 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Wed, 20 Apr 2016 22:03:45 +0800 Subject: [PATCH 09/89] readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a7eca3a..5ce98c11 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@ # CNode Material Design # +[![Release](https://img.shields.io/github/release/TakWolf/CNode-Material-Design.svg?style=flat)](https://github.com/TakWolf/CNode-Material-Design/releases/latest) [![Platform](https://img.shields.io/badge/platform-Android-green.svg?style=flat)](http://developer.android.com/index.html) [![API](https://img.shields.io/badge/API-9%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=9) -[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0) +[![License](https://img.shields.io/github/license/TakWolf/CNode-Material-Design.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0) ![Logo](/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png) From a97bb9555ede0facae5587c05329041d78b2e4cb Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 21 Apr 2016 01:54:09 +0800 Subject: [PATCH 10/89] =?UTF-8?q?=E6=9C=AC=E5=9C=B0markdown=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=AE=9E=E7=8E=B0@=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/cnodejs/android/md/util/FormatUtils.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/util/FormatUtils.java b/app/src/main/java/org/cnodejs/android/md/util/FormatUtils.java index 4f9161e2..3965f8f2 100644 --- a/app/src/main/java/org/cnodejs/android/md/util/FormatUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/util/FormatUtils.java @@ -104,9 +104,12 @@ public static String getCompatAvatarUrl(String avatarUrl) { private static final Markdown md = new Markdown(); public static String renderMarkdown(String text) { - if (TextUtils.isEmpty(text)) { - text = ""; - } + // 保证text不为null + text = TextUtils.isEmpty(text) ? "" : text; + // 解析@协议 + text = " " + text; + text = text.replaceAll(" @([a-zA-Z0-9_]+)", "\\[@$1\\]\\(https://cnodejs.org/user/$1\\)").trim(); + // 渲染markdown try { StringWriter out = new StringWriter(); md.transform(new StringReader(text), out); @@ -114,6 +117,7 @@ public static String renderMarkdown(String text) { } catch (ParseException e) { // nothing to do } + // 添加样式容器 return "
" + text + "
"; } From 944146589019d6912864c33a57e74b29ccc14d0d Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 21 Apr 2016 02:02:51 +0800 Subject: [PATCH 11/89] =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e19c5778..a120fad1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,7 +18,7 @@ android { minSdkVersion 9 targetSdkVersion 22 versionCode Integer.parseInt(time) - versionName "1.1.1-beta.1" + versionName "1.1.1-beta.2" manifestPlaceholders = [ UMENG_CHANNEL: "CNodeJS", From 7b29f53624307d735c39c5649749b1b721e6551c Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 21 Apr 2016 02:40:24 +0800 Subject: [PATCH 12/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9B=9E=E5=A4=8D0?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E7=9A=84=E5=B8=96=E5=AD=90=E4=B9=8B=E5=90=8E?= =?UTF-8?q?=EF=BC=8Cheader=E6=B2=A1=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnodejs/android/md/display/activity/TopicActivity.java | 3 ++- .../android/md/display/viewholder/TopicHeaderViewHolder.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index 6d4cfa80..d41537d5 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -269,8 +269,9 @@ public boolean onResultOk(Response response, Result.ReplyTopi reply.setCreateAt(new DateTime()); reply.setUpList(new ArrayList()); replyList.add(reply); - // 更新adapter并让recyclerView滑动到最底部 + // 更新header和adapter replyWindow.dismiss(); + headerViewHolder.update(replyList.size()); adapter.notifyDataSetChanged(); listView.smoothScrollToPosition(replyList.size()); // 清空回复框内容 diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java index b39416ef..cde32bbd 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java @@ -110,6 +110,10 @@ public void update(@NonNull TopicWithReply topic) { update(topic, topic.isCollect(), topic.getReplyList().size()); } + public void update(int replyCount) { + layoutNoReply.setVisibility(replyCount > 0 ? View.GONE : View.VISIBLE); + } + @OnClick(R.id.topic_item_header_img_avatar) protected void onBtnAvatarClick() { UserDetailActivity.startWithTransitionAnimation(activity, topic.getAuthor().getLoginName(), imgAvatar, topic.getAuthor().getAvatarUrl()); From 188809373938f715ee69261fe5e2c9ca799c3e55 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 22 Apr 2016 00:19:10 +0800 Subject: [PATCH 13/89] =?UTF-8?q?=E8=A1=A5=E5=85=85=E4=B8=80=E4=B8=AAcnode?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 5ce98c11..9ed43a5c 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,12 @@ > [https://cnodejs.org/topic/57111863434cfcfa52684a8e](https://cnodejs.org/topic/57111863434cfcfa52684a8e) +### [cnode-vue](https://github.com/ihanyang/cnode-vue) ### + +> Vue版 cnodejs.org社区 WebApp [线上访问](http://hanyang.coding.io/) + +> [https://cnodejs.org/topic/56f8beb9b819f527325e7883](https://cnodejs.org/topic/56f8beb9b819f527325e7883) + ### [CNode-android](https://github.com/iwhys/CNode-android) ### > 这是为CNodejs社区(https://cnodejs.org) 开发的原生Android版客户端。适用于Android4.0及以上。 From 09de1fe31679805ee7bf8446623acf1450a4240d Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sat, 23 Apr 2016 01:47:11 +0800 Subject: [PATCH 14/89] =?UTF-8?q?=E6=96=87=E6=A1=88=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnodejs/android/md/display/adapter/UserDetailAdapter.java | 2 +- .../java/org/cnodejs/android/md/model/api/ApiService.java | 4 ++-- app/src/main/res/layout/activity_notification_item.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/adapter/UserDetailAdapter.java b/app/src/main/java/org/cnodejs/android/md/display/adapter/UserDetailAdapter.java index 6cf34e00..1fe24f47 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/adapter/UserDetailAdapter.java +++ b/app/src/main/java/org/cnodejs/android/md/display/adapter/UserDetailAdapter.java @@ -19,7 +19,7 @@ public class UserDetailAdapter extends FragmentPagerAdapter { private final String[] titles = { "最近回复", "最新发布", - "主题收藏" + "话题收藏" }; public UserDetailAdapter(FragmentManager manager) { diff --git a/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java b/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java index a35f7d0a..906a1c03 100644 --- a/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java +++ b/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java @@ -20,7 +20,7 @@ public interface ApiService { //===== - // 主题 + // 话题 //===== @GET("topics") @@ -48,7 +48,7 @@ Call createTopic( ); //========= - // 主题收藏 + // 话题收藏 //========= @POST("topic_collect/collect") diff --git a/app/src/main/res/layout/activity_notification_item.xml b/app/src/main/res/layout/activity_notification_item.xml index 95a78cfb..b8b4e791 100644 --- a/app/src/main/res/layout/activity_notification_item.xml +++ b/app/src/main/res/layout/activity_notification_item.xml @@ -88,7 +88,7 @@ android:textColor="?android:attr/textColorSecondary" android:textSize="14sp" android:background="?attr/referenceBackgroundNormal" - tools:text="原话题:【深js拾遗】mbot 机器人大放送!!!!!!!先抢先得噢亲!!!!" /> + tools:text="原话题:这里是话题的标题" /> From 4b2bfc74af80095062c8ececd0e3dd0757a52085 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sat, 23 Apr 2016 01:54:08 +0800 Subject: [PATCH 15/89] =?UTF-8?q?=E6=96=87=E6=A1=88=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/cnodejs/android/md/model/api/ApiService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java b/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java index 906a1c03..5b10df65 100644 --- a/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java +++ b/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java @@ -71,7 +71,7 @@ Call>> getCollectTopicList( ); //===== - // 评论 + // 回复 //===== @POST("topic/{topicId}/replies") From e1449bc63901091fe44e54dd01fb9de0615ed9ad Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sat, 23 Apr 2016 02:16:49 +0800 Subject: [PATCH 16/89] =?UTF-8?q?=E8=AF=9D=E9=A2=98=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9B=9E=E5=A4=8D=E6=95=B0=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../viewholder/TopicHeaderViewHolder.java | 11 +++++++++- .../res/layout/activity_topic_item_header.xml | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java index cde32bbd..e5ceb5e0 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java @@ -67,6 +67,12 @@ public class TopicHeaderViewHolder { @Bind(R.id.topic_item_header_layout_no_reply) protected ViewGroup layoutNoReply; + @Bind(R.id.topic_item_header_layout_reply_count) + protected ViewGroup layoutReplyCount; + + @Bind(R.id.topic_item_header_tv_reply_count) + protected TextView tvReplyCount; + private final Activity activity; private Topic topic; private boolean isCollect; @@ -99,7 +105,8 @@ public void update(@Nullable Topic topic, boolean isCollect, int replyCount) { // 这里直接使用WebView,有性能问题 webContent.loadRenderedContent(topic.getHandleContent()); - layoutNoReply.setVisibility(replyCount > 0 ? View.GONE : View.VISIBLE); + // 更新回复数目 + update(replyCount); } else { layoutContent.setVisibility(View.GONE); iconGood.setVisibility(View.GONE); @@ -112,6 +119,8 @@ public void update(@NonNull TopicWithReply topic) { public void update(int replyCount) { layoutNoReply.setVisibility(replyCount > 0 ? View.GONE : View.VISIBLE); + layoutReplyCount.setVisibility(replyCount > 0 ? View.VISIBLE : View.GONE); + tvReplyCount.setText(replyCount + "条回复"); } @OnClick(R.id.topic_item_header_img_avatar) diff --git a/app/src/main/res/layout/activity_topic_item_header.xml b/app/src/main/res/layout/activity_topic_item_header.xml index a8457115..0c07b412 100644 --- a/app/src/main/res/layout/activity_topic_item_header.xml +++ b/app/src/main/res/layout/activity_topic_item_header.xml @@ -165,6 +165,26 @@
+ + + + + + + + Date: Sun, 24 Apr 2016 06:13:07 +0800 Subject: [PATCH 17/89] =?UTF-8?q?=E8=B5=84=E6=BA=90=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/CrashLogActivity.java | 2 +- .../md/display/activity/CreateTopicActivity.java | 12 ++++++------ ...ivity_new_topic.xml => activity_create_topic.xml} | 12 ++++++------ .../main/res/layout/activity_topic_reply_window.xml | 2 +- .../main/res/menu/{new_topic.xml => crash_log.xml} | 0 app/src/main/res/menu/create_topic.xml | 12 ++++++++++++ app/src/main/res/values/strings.xml | 4 ++-- 7 files changed, 28 insertions(+), 16 deletions(-) rename app/src/main/res/layout/{activity_new_topic.xml => activity_create_topic.xml} (92%) rename app/src/main/res/menu/{new_topic.xml => crash_log.xml} (100%) create mode 100644 app/src/main/res/menu/create_topic.xml diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java index ebcf13f4..ca84bb0a 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java @@ -39,7 +39,7 @@ protected void onCreate(Bundle savedInstanceState) { ButterKnife.bind(this); toolbar.setNavigationOnClickListener(new NavigationFinishClickListener(this)); - toolbar.inflateMenu(R.menu.new_topic); + toolbar.inflateMenu(R.menu.crash_log); toolbar.setOnMenuItemClickListener(this); //接收异常对象 diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java index 7daf815b..45b23bfa 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java @@ -30,19 +30,19 @@ public class CreateTopicActivity extends StatusBarActivity implements Toolbar.OnMenuItemClickListener { - @Bind(R.id.new_topic_toolbar) + @Bind(R.id.create_topic_toolbar) protected Toolbar toolbar; - @Bind(R.id.new_topic_spn_tab) + @Bind(R.id.create_topic_spn_tab) protected Spinner spnTab; - @Bind(R.id.new_topic_edt_title) + @Bind(R.id.create_topic_edt_title) protected EditText edtTitle; @Bind(R.id.editor_bar_layout_root) protected ViewGroup editorBar; - @Bind(R.id.new_topic_edt_content) + @Bind(R.id.create_topic_edt_content) protected EditText edtContent; private ProgressDialog progressDialog; @@ -53,11 +53,11 @@ public class CreateTopicActivity extends StatusBarActivity implements Toolbar.On protected void onCreate(Bundle savedInstanceState) { ThemeUtils.configThemeBeforeOnCreate(this, R.style.AppThemeLight, R.style.AppThemeDark); super.onCreate(savedInstanceState); - setContentView(R.layout.activity_new_topic); + setContentView(R.layout.activity_create_topic); ButterKnife.bind(this); toolbar.setNavigationOnClickListener(new NavigationFinishClickListener(this)); - toolbar.inflateMenu(R.menu.new_topic); + toolbar.inflateMenu(R.menu.create_topic); toolbar.setOnMenuItemClickListener(this); progressDialog = DialogUtils.createProgressDialog(this); diff --git a/app/src/main/res/layout/activity_new_topic.xml b/app/src/main/res/layout/activity_create_topic.xml similarity index 92% rename from app/src/main/res/layout/activity_new_topic.xml rename to app/src/main/res/layout/activity_create_topic.xml index 1d9ed549..acdb2248 100644 --- a/app/src/main/res/layout/activity_new_topic.xml +++ b/app/src/main/res/layout/activity_create_topic.xml @@ -18,7 +18,7 @@ app:layout_scrollFlags="scroll|enterAlways|snap"> @@ -59,14 +59,14 @@ @@ -91,7 +91,7 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior"> diff --git a/app/src/main/res/layout/activity_topic_reply_window.xml b/app/src/main/res/layout/activity_topic_reply_window.xml index fe36215e..91ebde67 100644 --- a/app/src/main/res/layout/activity_topic_reply_window.xml +++ b/app/src/main/res/layout/activity_topic_reply_window.xml @@ -68,7 +68,7 @@ android:paddingTop="16dp" android:paddingBottom="96dp" android:gravity="start" - android:hint="@string/new_topic_content_hint" + android:hint="@string/create_topic_content_hint" android:textSize="16sp" android:minLines="20" android:background="?attr/widgetBackgroundDark" /> diff --git a/app/src/main/res/menu/new_topic.xml b/app/src/main/res/menu/crash_log.xml similarity index 100% rename from app/src/main/res/menu/new_topic.xml rename to app/src/main/res/menu/crash_log.xml diff --git a/app/src/main/res/menu/create_topic.xml b/app/src/main/res/menu/create_topic.xml new file mode 100644 index 00000000..26298b8d --- /dev/null +++ b/app/src/main/res/menu/create_topic.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 165871ef..365bc238 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -100,8 +100,8 @@ 发送 发布到分类: - 标题,字数10字以上 - 说点什么吧… + 标题,字数10字以上 + 说点什么吧… 标题 添加连接 From be41c8b014b3b7b69ed90e63d697fb87b6e3191d Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sun, 24 Apr 2016 06:23:29 +0800 Subject: [PATCH 18/89] =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=B7=BB=E5=8A=A0=E6=B5=8F=E8=A7=88=E5=99=A8?= =?UTF-8?q?=E6=89=93=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/UserDetailActivity.java | 16 +++++++++++++++- app/src/main/res/menu/user_detail.xml | 12 ++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/menu/user_detail.xml diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java index 8d564240..058dbafe 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java @@ -13,6 +13,7 @@ import android.support.v7.widget.Toolbar; import android.text.Html; import android.text.TextUtils; +import android.view.MenuItem; import android.view.View; import android.widget.ImageView; import android.widget.TextView; @@ -43,7 +44,7 @@ import retrofit2.Call; import retrofit2.Response; -public class UserDetailActivity extends StatusBarActivity { +public class UserDetailActivity extends StatusBarActivity implements Toolbar.OnMenuItemClickListener { private static final String EXTRA_LOGIN_NAME = "loginName"; private static final String EXTRA_AVATAR_URL = "avatarUrl"; @@ -115,6 +116,8 @@ protected void onCreate(Bundle savedInstanceState) { ViewCompat.setTransitionName(imgAvatar, NAME_IMG_AVATAR); toolbar.setNavigationOnClickListener(new NavigationFinishClickListener(this)); + toolbar.inflateMenu(R.menu.user_detail); + toolbar.setOnMenuItemClickListener(this); adapter = new UserDetailAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); @@ -133,6 +136,17 @@ protected void onCreate(Bundle savedInstanceState) { getCollectTopicListAsyncTask(); } + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_open_in_browser: + ShipUtils.openInBrowser(this, "https://cnodejs.org/user/" + loginName); + return true; + default: + return false; + } + } + /** * Activity被销毁的时候不保存Fragment */ diff --git a/app/src/main/res/menu/user_detail.xml b/app/src/main/res/menu/user_detail.xml new file mode 100644 index 00000000..fb40c72c --- /dev/null +++ b/app/src/main/res/menu/user_detail.xml @@ -0,0 +1,12 @@ + + + + + + From f0abc156795dafa389b10f998b1f5db744e4a2d1 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Mon, 25 Apr 2016 05:23:40 +0800 Subject: [PATCH 19/89] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/org/cnodejs/android/md/util/ResUtils.java | 2 +- app/src/main/java/org/cnodejs/android/md/util/codec/DES3.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java b/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java index 5f677e07..1e3bdfc7 100644 --- a/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java @@ -16,7 +16,7 @@ private ResUtils() {} public static String getRawString(@NonNull Context context, @RawRes int rawId) { try { InputStream is = context.getResources().openRawResource(rawId); - BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8")); + BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { diff --git a/app/src/main/java/org/cnodejs/android/md/util/codec/DES3.java b/app/src/main/java/org/cnodejs/android/md/util/codec/DES3.java index f2cc191a..12c189ae 100644 --- a/app/src/main/java/org/cnodejs/android/md/util/codec/DES3.java +++ b/app/src/main/java/org/cnodejs/android/md/util/codec/DES3.java @@ -10,7 +10,7 @@ public class DES3 { private static final String IV = "01234567"; - private static final String CHARSET = "utf-8"; + private static final String CHARSET = "UTF-8"; public static String encrypt(String iv, String secretKey, String plainText) throws Exception { DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes()); From 690d25492bef23ac4879b1ca254845b1e81a5a62 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Mon, 25 Apr 2016 05:31:43 +0800 Subject: [PATCH 20/89] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/LicenseActivity.java | 10 +++++++- .../org/cnodejs/android/md/util/ResUtils.java | 24 ++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LicenseActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LicenseActivity.java index 2b26e8b6..ffc5b123 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LicenseActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LicenseActivity.java @@ -8,8 +8,11 @@ import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; import org.cnodejs.android.md.display.widget.ThemeUtils; +import org.cnodejs.android.md.display.widget.ToastUtils; import org.cnodejs.android.md.util.ResUtils; +import java.io.IOException; + import butterknife.Bind; import butterknife.ButterKnife; @@ -30,7 +33,12 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.setNavigationOnClickListener(new NavigationFinishClickListener(this)); - tvLicense.setText(ResUtils.getRawString(this, R.raw.open_source)); + try { + tvLicense.setText(ResUtils.getRawString(this, R.raw.open_source)); + } catch (IOException e) { + tvLicense.setText(null); + ToastUtils.with(this).show("资源读取失败"); + } } } diff --git a/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java b/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java index 1e3bdfc7..d3a8610b 100644 --- a/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/util/ResUtils.java @@ -13,21 +13,17 @@ public final class ResUtils { private ResUtils() {} - public static String getRawString(@NonNull Context context, @RawRes int rawId) { - try { - InputStream is = context.getResources().openRawResource(rawId); - BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); - StringBuilder sb = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - sb.append(line).append("\n"); - } - sb.deleteCharAt(sb.length() - 1); - reader.close(); - return sb.toString(); - } catch (IOException e) { - return ""; + public static String getRawString(@NonNull Context context, @RawRes int rawId) throws IOException { + InputStream is = context.getResources().openRawResource(rawId); + BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); } + sb.deleteCharAt(sb.length() - 1); + reader.close(); + return sb.toString(); } } From f717f2df6fdf51964691897cb9001d9b7ae0f986 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Mon, 25 Apr 2016 05:48:44 +0800 Subject: [PATCH 21/89] =?UTF-8?q?callback=E4=B8=AD=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=8F=96=E6=B6=88=E7=9A=84=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/md/model/api/CallbackAdapter.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/cnodejs/android/md/model/api/CallbackAdapter.java b/app/src/main/java/org/cnodejs/android/md/model/api/CallbackAdapter.java index 2ed30893..f60b5046 100644 --- a/app/src/main/java/org/cnodejs/android/md/model/api/CallbackAdapter.java +++ b/app/src/main/java/org/cnodejs/android/md/model/api/CallbackAdapter.java @@ -23,7 +23,13 @@ public final void onResponse(Call call, Response response) { @Override public final void onFailure(Call call, Throwable t) { - if (!onCallException(t, Result.buildError(t))) { + boolean interrupt; + if (call.isCanceled()) { + interrupt = onCallCancel(); + } else { + interrupt = onCallException(t, Result.buildError(t)); + } + if (!interrupt) { onFinish(); } } @@ -36,6 +42,10 @@ public boolean onResultError(Response response, Result.Error error) { return false; } + public boolean onCallCancel() { + return false; + } + public boolean onCallException(Throwable t, Result.Error error) { return false; } From 60f7b3f5f9848aeb292fd045866159a73b4cb4d9 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Tue, 26 Apr 2016 09:39:02 +0800 Subject: [PATCH 22/89] =?UTF-8?q?gradle=20=E5=8D=87=E7=BA=A7=E5=88=B0=202.?= =?UTF-8?q?13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/wrapper/gradle-wrapper.jar | Bin 53639 -> 53556 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 46 ++++++++++++----------- gradlew.bat | 6 +-- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c6137b87896c8f70315ae454e00a969ef5f6019..ca78035ef0501d802d4fc55381ef2d5c3ce0ec6e 100644 GIT binary patch delta 3268 zcmZWr2|SePAAjc^S7GF)QG>~mbDWWljWQ!gNJ2{F`n#{flx1jXU8N_BVo{_+EaTXA z?dBYeyAnn=i$qE~eNx%~JJ0;L{m<@vKJ)qg<~!f-?|Pp1d7q4{_=YQZac6tHz(xcS z5kcY&it@zOMKD7XerYC~XW=FNCgxQP4*8oBiczks;JKz>6Pi^D*8nZtA6&~Mps^?f z&Imk(K!jig1emfS(n1i?CQP7`7?&>`bp6F7n-)myc4=v$ROUpxNMq z0!mMI(kk`FV<*+Qhiw1)_ngqAQ!g6tHjX*1uYEjcg=;w*nY7SVk-DAqjI!8q!a=+6 zRU0`c@(S~oyBtYwI(7-wl6?tPlG+~mGv7a& zyCxrM`H1z4Yl}wLN2#^lFLRP~FW&3l zqd7mGUL+!F?C2TD8gU5PYaeiev9_VZxHuH8X>H9+ImPCbH6{*H-X#a03_a3Z(D?46 zUYcjLZsV1S^kVs(2#x>v3#32Qv5?$1&avGm5kBd)^Y&!USs7JXXxiUj|1* z7?`~n6q__t_*-Fq<1C$V_J=CBuQUs8{&ZGe!0X&<(Ws%_a;0*OUozhNu}jtlMopEQ zmu<@}RYt`|8&*WEOAKRqwzHuA+VQYOwZR(p0ms0c2k8-_-i1x!eall$&jKUa_e>X- zcGVnyd1OB3V3+!`U7l;5-~o028?;%nU{j`;lAx#TYWb~k7D3;3{%l!U>JeGeth8+D zjFD{VEF)8Yr82eF?R0WZq=3-=-(6AN`~r`!bt`kiBV=l|CqJ1kIVa-$m-=Ei7Mq{U zf1kf6VP?BFIjuL&!HtWCg5T=q|g>(JI^4=-~D^*;k~wh{Qf%MGx@O zk`A(Z70^`DfAf!RAJRuv3mR|jUktQHJ=h{2cY-5BGGp;VswSQ>YIEP|eU|u0Ei%df zRmgiVR5_}W^;%l6^NraM$uOlLi%#kmEgo$fsy#1(f1>7Ptt3btnzrnGnMkt=Ncw$& zn&PU9P*Qg1iYv5Jl3l!YeoMPdn{KvwaQj7v$&SLbkJN1oi}1_AS27ovu)uM{&=a=gJ( z`KpBCJK=TT4}!JRhqCAGy!{$1ESJz1uKTzN2AiTsf%ij z4Y|>8XM()jLUq1XCq0fGqu5hibe!7a^Er*DaXwY=ZI7OMp$%x#fGuEf~jl_RGzvyD>o9`nC?^06V z=aw2|-@D`Wz@r^M&X7v$8eKnFl_gGQ5bIw=#5Cn+FWBy1aelra@%MnSCIQ`72aj3i z4d1gU*8#@sA(h#;c!|EPY>*Fp3XU@e- zLH2t2D^!wO4Rs{&`30<+VnGBk0>0rF7 z!b|v+xtqt){%M$ptlx3taSpZsyc9Rh@RO@Isn|Bzi+xE5a2`=%kN+%LAR z8hGq&4x(C(zr58!b?Z*FOrdpavxGLk%?aB1wn%6_+8v?2-tGY{zT+sg z{v93!{<5!F5fL)RW6 z0MTwSDE;!pVlpzHG!2+`8~)#;8r?06lLZ;w8r&TK>bi+IMKI9475-Z8CZaT7U@)i% zw)Ln($gzir-aifug2^DKM_QS??5@@uwp>RMWEE@YE52NJ{ULF-hZkJDmx#6nVUQJg z*)ImQ3uN)vRIEjNOmD!ay&ZxPm4JDuJn-z}k*(x||LhhZKF9o$( zyG_DQV_H#6yOS?LR3@0t{0dn1h(T>;KM~!N4GU!V8$f6sgI?!ikSf?UzzgRiVR`Q= z*4%ciIU~MsCFM{{xgw?GY>z`_@Vtxmzm5w&QCef1tXI7+>)F)$V{9Q-+)Zqm_}9~@7S3tQkSZLCh5$`W5gSSnw-dhj z>h%~=354|%VUnUDBAU*GjZF+`KrKKlins&)glWzBwCrY}JWPeUkYOTPa)&pNpC!4g k4PiD0zx{;=Ul9ZnBPyhSpL2i5Y+z)9{Ue4#gjO#0UthZVsQ>@~ delta 3282 zcmZWrc|6ox8~+(=7)xU;4bjMw#AKJH7ujVCQErIr$rk0NF$k|joT8AWON2r*DQg%E z$r9bV*}_c{m8GI?uJ<=*ZoRM1`}^m4=6k;1=RD^*&pC5wH`$YaW5?QCvvcqw2oDcJ zvI)t=%JZPc;z5_IVy4~^+*0^bI2-a`iX2KQ-@(o_PZXh9B{2<9Vw+-GssJVe1A#=2 zSqOx1mOy}t=fQD7WVgUej4;ZzaEO%(nBhPW33PfAn35I+1#~I$C71aKoU_Qr$vhu= zRPS&0R#q2yFah6E;_$(|N`qFVf;;V%;~Ng10vCL=gSBXQeBqkedOLqQ{ji~K0$sed zzdL$E@pH6xao@!e-I-zoR@=TXRir zgi5ep{wL=nP?aXu+6oqODWZy}dE3 zNkLUlq4Z-Ai6m?3NLNmDDhM*-4Zz<@?d8Ro+&a-YoR3bx|-ynf?k`#JgpVp7)G!H-deXS*sS9XSxPnsXRBO$E!y-8&3k1s zmq;F}QH+}A)hbIoy4$%%T`lV6L*EV?J+0%u2bvlql^^=bYlXb_7t^?tIL{+nDdSYC z7dXQkVtGLG0_DDHuen09SQc?Mx6agU1z)Qeu~Z^Kx9arwJ+dqHS=E&MaJyU7hw+7! zE3T941r}YNI^^5NF0LW>b9%1#66YKzd|HY;tuG`v9M(w+vL5|hKNET4nU9lSRZ(eG zZFk}c;XvWRaD3d!J3`gSF7+M>l~eb(od|E(nQFaK5wG&5K=gFcw~^wQns>V9bD_Vq z+qfki4Snl<=JWBpFUzuP_-q}oOumaTv;J&-NUG83t@fR<2=Y*O+1Z@b-TTx$hl2wW zbK=weXjz~9=V~&C!<@fOj1`rMMBe2%f6KGp*TsoPFOa&=g``fs*ApeEm;OF+cDS9_ zFW5W#-lElMdPLexiU9XnOLr+wcfi)S`;TiLNmIwkCHqJ295-SR4F|)dq$}1e7>tL- z(>STZc(-#&1Ewj;59`Yg%K;YTmP@>JsUu<1H4k)W{dLk1ZHMpL$hK zYpxds<+ui4w`eA6-oz5iC-V>LeQ7#pbL_j+z?p<|<(7JRurnIMr$*iRCme5 zhuobPG8MeXteydtMTwB6O9bhi;L?R^1!;>S`SZ}s?m*Gvy%r-c?i$1RgWha zz6E)gKlT_TDr6VgsTN-ynIF{>sm)Z;!ase!DwJ19J9#$o3;Ev@#5zN>aSIYfmjV(X6#!(%=($9M@@7RjcE2nqie=`a{{*>;s`=r^6!#U##F3Uh10iVh6X+h z#RT9@^Yd3;yAvzOFXooy_t%Aljg5C1jdfZ-wCm&6S)lCW{_6G2w%2e%)LiWS@v(6; zg*~e)!}Ib6+lx-bwQ%_xv~Dd4<5eBLXcup5R~?F-)}Gkzmub9)H_>UIcAs8-?$BgK zuD;6WIuvuG(fe3tMnrV`D0YK;)75HGdX_|;$EUF_%ouSOZg^o1OS|BpqpZ%)2^~Eh zQ9kH6nXK|c$JTb7b-SuKbF<_+hn;z_%xgBJvMkmfK@eMz>tT#rJgDqQ(r_Tv(A2c* z)HIwzqp)DnLv@Qd%DkGZA~6UQJ>|&FA#@UdVswj@FeOV;SArI~+ukQ&@cy9Sd&Qca zCRvvZ&%c+SijqF7KcwQdoFjKcY2VBN&*)HWW}tf5b4<`srEfDvTb(0510v7?y~C$m)P;F+UHG-d+$L( z-wKXsYVIi|&DSNm^Adj-#ks3CepN4-iN;m8__(X-e|kr9yt!5KiQKCm&2@{o>4L&G z$J^hf2lHPh5t2XGz8-fPiVs`D*fG-o{+~ZEbeTZjOPL+DRA;Xg4ATLV-g6Lm;eX_c%v8|md+;ZQ~K5(_CP znPfSXvN{epw6BVt9XkK2UStia-}{9X2T+YzoEHxUSx7~_6N|&v1lY063~SOOoXya- zH~@+t8E$Hedup|?Emj^Wu%nLwAl0hz^HBiYTK6#<4rI5gLfhS{1ua{fA+*MAw$OsM zQ_ym@AB5Jq-4)uJ_G8cr(_IBNKLS8B-5w4-rV}uGM8V!pJoru*mtnH{!{<}++z1jP zfFSZ{(my^LrBxgf3&e52y@Ma>gE|Np2^k3A=#YR=Jqm@ZL&#oz8<=PCOEbe-Jb$or z7=3-niX({PkC>>XQ7C}asSTxpodis-36$n{%ED}3_6wgWLieABW<%U0yJGv#wA|pY zP7z2BlnJ~{V?z)Zb_CJcM2>WZTOs-9;YNwFo5;^SK%s{m*uvnKVQx1(+bBU2O$A-;&yPm&^8|Z6w*fl_KeL;_ zF$RI{B#2>bhrjX|1WdjcxLhUyV!dGDAp8x56?_0CQWos%#zDxwn}ETcfY9Y`1qd~u z5Z)h!c4hStVHR&?vCHOY2G-~a+WRvHX2IElP@W_>)*~y;On1MS{{{oy@MIi<7;GZu zfTA8782)1q0aG7|%5*{g6MiUref)QYDKvHnD&4OREz%0ZA%PJyh=!J(94D=G%I>3CdC0v_Y@ZmZubZ!px z*fS5-kB>&VmIlib{bVnURQZH}G0Q+9A|PdOfyF1R!f&APQZZ!i?_*WpvyXt8DM2B$ zfLx%ek2P%@iguTwdt$(BWEfJZpMarMp~r&{+=K+8eECVQ_(l?&{CY^LlFHR%RnuSGD3y>uoS \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then diff --git a/gradlew.bat b/gradlew.bat index 5f192121..832fdb60 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome From da2f21b67c356e886c4694f156585a3fb3b450e0 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Wed, 27 Apr 2016 12:36:45 +0800 Subject: [PATCH 23/89] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=88=B0=20Android=20Studio=202.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e600ac5e..eebc5a9a 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.0.0' + classpath 'com.android.tools.build:gradle:2.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From 8b057a0b66ac5fdc78592ae1a7ea116e08cf665b Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 04:12:00 +0800 Subject: [PATCH 24/89] =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2mvp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/LoginActivity.java | 83 ++++++++++--------- .../android/md/display/view/ILoginView.java | 19 +++++ .../presenter/contract/ILoginPresenter.java | 11 +++ .../presenter/implement/LoginPersenter.java | 50 +++++++++++ 4 files changed, 124 insertions(+), 39 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java index e237a790..8e403e0e 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java @@ -15,21 +15,21 @@ import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.view.ILoginView; import org.cnodejs.android.md.display.widget.ThemeUtils; import org.cnodejs.android.md.display.widget.ToastUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.ILoginPresenter; +import org.cnodejs.android.md.presenter.implement.LoginPersenter; import org.cnodejs.android.md.util.FormatUtils; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; import retrofit2.Call; -import retrofit2.Response; -public class LoginActivity extends StatusBarActivity { +public class LoginActivity extends StatusBarActivity implements ILoginView { public static final int REQUEST_LOGIN = FormatUtils.createRequestCode(); @@ -65,6 +65,8 @@ public void onClick(DialogInterface dialog, int which) { protected ProgressDialog progressDialog; + private ILoginPresenter loginPresenter; + @Override protected void onCreate(Bundle savedInstanceState) { ThemeUtils.configThemeBeforeOnCreate(this, R.style.AppThemeLight, R.style.AppThemeDark); @@ -76,6 +78,8 @@ protected void onCreate(Bundle savedInstanceState) { progressDialog = DialogUtils.createProgressDialog(this); progressDialog.setMessage(R.string.logging_in_$_); + + loginPresenter = new LoginPersenter(this, this); } @OnClick(R.id.login_btn_login) @@ -85,41 +89,7 @@ protected void onBtnLoginClick() { edtAccessToken.setError(getString(R.string.access_token_format_error)); edtAccessToken.requestFocus(); } else { - final Call call = ApiClient.service.accessToken(accessToken); - progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - - @Override - public void onCancel(DialogInterface dialog) { - call.cancel(); - } - - }); - progressDialog.show(); - call.enqueue(new DefaultToastCallback(this) { - - @Override - public boolean onResultOk(Response response, Result.Login loginInfo) { - LoginShared.login(LoginActivity.this, accessToken, loginInfo); - ToastUtils.with(LoginActivity.this).show(R.string.login_success); - setResult(RESULT_OK); - finish(); - return false; - } - - @Override - public boolean onResultErrorAuth(Response response, Result.Error error) { - edtAccessToken.setError(getString(R.string.access_token_auth_error)); - edtAccessToken.requestFocus(); - return false; - } - - @Override - public void onFinish() { - progressDialog.setOnCancelListener(null); - progressDialog.dismiss(); - } - - }); + loginPresenter.loginAsyncTask(accessToken); } } @@ -146,4 +116,39 @@ protected void onBtnLoginTipClick() { .show(); } + @Override + public void onLoginStart(@NonNull final Call call) { + progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + + @Override + public void onCancel(DialogInterface dialog) { + call.cancel(); + } + + }); + progressDialog.show(); + } + + @Override + public boolean onLoginResultOk(@NonNull String accessToken, @NonNull Result.Login loginInfo) { + LoginShared.login(this, accessToken, loginInfo); + ToastUtils.with(this).show(R.string.login_success); + setResult(RESULT_OK); + finish(); + return false; + } + + @Override + public boolean onLoginResultErrorAuth(@NonNull Result.Error error) { + edtAccessToken.setError(getString(R.string.access_token_auth_error)); + edtAccessToken.requestFocus(); + return false; + } + + @Override + public void onLoginFinish() { + progressDialog.setOnCancelListener(null); + progressDialog.dismiss(); + } + } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java new file mode 100644 index 00000000..ae2979e6 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java @@ -0,0 +1,19 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Result; + +import retrofit2.Call; + +public interface ILoginView { + + void onLoginStart(@NonNull Call call); + + boolean onLoginResultOk(@NonNull String accessToken, @NonNull Result.Login loginInfo); + + boolean onLoginResultErrorAuth(@NonNull Result.Error error); + + void onLoginFinish(); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java new file mode 100644 index 00000000..6b935c63 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java @@ -0,0 +1,11 @@ +package org.cnodejs.android.md.presenter.contract; + +import org.cnodejs.android.md.model.entity.Result; + +import retrofit2.Call; + +public interface ILoginPresenter { + + Call loginAsyncTask(String accessToken); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java new file mode 100644 index 00000000..e3d3b2ad --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java @@ -0,0 +1,50 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.display.view.ILoginView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.presenter.contract.ILoginPresenter; + +import retrofit2.Call; +import retrofit2.Response; + +public class LoginPersenter implements ILoginPresenter { + + private final Activity activity; + private final ILoginView loginView; + + public LoginPersenter(@NonNull Activity activity, @NonNull ILoginView loginView) { + this.activity = activity; + this.loginView = loginView; + } + + @Override + public Call loginAsyncTask(@NonNull final String accessToken) { + Call call = ApiClient.service.accessToken(accessToken); + loginView.onLoginStart(call); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result.Login loginInfo) { + return loginView.onLoginResultOk(accessToken, loginInfo); + } + + @Override + public boolean onResultErrorAuth(Response response, Result.Error error) { + return loginView.onLoginResultErrorAuth(error); + } + + @Override + public void onFinish() { + loginView.onLoginFinish(); + } + + }); + return call; + } + +} From 71cb21e5afe8aaa05429db0013f43908cd363744 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 04:48:44 +0800 Subject: [PATCH 25/89] =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/LoginActivity.java | 14 +++--- .../android/md/display/view/ILoginView.java | 2 + .../presenter/contract/ILoginPresenter.java | 6 +-- .../presenter/implement/LoginPersenter.java | 48 ++++++++++--------- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java index 8e403e0e..65811ed0 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java @@ -84,13 +84,7 @@ protected void onCreate(Bundle savedInstanceState) { @OnClick(R.id.login_btn_login) protected void onBtnLoginClick() { - final String accessToken = edtAccessToken.getText().toString().trim(); - if (!FormatUtils.isAccessToken(accessToken)) { - edtAccessToken.setError(getString(R.string.access_token_format_error)); - edtAccessToken.requestFocus(); - } else { - loginPresenter.loginAsyncTask(accessToken); - } + loginPresenter.loginAsyncTask(edtAccessToken.getText().toString().trim()); } @OnClick(R.id.login_btn_qrcode) @@ -116,6 +110,12 @@ protected void onBtnLoginTipClick() { .show(); } + @Override + public void onAccessTokenFormatError() { + edtAccessToken.setError(getString(R.string.access_token_format_error)); + edtAccessToken.requestFocus(); + } + @Override public void onLoginStart(@NonNull final Call call) { progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java index ae2979e6..9afff72a 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ILoginView.java @@ -8,6 +8,8 @@ public interface ILoginView { + void onAccessTokenFormatError(); + void onLoginStart(@NonNull Call call); boolean onLoginResultOk(@NonNull String accessToken, @NonNull Result.Login loginInfo); diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java index 6b935c63..c629bee1 100644 --- a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ILoginPresenter.java @@ -1,11 +1,7 @@ package org.cnodejs.android.md.presenter.contract; -import org.cnodejs.android.md.model.entity.Result; - -import retrofit2.Call; - public interface ILoginPresenter { - Call loginAsyncTask(String accessToken); + void loginAsyncTask(String accessToken); } diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java index e3d3b2ad..a42679d6 100644 --- a/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java @@ -8,6 +8,7 @@ import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.presenter.contract.ILoginPresenter; +import org.cnodejs.android.md.util.FormatUtils; import retrofit2.Call; import retrofit2.Response; @@ -23,28 +24,31 @@ public LoginPersenter(@NonNull Activity activity, @NonNull ILoginView loginView) } @Override - public Call loginAsyncTask(@NonNull final String accessToken) { - Call call = ApiClient.service.accessToken(accessToken); - loginView.onLoginStart(call); - call.enqueue(new DefaultToastCallback(activity) { - - @Override - public boolean onResultOk(Response response, Result.Login loginInfo) { - return loginView.onLoginResultOk(accessToken, loginInfo); - } - - @Override - public boolean onResultErrorAuth(Response response, Result.Error error) { - return loginView.onLoginResultErrorAuth(error); - } - - @Override - public void onFinish() { - loginView.onLoginFinish(); - } - - }); - return call; + public void loginAsyncTask(final String accessToken) { + if (!FormatUtils.isAccessToken(accessToken)) { + loginView.onAccessTokenFormatError(); + } else { + Call call = ApiClient.service.accessToken(accessToken); + loginView.onLoginStart(call); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result.Login loginInfo) { + return loginView.onLoginResultOk(accessToken, loginInfo); + } + + @Override + public boolean onResultErrorAuth(Response response, Result.Error error) { + return loginView.onLoginResultErrorAuth(error); + } + + @Override + public void onFinish() { + loginView.onLoginFinish(); + } + + }); + } } } From fd365a006c23a2400c4589805f0bfa80d7b922c4 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 05:00:30 +0800 Subject: [PATCH 26/89] =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E6=A1=86=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E8=81=94=E5=8A=A8Call=E7=9B=91=E5=90=AC=E5=99=A8?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/LoginActivity.java | 12 +++------- .../listener/DialogCancelCallListener.java | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/listener/DialogCancelCallListener.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java index 65811ed0..f77c7443 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java @@ -14,6 +14,7 @@ import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; +import org.cnodejs.android.md.display.listener.DialogCancelCallListener; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; import org.cnodejs.android.md.display.view.ILoginView; import org.cnodejs.android.md.display.widget.ThemeUtils; @@ -117,15 +118,8 @@ public void onAccessTokenFormatError() { } @Override - public void onLoginStart(@NonNull final Call call) { - progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - - @Override - public void onCancel(DialogInterface dialog) { - call.cancel(); - } - - }); + public void onLoginStart(@NonNull Call call) { + progressDialog.setOnCancelListener(new DialogCancelCallListener(call)); progressDialog.show(); } diff --git a/app/src/main/java/org/cnodejs/android/md/display/listener/DialogCancelCallListener.java b/app/src/main/java/org/cnodejs/android/md/display/listener/DialogCancelCallListener.java new file mode 100644 index 00000000..a6b8986d --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/listener/DialogCancelCallListener.java @@ -0,0 +1,23 @@ +package org.cnodejs.android.md.display.listener; + +import android.content.DialogInterface; +import android.support.annotation.NonNull; + +import retrofit2.Call; + +public class DialogCancelCallListener implements DialogInterface.OnCancelListener { + + private final Call call; + + public DialogCancelCallListener(@NonNull Call call) { + this.call = call; + } + + @Override + public void onCancel(DialogInterface dialog) { + if (!call.isCanceled()) { + call.cancel(); + } + } + +} From 1b959253f7ed155127187f5bc76a1acb93c81e81 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 06:52:25 +0800 Subject: [PATCH 27/89] =?UTF-8?q?=E4=B8=BB=E7=95=8C=E9=9D=A2mvp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/MainActivity.java | 248 +++++++----------- .../android/md/display/view/IMainView.java | 29 ++ .../md/presenter/contract/IMainPresenter.java | 17 ++ .../md/presenter/implement/MainPresenter.java | 127 +++++++++ 4 files changed, 270 insertions(+), 151 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/IMainView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/IMainPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/MainPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java index f55f5ffb..a22abf0d 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java @@ -3,6 +3,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.SwipeRefreshLayout; @@ -24,17 +25,17 @@ import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.listener.NavigationOpenClickListener; import org.cnodejs.android.md.display.listener.RecyclerViewLoadMoreListener; +import org.cnodejs.android.md.display.view.IMainView; import org.cnodejs.android.md.display.widget.RefreshLayoutUtils; import org.cnodejs.android.md.display.widget.ThemeUtils; import org.cnodejs.android.md.display.widget.ToastUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.CallbackAdapter; import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.entity.TabType; import org.cnodejs.android.md.model.entity.Topic; -import org.cnodejs.android.md.model.entity.User; import org.cnodejs.android.md.model.storage.LoginShared; import org.cnodejs.android.md.model.storage.SettingShared; +import org.cnodejs.android.md.presenter.contract.IMainPresenter; +import org.cnodejs.android.md.presenter.implement.MainPresenter; import org.cnodejs.android.md.util.FormatUtils; import org.cnodejs.android.md.util.HandlerUtils; @@ -44,10 +45,8 @@ import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; -import retrofit2.Call; -import retrofit2.Response; -public class MainActivity extends DrawerLayoutActivity implements SwipeRefreshLayout.OnRefreshListener, RecyclerViewLoadMoreListener.OnLoadMoreListener { +public class MainActivity extends DrawerLayoutActivity implements IMainView, SwipeRefreshLayout.OnRefreshListener, RecyclerViewLoadMoreListener.OnLoadMoreListener { // 抽屉导航布局 @Bind(R.id.main_drawer_layout) @@ -114,6 +113,8 @@ public class MainActivity extends DrawerLayoutActivity implements SwipeRefreshLa private final List topicList = new ArrayList<>(); private MainAdapter adapter; + private IMainPresenter mainPresenter; + // 首次按下返回键时间戳 private long firstBackPressedTime = 0; @@ -141,6 +142,8 @@ protected void onCreate(Bundle savedInstanceState) { recyclerView.addOnScrollListener(new RecyclerViewLoadMoreListener(linearLayoutManager, this, 20)); fabCreateTopic.attachToRecyclerView(recyclerView); + mainPresenter = new MainPresenter(this, this); + updateUserInfoViews(); imgThemeDark.setImageResource(enableThemeDark ? R.drawable.ic_wb_sunny_white_24dp : R.drawable.ic_brightness_3_white_24dp); @@ -153,7 +156,7 @@ protected void onCreate(Bundle savedInstanceState) { @Override protected void onResume() { super.onResume(); - getMessageCountAsyncTask(); + mainPresenter.getMessageCountAsyncTask(); // 判断是否需要切换主题 if (SettingShared.isEnableThemeDark(this) != enableThemeDark) { HandlerUtils.post(new Runnable() { @@ -172,8 +175,8 @@ public void run() { @Override public void onDrawerOpened(View drawerView) { updateUserInfoViews(); - getUserAsyncTask(); - getMessageCountAsyncTask(); + mainPresenter.getUserAsyncTask(); + mainPresenter.getMessageCountAsyncTask(); } @Override @@ -218,101 +221,9 @@ public void onDrawerClosed(View drawerView) { }; - private void updateUserInfoViews() { - if (TextUtils.isEmpty(LoginShared.getAccessToken(this))) { - Glide.with(this).load(R.drawable.image_placeholder).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); - tvLoginName.setText(R.string.click_avatar_to_login); - tvScore.setText(null); - btnLogout.setVisibility(View.GONE); - } else { - Glide.with(this).load(LoginShared.getAvatarUrl(this)).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); - tvLoginName.setText(LoginShared.getLoginName(this)); - tvScore.setText(getString(R.string.score_$) + LoginShared.getScore(this)); - btnLogout.setVisibility(View.VISIBLE); - } - } - - private void getUserAsyncTask() { - final String accessToken = LoginShared.getAccessToken(this); - if (!TextUtils.isEmpty(accessToken)) { - Call> call = ApiClient.service.getUser(LoginShared.getLoginName(this)); - call.enqueue(new CallbackAdapter>() { - - @Override - public boolean onResultOk(Response> response, Result.Data result) { - if (TextUtils.equals(accessToken, LoginShared.getAccessToken(MainActivity.this))) { - LoginShared.update(MainActivity.this, result.getData()); - updateUserInfoViews(); - } - return false; - } - - }); - } - } - - private void getMessageCountAsyncTask() { - final String accessToken = LoginShared.getAccessToken(this); - if (!TextUtils.isEmpty(accessToken)) { - Call> call = ApiClient.service.getMessageCount(accessToken); - call.enqueue(new CallbackAdapter>() { - - @Override - public boolean onResultOk(Response> response, Result.Data result) { - if (TextUtils.equals(accessToken, LoginShared.getAccessToken(MainActivity.this))) { - tvBadgerNotification.setText(FormatUtils.getNavigationDisplayCountText(result.getData())); - } - return false; - } - - }); - } - } - - /** - * 刷新和加载逻辑 - */ @Override public void onRefresh() { - final TabType tab = currentTab; - Call>> call = ApiClient.service.getTopicList(tab, 1, 20, true); - call.enqueue(new CallbackAdapter>>() { - - @Override - public boolean onResultOk(Response>> response, Result.Data> result) { - if (currentTab == tab) { - topicList.clear(); - topicList.addAll(result.getData()); - notifyDataSetChanged(); - currentPage = 1; - } - return false; - } - - @Override - public boolean onResultError(Response>> response, Result.Error error) { - if (currentTab == tab) { - ToastUtils.with(MainActivity.this).show(error.getErrorMessage()); - } - return false; - } - - @Override - public boolean onCallException(Throwable t, Result.Error error) { - if (currentTab == tab) { - ToastUtils.with(MainActivity.this).show(error.getErrorMessage()); - } - return false; - } - - @Override - public void onFinish() { - if (currentTab == tab) { - refreshLayout.setRefreshing(false); - } - } - - }); + mainPresenter.refreshTopicListAsyncTask(currentTab, 20, true); } @Override @@ -320,54 +231,7 @@ public void onLoadMore() { if (adapter.canLoadMore()) { adapter.setLoading(true); adapter.notifyItemChanged(adapter.getItemCount() - 1); - - final TabType tab = currentTab; - final int page = currentPage; - Call>> call = ApiClient.service.getTopicList(tab, page + 1, 20, true); - call.enqueue(new CallbackAdapter>>() { - - @Override - public boolean onResultOk(Response>> response, Result.Data> result) { - if (currentTab == tab && currentPage == page) { - if (result.getData().size() > 0) { - topicList.addAll(result.getData()); - adapter.setLoading(false); - adapter.notifyItemRangeInserted(topicList.size() - result.getData().size(), result.getData().size()); - currentPage++; - return true; - } else { - ToastUtils.with(MainActivity.this).show(R.string.have_no_more_data); - return false; - } - } - return false; - } - - @Override - public boolean onResultError(Response>> response, Result.Error error) { - if (currentTab == tab && currentPage == page) { - ToastUtils.with(MainActivity.this).show(error.getErrorMessage()); - } - return false; - } - - @Override - public boolean onCallException(Throwable t, Result.Error error) { - if (currentTab == tab && currentPage == page) { - ToastUtils.with(MainActivity.this).show(error.getErrorMessage()); - } - return false; - } - - @Override - public void onFinish() { - if (currentTab == tab && currentPage == page) { - adapter.setLoading(false); - adapter.notifyItemChanged(adapter.getItemCount() - 1); - } - } - - }); + mainPresenter.loadMoreTopicListAsyncTask(currentTab, currentPage, 20, true); } } @@ -508,7 +372,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == LoginActivity.REQUEST_LOGIN && resultCode == RESULT_OK) { updateUserInfoViews(); - getUserAsyncTask(); + mainPresenter.getUserAsyncTask(); } } @@ -530,4 +394,86 @@ public void onBackPressed() { } } + @Override + public boolean onRefreshTopicListResultOk(@NonNull TabType tab, @NonNull Result.Data> result) { + if (currentTab == tab) { + topicList.clear(); + topicList.addAll(result.getData()); + notifyDataSetChanged(); + currentPage = 1; + return false; + } else { + return true; + } + } + + @Override + public boolean onRefreshTopicListResultErrorOrCallException(@NonNull TabType tab, @NonNull Result.Error error) { + if (currentTab == tab) { + ToastUtils.with(this).show(error.getErrorMessage()); + return false; + } else { + return true; + } + } + + @Override + public void onRefreshTopicListFinish() { + refreshLayout.setRefreshing(false); + } + + @Override + public boolean onLoadMoreTopicListResultOk(@NonNull TabType tab, @NonNull Integer page, Result.Data> result) { + if (currentTab == tab && currentPage == page) { + if (result.getData().size() > 0) { + topicList.addAll(result.getData()); + adapter.setLoading(false); + adapter.notifyItemRangeInserted(topicList.size() - result.getData().size(), result.getData().size()); + currentPage++; + return true; + } else { + ToastUtils.with(this).show(R.string.have_no_more_data); + return false; + } + } else { + return true; + } + } + + @Override + public boolean onLoadMoreTopicListResultErrorOrCallException(@NonNull TabType tab, @NonNull Integer page, @NonNull Result.Error error) { + if (currentTab == tab && currentPage == page) { + ToastUtils.with(this).show(error.getErrorMessage()); + return false; + } else { + return true; + } + } + + @Override + public void onLoadMoreTopicListFinish() { + adapter.setLoading(false); + adapter.notifyItemChanged(adapter.getItemCount() - 1); + } + + @Override + public void updateUserInfoViews() { + if (TextUtils.isEmpty(LoginShared.getAccessToken(this))) { + Glide.with(this).load(R.drawable.image_placeholder).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); + tvLoginName.setText(R.string.click_avatar_to_login); + tvScore.setText(null); + btnLogout.setVisibility(View.GONE); + } else { + Glide.with(this).load(LoginShared.getAvatarUrl(this)).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); + tvLoginName.setText(LoginShared.getLoginName(this)); + tvScore.setText(getString(R.string.score_$) + LoginShared.getScore(this)); + btnLogout.setVisibility(View.VISIBLE); + } + } + + @Override + public void updateMessageCountViews(@NonNull Result.Data result) { + tvBadgerNotification.setText(FormatUtils.getNavigationDisplayCountText(result.getData())); + } + } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/IMainView.java b/app/src/main/java/org/cnodejs/android/md/display/view/IMainView.java new file mode 100644 index 00000000..6c9fb189 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/IMainView.java @@ -0,0 +1,29 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.TabType; +import org.cnodejs.android.md.model.entity.Topic; + +import java.util.List; + +public interface IMainView { + + boolean onRefreshTopicListResultOk(@NonNull TabType tab, @NonNull Result.Data> result); + + boolean onRefreshTopicListResultErrorOrCallException(@NonNull TabType tab, @NonNull Result.Error error); + + void onRefreshTopicListFinish(); + + boolean onLoadMoreTopicListResultOk(@NonNull TabType tab, @NonNull Integer page, Result.Data> result); + + boolean onLoadMoreTopicListResultErrorOrCallException(@NonNull TabType tab, @NonNull Integer page, @NonNull Result.Error error); + + void onLoadMoreTopicListFinish(); + + void updateUserInfoViews(); + + void updateMessageCountViews(@NonNull Result.Data result); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/IMainPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/IMainPresenter.java new file mode 100644 index 00000000..47817f1b --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/IMainPresenter.java @@ -0,0 +1,17 @@ +package org.cnodejs.android.md.presenter.contract; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.TabType; + +public interface IMainPresenter { + + void refreshTopicListAsyncTask(@NonNull TabType tab, @NonNull Integer limit, @NonNull Boolean mdrender); + + void loadMoreTopicListAsyncTask(@NonNull TabType tab, @NonNull Integer page, @NonNull Integer limit, @NonNull Boolean mdrender); + + void getUserAsyncTask(); + + void getMessageCountAsyncTask(); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/MainPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/MainPresenter.java new file mode 100644 index 00000000..ba75baba --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/MainPresenter.java @@ -0,0 +1,127 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; +import android.text.TextUtils; + +import org.cnodejs.android.md.display.view.IMainView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.CallbackAdapter; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.TabType; +import org.cnodejs.android.md.model.entity.Topic; +import org.cnodejs.android.md.model.entity.User; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.IMainPresenter; + +import java.util.List; + +import retrofit2.Call; +import retrofit2.Response; + +public class MainPresenter implements IMainPresenter { + + private final Activity activity; + private final IMainView mainView; + + public MainPresenter(@NonNull Activity activity, @NonNull IMainView mainView) { + this.activity = activity; + this.mainView = mainView; + } + + @Override + public void refreshTopicListAsyncTask(@NonNull final TabType tab, @NonNull Integer limit, @NonNull Boolean mdrender) { + Call>> call = ApiClient.service.getTopicList(tab, 1, limit, mdrender); + call.enqueue(new CallbackAdapter>>() { + + @Override + public boolean onResultOk(Response>> response, Result.Data> result) { + return mainView.onRefreshTopicListResultOk(tab, result); + } + + @Override + public boolean onResultError(Response>> response, Result.Error error) { + return mainView.onRefreshTopicListResultErrorOrCallException(tab, error); + } + + @Override + public boolean onCallException(Throwable t, Result.Error error) { + return mainView.onRefreshTopicListResultErrorOrCallException(tab, error); + } + + @Override + public void onFinish() { + mainView.onRefreshTopicListFinish(); + } + + }); + } + + @Override + public void loadMoreTopicListAsyncTask(@NonNull final TabType tab, @NonNull final Integer page, @NonNull Integer limit, @NonNull final Boolean mdrender) { + Call>> call = ApiClient.service.getTopicList(tab, page + 1, limit, mdrender); + call.enqueue(new CallbackAdapter>>() { + + @Override + public boolean onResultOk(Response>> response, Result.Data> result) { + return mainView.onLoadMoreTopicListResultOk(tab, page, result); + } + + @Override + public boolean onResultError(Response>> response, Result.Error error) { + return mainView.onLoadMoreTopicListResultErrorOrCallException(tab, page, error); + } + + @Override + public boolean onCallException(Throwable t, Result.Error error) { + return mainView.onLoadMoreTopicListResultErrorOrCallException(tab, page, error); + } + + @Override + public void onFinish() { + mainView.onLoadMoreTopicListFinish(); + } + + }); + } + + @Override + public void getUserAsyncTask() { + final String accessToken = LoginShared.getAccessToken(activity); + if (!TextUtils.isEmpty(accessToken)) { + Call> call = ApiClient.service.getUser(LoginShared.getLoginName(activity)); + call.enqueue(new CallbackAdapter>() { + + @Override + public boolean onResultOk(Response> response, Result.Data result) { + if (TextUtils.equals(accessToken, LoginShared.getAccessToken(activity))) { + LoginShared.update(activity, result.getData()); + mainView.updateUserInfoViews(); + } + return false; + } + + }); + } + } + + @Override + public void getMessageCountAsyncTask() { + final String accessToken = LoginShared.getAccessToken(activity); + if (!TextUtils.isEmpty(accessToken)) { + Call> call = ApiClient.service.getMessageCount(accessToken); + call.enqueue(new CallbackAdapter>() { + + @Override + public boolean onResultOk(Response> response, Result.Data result) { + if (TextUtils.equals(accessToken, LoginShared.getAccessToken(activity))) { + mainView.updateMessageCountViews(result); + } + return false; + } + + }); + } + } + +} From af0e93dbddb9dfd3d78d8e80d226df76cc86f435 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 07:36:10 +0800 Subject: [PATCH 28/89] =?UTF-8?q?=E4=B8=BB=E9=A2=98=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/md/display/activity/MainActivity.java | 9 +-------- .../android/md/display/widget/ThemeUtils.java | 14 +++++++++++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java index a22abf0d..e547f77f 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java @@ -159,14 +159,7 @@ protected void onResume() { mainPresenter.getMessageCountAsyncTask(); // 判断是否需要切换主题 if (SettingShared.isEnableThemeDark(this) != enableThemeDark) { - HandlerUtils.post(new Runnable() { - - @Override - public void run() { - ThemeUtils.recreateActivity(MainActivity.this); - } - - }); + ThemeUtils.recreateActivityDelayed(this); } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java b/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java index aaaa450e..ca76348d 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java @@ -13,6 +13,7 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.model.storage.SettingShared; +import org.cnodejs.android.md.util.HandlerUtils; public final class ThemeUtils { @@ -43,7 +44,7 @@ public static boolean configThemeBeforeOnCreate(Activity activity, @StyleRes int return enable; } - public static void recreateActivity(Activity activity) { + public static void recreateActivity(@NonNull Activity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { activity.recreate(); } else { @@ -55,6 +56,17 @@ public static void recreateActivity(Activity activity) { } } + public static void recreateActivityDelayed(@NonNull final Activity activity) { + HandlerUtils.post(new Runnable() { + + @Override + public void run() { + ThemeUtils.recreateActivity(activity); + } + + }); + } + public static int getDialogThemeRes(Context context) { return SettingShared.isEnableThemeDark(context) ? R.style.AppDialogDark : R.style.AppDialogLight; } From 910861655af3dcce5484ae41f8a04b0d24d3271f Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 07:37:05 +0800 Subject: [PATCH 29/89] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/cnodejs/android/md/display/widget/ThemeUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java b/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java index ca76348d..1ad3a3b2 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java @@ -38,7 +38,7 @@ public static Drawable getThemeAttrDrawable(@NonNull Context context, @AttrRes i } } - public static boolean configThemeBeforeOnCreate(Activity activity, @StyleRes int light, @StyleRes int dark) { + public static boolean configThemeBeforeOnCreate(@NonNull Activity activity, @StyleRes int light, @StyleRes int dark) { boolean enable = SettingShared.isEnableThemeDark(activity); activity.setTheme(enable ? dark : light); return enable; @@ -67,11 +67,11 @@ public void run() { }); } - public static int getDialogThemeRes(Context context) { + public static int getDialogThemeRes(@NonNull Context context) { return SettingShared.isEnableThemeDark(context) ? R.style.AppDialogDark : R.style.AppDialogLight; } - public static int getStatusBarHeight(Context context) { + public static int getStatusBarHeight(@NonNull Context context) { int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return resourceId > 0 ? context.getResources().getDimensionPixelSize(resourceId) : 0; } From a42e905b7c882769426f15f7b1bb2ff74aea4c7a Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 08:03:42 +0800 Subject: [PATCH 30/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implement/{LoginPersenter.java => LoginPresenter.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename app/src/main/java/org/cnodejs/android/md/presenter/implement/{LoginPersenter.java => LoginPresenter.java} (93%) diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPresenter.java similarity index 93% rename from app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java rename to app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPresenter.java index a42679d6..d0d29817 100644 --- a/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPersenter.java +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/LoginPresenter.java @@ -13,12 +13,12 @@ import retrofit2.Call; import retrofit2.Response; -public class LoginPersenter implements ILoginPresenter { +public class LoginPresenter implements ILoginPresenter { private final Activity activity; private final ILoginView loginView; - public LoginPersenter(@NonNull Activity activity, @NonNull ILoginView loginView) { + public LoginPresenter(@NonNull Activity activity, @NonNull ILoginView loginView) { this.activity = activity; this.loginView = loginView; } From eb628e5b9552ff821fab09ccf53363057b2d79ab Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 08:22:05 +0800 Subject: [PATCH 31/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8C=85=E5=90=8D?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnodejs/android/md/display/activity/LoginActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java index f77c7443..bda7b17b 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java @@ -22,7 +22,7 @@ import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.storage.LoginShared; import org.cnodejs.android.md.presenter.contract.ILoginPresenter; -import org.cnodejs.android.md.presenter.implement.LoginPersenter; +import org.cnodejs.android.md.presenter.implement.LoginPresenter; import org.cnodejs.android.md.util.FormatUtils; import butterknife.Bind; @@ -80,7 +80,7 @@ protected void onCreate(Bundle savedInstanceState) { progressDialog = DialogUtils.createProgressDialog(this); progressDialog.setMessage(R.string.logging_in_$_); - loginPresenter = new LoginPersenter(this, this); + loginPresenter = new LoginPresenter(this, this); } @OnClick(R.id.login_btn_login) From e67cc6f5112ba1e34ba88da3f9a5af1d9494a5c2 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 08:22:36 +0800 Subject: [PATCH 32/89] =?UTF-8?q?=E5=8F=91=E5=B8=83=E5=B8=96=E5=AD=90mvp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../display/activity/CreateTopicActivity.java | 84 +++++++++---------- .../md/display/view/ICreateTopicView.java | 19 +++++ .../contract/ICreateTopicPresenter.java | 11 +++ .../implement/CreateTopicPresenter.java | 57 +++++++++++++ 4 files changed, 128 insertions(+), 43 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/ICreateTopicView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java index 45b23bfa..4c9d6c7e 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java @@ -1,6 +1,7 @@ package org.cnodejs.android.md.display.activity; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.widget.Toolbar; import android.view.MenuItem; import android.view.ViewGroup; @@ -8,27 +9,25 @@ import android.widget.Spinner; import org.cnodejs.android.md.R; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.DefaultToastCallback; -import org.cnodejs.android.md.model.entity.Result; -import org.cnodejs.android.md.model.entity.TabType; -import org.cnodejs.android.md.model.storage.LoginShared; -import org.cnodejs.android.md.model.storage.SettingShared; -import org.cnodejs.android.md.model.storage.TopicShared; import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.view.ICreateTopicView; import org.cnodejs.android.md.display.widget.EditorBarHandler; import org.cnodejs.android.md.display.widget.ThemeUtils; import org.cnodejs.android.md.display.widget.ToastUtils; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.TabType; +import org.cnodejs.android.md.model.storage.SettingShared; +import org.cnodejs.android.md.model.storage.TopicShared; +import org.cnodejs.android.md.presenter.contract.ICreateTopicPresenter; +import org.cnodejs.android.md.presenter.implement.CreateTopicPresenter; import butterknife.Bind; import butterknife.ButterKnife; -import retrofit2.Call; -import retrofit2.Response; -public class CreateTopicActivity extends StatusBarActivity implements Toolbar.OnMenuItemClickListener { +public class CreateTopicActivity extends StatusBarActivity implements Toolbar.OnMenuItemClickListener, ICreateTopicView { @Bind(R.id.create_topic_toolbar) protected Toolbar toolbar; @@ -47,6 +46,8 @@ public class CreateTopicActivity extends StatusBarActivity implements Toolbar.On private ProgressDialog progressDialog; + private ICreateTopicPresenter createTopicPresenter; + private boolean saveTopicDraft = true; @Override @@ -75,6 +76,8 @@ protected void onCreate(Bundle savedInstanceState) { edtTitle.setText(TopicShared.getNewTopicTitle(this)); edtTitle.setSelection(edtTitle.length()); // 这个必须最后调用 } + + createTopicPresenter = new CreateTopicPresenter(this, this); } /** @@ -94,21 +97,7 @@ protected void onPause() { public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.action_send: - if (edtTitle.length() < 10) { - edtTitle.requestFocus(); - ToastUtils.with(this).show(R.string.title_empty_error_tip); - } else if (edtContent.length() == 0) { - edtContent.requestFocus(); - ToastUtils.with(this).show(R.string.content_empty_error_tip); - } else { - TabType tab = getTabByPosition(spnTab.getSelectedItemPosition()); - String title = edtTitle.getText().toString().trim(); - String content = edtContent.getText().toString(); - if (SettingShared.isEnableTopicSign(this)) { // 添加小尾巴 - content += "\n\n" + SettingShared.getTopicSignContent(this); - } - createTipicAsyncTask(tab, title, content); - } + createTopicPresenter.createTipicAsyncTask(getTabByPosition(spnTab.getSelectedItemPosition()), edtTitle.getText().toString().trim(), edtContent.getText().toString().trim()); return true; default: return false; @@ -128,27 +117,36 @@ private TabType getTabByPosition(int position) { } } - private void createTipicAsyncTask(TabType tab, String title, String content) { + @Override + public void onTitleEmptyError() { + ToastUtils.with(this).show(R.string.title_empty_error_tip); + edtTitle.requestFocus(); + } + + @Override + public void onContentEmptyError() { + ToastUtils.with(this).show(R.string.content_empty_error_tip); + edtContent.requestFocus(); + } + + @Override + public void onCreateTopicStart() { progressDialog.show(); - Call call = ApiClient.service.createTopic(LoginShared.getAccessToken(this), tab, title, content); - call.enqueue(new DefaultToastCallback(this) { - - @Override - public boolean onResultOk(Response response, Result.CreateTopic result) { - saveTopicDraft = false; - TopicShared.clear(CreateTopicActivity.this); - ToastUtils.with(CreateTopicActivity.this).show(R.string.post_success); - TopicActivity.start(CreateTopicActivity.this, result.getTopicId()); - finish(); - return false; - } + } - @Override - public void onFinish() { - progressDialog.dismiss(); - } + @Override + public boolean onCreateTopicResultOk(@NonNull Result.CreateTopic result) { + saveTopicDraft = false; + TopicShared.clear(this); + ToastUtils.with(this).show(R.string.post_success); + TopicActivity.start(this, result.getTopicId()); + finish(); + return false; + } - }); + @Override + public void onCreateTopicFinish() { + progressDialog.dismiss(); } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ICreateTopicView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ICreateTopicView.java new file mode 100644 index 00000000..f1e176cb --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ICreateTopicView.java @@ -0,0 +1,19 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Result; + +public interface ICreateTopicView { + + void onTitleEmptyError(); + + void onContentEmptyError(); + + void onCreateTopicStart(); + + boolean onCreateTopicResultOk(@NonNull Result.CreateTopic result); + + void onCreateTopicFinish(); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java new file mode 100644 index 00000000..279d5eeb --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java @@ -0,0 +1,11 @@ +package org.cnodejs.android.md.presenter.contract; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.TabType; + +public interface ICreateTopicPresenter { + + void createTipicAsyncTask(@NonNull TabType tab, String title, String content); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java new file mode 100644 index 00000000..71ebfbbf --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java @@ -0,0 +1,57 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; +import android.text.TextUtils; + +import org.cnodejs.android.md.display.view.ICreateTopicView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.TabType; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.model.storage.SettingShared; +import org.cnodejs.android.md.presenter.contract.ICreateTopicPresenter; + +import retrofit2.Call; +import retrofit2.Response; + +public class CreateTopicPresenter implements ICreateTopicPresenter { + + private final Activity activity; + private final ICreateTopicView createTopicView; + + public CreateTopicPresenter(@NonNull Activity activity, @NonNull ICreateTopicView createTopicView) { + this.activity = activity; + this.createTopicView = createTopicView; + } + + @Override + public void createTipicAsyncTask(@NonNull TabType tab, String title, String content) { + if (TextUtils.isEmpty(title) || title.length() < 10) { + createTopicView.onTitleEmptyError(); + } else if (TextUtils.isEmpty(content)) { + createTopicView.onContentEmptyError(); + } else { + if (SettingShared.isEnableTopicSign(activity)) { // 添加小尾巴 + content += "\n\n" + SettingShared.getTopicSignContent(activity); + } + createTopicView.onCreateTopicStart(); + Call call = ApiClient.service.createTopic(LoginShared.getAccessToken(activity), tab, title, content); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result.CreateTopic result) { + return createTopicView.onCreateTopicResultOk(result); + } + + @Override + public void onFinish() { + createTopicView.onCreateTopicFinish(); + } + + }); + } + } + +} From 2d7fa247edb701514d8d2c36bc5f33094c947256 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 10:39:38 +0800 Subject: [PATCH 33/89] =?UTF-8?q?=E8=AF=9D=E9=A2=98=E8=AF=A6=E6=83=85?= =?UTF-8?q?=EF=BC=8C=E5=9B=9E=E5=A4=8Dwindow=E9=80=BB=E8=BE=91=E6=8F=90?= =?UTF-8?q?=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/TopicActivity.java | 129 ++-------------- .../viewholder/TopicReplyViewHolder.java | 139 ++++++++++++++++++ 2 files changed, 150 insertions(+), 118 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index d41537d5..c6db9085 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -3,47 +3,35 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.Toolbar; import android.text.TextUtils; -import android.view.Gravity; -import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.EditText; import android.widget.ListView; -import android.widget.PopupWindow; import com.melnykov.fab.FloatingActionButton; import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.adapter.TopicAdapter; import org.cnodejs.android.md.display.base.StatusBarActivity; -import org.cnodejs.android.md.display.dialog.DialogUtils; -import org.cnodejs.android.md.display.dialog.ProgressDialog; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; import org.cnodejs.android.md.display.viewholder.TopicHeaderViewHolder; -import org.cnodejs.android.md.display.widget.EditorBarHandler; +import org.cnodejs.android.md.display.viewholder.TopicReplyViewHolder; import org.cnodejs.android.md.display.widget.RefreshLayoutUtils; import org.cnodejs.android.md.display.widget.ThemeUtils; -import org.cnodejs.android.md.display.widget.ToastUtils; import org.cnodejs.android.md.model.api.ApiClient; import org.cnodejs.android.md.model.api.DefaultToastCallback; -import org.cnodejs.android.md.model.entity.Author; import org.cnodejs.android.md.model.entity.Reply; import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.entity.Topic; import org.cnodejs.android.md.model.entity.TopicWithReply; import org.cnodejs.android.md.model.storage.LoginShared; -import org.cnodejs.android.md.model.storage.SettingShared; import org.cnodejs.android.md.model.util.EntityUtils; -import org.cnodejs.android.md.util.FormatUtils; import org.cnodejs.android.md.util.ShipUtils; -import org.joda.time.DateTime; import java.util.ArrayList; import java.util.List; @@ -54,7 +42,7 @@ import retrofit2.Call; import retrofit2.Response; -public class TopicActivity extends StatusBarActivity implements SwipeRefreshLayout.OnRefreshListener, TopicAdapter.OnAtClickListener, Toolbar.OnMenuItemClickListener { +public class TopicActivity extends StatusBarActivity implements SwipeRefreshLayout.OnRefreshListener, Toolbar.OnMenuItemClickListener { private static final String EXTRA_TOPIC_ID = "topicId"; private static final String EXTRA_TOPIC = "topic"; @@ -97,15 +85,11 @@ public static void start(@NonNull Context context, String topicId) { @Bind(R.id.topic_fab_reply) protected FloatingActionButton fabReply; - private PopupWindow replyWindow; - private ReplyHandler replyHandler; - - private ProgressDialog progressDialog; - private String topicId; private Topic topic; private final List replyList = new ArrayList<>(); + private TopicReplyViewHolder replyViewHolder; private TopicHeaderViewHolder headerViewHolder; private TopicAdapter adapter; @@ -125,31 +109,16 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.inflateMenu(R.menu.topic); toolbar.setOnMenuItemClickListener(this); + replyViewHolder = new TopicReplyViewHolder(this, layoutRoot, topicId, this); headerViewHolder = new TopicHeaderViewHolder(this, listView); headerViewHolder.update(topic, false, 0); - adapter = new TopicAdapter(this, replyList, this); + adapter = new TopicAdapter(this, replyList, replyViewHolder); listView.setAdapter(adapter); iconNoData.setVisibility(topic == null ? View.VISIBLE : View.GONE); fabReply.attachToListView(listView); - // 创建回复窗口 - LayoutInflater inflater = LayoutInflater.from(this); - View view = inflater.inflate(R.layout.activity_topic_reply_window, layoutRoot, false); - replyHandler = new ReplyHandler(view); - - replyWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - replyWindow.setBackgroundDrawable(new ColorDrawable(0x01000000)); - replyWindow.setFocusable(true); - replyWindow.setOutsideTouchable(true); - replyWindow.setAnimationStyle(R.style.AppWidget_ReplyWindowAnim); - // - END - - - progressDialog = DialogUtils.createProgressDialog(this); - progressDialog.setMessage(R.string.posting_$_); - progressDialog.setCancelable(false); - RefreshLayoutUtils.initOnCreate(refreshLayout, this); RefreshLayoutUtils.refreshOnCreate(refreshLayout, this); } @@ -193,16 +162,10 @@ public void onFinish() { }); } - @Override - public void onAt(String loginName) { - replyHandler.edtContent.getText().insert(replyHandler.edtContent.getSelectionEnd(), " @" + loginName + " "); - replyWindow.showAtLocation(layoutRoot, Gravity.BOTTOM, 0, 0); - } - @OnClick(R.id.topic_fab_reply) protected void onBtnReplyClick() { if (topic != null && LoginActivity.startForResultWithAccessTokenCheck(this)) { - replyWindow.showAtLocation(layoutRoot, Gravity.BOTTOM, 0, 0); + replyViewHolder.showReplyWindow(); } } @@ -215,81 +178,11 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } } - //============== - // 回复框逻辑处理 - //============== - - protected class ReplyHandler { - - @Bind(R.id.editor_bar_layout_root) - protected ViewGroup editorBar; - - @Bind(R.id.topic_reply_window_edt_content) - protected EditText edtContent; - - protected ReplyHandler(View view) { - ButterKnife.bind(this, view); - new EditorBarHandler(TopicActivity.this, editorBar, edtContent); // 创建editorBar - } - - @OnClick(R.id.topic_reply_window_btn_tool_close) - protected void onBtnToolCloseClick() { - replyWindow.dismiss(); - } - - @OnClick(R.id.topic_reply_window_btn_tool_send) - protected void onBtnToolSendClick() { - if (edtContent.length() == 0) { - ToastUtils.with(TopicActivity.this).show(R.string.content_empty_error_tip); - } else { - String content = edtContent.getText().toString(); - if (SettingShared.isEnableTopicSign(TopicActivity.this)) { // 添加小尾巴 - content += "\n\n" + SettingShared.getTopicSignContent(TopicActivity.this); - } - replyTopicAsyncTask(content); - } - } - - private void replyTopicAsyncTask(final String content) { - progressDialog.show(); - Call call = ApiClient.service.replyTopic(topicId, LoginShared.getAccessToken(TopicActivity.this), content, null); - call.enqueue(new DefaultToastCallback(TopicActivity.this) { - - @Override - public boolean onResultOk(Response response, Result.ReplyTopic result) { - // 本地创建一个回复对象 - Reply reply = new Reply(); - reply.setId(result.getReplyId()); - Author author = new Author(); - author.setLoginName(LoginShared.getLoginName(TopicActivity.this)); - author.setAvatarUrl(LoginShared.getAvatarUrl(TopicActivity.this)); - reply.setAuthor(author); - reply.setContent(content); - reply.setHandleContent(FormatUtils.renderMarkdown(content)); // 本地要做预渲染处理 - reply.setCreateAt(new DateTime()); - reply.setUpList(new ArrayList()); - replyList.add(reply); - // 更新header和adapter - replyWindow.dismiss(); - headerViewHolder.update(replyList.size()); - adapter.notifyDataSetChanged(); - listView.smoothScrollToPosition(replyList.size()); - // 清空回复框内容 - edtContent.setText(null); - // 提示 - ToastUtils.with(TopicActivity.this).show(R.string.post_success); - // 继续执行onFinish() - return false; - } - - @Override - public void onFinish() { - progressDialog.dismiss(); - } - - }); - } - + public void insertReplyAndUpdateViews(@NonNull Reply reply) { + replyList.add(reply); + headerViewHolder.update(replyList.size()); + adapter.notifyDataSetChanged(); + listView.smoothScrollToPosition(replyList.size()); } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java new file mode 100644 index 00000000..f1de74f9 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java @@ -0,0 +1,139 @@ +package org.cnodejs.android.md.display.viewholder; + +import android.app.Activity; +import android.graphics.drawable.ColorDrawable; +import android.support.annotation.NonNull; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.PopupWindow; + +import org.cnodejs.android.md.R; +import org.cnodejs.android.md.display.activity.TopicActivity; +import org.cnodejs.android.md.display.adapter.TopicAdapter; +import org.cnodejs.android.md.display.dialog.DialogUtils; +import org.cnodejs.android.md.display.dialog.ProgressDialog; +import org.cnodejs.android.md.display.widget.EditorBarHandler; +import org.cnodejs.android.md.display.widget.ToastUtils; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Author; +import org.cnodejs.android.md.model.entity.Reply; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.model.storage.SettingShared; +import org.cnodejs.android.md.util.FormatUtils; +import org.joda.time.DateTime; + +import java.util.ArrayList; + +import butterknife.Bind; +import butterknife.ButterKnife; +import butterknife.OnClick; +import retrofit2.Call; +import retrofit2.Response; + +public class TopicReplyViewHolder implements TopicAdapter.OnAtClickListener { + + @Bind(R.id.editor_bar_layout_root) + protected ViewGroup editorBar; + + @Bind(R.id.topic_reply_window_edt_content) + protected EditText edtContent; + + private final Activity activity; + private final ViewGroup layoutRoot; + private final String topicId; + private final TopicActivity topicActivity; + private final PopupWindow replyWindow; + private final ProgressDialog progressDialog; + + public TopicReplyViewHolder(@NonNull Activity activity, @NonNull ViewGroup layoutRoot, @NonNull String topicId, @NonNull TopicActivity topicActivity) { + this.activity = activity; + this.layoutRoot = layoutRoot; + this.topicId = topicId; + this.topicActivity = topicActivity; + LayoutInflater inflater = LayoutInflater.from(activity); + View view = inflater.inflate(R.layout.activity_topic_reply_window, layoutRoot, false); + ButterKnife.bind(this, view); + + replyWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + replyWindow.setBackgroundDrawable(new ColorDrawable(0x01000000)); + replyWindow.setFocusable(true); + replyWindow.setOutsideTouchable(true); + replyWindow.setAnimationStyle(R.style.AppWidget_ReplyWindowAnim); + + progressDialog = DialogUtils.createProgressDialog(activity); + progressDialog.setMessage(R.string.posting_$_); + progressDialog.setCancelable(false); + + new EditorBarHandler(activity, editorBar, edtContent); // 创建editorBar + } + + public void showReplyWindow() { + replyWindow.showAtLocation(layoutRoot, Gravity.BOTTOM, 0, 0); + } + + public void dismissReplyWindow() { + replyWindow.dismiss(); + } + + @OnClick(R.id.topic_reply_window_btn_tool_close) + protected void onBtnToolCloseClick() { + dismissReplyWindow(); + } + + @OnClick(R.id.topic_reply_window_btn_tool_send) + protected void onBtnToolSendClick() { + if (edtContent.length() == 0) { + ToastUtils.with(activity).show(R.string.content_empty_error_tip); + } else { + String content = edtContent.getText().toString(); + if (SettingShared.isEnableTopicSign(activity)) { // 添加小尾巴 + content += "\n\n" + SettingShared.getTopicSignContent(activity); + } + replyTopicAsyncTask(content); + } + } + + private void replyTopicAsyncTask(final String content) { + progressDialog.show(); + Call call = ApiClient.service.replyTopic(topicId, LoginShared.getAccessToken(activity), content, null); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result.ReplyTopic result) { + Reply reply = new Reply(); + reply.setId(result.getReplyId()); + Author author = new Author(); + author.setLoginName(LoginShared.getLoginName(activity)); + author.setAvatarUrl(LoginShared.getAvatarUrl(activity)); + reply.setAuthor(author); + reply.setContent(content); + reply.setHandleContent(FormatUtils.renderMarkdown(content)); // 本地要做预渲染处理 + reply.setCreateAt(new DateTime()); + reply.setUpList(new ArrayList()); + topicActivity.insertReplyAndUpdateViews(reply); + dismissReplyWindow(); + edtContent.setText(null); + ToastUtils.with(activity).show(R.string.post_success); + return false; + } + + @Override + public void onFinish() { + progressDialog.dismiss(); + } + + }); + } + + @Override + public void onAt(String loginName) { + edtContent.getText().insert(edtContent.getSelectionEnd(), " @" + loginName + " "); + showReplyWindow(); + } + +} From 2090edc67fe1ebb6adcb48384bb6f40f22ee083e Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 11:07:41 +0800 Subject: [PATCH 34/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/md/display/activity/CreateTopicActivity.java | 2 +- .../android/md/presenter/contract/ICreateTopicPresenter.java | 2 +- .../android/md/presenter/implement/CreateTopicPresenter.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java index 4c9d6c7e..5f646e3f 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java @@ -97,7 +97,7 @@ protected void onPause() { public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.action_send: - createTopicPresenter.createTipicAsyncTask(getTabByPosition(spnTab.getSelectedItemPosition()), edtTitle.getText().toString().trim(), edtContent.getText().toString().trim()); + createTopicPresenter.createTopicAsyncTask(getTabByPosition(spnTab.getSelectedItemPosition()), edtTitle.getText().toString().trim(), edtContent.getText().toString().trim()); return true; default: return false; diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java index 279d5eeb..08e70265 100644 --- a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ICreateTopicPresenter.java @@ -6,6 +6,6 @@ public interface ICreateTopicPresenter { - void createTipicAsyncTask(@NonNull TabType tab, String title, String content); + void createTopicAsyncTask(@NonNull TabType tab, String title, String content); } diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java index 71ebfbbf..2f81b93e 100644 --- a/app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/CreateTopicPresenter.java @@ -27,7 +27,7 @@ public CreateTopicPresenter(@NonNull Activity activity, @NonNull ICreateTopicVie } @Override - public void createTipicAsyncTask(@NonNull TabType tab, String title, String content) { + public void createTopicAsyncTask(@NonNull TabType tab, String title, String content) { if (TextUtils.isEmpty(title) || title.length() < 10) { createTopicView.onTitleEmptyError(); } else if (TextUtils.isEmpty(content)) { From 6e9849f65c3cfa689544610e0808ed5a8f5ca8df Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 11:17:20 +0800 Subject: [PATCH 35/89] topic mvp --- .../md/display/activity/TopicActivity.java | 64 +++++++++---------- .../android/md/display/view/ITopicView.java | 17 +++++ .../viewholder/TopicReplyViewHolder.java | 10 +-- .../presenter/contract/ITopicPresenter.java | 9 +++ .../presenter/implement/TopicPresenter.java | 45 +++++++++++++ 5 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/ITopicView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index c6db9085..80b580f7 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -19,18 +19,18 @@ import org.cnodejs.android.md.display.adapter.TopicAdapter; import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.view.ITopicView; import org.cnodejs.android.md.display.viewholder.TopicHeaderViewHolder; import org.cnodejs.android.md.display.viewholder.TopicReplyViewHolder; import org.cnodejs.android.md.display.widget.RefreshLayoutUtils; import org.cnodejs.android.md.display.widget.ThemeUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Reply; import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.entity.Topic; import org.cnodejs.android.md.model.entity.TopicWithReply; -import org.cnodejs.android.md.model.storage.LoginShared; import org.cnodejs.android.md.model.util.EntityUtils; +import org.cnodejs.android.md.presenter.contract.ITopicPresenter; +import org.cnodejs.android.md.presenter.implement.TopicPresenter; import org.cnodejs.android.md.util.ShipUtils; import java.util.ArrayList; @@ -39,10 +39,8 @@ import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; -import retrofit2.Call; -import retrofit2.Response; -public class TopicActivity extends StatusBarActivity implements SwipeRefreshLayout.OnRefreshListener, Toolbar.OnMenuItemClickListener { +public class TopicActivity extends StatusBarActivity implements ITopicView, SwipeRefreshLayout.OnRefreshListener, Toolbar.OnMenuItemClickListener { private static final String EXTRA_TOPIC_ID = "topicId"; private static final String EXTRA_TOPIC = "topic"; @@ -93,6 +91,8 @@ public static void start(@NonNull Context context, String topicId) { private TopicHeaderViewHolder headerViewHolder; private TopicAdapter adapter; + private ITopicPresenter topicPresenter; + @Override protected void onCreate(Bundle savedInstanceState) { ThemeUtils.configThemeBeforeOnCreate(this, R.style.AppThemeLight, R.style.AppThemeDark); @@ -119,6 +119,8 @@ protected void onCreate(Bundle savedInstanceState) { fabReply.attachToListView(listView); + topicPresenter = new TopicPresenter(this, this); + RefreshLayoutUtils.initOnCreate(refreshLayout, this); RefreshLayoutUtils.refreshOnCreate(refreshLayout, this); } @@ -136,30 +138,7 @@ public boolean onMenuItemClick(MenuItem item) { @Override public void onRefresh() { - Call> call = ApiClient.service.getTopic(topicId, LoginShared.getAccessToken(this), true); - call.enqueue(new DefaultToastCallback>(this) { - - @Override - public boolean onResultOk(Response> response, Result.Data result) { - if (!isFinishing()) { - topic = result.getData(); - headerViewHolder.update(result.getData()); - replyList.clear(); - replyList.addAll(result.getData().getReplyList()); - adapter.notifyDataSetChanged(); - iconNoData.setVisibility(View.GONE); - } - return false; - } - - @Override - public void onFinish() { - if (!isFinishing()) { - refreshLayout.setRefreshing(false); - } - } - - }); + topicPresenter.getTopicAsyncTask(topicId); } @OnClick(R.id.topic_fab_reply) @@ -178,9 +157,30 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } } - public void insertReplyAndUpdateViews(@NonNull Reply reply) { - replyList.add(reply); + @Override + public boolean onGetTopicResultOk(@NonNull Result.Data result) { + if (!isFinishing()) { + topic = result.getData(); + headerViewHolder.update(result.getData()); + replyList.clear(); + replyList.addAll(result.getData().getReplyList()); + adapter.notifyDataSetChanged(); + iconNoData.setVisibility(View.GONE); + return false; + } else { + return true; + } + } + + @Override + public void onGetTopicFinish() { + refreshLayout.setRefreshing(false); + } + + @Override + public void appendReplyAndUpdateViews(@NonNull Reply reply) { headerViewHolder.update(replyList.size()); + replyList.add(reply); adapter.notifyDataSetChanged(); listView.smoothScrollToPosition(replyList.size()); } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ITopicView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicView.java new file mode 100644 index 00000000..594ce54d --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicView.java @@ -0,0 +1,17 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Reply; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.TopicWithReply; + +public interface ITopicView { + + boolean onGetTopicResultOk(@NonNull Result.Data result); + + void onGetTopicFinish(); + + void appendReplyAndUpdateViews(@NonNull Reply reply); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java index f1de74f9..5d72023f 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java @@ -11,10 +11,10 @@ import android.widget.PopupWindow; import org.cnodejs.android.md.R; -import org.cnodejs.android.md.display.activity.TopicActivity; import org.cnodejs.android.md.display.adapter.TopicAdapter; import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; +import org.cnodejs.android.md.display.view.ITopicView; import org.cnodejs.android.md.display.widget.EditorBarHandler; import org.cnodejs.android.md.display.widget.ToastUtils; import org.cnodejs.android.md.model.api.ApiClient; @@ -46,15 +46,15 @@ public class TopicReplyViewHolder implements TopicAdapter.OnAtClickListener { private final Activity activity; private final ViewGroup layoutRoot; private final String topicId; - private final TopicActivity topicActivity; + private final ITopicView topicView; private final PopupWindow replyWindow; private final ProgressDialog progressDialog; - public TopicReplyViewHolder(@NonNull Activity activity, @NonNull ViewGroup layoutRoot, @NonNull String topicId, @NonNull TopicActivity topicActivity) { + public TopicReplyViewHolder(@NonNull Activity activity, @NonNull ViewGroup layoutRoot, @NonNull String topicId, @NonNull ITopicView topicView) { this.activity = activity; this.layoutRoot = layoutRoot; this.topicId = topicId; - this.topicActivity = topicActivity; + this.topicView = topicView; LayoutInflater inflater = LayoutInflater.from(activity); View view = inflater.inflate(R.layout.activity_topic_reply_window, layoutRoot, false); ButterKnife.bind(this, view); @@ -115,7 +115,7 @@ public boolean onResultOk(Response response, Result.ReplyTopi reply.setHandleContent(FormatUtils.renderMarkdown(content)); // 本地要做预渲染处理 reply.setCreateAt(new DateTime()); reply.setUpList(new ArrayList()); - topicActivity.insertReplyAndUpdateViews(reply); + topicView.appendReplyAndUpdateViews(reply); dismissReplyWindow(); edtContent.setText(null); ToastUtils.with(activity).show(R.string.post_success); diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicPresenter.java new file mode 100644 index 00000000..d175fd26 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicPresenter.java @@ -0,0 +1,9 @@ +package org.cnodejs.android.md.presenter.contract; + +import android.support.annotation.NonNull; + +public interface ITopicPresenter { + + void getTopicAsyncTask(@NonNull String topicId); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicPresenter.java new file mode 100644 index 00000000..1939f476 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicPresenter.java @@ -0,0 +1,45 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.display.view.ITopicView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.TopicWithReply; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.ITopicPresenter; + +import retrofit2.Call; +import retrofit2.Response; + +public class TopicPresenter implements ITopicPresenter { + + private final Activity activity; + private final ITopicView topicView; + + public TopicPresenter(@NonNull Activity activity, @NonNull ITopicView topicView) { + this.activity = activity; + this.topicView = topicView; + } + + @Override + public void getTopicAsyncTask(@NonNull String topicId) { + Call> call = ApiClient.service.getTopic(topicId, LoginShared.getAccessToken(activity), true); + call.enqueue(new DefaultToastCallback>(activity) { + + @Override + public boolean onResultOk(Response> response, Result.Data result) { + return topicView.onGetTopicResultOk(result); + } + + @Override + public void onFinish() { + topicView.onGetTopicFinish(); + } + + }); + } + +} From 166babf0fc9b94fe4fd22eaad0c19fd1b7c77201 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 12:11:32 +0800 Subject: [PATCH 36/89] topicReply mvp --- .../md/display/activity/TopicActivity.java | 9 +- .../md/display/adapter/TopicAdapter.java | 15 +-- .../md/display/view/ITopicReplyView.java | 23 ++++ .../viewholder/TopicReplyViewHolder.java | 101 +++++++----------- .../android/md/model/api/ApiService.java | 2 +- .../contract/ITopicReplyPresenter.java | 9 ++ .../implement/TopicReplyPresenter.java | 74 +++++++++++++ 7 files changed, 158 insertions(+), 75 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/ITopicReplyView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicReplyPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicReplyPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index 80b580f7..4a4c2d91 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -19,6 +19,7 @@ import org.cnodejs.android.md.display.adapter.TopicAdapter; import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.view.ITopicReplyView; import org.cnodejs.android.md.display.view.ITopicView; import org.cnodejs.android.md.display.viewholder.TopicHeaderViewHolder; import org.cnodejs.android.md.display.viewholder.TopicReplyViewHolder; @@ -87,7 +88,7 @@ public static void start(@NonNull Context context, String topicId) { private Topic topic; private final List replyList = new ArrayList<>(); - private TopicReplyViewHolder replyViewHolder; + private ITopicReplyView topicReplyView; private TopicHeaderViewHolder headerViewHolder; private TopicAdapter adapter; @@ -109,10 +110,10 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.inflateMenu(R.menu.topic); toolbar.setOnMenuItemClickListener(this); - replyViewHolder = new TopicReplyViewHolder(this, layoutRoot, topicId, this); + topicReplyView = new TopicReplyViewHolder(this, layoutRoot, topicId, this); headerViewHolder = new TopicHeaderViewHolder(this, listView); headerViewHolder.update(topic, false, 0); - adapter = new TopicAdapter(this, replyList, replyViewHolder); + adapter = new TopicAdapter(this, replyList, topicReplyView); listView.setAdapter(adapter); iconNoData.setVisibility(topic == null ? View.VISIBLE : View.GONE); @@ -144,7 +145,7 @@ public void onRefresh() { @OnClick(R.id.topic_fab_reply) protected void onBtnReplyClick() { if (topic != null && LoginActivity.startForResultWithAccessTokenCheck(this)) { - replyViewHolder.showReplyWindow(); + topicReplyView.showReplyWindow(); } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java index 36504a3e..7f26cb5d 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java +++ b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java @@ -15,6 +15,7 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.activity.LoginActivity; import org.cnodejs.android.md.display.activity.UserDetailActivity; +import org.cnodejs.android.md.display.view.ITopicReplyView; import org.cnodejs.android.md.display.widget.CNodeWebView; import org.cnodejs.android.md.display.widget.ToastUtils; import org.cnodejs.android.md.model.api.ApiClient; @@ -34,22 +35,16 @@ public class TopicAdapter extends BaseAdapter { - public interface OnAtClickListener { - - void onAt(String loginName); - - } - private final Activity activity; private final LayoutInflater inflater; private final List replyList; - private final OnAtClickListener onAtClickListener; + private final ITopicReplyView topicReplyView; - public TopicAdapter(@NonNull Activity activity, @NonNull List replyList, @NonNull OnAtClickListener onAtClickListener) { + public TopicAdapter(@NonNull Activity activity, @NonNull List replyList, @NonNull ITopicReplyView topicReplyView) { this.activity = activity; inflater = LayoutInflater.from(activity); this.replyList = replyList; - this.onAtClickListener = onAtClickListener; + this.topicReplyView = topicReplyView; } @Override @@ -151,7 +146,7 @@ protected void onBtnUpsClick() { @OnClick(R.id.topic_item_reply_btn_at) protected void onBtnAtClick() { if (LoginActivity.startForResultWithAccessTokenCheck(activity)) { - onAtClickListener.onAt(reply.getAuthor().getLoginName()); + topicReplyView.onAt(reply); } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ITopicReplyView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicReplyView.java new file mode 100644 index 00000000..0a794d06 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicReplyView.java @@ -0,0 +1,23 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Reply; + +public interface ITopicReplyView { + + void showReplyWindow(); + + void dismissReplyWindow(); + + void onAt(@NonNull Reply target); + + void onContentEmptyError(); + + void onReplyTopicStart(); + + boolean onReplyTopicResultOk(@NonNull Reply reply); + + void onReplyTopicFinish(); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java index 5d72023f..2f62a548 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java @@ -11,31 +11,21 @@ import android.widget.PopupWindow; import org.cnodejs.android.md.R; -import org.cnodejs.android.md.display.adapter.TopicAdapter; import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; +import org.cnodejs.android.md.display.view.ITopicReplyView; import org.cnodejs.android.md.display.view.ITopicView; import org.cnodejs.android.md.display.widget.EditorBarHandler; import org.cnodejs.android.md.display.widget.ToastUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.DefaultToastCallback; -import org.cnodejs.android.md.model.entity.Author; import org.cnodejs.android.md.model.entity.Reply; -import org.cnodejs.android.md.model.entity.Result; -import org.cnodejs.android.md.model.storage.LoginShared; -import org.cnodejs.android.md.model.storage.SettingShared; -import org.cnodejs.android.md.util.FormatUtils; -import org.joda.time.DateTime; - -import java.util.ArrayList; +import org.cnodejs.android.md.presenter.contract.ITopicReplyPresenter; +import org.cnodejs.android.md.presenter.implement.TopicReplyPresenter; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; -import retrofit2.Call; -import retrofit2.Response; -public class TopicReplyViewHolder implements TopicAdapter.OnAtClickListener { +public class TopicReplyViewHolder implements ITopicReplyView { @Bind(R.id.editor_bar_layout_root) protected ViewGroup editorBar; @@ -50,6 +40,8 @@ public class TopicReplyViewHolder implements TopicAdapter.OnAtClickListener { private final PopupWindow replyWindow; private final ProgressDialog progressDialog; + private final ITopicReplyPresenter topicReplyPresenter; + public TopicReplyViewHolder(@NonNull Activity activity, @NonNull ViewGroup layoutRoot, @NonNull String topicId, @NonNull ITopicView topicView) { this.activity = activity; this.layoutRoot = layoutRoot; @@ -70,70 +62,59 @@ public TopicReplyViewHolder(@NonNull Activity activity, @NonNull ViewGroup layou progressDialog.setCancelable(false); new EditorBarHandler(activity, editorBar, edtContent); // 创建editorBar + + topicReplyPresenter = new TopicReplyPresenter(activity, this); + } + + @OnClick(R.id.topic_reply_window_btn_tool_close) + protected void onBtnToolCloseClick() { + dismissReplyWindow(); } + @OnClick(R.id.topic_reply_window_btn_tool_send) + protected void onBtnToolSendClick() { + topicReplyPresenter.replyTopicAsyncTask(topicId, edtContent.getText().toString().trim(), null); + } + + @Override public void showReplyWindow() { replyWindow.showAtLocation(layoutRoot, Gravity.BOTTOM, 0, 0); } + @Override public void dismissReplyWindow() { replyWindow.dismiss(); } - @OnClick(R.id.topic_reply_window_btn_tool_close) - protected void onBtnToolCloseClick() { - dismissReplyWindow(); + @Override + public void onAt(@NonNull Reply target) { + edtContent.getText().insert(edtContent.getSelectionEnd(), " @" + target.getAuthor().getLoginName() + " "); + showReplyWindow(); } - @OnClick(R.id.topic_reply_window_btn_tool_send) - protected void onBtnToolSendClick() { - if (edtContent.length() == 0) { - ToastUtils.with(activity).show(R.string.content_empty_error_tip); - } else { - String content = edtContent.getText().toString(); - if (SettingShared.isEnableTopicSign(activity)) { // 添加小尾巴 - content += "\n\n" + SettingShared.getTopicSignContent(activity); - } - replyTopicAsyncTask(content); - } + @Override + public void onContentEmptyError() { + ToastUtils.with(activity).show(R.string.content_empty_error_tip); + edtContent.requestFocus(); } - private void replyTopicAsyncTask(final String content) { + @Override + public void onReplyTopicStart() { progressDialog.show(); - Call call = ApiClient.service.replyTopic(topicId, LoginShared.getAccessToken(activity), content, null); - call.enqueue(new DefaultToastCallback(activity) { - - @Override - public boolean onResultOk(Response response, Result.ReplyTopic result) { - Reply reply = new Reply(); - reply.setId(result.getReplyId()); - Author author = new Author(); - author.setLoginName(LoginShared.getLoginName(activity)); - author.setAvatarUrl(LoginShared.getAvatarUrl(activity)); - reply.setAuthor(author); - reply.setContent(content); - reply.setHandleContent(FormatUtils.renderMarkdown(content)); // 本地要做预渲染处理 - reply.setCreateAt(new DateTime()); - reply.setUpList(new ArrayList()); - topicView.appendReplyAndUpdateViews(reply); - dismissReplyWindow(); - edtContent.setText(null); - ToastUtils.with(activity).show(R.string.post_success); - return false; - } - - @Override - public void onFinish() { - progressDialog.dismiss(); - } - - }); } @Override - public void onAt(String loginName) { - edtContent.getText().insert(edtContent.getSelectionEnd(), " @" + loginName + " "); - showReplyWindow(); + public boolean onReplyTopicResultOk(@NonNull Reply reply) { + topicView.appendReplyAndUpdateViews(reply); + dismissReplyWindow(); + edtContent.setText(null); + ToastUtils.with(activity).show(R.string.post_success); + return false; + } + + @Override + public void onReplyTopicFinish() { + progressDialog.dismiss(); } } diff --git a/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java b/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java index 5b10df65..6bf00b5a 100644 --- a/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java +++ b/app/src/main/java/org/cnodejs/android/md/model/api/ApiService.java @@ -80,7 +80,7 @@ Call replyTopic( @Path("topicId") String topicId, @Field("accesstoken") String accessToken, @Field("content") String content, - @Field("reply_id") String replyId + @Field("reply_id") String targetId ); @POST("reply/{replyId}/ups") diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicReplyPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicReplyPresenter.java new file mode 100644 index 00000000..68d133a4 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicReplyPresenter.java @@ -0,0 +1,9 @@ +package org.cnodejs.android.md.presenter.contract; + +import android.support.annotation.NonNull; + +public interface ITopicReplyPresenter { + + void replyTopicAsyncTask(@NonNull String topicId, String content, String targetId); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicReplyPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicReplyPresenter.java new file mode 100644 index 00000000..b876daa5 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicReplyPresenter.java @@ -0,0 +1,74 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; +import android.text.TextUtils; + +import org.cnodejs.android.md.display.view.ITopicReplyView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Author; +import org.cnodejs.android.md.model.entity.Reply; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.model.storage.SettingShared; +import org.cnodejs.android.md.presenter.contract.ITopicReplyPresenter; +import org.cnodejs.android.md.util.FormatUtils; +import org.joda.time.DateTime; + +import java.util.ArrayList; + +import retrofit2.Call; +import retrofit2.Response; + +public class TopicReplyPresenter implements ITopicReplyPresenter { + + private final Activity activity; + private final ITopicReplyView topicReplyView; + + public TopicReplyPresenter(@NonNull Activity activity, @NonNull ITopicReplyView topicReplyView) { + this.activity = activity; + this.topicReplyView = topicReplyView; + } + + @Override + public void replyTopicAsyncTask(@NonNull String topicId, String content, final String targetId) { + if (TextUtils.isEmpty(content)) { + topicReplyView.onContentEmptyError(); + } else { + final String finalContent; + if (SettingShared.isEnableTopicSign(activity)) { // 添加小尾巴 + finalContent = content + "\n\n" + SettingShared.getTopicSignContent(activity); + } else { + finalContent = content; + } + topicReplyView.onReplyTopicStart(); + Call call = ApiClient.service.replyTopic(topicId, LoginShared.getAccessToken(activity), content, targetId); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result.ReplyTopic result) { + Reply reply = new Reply(); + reply.setId(result.getReplyId()); + Author author = new Author(); + author.setLoginName(LoginShared.getLoginName(activity)); + author.setAvatarUrl(LoginShared.getAvatarUrl(activity)); + reply.setAuthor(author); + reply.setContent(finalContent); + reply.setHandleContent(FormatUtils.renderMarkdown(finalContent)); // 本地要做预渲染处理 + reply.setCreateAt(new DateTime()); + reply.setUpList(new ArrayList()); + reply.setReplyId(targetId); + return topicReplyView.onReplyTopicResultOk(reply); + } + + @Override + public void onFinish() { + topicReplyView.onReplyTopicFinish(); + } + + }); + } + } + +} From 5f50ab5cb8ec6a854016fc86cc8553fa5762ad89 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Thu, 28 Apr 2016 23:16:55 +0800 Subject: [PATCH 37/89] =?UTF-8?q?=E8=AF=9D=E9=A2=98header=20mvp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/TopicActivity.java | 11 +- .../md/display/view/ITopicHeaderView.java | 22 ++++ .../viewholder/TopicHeaderViewHolder.java | 103 ++++++++---------- .../contract/ITopicHeaderPresenter.java | 11 ++ .../implement/TopicHeaderPresenter.java | 52 +++++++++ 5 files changed, 137 insertions(+), 62 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicHeaderPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index 4a4c2d91..eaa80930 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -19,6 +19,7 @@ import org.cnodejs.android.md.display.adapter.TopicAdapter; import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.view.ITopicHeaderView; import org.cnodejs.android.md.display.view.ITopicReplyView; import org.cnodejs.android.md.display.view.ITopicView; import org.cnodejs.android.md.display.viewholder.TopicHeaderViewHolder; @@ -89,7 +90,7 @@ public static void start(@NonNull Context context, String topicId) { private final List replyList = new ArrayList<>(); private ITopicReplyView topicReplyView; - private TopicHeaderViewHolder headerViewHolder; + private ITopicHeaderView topicHeaderView; private TopicAdapter adapter; private ITopicPresenter topicPresenter; @@ -111,8 +112,8 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.setOnMenuItemClickListener(this); topicReplyView = new TopicReplyViewHolder(this, layoutRoot, topicId, this); - headerViewHolder = new TopicHeaderViewHolder(this, listView); - headerViewHolder.update(topic, false, 0); + topicHeaderView = new TopicHeaderViewHolder(this, listView); + topicHeaderView.updateViews(topic, false, 0); adapter = new TopicAdapter(this, replyList, topicReplyView); listView.setAdapter(adapter); @@ -162,7 +163,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { public boolean onGetTopicResultOk(@NonNull Result.Data result) { if (!isFinishing()) { topic = result.getData(); - headerViewHolder.update(result.getData()); + topicHeaderView.updateViews(result.getData()); replyList.clear(); replyList.addAll(result.getData().getReplyList()); adapter.notifyDataSetChanged(); @@ -180,7 +181,7 @@ public void onGetTopicFinish() { @Override public void appendReplyAndUpdateViews(@NonNull Reply reply) { - headerViewHolder.update(replyList.size()); + topicHeaderView.updateReplyCount(replyList.size()); replyList.add(reply); adapter.notifyDataSetChanged(); listView.smoothScrollToPosition(replyList.size()); diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java new file mode 100644 index 00000000..5411775a --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java @@ -0,0 +1,22 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.Topic; +import org.cnodejs.android.md.model.entity.TopicWithReply; + +public interface ITopicHeaderView { + + void updateViews(@Nullable Topic topic, boolean isCollect, int replyCount); + + void updateViews(@NonNull TopicWithReply topic); + + void updateReplyCount(int replyCount); + + boolean onCollectTopicResultOk(Result result); + + boolean OnDecollectTopicResultOk(Result result); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java index e5ceb5e0..2f396a88 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java @@ -16,23 +16,21 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.activity.LoginActivity; import org.cnodejs.android.md.display.activity.UserDetailActivity; +import org.cnodejs.android.md.display.view.ITopicHeaderView; import org.cnodejs.android.md.display.widget.CNodeWebView; import org.cnodejs.android.md.display.widget.ThemeUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.entity.Topic; import org.cnodejs.android.md.model.entity.TopicWithReply; -import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.ITopicHeaderPresenter; +import org.cnodejs.android.md.presenter.implement.TopicHeaderPresenter; import org.cnodejs.android.md.util.FormatUtils; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; -import retrofit2.Call; -import retrofit2.Response; -public class TopicHeaderViewHolder { +public class TopicHeaderViewHolder implements ITopicHeaderView { @Bind(R.id.topic_item_header_layout_content) protected ViewGroup layoutContent; @@ -77,15 +75,37 @@ public class TopicHeaderViewHolder { private Topic topic; private boolean isCollect; + private final ITopicHeaderPresenter topicHeaderPresenter; + public TopicHeaderViewHolder(@NonNull Activity activity, @NonNull ListView listView) { this.activity = activity; LayoutInflater inflater = LayoutInflater.from(activity); View headerView = inflater.inflate(R.layout.activity_topic_item_header, listView, false); ButterKnife.bind(this, headerView); listView.addHeaderView(headerView, null, false); + this.topicHeaderPresenter = new TopicHeaderPresenter(activity, this); + } + + @OnClick(R.id.topic_item_header_img_avatar) + protected void onBtnAvatarClick() { + UserDetailActivity.startWithTransitionAnimation(activity, topic.getAuthor().getLoginName(), imgAvatar, topic.getAuthor().getAvatarUrl()); } - public void update(@Nullable Topic topic, boolean isCollect, int replyCount) { + @OnClick(R.id.topic_item_header_btn_favorite) + protected void onBtnFavoriteClick() { + if (topic != null) { + if (LoginActivity.startForResultWithAccessTokenCheck(activity)) { + if (isCollect) { + topicHeaderPresenter.decollectTopicAsyncTask(topic.getId()); + } else { + topicHeaderPresenter.collectTopicAsyncTask(topic.getId()); + } + } + } + } + + @Override + public void updateViews(@Nullable Topic topic, boolean isCollect, int replyCount) { this.topic = topic; this.isCollect = isCollect; if (topic != null) { @@ -105,72 +125,41 @@ public void update(@Nullable Topic topic, boolean isCollect, int replyCount) { // 这里直接使用WebView,有性能问题 webContent.loadRenderedContent(topic.getHandleContent()); - // 更新回复数目 - update(replyCount); + updateReplyCount(replyCount); } else { layoutContent.setVisibility(View.GONE); iconGood.setVisibility(View.GONE); } } - public void update(@NonNull TopicWithReply topic) { - update(topic, topic.isCollect(), topic.getReplyList().size()); + @Override + public void updateViews(@NonNull TopicWithReply topic) { + updateViews(topic, topic.isCollect(), topic.getReplyList().size()); } - public void update(int replyCount) { + @Override + public void updateReplyCount(int replyCount) { layoutNoReply.setVisibility(replyCount > 0 ? View.GONE : View.VISIBLE); layoutReplyCount.setVisibility(replyCount > 0 ? View.VISIBLE : View.GONE); tvReplyCount.setText(replyCount + "条回复"); } - @OnClick(R.id.topic_item_header_img_avatar) - protected void onBtnAvatarClick() { - UserDetailActivity.startWithTransitionAnimation(activity, topic.getAuthor().getLoginName(), imgAvatar, topic.getAuthor().getAvatarUrl()); - } - - @OnClick(R.id.topic_item_header_btn_favorite) - protected void onBtnFavoriteClick() { - if (topic != null) { - if (LoginActivity.startForResultWithAccessTokenCheck(activity)) { - if (isCollect) { - decollectTopicAsyncTask(); - } else { - collectTopicAsyncTask(); - } - } + @Override + public boolean onCollectTopicResultOk(Result result) { + if (!activity.isFinishing()) { + isCollect = true; + btnFavorite.setImageResource(R.drawable.ic_favorite_theme_24dp); } + return false; } - private void collectTopicAsyncTask() { - Call call = ApiClient.service.collectTopic(LoginShared.getAccessToken(activity), topic.getId()); - call.enqueue(new DefaultToastCallback(activity) { - - @Override - public boolean onResultOk(Response response, Result result) { - if (!activity.isFinishing()) { - isCollect = true; - btnFavorite.setImageResource(R.drawable.ic_favorite_theme_24dp); - } - return false; - } - - }); - } - - private void decollectTopicAsyncTask() { - Call call = ApiClient.service.decollectTopic(LoginShared.getAccessToken(activity), topic.getId()); - call.enqueue(new DefaultToastCallback(activity) { - - @Override - public boolean onResultOk(Response response, Result result) { - if (!activity.isFinishing()) { - isCollect = false; - btnFavorite.setImageResource(R.drawable.ic_favorite_outline_grey600_24dp); - } - return false; - } - - }); + @Override + public boolean OnDecollectTopicResultOk(Result result) { + if (!activity.isFinishing()) { + isCollect = false; + btnFavorite.setImageResource(R.drawable.ic_favorite_outline_grey600_24dp); + } + return false; } } diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicHeaderPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicHeaderPresenter.java new file mode 100644 index 00000000..c4d9331c --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicHeaderPresenter.java @@ -0,0 +1,11 @@ +package org.cnodejs.android.md.presenter.contract; + +import android.support.annotation.NonNull; + +public interface ITopicHeaderPresenter { + + void collectTopicAsyncTask(@NonNull String topicId); + + void decollectTopicAsyncTask(@NonNull String topicId); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java new file mode 100644 index 00000000..0b8d1020 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java @@ -0,0 +1,52 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.display.view.ITopicHeaderView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.ITopicHeaderPresenter; + +import retrofit2.Call; +import retrofit2.Response; + +public class TopicHeaderPresenter implements ITopicHeaderPresenter { + + private final Activity activity; + private final ITopicHeaderView topicHeaderView; + + public TopicHeaderPresenter(@NonNull Activity activity, @NonNull ITopicHeaderView topicHeaderView) { + this.activity = activity; + this.topicHeaderView = topicHeaderView; + } + + @Override + public void collectTopicAsyncTask(@NonNull String topicId) { + Call call = ApiClient.service.collectTopic(LoginShared.getAccessToken(activity), topicId); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result result) { + return topicHeaderView.onCollectTopicResultOk(result); + } + + }); + } + + @Override + public void decollectTopicAsyncTask(@NonNull String topicId) { + Call call = ApiClient.service.decollectTopic(LoginShared.getAccessToken(activity), topicId); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result result) { + return topicHeaderView.OnDecollectTopicResultOk(result); + } + + }); + } + +} From 7824a6f88a4b46a997ad51263f54343b61f6361c Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 02:54:55 +0800 Subject: [PATCH 38/89] =?UTF-8?q?=E7=94=A8=E6=88=B7=E9=A1=B5=E9=9D=A2=20mv?= =?UTF-8?q?p?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../display/activity/UserDetailActivity.java | 169 +++++++----------- .../md/display/view/IUserDetailView.java | 27 +++ .../contract/IUserDetailPresenter.java | 11 ++ .../implement/UserDetailPresenter.java | 120 +++++++++++++ 4 files changed, 224 insertions(+), 103 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/IUserDetailView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/IUserDetailPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/UserDetailPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java index 058dbafe..3479c8d0 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/UserDetailActivity.java @@ -25,15 +25,14 @@ import org.cnodejs.android.md.display.adapter.UserDetailAdapter; import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.view.IUserDetailView; import org.cnodejs.android.md.display.widget.ThemeUtils; import org.cnodejs.android.md.display.widget.ToastUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.CallbackAdapter; -import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.entity.Topic; import org.cnodejs.android.md.model.entity.User; -import org.cnodejs.android.md.util.HandlerUtils; +import org.cnodejs.android.md.presenter.contract.IUserDetailPresenter; +import org.cnodejs.android.md.presenter.implement.UserDetailPresenter; import org.cnodejs.android.md.util.ShipUtils; import java.util.List; @@ -41,10 +40,8 @@ import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; -import retrofit2.Call; -import retrofit2.Response; -public class UserDetailActivity extends StatusBarActivity implements Toolbar.OnMenuItemClickListener { +public class UserDetailActivity extends StatusBarActivity implements IUserDetailView, Toolbar.OnMenuItemClickListener { private static final String EXTRA_LOGIN_NAME = "loginName"; private static final String EXTRA_AVATAR_URL = "avatarUrl"; @@ -100,11 +97,12 @@ public static void start(@NonNull Context context, String loginName) { private UserDetailAdapter adapter; + private IUserDetailPresenter userDetailPresenter; + private String loginName; private String githubUsername; private boolean loading = false; - private long startLoadingTime = 0; @Override protected void onCreate(Bundle savedInstanceState) { @@ -132,8 +130,10 @@ protected void onCreate(Bundle savedInstanceState) { Glide.with(this).load(avatarUrl).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); } - getUserAsyncTask(); - getCollectTopicListAsyncTask(); + userDetailPresenter = new UserDetailPresenter(this, this); + + userDetailPresenter.getUserAsyncTask(loginName); + userDetailPresenter.getCollectTopicListAsyncTask(loginName); } @Override @@ -156,8 +156,8 @@ protected void onSaveInstanceState(Bundle outState) {} @OnClick(R.id.user_detail_img_avatar) protected void onBtnAvatarClick() { if (!loading) { - getUserAsyncTask(); - getCollectTopicListAsyncTask(); + userDetailPresenter.getUserAsyncTask(loginName); + userDetailPresenter.getCollectTopicListAsyncTask(loginName); } } @@ -168,7 +168,52 @@ protected void onBtnGithubUsernameClick() { } } - private void updateUserInfoViews(User user) { + @Override + public void onGetUserStart() { + loading = true; + progressWheel.spin(); + } + + @Override + public boolean onGetUserResultOk(@NonNull Result.Data result) { + if (!isFinishing()) { + updateUserInfoViews(result.getData()); + adapter.update(result.getData()); + githubUsername = result.getData().getGithubUsername(); + return false; + } else { + return true; + } + } + + @Override + public boolean onGetUserResultError(@NonNull Result.Error error) { + if (!isFinishing()) { + ToastUtils.with(this).show(error.getErrorMessage()); + return false; + } else { + return true; + } + } + + @Override + public boolean onGetUserLoadError() { + if (!isFinishing()) { + ToastUtils.with(this).show(R.string.data_load_faild_and_click_avatar_to_reload); + return false; + } else { + return true; + } + } + + @Override + public void onGetUserFinish() { + progressWheel.stopSpinning(); + loading = false; + } + + @Override + public void updateUserInfoViews(@NonNull User user) { Glide.with(this).load(user.getAvatarUrl()).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); tvLoginName.setText(user.getLoginName()); if (TextUtils.isEmpty(user.getGithubUsername())) { @@ -182,96 +227,14 @@ private void updateUserInfoViews(User user) { tvScore.setText(getString(R.string.score_$) + user.getScore()); } - private void getUserAsyncTask() { - loading = true; - startLoadingTime = System.currentTimeMillis(); - progressWheel.spin(); - Call> call = ApiClient.service.getUser(loginName); - call.enqueue(new CallbackAdapter>() { - - private long getPostTime() { - long postTime = 1000 - (System.currentTimeMillis() - startLoadingTime); - if (postTime > 0) { - return postTime; - } else { - return 0; - } - } - - @Override - public boolean onResultOk(Response> response, final Result.Data result) { - HandlerUtils.postDelayed(new Runnable() { - - @Override - public void run() { - if (!isFinishing()) { - updateUserInfoViews(result.getData()); - adapter.update(result.getData()); - githubUsername = result.getData().getGithubUsername(); - onFinish(); - } - } - - }, getPostTime()); - return true; - } - - @Override - public boolean onResultError(final Response> response, final Result.Error error) { - HandlerUtils.postDelayed(new Runnable() { - - @Override - public void run() { - if (!isFinishing()) { - if (response.code() == 404) { - ToastUtils.with(UserDetailActivity.this).show(error.getErrorMessage()); - } else { - ToastUtils.with(UserDetailActivity.this).show(R.string.data_load_faild_and_click_avatar_to_reload); - } - onFinish(); - } - } - - }, getPostTime()); - return true; - } - - @Override - public boolean onCallException(Throwable t, Result.Error error) { - HandlerUtils.postDelayed(new Runnable() { - - @Override - public void run() { - if (!isFinishing()) { - ToastUtils.with(UserDetailActivity.this).show(R.string.data_load_faild_and_click_avatar_to_reload); - onFinish(); - } - } - - }, getPostTime()); - return true; - } - - @Override - public void onFinish() { - progressWheel.stopSpinning(); - loading = false; - } - - }); - } - - private void getCollectTopicListAsyncTask() { - Call>> call = ApiClient.service.getCollectTopicList(loginName); - call.enqueue(new DefaultToastCallback>>(this) { - - @Override - public boolean onResultOk(Response>> response, Result.Data> result) { - adapter.update(result.getData()); - return false; - } - - }); + @Override + public boolean onGetCollectTopicListResultOk(@NonNull Result.Data> result) { + if (!isFinishing()) { + adapter.update(result.getData()); + return false; + } else { + return true; + } } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/IUserDetailView.java b/app/src/main/java/org/cnodejs/android/md/display/view/IUserDetailView.java new file mode 100644 index 00000000..ccfc0f48 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/IUserDetailView.java @@ -0,0 +1,27 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.Topic; +import org.cnodejs.android.md.model.entity.User; + +import java.util.List; + +public interface IUserDetailView { + + void onGetUserStart(); + + boolean onGetUserResultOk(@NonNull Result.Data result); + + boolean onGetUserResultError(@NonNull Result.Error error); + + boolean onGetUserLoadError(); + + void onGetUserFinish(); + + void updateUserInfoViews(@NonNull User user); + + boolean onGetCollectTopicListResultOk(@NonNull Result.Data> result); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/IUserDetailPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/IUserDetailPresenter.java new file mode 100644 index 00000000..9705f78b --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/IUserDetailPresenter.java @@ -0,0 +1,11 @@ +package org.cnodejs.android.md.presenter.contract; + +import android.support.annotation.NonNull; + +public interface IUserDetailPresenter { + + void getUserAsyncTask(@NonNull String loginName); + + void getCollectTopicListAsyncTask(@NonNull String loginName); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/UserDetailPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/UserDetailPresenter.java new file mode 100644 index 00000000..6a75bbeb --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/UserDetailPresenter.java @@ -0,0 +1,120 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.display.view.IUserDetailView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.CallbackAdapter; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.entity.Topic; +import org.cnodejs.android.md.model.entity.User; +import org.cnodejs.android.md.presenter.contract.IUserDetailPresenter; +import org.cnodejs.android.md.util.HandlerUtils; + +import java.util.List; + +import retrofit2.Call; +import retrofit2.Response; + +public class UserDetailPresenter implements IUserDetailPresenter { + + private final Activity activity; + private final IUserDetailView userDetailView; + + public UserDetailPresenter(@NonNull Activity activity, @NonNull IUserDetailView userDetailView) { + this.activity = activity; + this.userDetailView = userDetailView; + } + + @Override + public void getUserAsyncTask(@NonNull String loginName) { + userDetailView.onGetUserStart(); + Call> call = ApiClient.service.getUser(loginName); + call.enqueue(new CallbackAdapter>() { + + private long startLoadingTime = System.currentTimeMillis(); + + private long getPostTime() { + long postTime = 1000 - (System.currentTimeMillis() - startLoadingTime); + if (postTime > 0) { + return postTime; + } else { + return 0; + } + } + + @Override + public boolean onResultOk(Response> response, final Result.Data result) { + HandlerUtils.postDelayed(new Runnable() { + + @Override + public void run() { + if (!userDetailView.onGetUserResultOk(result)) { + onFinish(); + } + } + + }, getPostTime()); + return true; + } + + @Override + public boolean onResultError(final Response> response, final Result.Error error) { + HandlerUtils.postDelayed(new Runnable() { + + @Override + public void run() { + boolean interrupt; + if (response.code() == 404) { + interrupt = userDetailView.onGetUserResultError(error); + } else { + interrupt = userDetailView.onGetUserLoadError(); + } + if (!interrupt) { + onFinish(); + } + } + + }, getPostTime()); + return true; + } + + @Override + public boolean onCallException(Throwable t, Result.Error error) { + HandlerUtils.postDelayed(new Runnable() { + + @Override + public void run() { + if (!userDetailView.onGetUserLoadError()) { + onFinish(); + } + } + + }, getPostTime()); + return true; + } + + @Override + public void onFinish() { + userDetailView.onGetUserFinish(); + } + + }); + } + + @Override + public void getCollectTopicListAsyncTask(@NonNull String loginName) { + Call>> call = ApiClient.service.getCollectTopicList(loginName); + call.enqueue(new DefaultToastCallback>>(activity) { + + @Override + public boolean onResultOk(Response>> response, Result.Data> result) { + return userDetailView.onGetCollectTopicListResultOk(result); + } + + }); + } + +} From 17f7337729dac135bf85b5e60ea609d3730ba5b2 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 03:47:22 +0800 Subject: [PATCH 39/89] =?UTF-8?q?=E9=80=9A=E7=9F=A5=E9=A1=B5=E9=9D=A2=20mv?= =?UTF-8?q?p?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/NotificationActivity.java | 93 +++++++++---------- .../md/display/view/INotificationView.java | 16 ++++ .../contract/INotificationPresenter.java | 9 ++ .../implement/NotificationPresenter.java | 58 ++++++++++++ 4 files changed, 127 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/INotificationView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/INotificationPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/NotificationPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/NotificationActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/NotificationActivity.java index 732f73e9..bbccc842 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/NotificationActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/NotificationActivity.java @@ -1,6 +1,7 @@ package org.cnodejs.android.md.display.activity; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -12,24 +13,22 @@ import org.cnodejs.android.md.display.adapter.NotificationAdapter; import org.cnodejs.android.md.display.base.StatusBarActivity; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; +import org.cnodejs.android.md.display.view.INotificationView; import org.cnodejs.android.md.display.widget.RefreshLayoutUtils; import org.cnodejs.android.md.display.widget.ThemeUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Message; import org.cnodejs.android.md.model.entity.Notification; import org.cnodejs.android.md.model.entity.Result; -import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.INotificationPresenter; +import org.cnodejs.android.md.presenter.implement.NotificationPresenter; import java.util.ArrayList; import java.util.List; import butterknife.Bind; import butterknife.ButterKnife; -import retrofit2.Call; -import retrofit2.Response; -public class NotificationActivity extends StatusBarActivity implements Toolbar.OnMenuItemClickListener, SwipeRefreshLayout.OnRefreshListener { +public class NotificationActivity extends StatusBarActivity implements INotificationView, Toolbar.OnMenuItemClickListener, SwipeRefreshLayout.OnRefreshListener { @Bind(R.id.notification_toolbar) protected Toolbar toolbar; @@ -46,6 +45,8 @@ public class NotificationActivity extends StatusBarActivity implements Toolbar.O private NotificationAdapter adapter; private List messageList = new ArrayList<>(); + private INotificationPresenter notificationPresenter; + @Override protected void onCreate(Bundle savedInstanceState) { ThemeUtils.configThemeBeforeOnCreate(this, R.style.AppThemeLight, R.style.AppThemeDark); @@ -61,34 +62,26 @@ protected void onCreate(Bundle savedInstanceState) { adapter = new NotificationAdapter(this, messageList); recyclerView.setAdapter(adapter); + notificationPresenter = new NotificationPresenter(this, this); + RefreshLayoutUtils.initOnCreate(refreshLayout, this); RefreshLayoutUtils.refreshOnCreate(refreshLayout, this); } @Override - public void onRefresh() { - Call> call = ApiClient.service.getMessages(LoginShared.getAccessToken(this), true); - call.enqueue(new DefaultToastCallback>(this) { - - @Override - public boolean onResultOk(Response> response, Result.Data result) { - if (!isFinishing()) { - messageList.clear(); - messageList.addAll(result.getData().getHasNotReadMessageList()); - messageList.addAll(result.getData().getHasReadMessageList()); - notifyDataSetChanged(); - } + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_done_all: + notificationPresenter.markAllMessageReadAsyncTask(); + return true; + default: return false; - } - - @Override - public void onFinish() { - if (!isFinishing()) { - refreshLayout.setRefreshing(false); - } - } + } + } - }); + @Override + public void onRefresh() { + notificationPresenter.getMessagesAsyncTask(); } private void notifyDataSetChanged() { @@ -97,32 +90,34 @@ private void notifyDataSetChanged() { } @Override - public boolean onMenuItemClick(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_done_all: - markAllMessageReadAsyncTask(); - return true; - default: - return false; + public boolean onGetMessagesResultOk(@NonNull Result.Data result) { + if (!isFinishing()) { + messageList.clear(); + messageList.addAll(result.getData().getHasNotReadMessageList()); + messageList.addAll(result.getData().getHasReadMessageList()); + notifyDataSetChanged(); + return false; + } else { + return true; } } - private void markAllMessageReadAsyncTask() { - Call call = ApiClient.service.markAllMessageRead(LoginShared.getAccessToken(this)); - call.enqueue(new DefaultToastCallback(this) { - - @Override - public boolean onResultOk(Response response, Result result) { - if (!isFinishing()) { - for (Message message : messageList) { - message.setRead(true); - } - notifyDataSetChanged(); - } - return false; - } + @Override + public void onGetMessagesFinish() { + refreshLayout.setRefreshing(false); + } - }); + @Override + public boolean onMarkAllMessageReadResultOk() { + if (!isFinishing()) { + for (Message message : messageList) { + message.setRead(true); + } + notifyDataSetChanged(); + return false; + } else { + return true; + } } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/INotificationView.java b/app/src/main/java/org/cnodejs/android/md/display/view/INotificationView.java new file mode 100644 index 00000000..13f777c5 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/INotificationView.java @@ -0,0 +1,16 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Notification; +import org.cnodejs.android.md.model.entity.Result; + +public interface INotificationView { + + boolean onGetMessagesResultOk(@NonNull Result.Data result); + + void onGetMessagesFinish(); + + boolean onMarkAllMessageReadResultOk(); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/INotificationPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/INotificationPresenter.java new file mode 100644 index 00000000..c309e269 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/INotificationPresenter.java @@ -0,0 +1,9 @@ +package org.cnodejs.android.md.presenter.contract; + +public interface INotificationPresenter { + + void getMessagesAsyncTask(); + + void markAllMessageReadAsyncTask(); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/NotificationPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/NotificationPresenter.java new file mode 100644 index 00000000..66de8083 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/NotificationPresenter.java @@ -0,0 +1,58 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.display.view.INotificationView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Notification; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.INotificationPresenter; + +import retrofit2.Call; +import retrofit2.Response; + +public class NotificationPresenter implements INotificationPresenter { + + private final Activity activity; + private final INotificationView notificationView; + + public NotificationPresenter(@NonNull Activity activity, @NonNull INotificationView notificationView) { + this.activity = activity; + this.notificationView = notificationView; + } + + @Override + public void getMessagesAsyncTask() { + Call> call = ApiClient.service.getMessages(LoginShared.getAccessToken(activity), true); + call.enqueue(new DefaultToastCallback>(activity) { + + @Override + public boolean onResultOk(Response> response, Result.Data result) { + return notificationView.onGetMessagesResultOk(result); + } + + @Override + public void onFinish() { + notificationView.onGetMessagesFinish(); + } + + }); + } + + @Override + public void markAllMessageReadAsyncTask() { + Call call = ApiClient.service.markAllMessageRead(LoginShared.getAccessToken(activity)); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result result) { + return notificationView.onMarkAllMessageReadResultOk(); + } + + }); + } + +} From 07484fa6aa767851629e9e4c7c325243211a3fcc Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 03:59:05 +0800 Subject: [PATCH 40/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8B=BC=E5=86=99?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/cnodejs/android/md/display/view/ITopicHeaderView.java | 2 +- .../android/md/display/viewholder/TopicHeaderViewHolder.java | 2 +- .../android/md/presenter/implement/TopicHeaderPresenter.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java index 5411775a..81e4a3be 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicHeaderView.java @@ -17,6 +17,6 @@ public interface ITopicHeaderView { boolean onCollectTopicResultOk(Result result); - boolean OnDecollectTopicResultOk(Result result); + boolean onDecollectTopicResultOk(Result result); } diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java index 2f396a88..e7412ac5 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java @@ -154,7 +154,7 @@ public boolean onCollectTopicResultOk(Result result) { } @Override - public boolean OnDecollectTopicResultOk(Result result) { + public boolean onDecollectTopicResultOk(Result result) { if (!activity.isFinishing()) { isCollect = false; btnFavorite.setImageResource(R.drawable.ic_favorite_outline_grey600_24dp); diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java index 0b8d1020..6d292626 100644 --- a/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicHeaderPresenter.java @@ -43,7 +43,7 @@ public void decollectTopicAsyncTask(@NonNull String topicId) { @Override public boolean onResultOk(Response response, Result result) { - return topicHeaderView.OnDecollectTopicResultOk(result); + return topicHeaderView.onDecollectTopicResultOk(result); } }); From eacece4b150e6ea4f187037ee439f7e95e3ce945 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 04:27:28 +0800 Subject: [PATCH 41/89] =?UTF-8?q?=E8=B5=84=E6=BA=90=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../viewholder/TopicHeaderViewHolder.java | 32 ++++++++--------- ...m_header.xml => activity_topic_header.xml} | 34 +++++++++---------- 2 files changed, 33 insertions(+), 33 deletions(-) rename app/src/main/res/layout/{activity_topic_item_header.xml => activity_topic_header.xml} (86%) diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java index e7412ac5..2c33b840 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicHeaderViewHolder.java @@ -32,43 +32,43 @@ public class TopicHeaderViewHolder implements ITopicHeaderView { - @Bind(R.id.topic_item_header_layout_content) + @Bind(R.id.topic_header_layout_content) protected ViewGroup layoutContent; - @Bind(R.id.topic_item_header_icon_good) + @Bind(R.id.topic_header_icon_good) protected View iconGood; - @Bind(R.id.topic_item_header_tv_title) + @Bind(R.id.topic_header_tv_title) protected TextView tvTitle; - @Bind(R.id.topic_item_header_img_avatar) + @Bind(R.id.topic_header_img_avatar) protected ImageView imgAvatar; - @Bind(R.id.topic_item_header_tv_tab) + @Bind(R.id.topic_header_tv_tab) protected TextView tvTab; - @Bind(R.id.topic_item_header_tv_login_name) + @Bind(R.id.topic_header_tv_login_name) protected TextView tvLoginName; - @Bind(R.id.topic_item_header_tv_create_time) + @Bind(R.id.topic_header_tv_create_time) protected TextView tvCreateTime; - @Bind(R.id.topic_item_header_tv_visit_count) + @Bind(R.id.topic_header_tv_visit_count) protected TextView tvVisitCount; - @Bind(R.id.topic_item_header_btn_favorite) + @Bind(R.id.topic_header_btn_favorite) protected ImageView btnFavorite; - @Bind(R.id.topic_item_header_web_content) + @Bind(R.id.topic_header_web_content) protected CNodeWebView webContent; - @Bind(R.id.topic_item_header_layout_no_reply) + @Bind(R.id.topic_header_layout_no_reply) protected ViewGroup layoutNoReply; - @Bind(R.id.topic_item_header_layout_reply_count) + @Bind(R.id.topic_header_layout_reply_count) protected ViewGroup layoutReplyCount; - @Bind(R.id.topic_item_header_tv_reply_count) + @Bind(R.id.topic_header_tv_reply_count) protected TextView tvReplyCount; private final Activity activity; @@ -80,18 +80,18 @@ public class TopicHeaderViewHolder implements ITopicHeaderView { public TopicHeaderViewHolder(@NonNull Activity activity, @NonNull ListView listView) { this.activity = activity; LayoutInflater inflater = LayoutInflater.from(activity); - View headerView = inflater.inflate(R.layout.activity_topic_item_header, listView, false); + View headerView = inflater.inflate(R.layout.activity_topic_header, listView, false); ButterKnife.bind(this, headerView); listView.addHeaderView(headerView, null, false); this.topicHeaderPresenter = new TopicHeaderPresenter(activity, this); } - @OnClick(R.id.topic_item_header_img_avatar) + @OnClick(R.id.topic_header_img_avatar) protected void onBtnAvatarClick() { UserDetailActivity.startWithTransitionAnimation(activity, topic.getAuthor().getLoginName(), imgAvatar, topic.getAuthor().getAvatarUrl()); } - @OnClick(R.id.topic_item_header_btn_favorite) + @OnClick(R.id.topic_header_btn_favorite) protected void onBtnFavoriteClick() { if (topic != null) { if (LoginActivity.startForResultWithAccessTokenCheck(activity)) { diff --git a/app/src/main/res/layout/activity_topic_item_header.xml b/app/src/main/res/layout/activity_topic_header.xml similarity index 86% rename from app/src/main/res/layout/activity_topic_item_header.xml rename to app/src/main/res/layout/activity_topic_header.xml index 0c07b412..f7ab33f0 100644 --- a/app/src/main/res/layout/activity_topic_item_header.xml +++ b/app/src/main/res/layout/activity_topic_header.xml @@ -5,7 +5,7 @@ android:layout_height="wrap_content"> @@ -17,7 +17,7 @@ android:orientation="vertical"> @@ -146,7 +146,7 @@ @@ -166,13 +166,13 @@ Date: Fri, 29 Apr 2016 05:04:58 +0800 Subject: [PATCH 42/89] reply item mvp --- .../md/display/adapter/TopicAdapter.java | 76 +++++++++---------- .../md/display/view/ITopicItemReplyView.java | 15 ++++ .../contract/ITopicItemReplyPresenter.java | 11 +++ .../implement/TopicItemReplyPresenter.java | 45 +++++++++++ 4 files changed, 107 insertions(+), 40 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/view/ITopicItemReplyView.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicItemReplyPresenter.java create mode 100644 app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicItemReplyPresenter.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java index 7f26cb5d..1b0e65c2 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java +++ b/app/src/main/java/org/cnodejs/android/md/display/adapter/TopicAdapter.java @@ -15,14 +15,14 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.activity.LoginActivity; import org.cnodejs.android.md.display.activity.UserDetailActivity; +import org.cnodejs.android.md.display.view.ITopicItemReplyView; import org.cnodejs.android.md.display.view.ITopicReplyView; import org.cnodejs.android.md.display.widget.CNodeWebView; import org.cnodejs.android.md.display.widget.ToastUtils; -import org.cnodejs.android.md.model.api.ApiClient; -import org.cnodejs.android.md.model.api.DefaultToastCallback; import org.cnodejs.android.md.model.entity.Reply; -import org.cnodejs.android.md.model.entity.Result; import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.ITopicItemReplyPresenter; +import org.cnodejs.android.md.presenter.implement.TopicItemReplyPresenter; import org.cnodejs.android.md.util.FormatUtils; import java.util.List; @@ -30,8 +30,6 @@ import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; -import retrofit2.Call; -import retrofit2.Response; public class TopicAdapter extends BaseAdapter { @@ -76,7 +74,7 @@ public View getView(int position, View convertView, ViewGroup parent) { return convertView; } - public class ViewHolder extends RecyclerView.ViewHolder { + public class ViewHolder extends RecyclerView.ViewHolder implements ITopicItemReplyView { @Bind(R.id.topic_item_reply_img_avatar) protected ImageView imgAvatar; @@ -102,29 +100,21 @@ public class ViewHolder extends RecyclerView.ViewHolder { @Bind(R.id.topic_item_reply_icon_shadow_gap) protected View iconShadowGap; + private final ITopicItemReplyPresenter topicItemReplyPresenter; + private Reply reply; private int position = -1; public ViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); + topicItemReplyPresenter = new TopicItemReplyPresenter(activity, this); } public void update(int position) { this.position = position; reply = replyList.get(position); - - Glide.with(activity).load(reply.getAuthor().getAvatarUrl()).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); - tvLoginName.setText(reply.getAuthor().getLoginName()); - tvIndex.setText(position + 1 + "楼"); - tvCreateTime.setText(FormatUtils.getRecentlyTimeText(reply.getCreateAt())); - btnUps.setText(String.valueOf(reply.getUpList().size())); - btnUps.setCompoundDrawablesWithIntrinsicBounds(reply.getUpList().contains(LoginShared.getId(activity)) ? R.drawable.ic_thumb_up_theme_24dp : R.drawable.ic_thumb_up_grey600_24dp, 0, 0, 0); - iconDeepLine.setVisibility(position == replyList.size() - 1 ? View.GONE : View.VISIBLE); - iconShadowGap.setVisibility(position == replyList.size() - 1 ? View.VISIBLE : View.GONE); - - // 这里直接使用WebView,有性能问题 - webContent.loadRenderedContent(reply.getHandleContent()); + updateReplyViews(reply); } @OnClick(R.id.topic_item_reply_img_avatar) @@ -138,7 +128,7 @@ protected void onBtnUpsClick() { if (reply.getAuthor().getLoginName().equals(LoginShared.getLoginName(activity))) { ToastUtils.with(activity).show(R.string.can_not_up_yourself_reply); } else { - upReplyAsyncTask(this); + topicItemReplyPresenter.upReplyAsyncTask(reply, position); } } } @@ -150,32 +140,38 @@ protected void onBtnAtClick() { } } - } + @Override + public void updateReplyViews(@NonNull Reply reply) { + Glide.with(activity).load(reply.getAuthor().getAvatarUrl()).placeholder(R.drawable.image_placeholder).dontAnimate().into(imgAvatar); + tvLoginName.setText(reply.getAuthor().getLoginName()); + tvIndex.setText(position + 1 + "楼"); + tvCreateTime.setText(FormatUtils.getRecentlyTimeText(reply.getCreateAt())); + updateUpViews(reply); + iconDeepLine.setVisibility(position == replyList.size() - 1 ? View.GONE : View.VISIBLE); + iconShadowGap.setVisibility(position == replyList.size() - 1 ? View.VISIBLE : View.GONE); + + // 这里直接使用WebView,有性能问题 + webContent.loadRenderedContent(reply.getHandleContent()); + } - private void upReplyAsyncTask(final ViewHolder holder) { - final int position = holder.position; // 标记当时的位置信息 - final Reply reply = holder.reply; // 保存当时的回复对象 - Call call = ApiClient.service.upReply(holder.reply.getId(), LoginShared.getAccessToken(activity)); - call.enqueue(new DefaultToastCallback(activity) { - - @Override - public boolean onResultOk(Response response, Result.UpReply result) { - if (!activity.isFinishing()) { - if (result.getAction() == Reply.UpAction.up) { - reply.getUpList().add(LoginShared.getId(activity)); - } else if (result.getAction() == Reply.UpAction.down) { - reply.getUpList().remove(LoginShared.getId(activity)); - } - // 如果位置没有变,则更新界面 - if (position == holder.position) { - holder.btnUps.setText(String.valueOf(holder.reply.getUpList().size())); - holder.btnUps.setCompoundDrawablesWithIntrinsicBounds(holder.reply.getUpList().contains(LoginShared.getId(activity)) ? R.drawable.ic_thumb_up_theme_24dp : R.drawable.ic_thumb_up_grey600_24dp, 0, 0, 0); - } + @Override + public void updateUpViews(@NonNull Reply reply) { + btnUps.setText(String.valueOf(reply.getUpList().size())); + btnUps.setCompoundDrawablesWithIntrinsicBounds(reply.getUpList().contains(LoginShared.getId(activity)) ? R.drawable.ic_thumb_up_theme_24dp : R.drawable.ic_thumb_up_grey600_24dp, 0, 0, 0); + } + + @Override + public boolean onUpReplyResultOk(@NonNull Reply reply, int position) { + if (!activity.isFinishing()) { + if (position == this.position) { + updateUpViews(reply); } return false; + } else { + return true; } + } - }); } } diff --git a/app/src/main/java/org/cnodejs/android/md/display/view/ITopicItemReplyView.java b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicItemReplyView.java new file mode 100644 index 00000000..5eb32697 --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/view/ITopicItemReplyView.java @@ -0,0 +1,15 @@ +package org.cnodejs.android.md.display.view; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Reply; + +public interface ITopicItemReplyView { + + void updateReplyViews(@NonNull Reply reply); + + void updateUpViews(@NonNull Reply reply); + + boolean onUpReplyResultOk(@NonNull Reply reply, int position); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicItemReplyPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicItemReplyPresenter.java new file mode 100644 index 00000000..c507183a --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/contract/ITopicItemReplyPresenter.java @@ -0,0 +1,11 @@ +package org.cnodejs.android.md.presenter.contract; + +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.model.entity.Reply; + +public interface ITopicItemReplyPresenter { + + void upReplyAsyncTask(@NonNull Reply reply, int position); + +} diff --git a/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicItemReplyPresenter.java b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicItemReplyPresenter.java new file mode 100644 index 00000000..e02d44ff --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/presenter/implement/TopicItemReplyPresenter.java @@ -0,0 +1,45 @@ +package org.cnodejs.android.md.presenter.implement; + +import android.app.Activity; +import android.support.annotation.NonNull; + +import org.cnodejs.android.md.display.view.ITopicItemReplyView; +import org.cnodejs.android.md.model.api.ApiClient; +import org.cnodejs.android.md.model.api.DefaultToastCallback; +import org.cnodejs.android.md.model.entity.Reply; +import org.cnodejs.android.md.model.entity.Result; +import org.cnodejs.android.md.model.storage.LoginShared; +import org.cnodejs.android.md.presenter.contract.ITopicItemReplyPresenter; + +import retrofit2.Call; +import retrofit2.Response; + +public class TopicItemReplyPresenter implements ITopicItemReplyPresenter { + + private final Activity activity; + private final ITopicItemReplyView topicItemReplyView; + + public TopicItemReplyPresenter(@NonNull Activity activity, @NonNull ITopicItemReplyView topicItemReplyView) { + this.activity = activity; + this.topicItemReplyView = topicItemReplyView; + } + + @Override + public void upReplyAsyncTask(@NonNull final Reply reply, final int position) { + Call call = ApiClient.service.upReply(reply.getId(), LoginShared.getAccessToken(activity)); + call.enqueue(new DefaultToastCallback(activity) { + + @Override + public boolean onResultOk(Response response, Result.UpReply result) { + if (result.getAction() == Reply.UpAction.up) { + reply.getUpList().add(LoginShared.getId(activity)); + } else if (result.getAction() == Reply.UpAction.down) { + reply.getUpList().remove(LoginShared.getId(activity)); + } + return topicItemReplyView.onUpReplyResultOk(reply, position); + } + + }); + } + +} From 16ce21bca83ca4b4a874ab9172b01fe716d99b85 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 08:44:42 +0800 Subject: [PATCH 43/89] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/drawable-xxxhdpi/ic_share_white_24dp.png | Bin 0 -> 1115 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_share_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..bb521c141bfc1d6ca7aba0f34ab4638f86b0bbe0 GIT binary patch literal 1115 zcmV-h1f=_kP)004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00002VoOIv0RM-N%)bBt010qN zS#tmY3ljhU3ljkVnw%H_00YxWL_t(|+U=T6NK{c2$0tLAs7!;*Ce4rNgBERSQ>&y% zT9k{ZML7~wv?wGi`j8;q^dTX(X_JXjW+YOXktu>MYEvtr(vmRBzOXViQ=9pu_vF6Z$$zu~_BJ?GrN51+f2&jauPJOB^C0~oVnh;b*tG74#-8-Q+FIL%V` z04(7)A;w3D8q(bWu$v#KqMv|tfD=TDW0C=Ki6(YR1xTkqDu6x~%LJ$<+NhEUkRC>P zR1qXq9zX#maakFqcw>4bvaSF9RTkeSF3|%4L)i>v)Ql_{sw30sK^AEka~FT~5!SfIdZfA0m`= zLH0Y{&}7r0NN#{aW|GYpW%^&(>TFB7f``iFsz=+DB+A0*(h!$Pbh4?BqeLl}t*jsS zbP{>orGs92c*$)J>ONfi0b~J@OQ#A3BAR#`{#K{S5_7+}g<#D0IS({)ndR}smxS(tgTgi0#e&A@tN~L>hBAPev;uI`Lh`oB zr8z(vLBr$+D6&s3%>hmtrf;)cngcW#rQaa$nzd_k22aibn9VMS+zv1(58#~ispHUuOP?%WD9em<_Q~sHzATo*%I(%gz#e&>>=!0dru^(5v&J2^ z%QZY!YF2qPGk@o8m(vI+8=@YLOs2frrw=-LZDVtoA;KOmQbi@D>?KWx@l_|Ubz`ip zn`oZ!drNd@i2aAXPF~M5o4MRlLe`KV!8fXt*Z0by{7AHuBEvVTlUIGT5ii9zs+L!M z+>&E_)ybf}`wP1207I(ZF$f+x$foD~@%^(Rqzz0E}Fx%Lq7af2-n hzyt6AJb?cK;5XZ0#A>dCZ#Dn`002ovPDHLkV1hi5?Gyk2 literal 0 HcmV?d00001 From 37bfdecdc1f41ae66be07b5c1a9be76d22044781 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 08:50:01 +0800 Subject: [PATCH 44/89] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/cnodejs/android/md/util/ShipUtils.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/org/cnodejs/android/md/util/ShipUtils.java b/app/src/main/java/org/cnodejs/android/md/util/ShipUtils.java index 80cac711..a8c11bf1 100644 --- a/app/src/main/java/org/cnodejs/android/md/util/ShipUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/util/ShipUtils.java @@ -44,4 +44,11 @@ public static void sendEmail(Context context, String email, String subject, Stri } } + public static void share(Context context, String text) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, text); + context.startActivity(Intent.createChooser(intent, "分享到:")); + } + } From e086736a180e197c4475dc4e80c882dd2145914a Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 08:52:53 +0800 Subject: [PATCH 45/89] =?UTF-8?q?=E8=AF=9D=E9=A2=98=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=88=86=E4=BA=AB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cnodejs/android/md/display/activity/TopicActivity.java | 6 ++++-- app/src/main/res/menu/topic.xml | 6 +++--- app/src/main/res/values/strings.xml | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java index eaa80930..23a4b772 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/TopicActivity.java @@ -130,8 +130,10 @@ protected void onCreate(Bundle savedInstanceState) { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { - case R.id.action_open_in_browser: - ShipUtils.openInBrowser(this, "https://cnodejs.org/topic/" + topicId); + case R.id.action_share: + if (topic != null) { + ShipUtils.share(this, "《" + topic.getTitle() + "》\nhttps://cnodejs.org/topic/" + topicId + "\n—— 来自CNode社区"); + } return true; default: return false; diff --git a/app/src/main/res/menu/topic.xml b/app/src/main/res/menu/topic.xml index fb40c72c..68432ac5 100644 --- a/app/src/main/res/menu/topic.xml +++ b/app/src/main/res/menu/topic.xml @@ -3,9 +3,9 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 365bc238..4ceb25a2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -97,6 +97,7 @@ 默认尾巴 在浏览器中打开 + 分享 发送 发布到分类: From fe31d70fa5c5489571ee6af98a1cdea75d6be3ea Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 08:58:17 +0800 Subject: [PATCH 46/89] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/cnodejs/android/md/display/activity/AboutActivity.java | 3 ++- .../cnodejs/android/md/display/activity/CrashLogActivity.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/AboutActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/AboutActivity.java index 463f261f..d80b910e 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/AboutActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/AboutActivity.java @@ -70,7 +70,8 @@ protected void onBtnAdviceFeedbackClick() { this, "takwolf@foxmail.com", "来自 CNodeMD-" + VERSION_TEXT + " 的客户端反馈", - "设备信息:Android " + Build.VERSION.RELEASE + " - " + Build.MANUFACTURER + " - " + Build.MODEL + "\n(如果涉及隐私请手动删除这个内容)\n\n"); + "设备信息:Android " + Build.VERSION.RELEASE + " - " + Build.MANUFACTURER + " - " + Build.MODEL + "\n(如果涉及隐私请手动删除这个内容)\n\n" + ); } @OnClick(R.id.about_btn_open_source_license) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java index ca84bb0a..b1d7593a 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/CrashLogActivity.java @@ -84,7 +84,8 @@ public boolean onMenuItemClick(MenuItem item) { this, "takwolf@foxmail.com", "来自 CNodeMD-" + AboutActivity.VERSION_TEXT + " 的客户端崩溃日志", - crashLog); + crashLog + ); return true; default: return false; From 5ed5b5bb3af84648d1ea78cd66f5c8c090cde6d8 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Fri, 29 Apr 2016 22:04:11 +0800 Subject: [PATCH 47/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=AF=9D=E9=A2=98=E9=A1=B5=E9=9D=A2=E8=BE=93=E5=85=A5=E6=A1=86?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_create_topic.xml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/layout/activity_create_topic.xml b/app/src/main/res/layout/activity_create_topic.xml index acdb2248..99263824 100644 --- a/app/src/main/res/layout/activity_create_topic.xml +++ b/app/src/main/res/layout/activity_create_topic.xml @@ -94,14 +94,11 @@ android:id="@+id/create_topic_edt_content" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingLeft="16dp" - android:paddingRight="16dp" - android:paddingTop="16dp" - android:paddingBottom="96dp" + android:padding="16dp" android:gravity="start" android:hint="@string/create_topic_content_hint" android:textSize="16sp" - android:minLines="30" + android:minLines="10" android:background="?attr/widgetBackgroundDark" /> From b5e2b852d7598f7139a3e05d59f8446313fb8a5e Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sat, 30 Apr 2016 16:46:51 +0800 Subject: [PATCH 48/89] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=AF=9D=E9=A2=98=E8=BE=93=E5=85=A5=E6=A1=86=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E8=89=B2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_create_topic.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/activity_create_topic.xml b/app/src/main/res/layout/activity_create_topic.xml index 99263824..b9165d6a 100644 --- a/app/src/main/res/layout/activity_create_topic.xml +++ b/app/src/main/res/layout/activity_create_topic.xml @@ -88,6 +88,7 @@ + android:background="@android:color/transparent" /> From 7dd6ee20a815ac5ee919790aa744124f0fa4ee06 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sat, 30 Apr 2016 22:04:37 +0800 Subject: [PATCH 49/89] =?UTF-8?q?ProgressDialog=E6=9E=84=E5=BB=BA=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../display/activity/CreateTopicActivity.java | 3 +-- .../md/display/activity/LoginActivity.java | 2 +- .../md/display/dialog/DialogUtils.java | 4 ---- .../md/display/dialog/ProgressDialog.java | 22 ++++++------------- .../viewholder/TopicReplyViewHolder.java | 3 +-- app/src/main/res/values/styles.xml | 6 +++++ 6 files changed, 16 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java index 5f646e3f..3da60e65 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/CreateTopicActivity.java @@ -10,7 +10,6 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.base.StatusBarActivity; -import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; import org.cnodejs.android.md.display.view.ICreateTopicView; @@ -61,7 +60,7 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.inflateMenu(R.menu.create_topic); toolbar.setOnMenuItemClickListener(this); - progressDialog = DialogUtils.createProgressDialog(this); + progressDialog = ProgressDialog.createWithAutoTheme(this); progressDialog.setMessage(R.string.posting_$_); progressDialog.setCancelable(false); diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java index bda7b17b..ab7681f8 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java @@ -77,7 +77,7 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.setNavigationOnClickListener(new NavigationFinishClickListener(this)); - progressDialog = DialogUtils.createProgressDialog(this); + progressDialog = ProgressDialog.createWithAutoTheme(this); progressDialog.setMessage(R.string.logging_in_$_); loginPresenter = new LoginPresenter(this, this); diff --git a/app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java b/app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java index 6f0b9e09..8f9fd9ae 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java @@ -9,10 +9,6 @@ public final class DialogUtils { private DialogUtils() {} - public static ProgressDialog createProgressDialog(Context context) { - return new ProgressDialog(context, ThemeUtils.getDialogThemeRes(context)); - } - public static AlertDialog.Builder createAlertDialogBuilder(Context context) { return new AlertDialog.Builder(context, ThemeUtils.getDialogThemeRes(context)); } diff --git a/app/src/main/java/org/cnodejs/android/md/display/dialog/ProgressDialog.java b/app/src/main/java/org/cnodejs/android/md/display/dialog/ProgressDialog.java index 0abd1613..53a1f783 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/dialog/ProgressDialog.java +++ b/app/src/main/java/org/cnodejs/android/md/display/dialog/ProgressDialog.java @@ -1,6 +1,7 @@ package org.cnodejs.android.md.display.dialog; -import android.content.Context; +import android.app.Activity; +import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.support.v7.app.AppCompatDialog; import android.text.TextUtils; @@ -9,31 +10,22 @@ import android.widget.TextView; import org.cnodejs.android.md.R; +import org.cnodejs.android.md.model.storage.SettingShared; import butterknife.Bind; import butterknife.ButterKnife; public class ProgressDialog extends AppCompatDialog { - public ProgressDialog(Context context) { - super(context); - init(); - } - - public ProgressDialog(Context context, int theme) { - super(context, theme); - init(); - } - - protected ProgressDialog(Context context, boolean cancelable, OnCancelListener cancelListener) { - super(context, cancelable, cancelListener); - init(); + public static ProgressDialog createWithAutoTheme(@NonNull Activity activity) { + return new ProgressDialog(activity, SettingShared.isEnableThemeDark(activity) ? R.style.AppDialogDark_Alert : R.style.AppDialogLight_Alert); } @Bind(R.id.dialog_progress_tv_message) protected TextView tvMessage; - private void init() { + private ProgressDialog(@NonNull Activity activity, int theme) { + super(activity, theme); supportRequestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.dialog_progress); ButterKnife.bind(this); diff --git a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java index 2f62a548..ce303b2e 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java +++ b/app/src/main/java/org/cnodejs/android/md/display/viewholder/TopicReplyViewHolder.java @@ -11,7 +11,6 @@ import android.widget.PopupWindow; import org.cnodejs.android.md.R; -import org.cnodejs.android.md.display.dialog.DialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; import org.cnodejs.android.md.display.view.ITopicReplyView; import org.cnodejs.android.md.display.view.ITopicView; @@ -57,7 +56,7 @@ public TopicReplyViewHolder(@NonNull Activity activity, @NonNull ViewGroup layou replyWindow.setOutsideTouchable(true); replyWindow.setAnimationStyle(R.style.AppWidget_ReplyWindowAnim); - progressDialog = DialogUtils.createProgressDialog(activity); + progressDialog = ProgressDialog.createWithAutoTheme(activity); progressDialog.setMessage(R.string.posting_$_); progressDialog.setCancelable(false); diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 394edf9d..1c65d83e 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -53,6 +53,9 @@ @color/color_primary @color/color_primary_dark @color/color_accent + + + @@ -62,6 +65,9 @@ @color/color_primary @color/color_primary_dark @color/color_accent + + + From bba6b5d17f11a3bd499ad7df96d14bcf2dc28a17 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sat, 30 Apr 2016 22:12:24 +0800 Subject: [PATCH 50/89] =?UTF-8?q?AlertDialog=E6=9E=84=E5=BB=BA=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../md/display/activity/LoginActivity.java | 6 +++--- .../md/display/activity/MainActivity.java | 4 ++-- .../md/display/activity/QRCodeActivity.java | 4 ++-- .../md/display/dialog/AlertDialogUtils.java | 18 ++++++++++++++++++ .../android/md/display/dialog/DialogUtils.java | 16 ---------------- .../md/display/widget/EditorBarHandler.java | 4 ++-- .../android/md/display/widget/ThemeUtils.java | 5 ----- .../md/model/api/DefaultToastCallback.java | 4 ++-- 8 files changed, 29 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/org/cnodejs/android/md/display/dialog/AlertDialogUtils.java delete mode 100644 app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java index ab7681f8..c06922d0 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/LoginActivity.java @@ -12,7 +12,7 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.base.StatusBarActivity; -import org.cnodejs.android.md.display.dialog.DialogUtils; +import org.cnodejs.android.md.display.dialog.AlertDialogUtils; import org.cnodejs.android.md.display.dialog.ProgressDialog; import org.cnodejs.android.md.display.listener.DialogCancelCallListener; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; @@ -40,7 +40,7 @@ public static void startForResult(@NonNull Activity activity) { public static boolean startForResultWithAccessTokenCheck(@NonNull final Activity activity) { if (TextUtils.isEmpty(LoginShared.getAccessToken(activity))) { - DialogUtils.createAlertDialogBuilder(activity) + AlertDialogUtils.createBuilderWithAutoTheme(activity) .setMessage(R.string.need_login_tip) .setPositiveButton(R.string.login, new DialogInterface.OnClickListener() { @@ -105,7 +105,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { @OnClick(R.id.login_btn_login_tip) protected void onBtnLoginTipClick() { - DialogUtils.createAlertDialogBuilder(this) + AlertDialogUtils.createBuilderWithAutoTheme(this) .setMessage(R.string.how_to_get_access_token_tip_content) .setPositiveButton(R.string.confirm, null) .show(); diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java index e547f77f..609eac26 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/MainActivity.java @@ -22,7 +22,7 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.adapter.MainAdapter; import org.cnodejs.android.md.display.base.DrawerLayoutActivity; -import org.cnodejs.android.md.display.dialog.DialogUtils; +import org.cnodejs.android.md.display.dialog.AlertDialogUtils; import org.cnodejs.android.md.display.listener.NavigationOpenClickListener; import org.cnodejs.android.md.display.listener.RecyclerViewLoadMoreListener; import org.cnodejs.android.md.display.view.IMainView; @@ -310,7 +310,7 @@ public void startDelayed() { */ @OnClick(R.id.main_nav_btn_logout) protected void onBtnLogoutClick() { - DialogUtils.createAlertDialogBuilder(this) + AlertDialogUtils.createBuilderWithAutoTheme(this) .setMessage(R.string.logout_tip) .setPositiveButton(R.string.logout, new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/org/cnodejs/android/md/display/activity/QRCodeActivity.java b/app/src/main/java/org/cnodejs/android/md/display/activity/QRCodeActivity.java index 36f65e81..ef0fce3c 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/activity/QRCodeActivity.java +++ b/app/src/main/java/org/cnodejs/android/md/display/activity/QRCodeActivity.java @@ -14,7 +14,7 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.base.StatusBarActivity; -import org.cnodejs.android.md.display.dialog.DialogUtils; +import org.cnodejs.android.md.display.dialog.AlertDialogUtils; import org.cnodejs.android.md.display.listener.NavigationFinishClickListener; import org.cnodejs.android.md.util.FormatUtils; @@ -74,7 +74,7 @@ public void onQRCodeRead(String text, PointF[] points) { @Override public void cameraNotFound() { - DialogUtils.createAlertDialogBuilder(this) + AlertDialogUtils.createBuilderWithAutoTheme(this) .setMessage(R.string.can_not_open_camera) .setPositiveButton(R.string.confirm, null) .setOnDismissListener(new DialogInterface.OnDismissListener() { diff --git a/app/src/main/java/org/cnodejs/android/md/display/dialog/AlertDialogUtils.java b/app/src/main/java/org/cnodejs/android/md/display/dialog/AlertDialogUtils.java new file mode 100644 index 00000000..20c7315c --- /dev/null +++ b/app/src/main/java/org/cnodejs/android/md/display/dialog/AlertDialogUtils.java @@ -0,0 +1,18 @@ +package org.cnodejs.android.md.display.dialog; + +import android.app.Activity; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; + +import org.cnodejs.android.md.R; +import org.cnodejs.android.md.model.storage.SettingShared; + +public final class AlertDialogUtils { + + private AlertDialogUtils() {} + + public static AlertDialog.Builder createBuilderWithAutoTheme(@NonNull Activity activity) { + return new AlertDialog.Builder(activity, SettingShared.isEnableThemeDark(activity) ? R.style.AppDialogDark_Alert : R.style.AppDialogLight_Alert); + } + +} diff --git a/app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java b/app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java deleted file mode 100644 index 8f9fd9ae..00000000 --- a/app/src/main/java/org/cnodejs/android/md/display/dialog/DialogUtils.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.cnodejs.android.md.display.dialog; - -import android.content.Context; -import android.support.v7.app.AlertDialog; - -import org.cnodejs.android.md.display.widget.ThemeUtils; - -public final class DialogUtils { - - private DialogUtils() {} - - public static AlertDialog.Builder createAlertDialogBuilder(Context context) { - return new AlertDialog.Builder(context, ThemeUtils.getDialogThemeRes(context)); - } - -} diff --git a/app/src/main/java/org/cnodejs/android/md/display/widget/EditorBarHandler.java b/app/src/main/java/org/cnodejs/android/md/display/widget/EditorBarHandler.java index 48f3c4e6..09fd09cd 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/widget/EditorBarHandler.java +++ b/app/src/main/java/org/cnodejs/android/md/display/widget/EditorBarHandler.java @@ -12,7 +12,7 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.model.storage.SettingShared; import org.cnodejs.android.md.display.activity.MarkdownPreviewActivity; -import org.cnodejs.android.md.display.dialog.DialogUtils; +import org.cnodejs.android.md.display.dialog.AlertDialogUtils; import butterknife.ButterKnife; import butterknife.OnClick; @@ -113,7 +113,7 @@ protected void onBtnInsertCodeClick() { */ @OnClick(R.id.editor_bar_btn_insert_link) protected void onBtnInsertLinkClick() { - DialogUtils.createAlertDialogBuilder(activity) + AlertDialogUtils.createBuilderWithAutoTheme(activity) .setIcon(R.drawable.ic_insert_link_grey600_24dp) .setTitle(R.string.add_link) .setView(R.layout.dialog_tool_insert_link) diff --git a/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java b/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java index 1ad3a3b2..81b0f588 100644 --- a/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java +++ b/app/src/main/java/org/cnodejs/android/md/display/widget/ThemeUtils.java @@ -11,7 +11,6 @@ import android.support.annotation.NonNull; import android.support.annotation.StyleRes; -import org.cnodejs.android.md.R; import org.cnodejs.android.md.model.storage.SettingShared; import org.cnodejs.android.md.util.HandlerUtils; @@ -67,10 +66,6 @@ public void run() { }); } - public static int getDialogThemeRes(@NonNull Context context) { - return SettingShared.isEnableThemeDark(context) ? R.style.AppDialogDark : R.style.AppDialogLight; - } - public static int getStatusBarHeight(@NonNull Context context) { int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return resourceId > 0 ? context.getResources().getDimensionPixelSize(resourceId) : 0; diff --git a/app/src/main/java/org/cnodejs/android/md/model/api/DefaultToastCallback.java b/app/src/main/java/org/cnodejs/android/md/model/api/DefaultToastCallback.java index c7629b7e..66f3d46b 100644 --- a/app/src/main/java/org/cnodejs/android/md/model/api/DefaultToastCallback.java +++ b/app/src/main/java/org/cnodejs/android/md/model/api/DefaultToastCallback.java @@ -6,7 +6,7 @@ import org.cnodejs.android.md.R; import org.cnodejs.android.md.display.activity.LoginActivity; -import org.cnodejs.android.md.display.dialog.DialogUtils; +import org.cnodejs.android.md.display.dialog.AlertDialogUtils; import org.cnodejs.android.md.display.widget.ToastUtils; import org.cnodejs.android.md.model.entity.Result; @@ -31,7 +31,7 @@ public final boolean onResultError(Response response, Result.Error error) { public boolean onResultErrorAuth(Response response, Result.Error error) { if (!activity.isFinishing()) { - DialogUtils.createAlertDialogBuilder(activity) + AlertDialogUtils.createBuilderWithAutoTheme(activity) .setMessage(R.string.access_token_out_of_date) .setPositiveButton(R.string.relogin, new DialogInterface.OnClickListener() { From 47e8bab74249c8cebd23dff492f57eb86c9b603f Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sun, 1 May 2016 00:02:10 +0800 Subject: [PATCH 51/89] =?UTF-8?q?bottom=20sheet=20=E5=8A=A8=E7=94=BB?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/anim/bottom_sheet_slide_in.xml | 7 +++++++ app/src/main/res/anim/bottom_sheet_slide_out.xml | 7 +++++++ app/src/main/res/anim/reply_window_popup_in.xml | 5 ----- app/src/main/res/anim/reply_window_popup_out.xml | 5 ----- 4 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 app/src/main/res/anim/bottom_sheet_slide_in.xml create mode 100644 app/src/main/res/anim/bottom_sheet_slide_out.xml delete mode 100644 app/src/main/res/anim/reply_window_popup_in.xml delete mode 100644 app/src/main/res/anim/reply_window_popup_out.xml diff --git a/app/src/main/res/anim/bottom_sheet_slide_in.xml b/app/src/main/res/anim/bottom_sheet_slide_in.xml new file mode 100644 index 00000000..ef1fa6d0 --- /dev/null +++ b/app/src/main/res/anim/bottom_sheet_slide_in.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/bottom_sheet_slide_out.xml b/app/src/main/res/anim/bottom_sheet_slide_out.xml new file mode 100644 index 00000000..1dc0f793 --- /dev/null +++ b/app/src/main/res/anim/bottom_sheet_slide_out.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/reply_window_popup_in.xml b/app/src/main/res/anim/reply_window_popup_in.xml deleted file mode 100644 index 222354ea..00000000 --- a/app/src/main/res/anim/reply_window_popup_in.xml +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/anim/reply_window_popup_out.xml b/app/src/main/res/anim/reply_window_popup_out.xml deleted file mode 100644 index 7edd0267..00000000 --- a/app/src/main/res/anim/reply_window_popup_out.xml +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file From 3712a9eb87d5ae67f4c9d2308dbed64949344c63 Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sun, 1 May 2016 00:07:45 +0800 Subject: [PATCH 52/89] =?UTF-8?q?=E5=AE=9A=E4=B9=89bottom=20sheet=E5=8A=A8?= =?UTF-8?q?=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/styles.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 1c65d83e..c32ca73b 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -148,10 +148,12 @@ @drawable/button_stroke_image - - From 1579b9b67d7927ef5e4fa39ec20f4553af4cca9d Mon Sep 17 00:00:00 2001 From: TakWolf Date: Sun, 1 May 2016 00:15:09 +0800 Subject: [PATCH 53/89] =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E6=A1=86=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/styles.xml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index c32ca73b..fe106d33 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -49,24 +49,38 @@ - + - + + + + +