N>~uq2C*L$C#kyqMw7c@Vga
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
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_my_game.xml b/app/src/main/res/menu/menu_my_game.xml
new file mode 100644
index 0000000000..068cc30ff4
--- /dev/null
+++ b/app/src/main/res/menu/menu_my_game.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
From 44dab8246f90ae72d51009c6aa70f404eef2ba7d Mon Sep 17 00:00:00 2001
From: leafwai
Date: Fri, 5 Nov 2021 18:08:15 +0800
Subject: [PATCH 03/49] =?UTF-8?q?=E3=80=90=E5=85=89=E7=8E=AF=E5=8A=A9?=
=?UTF-8?q?=E6=89=8BV5.5.0=E3=80=91=E6=B8=B8=E6=88=8F=E5=8D=95=E5=B9=BF?=
=?UTF-8?q?=E5=9C=BA(=E9=80=89=E6=8B=A9=E6=A0=87=E7=AD=BEUI=EF=BC=89https:?=
=?UTF-8?q?//git.ghzs.com/pm/halo-app-issues/-/issues/1598?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/src/main/AndroidManifest.xml | 8 ++
.../square/GameCollectionTagSelectActivity.kt | 29 ++++++
.../square/GameCollectionTagSelectFragment.kt | 93 ++++++++++++++++++
...ame_collection_tag_text_color_selector.xml | 5 +
.../ic_game_collection_tag_close.png | Bin 0 -> 389 bytes
.../bg_game_collection_tag_select.xml | 5 +
.../bg_game_collection_tag_unselect.xml | 7 ++
.../drawable/game_collection_tag_selector.xml | 5 +
.../fragment_game_collection_tag_select.xml | 38 +++++++
.../game_collection_selected_tag_item.xml | 31 ++++++
.../layout/game_collection_tag_body_item.xml | 20 ++++
.../game_collection_tag_header_item.xml | 19 ++++
.../item_game_collection_selected_tag.xml | 40 ++++++++
.../res/layout/item_game_collection_tag.xml | 25 +++++
app/src/main/res/layout/layout_menu_save.xml | 18 ++++
app/src/main/res/menu/menu_save.xml | 11 +++
16 files changed, 354 insertions(+)
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionTagSelectActivity.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionTagSelectFragment.kt
create mode 100644 app/src/main/res/color/game_collection_tag_text_color_selector.xml
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_tag_close.png
create mode 100644 app/src/main/res/drawable/bg_game_collection_tag_select.xml
create mode 100644 app/src/main/res/drawable/bg_game_collection_tag_unselect.xml
create mode 100644 app/src/main/res/drawable/game_collection_tag_selector.xml
create mode 100644 app/src/main/res/layout/fragment_game_collection_tag_select.xml
create mode 100644 app/src/main/res/layout/game_collection_selected_tag_item.xml
create mode 100644 app/src/main/res/layout/game_collection_tag_body_item.xml
create mode 100644 app/src/main/res/layout/game_collection_tag_header_item.xml
create mode 100644 app/src/main/res/layout/item_game_collection_selected_tag.xml
create mode 100644 app/src/main/res/layout/item_game_collection_tag.xml
create mode 100644 app/src/main/res/layout/layout_menu_save.xml
create mode 100644 app/src/main/res/menu/menu_save.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index df0dbb1963..c20004c6ba 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -730,6 +730,14 @@
android:name="com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity"
android:screenOrientation="portrait" />
+
+
+
+
Unit) = {
+ mAdapter?.multipleTagList?.let { list ->
+ mBinding?.selectedTagContainer?.removeAllViews()
+ for (name in list) {
+ val selectedTagView = ItemGameCollectionSelectedTagBinding.inflate(layoutInflater)
+ selectedTagView.run {
+ tagTv.text = name
+ root.setOnClickListener {
+ list.remove(name)
+ mBinding?.selectedTagContainer?.removeView(selectedTagView.root)
+ mAdapter?.notifyDataSetChanged()
+ mBinding?.selectedTagScrollView?.visibility = if (firstVisibleItemPosition == 0 || list.isEmpty()) View.GONE else View.VISIBLE
+ }
+ }
+ mBinding?.selectedTagContainer?.addView(selectedTagView.root)
+ }
+ mBinding?.selectedTagScrollView?.visibility = if (firstVisibleItemPosition == 0 || list.isEmpty()) View.GONE else View.VISIBLE
+ }
+ }
+
+ override fun getLayoutId(): Int = 0
+
+ override fun getInflatedLayout() =
+ FragmentGameCollectionTagSelectBinding.inflate(layoutInflater).apply {
+ mBinding = this
+ }.root
+
+ override fun onMenuItemClick(menuItem: MenuItem?) {
+ if (menuItem?.itemId == R.id.layout_menu_save) {
+ requireActivity().setResult(
+ GameCollectionSquareFragment.TAG_SELECT_REQUEST,
+ Intent().putExtra("tagName", mAdapter?.singleTagName)
+ )
+ requireActivity().finish()
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val data = arrayListOf(
+ "游戏玩法",
+ "body",
+ "游戏题材",
+ "body",
+ "游戏题材",
+ "body",
+ "游戏玩法",
+ "body",
+ "游戏玩法",
+ "body",
+ "游戏玩法",
+ "body",
+ "游戏玩法",
+ "body"
+ )
+ mAdapter = GameCollectionTagAdapter(requireContext(), true, data, updateSelectedTagView)
+ mBinding?.tagRv?.run {
+ layoutManager = LinearLayoutManager(requireContext())
+ adapter = mAdapter
+ addOnScrollListener(object :RecyclerView.OnScrollListener(){
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+ when (newState) {
+ RecyclerView.SCROLL_STATE_IDLE -> firstVisibleItemPosition = (layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
+ RecyclerView.SCROLL_STATE_DRAGGING -> firstVisibleItemPosition = (layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
+ }
+ mBinding?.selectedTagScrollView?.visibility = if (firstVisibleItemPosition == 0 || mAdapter?.multipleTagList?.isEmpty() == true) View.GONE else View.VISIBLE
+ }
+ })
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/color/game_collection_tag_text_color_selector.xml b/app/src/main/res/color/game_collection_tag_text_color_selector.xml
new file mode 100644
index 0000000000..ec1c4419b0
--- /dev/null
+++ b/app/src/main/res/color/game_collection_tag_text_color_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_game_collection_tag_close.png b/app/src/main/res/drawable-xxxhdpi/ic_game_collection_tag_close.png
new file mode 100644
index 0000000000000000000000000000000000000000..98a1e5dfc15f0de3e2ed65aac8fd3a5baf117448
GIT binary patch
literal 389
zcmV;00eb$4P)k5M~427E~pFVj|F)9%zS<8hn0cZqiVn#4(0E-Yy>>Wl0fDnM#Lv@g$5_j%S;?r8>
z08;$m+985q19*r>K(GKj#akh`0DtpoQPiK@!>C?Yxy{POazG>Gsh9wGs?xnY;XpWG
jtU$Dov4H0A
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_game_collection_tag_unselect.xml b/app/src/main/res/drawable/bg_game_collection_tag_unselect.xml
new file mode 100644
index 0000000000..0683c258fc
--- /dev/null
+++ b/app/src/main/res/drawable/bg_game_collection_tag_unselect.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/game_collection_tag_selector.xml b/app/src/main/res/drawable/game_collection_tag_selector.xml
new file mode 100644
index 0000000000..dd68f2d7fe
--- /dev/null
+++ b/app/src/main/res/drawable/game_collection_tag_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_game_collection_tag_select.xml b/app/src/main/res/layout/fragment_game_collection_tag_select.xml
new file mode 100644
index 0000000000..bdc9bc5918
--- /dev/null
+++ b/app/src/main/res/layout/fragment_game_collection_tag_select.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/game_collection_selected_tag_item.xml b/app/src/main/res/layout/game_collection_selected_tag_item.xml
new file mode 100644
index 0000000000..9957806ec3
--- /dev/null
+++ b/app/src/main/res/layout/game_collection_selected_tag_item.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/game_collection_tag_body_item.xml b/app/src/main/res/layout/game_collection_tag_body_item.xml
new file mode 100644
index 0000000000..402bc80584
--- /dev/null
+++ b/app/src/main/res/layout/game_collection_tag_body_item.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/game_collection_tag_header_item.xml b/app/src/main/res/layout/game_collection_tag_header_item.xml
new file mode 100644
index 0000000000..65e105061b
--- /dev/null
+++ b/app/src/main/res/layout/game_collection_tag_header_item.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_game_collection_selected_tag.xml b/app/src/main/res/layout/item_game_collection_selected_tag.xml
new file mode 100644
index 0000000000..21f15f9800
--- /dev/null
+++ b/app/src/main/res/layout/item_game_collection_selected_tag.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_game_collection_tag.xml b/app/src/main/res/layout/item_game_collection_tag.xml
new file mode 100644
index 0000000000..afae12e218
--- /dev/null
+++ b/app/src/main/res/layout/item_game_collection_tag.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_menu_save.xml b/app/src/main/res/layout/layout_menu_save.xml
new file mode 100644
index 0000000000..860f643b6b
--- /dev/null
+++ b/app/src/main/res/layout/layout_menu_save.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/menu_save.xml b/app/src/main/res/menu/menu_save.xml
new file mode 100644
index 0000000000..b14097d34f
--- /dev/null
+++ b/app/src/main/res/menu/menu_save.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
From 001cbfcdb68b1df7df4986d692d89bf5391df4b4 Mon Sep 17 00:00:00 2001
From: jack <1484288157@qq.com>
Date: Sat, 6 Nov 2021 15:55:06 +0800
Subject: [PATCH 04/49] =?UTF-8?q?=E3=80=90=E5=85=89=E7=8E=AF=E5=8A=A9?=
=?UTF-8?q?=E6=89=8BV5.5.0=E3=80=91=E5=88=9B=E5=BB=BA/=E7=BC=96=E8=BE=91?=
=?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=8D=95(=E9=80=89=E6=8B=A9=E6=B8=B8?=
=?UTF-8?q?=E6=88=8F/=E6=B7=BB=E5=8A=A0=E6=B8=B8=E6=88=8FUI)=20https://git?=
=?UTF-8?q?.ghzs.com/pm/halo-app-issues/-/issues/1604?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/src/main/AndroidManifest.xml | 10 +-
.../com/gh/common/util/SingletonHolder.kt | 26 +++
.../gamecollection/choose/AddGamesActivity.kt | 19 ++
.../gamecollection/choose/AddGamesFragment.kt | 19 ++
.../choose/AddSearchAndPlayedGameAdapter.kt | 44 ++++
.../choose/AddSearchGameFragment.kt | 59 ++++++
.../choose/AddUserPlayedGameFragment.kt | 51 +++++
.../choose/ChooseGamesActivity.kt | 23 ++
.../choose/ChooseGamesAdapter.kt | 69 ++++++
.../choose/ChooseGamesFragment.kt | 108 ++++++++++
.../choose/ChooseGamesRepository.kt | 12 ++
.../choose/ChooseGamesViewModel.kt | 21 ++
.../publish/GameCollectionEditActivity.kt | 39 +++-
...odel.kt => GameCollectionEditViewModel.kt} | 2 +-
.../gamecenter/mygame/PlayedGameViewModel.kt | 50 ++---
.../home/game/UserPlayedGameFragment.kt | 2 +-
.../gh/gamecenter/qa/editor/GameActivity.kt | 197 +-----------------
.../gh/gamecenter/qa/editor/GameAdapter.kt | 2 +-
.../gh/gamecenter/qa/editor/GameFragment.kt | 190 +++++++++++++++++
.../drawable-xxxhdpi/ic_choose_games_drag.png | Bin 0 -> 473 bytes
.../drawable-xxxhdpi/ic_choose_games_top.png | Bin 0 -> 1491 bytes
.../res/drawable-xxxhdpi/icon_add_games.webp | Bin 0 -> 3594 bytes
.../res/drawable/bg_shape_f5_radius_6.xml | 6 +
.../layout/activity_editor_insert_game.xml | 3 -
.../layout/activity_game_collection_edit.xml | 10 +-
.../layout/fragment_add_user_played_game.xml | 57 +++++
.../main/res/layout/fragment_choose_games.xml | 56 +++++
.../main/res/layout/fragment_search_game.xml | 162 ++++++++++++++
app/src/main/res/layout/item_choose_games.xml | 116 +++++++++++
app/src/main/res/layout/layout_menu_save.xml | 18 ++
app/src/main/res/menu/menu_save.xml | 11 +
31 files changed, 1146 insertions(+), 236 deletions(-)
create mode 100644 app/src/main/java/com/gh/common/util/SingletonHolder.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt
rename app/src/main/java/com/gh/gamecenter/gamecollection/publish/{GameCollectionViewModel.kt => GameCollectionEditViewModel.kt} (61%)
create mode 100644 app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_choose_games_drag.png
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_choose_games_top.png
create mode 100644 app/src/main/res/drawable-xxxhdpi/icon_add_games.webp
create mode 100644 app/src/main/res/drawable/bg_shape_f5_radius_6.xml
create mode 100644 app/src/main/res/layout/fragment_add_user_played_game.xml
create mode 100644 app/src/main/res/layout/fragment_choose_games.xml
create mode 100644 app/src/main/res/layout/fragment_search_game.xml
create mode 100644 app/src/main/res/layout/item_choose_games.xml
create mode 100644 app/src/main/res/layout/layout_menu_save.xml
create mode 100644 app/src/main/res/menu/menu_save.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index df0dbb1963..74fc368709 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -727,7 +727,15 @@
android:screenOrientation="portrait" />
+
+
+
+
(creator: () -> T) {
+ private var creator: (() -> T)? = creator
+
+ @Volatile
+ private var instance: T? = null
+
+ fun getInstance(): T {
+ val obj = instance
+ if (obj != null) {
+ return obj
+ }
+ return synchronized(this) {
+ val obj1 = instance
+ if (obj1 != null) {
+ obj1
+ } else {
+ val created = creator!!()
+ instance = created
+ creator = null
+ created
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt
new file mode 100644
index 0000000000..09a979b0d0
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesActivity.kt
@@ -0,0 +1,19 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.gamecenter.NormalActivity
+
+class AddGamesActivity : NormalActivity() {
+
+ override fun provideNormalIntent(): Intent {
+ return getTargetIntent(this, AddGamesActivity::class.java, AddGamesFragment::class.java)
+ }
+
+ companion object {
+ fun getIntent(context: Context): Intent {
+ return getTargetIntent(context, AddGamesActivity::class.java, AddGamesFragment::class.java)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt
new file mode 100644
index 0000000000..b994ba2dfa
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddGamesFragment.kt
@@ -0,0 +1,19 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import androidx.core.os.bundleOf
+import androidx.fragment.app.Fragment
+import com.gh.base.fragment.BaseLazyTabFragment
+import com.gh.common.util.EntranceUtils
+
+class AddGamesFragment : BaseLazyTabFragment() {
+
+ override fun initFragmentList(fragments: MutableList) {
+ fragments.add(AddSearchGameFragment().apply { bundleOf(EntranceUtils.KEY_NAVIGATION_TITLE to "添加游戏") })
+ fragments.add(AddUserPlayedGameFragment())
+ }
+
+ override fun initTabTitleList(tabTitleList: MutableList) {
+ tabTitleList.add("搜索游戏")
+ tabTitleList.add("玩过游戏")
+ }
+}
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt
new file mode 100644
index 0000000000..3864f12d74
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchAndPlayedGameAdapter.kt
@@ -0,0 +1,44 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.ToastUtils
+import com.gh.common.util.toColor
+import com.gh.common.util.toDrawable
+import com.gh.gamecenter.R
+import com.gh.gamecenter.game.GameItemViewHolder
+import com.gh.gamecenter.qa.editor.GameAdapter
+
+class AddSearchAndPlayedGameAdapter(context: Context, val mChooseGamesViewModel: ChooseGamesViewModel) : GameAdapter(context) {
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder is GameItemViewHolder) {
+ val entity = mEntityList[position]
+ val isSelected = mChooseGamesViewModel.chooseGamesLiveData.value?.find { it.id == entity.id } != null
+ holder.binding.game = entity
+ holder.binding.downloadBtn.text = if (isSelected) "删除" else "添加"
+ holder.binding.downloadBtn.background =
+ if (isSelected) R.drawable.bg_shape_f5_radius_999.toDrawable() else R.drawable.download_button_normal_style.toDrawable()
+ holder.binding.downloadBtn.setTextColor(if (isSelected) R.color.text_999999.toColor() else R.color.white.toColor())
+
+ holder.binding.downloadBtn.setOnClickListener {
+ val chooseGameList = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
+ if (isSelected) {
+ chooseGameList.remove(chooseGameList.find { it.id == entity.id })
+ ToastUtils.showToast("游戏已移除")
+ } else {
+ if (chooseGameList.size >= 100) {
+ ToastUtils.showToast("已添加游戏到达上限")
+ return@setOnClickListener
+ }
+ chooseGameList.add(entity)
+ ToastUtils.showToast("游戏已添加")
+ }
+ notifyItemChanged(position)
+ mChooseGamesViewModel.chooseGamesLiveData.postValue(chooseGameList)
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt
new file mode 100644
index 0000000000..ab0a01cb9c
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt
@@ -0,0 +1,59 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.os.Bundle
+import android.view.View
+import androidx.core.widget.doOnTextChanged
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.goneIf
+import com.gh.common.util.viewModelProvider
+import com.gh.gamecenter.R
+import com.gh.gamecenter.SuggestionActivity
+import com.gh.gamecenter.databinding.FragmentSearchGameBinding
+import com.gh.gamecenter.qa.editor.GameAdapter
+import com.gh.gamecenter.qa.editor.GameFragment
+import com.gh.gamecenter.suggest.SuggestType
+
+class AddSearchGameFragment : GameFragment() {
+
+ private lateinit var mBinding: FragmentSearchGameBinding
+ private lateinit var mChooseGamesViewModel: ChooseGamesViewModel
+
+ override fun getLayoutId(): Int = 0
+
+ override fun getInflatedLayout(): View {
+ return FragmentSearchGameBinding.bind(layoutInflater.inflate(R.layout.fragment_search_game, null, false)).apply {
+ mBinding = this
+ }.root
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory())
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setNavigationTitle("添加游戏")
+ noneText.text = "没有找到相关游戏,换个搜索词试试?"
+ searchEt.doOnTextChanged { text, _, _, _ ->
+ mBinding.promptTv.goneIf(!text.isNullOrEmpty())
+ }
+
+ mBinding.applyGameTv.setOnClickListener {
+ SuggestionActivity.startSuggestionActivity(requireContext(), SuggestType.gameCollect, "求游戏:")
+ }
+ }
+
+ override fun getItemDecoration(): RecyclerView.ItemDecoration? {
+ return null
+ }
+
+ override fun provideListAdapter(): GameAdapter? {
+ if (mAdapter == null) {
+ mAdapter = AddSearchAndPlayedGameAdapter(requireContext(), mChooseGamesViewModel)
+ }
+ return mAdapter
+ }
+
+ override fun isAutoShowKeyboard(): Boolean = false
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt
new file mode 100644
index 0000000000..c2801c2e23
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddUserPlayedGameFragment.kt
@@ -0,0 +1,51 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.os.Bundle
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.EntranceUtils
+import com.gh.common.util.toColor
+import com.gh.common.util.viewModelProvider
+import com.gh.gamecenter.R
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.mygame.PlayedGameViewModel
+import com.gh.gamecenter.qa.editor.GameAdapter
+
+class AddUserPlayedGameFragment : ListFragment() {
+
+ private var mAdapter: GameAdapter? = null
+ private lateinit var mViewModel: PlayedGameViewModel
+ private lateinit var mChooseGamesViewModel: ChooseGamesViewModel
+
+ override fun getLayoutId(): Int = R.layout.fragment_add_user_played_game
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory())
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mCachedView.setBackgroundColor(R.color.white.toColor())
+ }
+
+ override fun provideListAdapter(): ListAdapter {
+ return mAdapter ?: AddSearchAndPlayedGameAdapter(requireContext(), mChooseGamesViewModel).apply {
+ mAdapter = this
+ }
+ }
+
+ override fun getItemDecoration(): RecyclerView.ItemDecoration? {
+ return null
+ }
+
+ override fun provideListViewModel(): PlayedGameViewModel {
+ val userId = arguments?.getString(EntranceUtils.KEY_USER_ID)
+ ?: UserManager.getInstance().userId
+ mViewModel = viewModelProvider(PlayedGameViewModel.Factory(userId, true))
+ return mViewModel
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt
new file mode 100644
index 0000000000..0769fa62a5
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesActivity.kt
@@ -0,0 +1,23 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.gamecenter.NormalActivity
+
+class ChooseGamesActivity : NormalActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setNavigationTitle("选择游戏")
+ }
+
+ override fun provideNormalIntent(): Intent {
+ return getTargetIntent(this, ChooseGamesActivity::class.java, ChooseGamesFragment::class.java)
+ }
+
+ companion object {
+ fun getIntent(context: Context): Intent {
+ return getTargetIntent(context, ChooseGamesActivity::class.java, ChooseGamesFragment::class.java)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt
new file mode 100644
index 0000000000..3fcf57c08e
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt
@@ -0,0 +1,69 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.view.MotionEvent
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.TextHelper
+import com.gh.common.util.consume
+import com.gh.common.util.toBinding
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.databinding.ItemChooseGamesBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class ChooseGamesAdapter(context: Context, val dragListener: ItemDragListener) :
+ ListAdapter(context) {
+
+
+ public override fun setListData(updateData: MutableList?) {
+ super.setListData(updateData)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return ChooseGamesViewHolder(parent.toBinding())
+ }
+
+ override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
+ return oldItem == newItem
+ }
+
+ override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
+ return oldItem?.id == newItem?.id
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder is ChooseGamesViewHolder) {
+ val gameEntity = mEntityList[position]
+ holder.binding.gameNameTv.text = gameEntity.name
+ holder.binding.gameIcon.displayGameIcon(gameEntity)
+ holder.binding.recommendReasonEt.filters = arrayOf(TextHelper.getFilter(45, "最多输入45个字"))
+ holder.binding.deleteIv.setOnClickListener {
+ dragListener.deleteItem(gameEntity)
+ }
+ holder.binding.dragView.setOnTouchListener { _, event ->
+ consume {
+ if (event.action == MotionEvent.ACTION_DOWN) {
+ dragListener.startDragItem(holder)
+ }
+ }
+ }
+ holder.binding.topView.setOnClickListener {
+ dragListener.setToTop(holder)
+ }
+ }
+ }
+
+ override fun getItemCount(): Int = mEntityList.size
+
+ class ChooseGamesViewHolder(val binding: ItemChooseGamesBinding) : BaseRecyclerViewHolder(binding.root)
+
+ interface ItemDragListener {
+ fun startDragItem(holder: RecyclerView.ViewHolder)
+ fun setToTop(holder: RecyclerView.ViewHolder)
+ fun deleteItem(entity: GameEntity)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt
new file mode 100644
index 0000000000..9aed0f7833
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt
@@ -0,0 +1,108 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.os.Bundle
+import android.view.View
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.goneIf
+import com.gh.common.util.viewModelProvider
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.FragmentChooseGamesBinding
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.normal.NormalFragment
+import java.util.*
+
+class ChooseGamesFragment : NormalFragment(), ChooseGamesAdapter.ItemDragListener {
+
+ private lateinit var mBinding: FragmentChooseGamesBinding
+ private lateinit var mViewModel: ChooseGamesViewModel
+ private lateinit var mAdapter: ChooseGamesAdapter
+
+ private val mItemTouchCallback = object : ItemTouchHelper.Callback() {
+ override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
+ return makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0)
+ }
+
+ override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
+ mAdapter.notifyItemMoved(viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
+ Collections.swap(mAdapter.entityList, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
+ val games = mViewModel.chooseGamesLiveData.value ?: arrayListOf()
+ Collections.swap(games, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
+ return true
+ }
+
+ override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
+
+ }
+
+ override fun canDropOver(recyclerView: RecyclerView, current: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
+ return true
+ }
+
+ override fun isLongPressDragEnabled(): Boolean {
+ return false
+ }
+
+ }
+ private val mItemTouchHelper = ItemTouchHelper(mItemTouchCallback)
+
+ override fun getLayoutId(): Int = 0
+
+ override fun getInflatedLayout(): View {
+ return FragmentChooseGamesBinding.inflate(layoutInflater, null, false).apply {
+ mBinding = this
+ }.root
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ initMenu(R.menu.menu_save)
+ mViewModel = viewModelProvider(ChooseGamesViewModel.Factory())
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mViewModel.chooseGamesLiveData.observe(viewLifecycleOwner) {
+ mBinding.addGamesTv.goneIf(it.isNotEmpty())
+ mBinding.gamesRv.goneIf(it.isEmpty())
+ mAdapter.setListData(it)
+ mBinding.gameCountTv.text = "已收录${it.size}款游戏"
+ }
+ mBinding.gamesRv.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ adapter = ChooseGamesAdapter(requireContext(), this@ChooseGamesFragment).apply {
+ mAdapter = this
+ }
+ mItemTouchHelper.attachToRecyclerView(this)
+ }
+
+ mBinding.addGamesButton.setOnClickListener {
+ requireContext().startActivity(AddGamesActivity.getIntent(requireContext()))
+ }
+
+ mBinding.addGamesTv.setOnClickListener { mBinding.addGamesButton.performClick() }
+
+ }
+
+ override fun startDragItem(holder: RecyclerView.ViewHolder) {
+ mItemTouchHelper.startDrag(holder)
+ }
+
+ override fun setToTop(holder: RecyclerView.ViewHolder) {
+ val holderPosition = holder.bindingAdapterPosition
+ for (i in holderPosition downTo 1) {
+ mAdapter.notifyItemMoved(i, i - 1)
+ Collections.swap(mAdapter.entityList, i, i - 1)
+ val games = mViewModel.chooseGamesLiveData.value ?: arrayListOf()
+ Collections.swap(games, i, i - 1)
+ }
+ }
+
+ override fun deleteItem(entity: GameEntity) {
+ val chooseGames = mViewModel.chooseGamesLiveData.value
+ chooseGames?.remove(entity)
+ mViewModel.chooseGamesLiveData.postValue(chooseGames)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt
new file mode 100644
index 0000000000..4ccdd3d248
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesRepository.kt
@@ -0,0 +1,12 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import androidx.lifecycle.MutableLiveData
+import com.gh.common.util.SingletonHolder
+import com.gh.gamecenter.entity.GameEntity
+
+class ChooseGamesRepository private constructor() {
+
+ val chooseGamesLiveData: MutableLiveData> = MutableLiveData()
+
+ companion object : SingletonHolder(::ChooseGamesRepository)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt
new file mode 100644
index 0000000000..3822a7e5d1
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesViewModel.kt
@@ -0,0 +1,21 @@
+package com.gh.gamecenter.gamecollection.choose
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.halo.assistant.HaloApp
+
+class ChooseGamesViewModel(application: Application, repository: ChooseGamesRepository) : AndroidViewModel(application) {
+
+ val chooseGamesLiveData = repository.chooseGamesLiveData
+
+ class Factory : ViewModelProvider.NewInstanceFactory() {
+ override fun create(modelClass: Class): T {
+ return ChooseGamesViewModel(
+ HaloApp.getInstance().application,
+ ChooseGamesRepository.getInstance()
+ ) as T
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt
index f80adc305c..c85d47a426 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt
@@ -11,6 +11,8 @@ import com.gh.common.util.*
import com.gh.gamecenter.CropImageActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ActivityGameCollectionEditBinding
+import com.gh.gamecenter.gamecollection.choose.ChooseGamesActivity
+import com.gh.gamecenter.gamecollection.choose.ChooseGamesViewModel
import com.gh.gamecenter.qa.editor.LocalMediaActivity
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
@@ -19,7 +21,8 @@ class GameCollectionEditActivity : ToolBarActivity() {
private lateinit var mMenuPost: MenuItem
private lateinit var mBinding: ActivityGameCollectionEditBinding
- private lateinit var mViewModel: GameCollectionViewModel
+ private lateinit var mViewModel: GameCollectionEditViewModel
+ private lateinit var mChooseGamesViewModel: ChooseGamesViewModel
override fun getLayoutId(): Int = R.layout.activity_game_collection_edit
@@ -27,6 +30,7 @@ class GameCollectionEditActivity : ToolBarActivity() {
super.onCreate(savedInstanceState)
mBinding = ActivityGameCollectionEditBinding.bind(mContentView)
mViewModel = viewModelProvider()
+ mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory())
setToolbarMenu(R.menu.menu_game_collection_edit)
mMenuPost = getMenuItem(R.id.menu_game_collection_post)
setNavigationTitle("创建游戏单")
@@ -63,6 +67,10 @@ class GameCollectionEditActivity : ToolBarActivity() {
mBinding.gameCollectionIntroduceEt.doOnTextChanged { text, start, before, count ->
mBinding.introduceSizeTv.text = "${text?.length ?: 0}/200"
}
+
+ mBinding.chooseGameContainer.setOnClickListener {
+ startActivityForResult(ChooseGamesActivity.getIntent(this), REQUEST_CHOOSE_GAMES)
+ }
}
private fun initData() {
@@ -70,7 +78,10 @@ class GameCollectionEditActivity : ToolBarActivity() {
}
private fun observeData() {
-
+ mChooseGamesViewModel.chooseGamesLiveData.observe(this) {
+ mBinding.gamesTv.text = if (it.isEmpty()) "选择游戏" else "已选 ${it.size} 款游戏"
+ mBinding.gamesTipTv.goneIf(it.isNotEmpty())
+ }
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
@@ -80,16 +91,21 @@ class GameCollectionEditActivity : ToolBarActivity() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (data == null || resultCode != Activity.RESULT_OK) return
- if (requestCode == REQUEST_CODE_IMAGE) {
- val selectedPaths = Matisse.obtainResult(data)
- if (!selectedPaths.isNullOrEmpty()) {
- val path = PathUtils.getPath(this, selectedPaths[0])
- val intent = CropImageActivity.getIntent(this, path, 142 / 328F, false, mEntrance)
- startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
+ when (requestCode) {
+ REQUEST_CODE_IMAGE -> {
+ val selectedPaths = Matisse.obtainResult(data)
+ if (!selectedPaths.isNullOrEmpty()) {
+ val path = PathUtils.getPath(this, selectedPaths[0])
+ val intent = CropImageActivity.getIntent(this, path, 142 / 328F, false, mEntrance)
+ startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
+ }
+ }
+ REQUEST_CODE_IMAGE_CROP -> {
+ val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
+ initPosterUI(imagePath)
+ }
+ REQUEST_CHOOSE_GAMES -> {
}
- } else if (requestCode == REQUEST_CODE_IMAGE_CROP) {
- val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
- initPosterUI(imagePath)
}
}
@@ -109,6 +125,7 @@ class GameCollectionEditActivity : ToolBarActivity() {
const val REQUEST_CODE_IMAGE = 100
const val REQUEST_CODE_IMAGE_CROP = 101
+ const val REQUEST_CHOOSE_GAMES = 102
@JvmStatic
fun getIntent(context: Context): Intent {
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt
similarity index 61%
rename from app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionViewModel.kt
rename to app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt
index 251c02bcf6..173e63e661 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt
@@ -3,6 +3,6 @@ package com.gh.gamecenter.gamecollection.publish
import android.app.Application
import androidx.lifecycle.AndroidViewModel
-class GameCollectionViewModel(application: Application) : AndroidViewModel(application) {
+class GameCollectionEditViewModel(application: Application) : AndroidViewModel(application) {
var imagePath = ""
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt
index 203f6982f9..17bb6bd809 100644
--- a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt
@@ -16,8 +16,8 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
-class PlayedGameViewModel(application: Application, var userId: String)
- : ListViewModel(application) {
+class PlayedGameViewModel(application: Application, var userId: String, val isKeepTagStyle: Boolean = false) :
+ ListViewModel(application) {
override fun provideDataObservable(page: Int): Observable>? {
return null
@@ -29,9 +29,11 @@ class PlayedGameViewModel(application: Application, var userId: String)
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData) {
- it.forEach { game ->
- game.hideSizeInsideDes = true
- game.tagStyle.clear()
+ if (!isKeepTagStyle) {
+ it.forEach { game ->
+ game.hideSizeInsideDes = true
+ game.tagStyle.clear()
+ }
}
mResultLiveData.postValue(it)
}
@@ -40,32 +42,32 @@ class PlayedGameViewModel(application: Application, var userId: String)
@SuppressLint("CheckResult")
fun deletePlayedGame(gameEntity: GameEntity) {
RetrofitManager.getInstance(getApplication()).api
- .deletePlayedGame(userId, gameEntity.playedGameId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : BiResponse() {
- override fun onSuccess(data: ResponseBody) {
- mListLiveData.value?.let {
- for (game in it) {
- if (gameEntity.id == game.id) {
- it.remove(game)
- mListLiveData.postValue(it)
- break
- }
+ .deletePlayedGame(userId, gameEntity.playedGameId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ mListLiveData.value?.let {
+ for (game in it) {
+ if (gameEntity.id == game.id) {
+ it.remove(game)
+ mListLiveData.postValue(it)
+ break
}
}
}
+ }
- override fun onFailure(exception: Exception) {
- super.onFailure(exception)
- Utils.toast(getApplication(), exception.localizedMessage)
- }
- })
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ Utils.toast(getApplication(), exception.localizedMessage)
+ }
+ })
}
- class Factory(private val mUserId: String) : ViewModelProvider.NewInstanceFactory() {
+ class Factory(private val mUserId: String, val isKeepTagStyle: Boolean = false) : ViewModelProvider.NewInstanceFactory() {
override fun create(modelClass: Class): T {
- return PlayedGameViewModel(HaloApp.getInstance().application, mUserId) as T
+ return PlayedGameViewModel(HaloApp.getInstance().application, mUserId, isKeepTagStyle) as T
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt
index 5eab999e09..e810967e03 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt
@@ -26,7 +26,7 @@ import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
-class UserPlayedGameFragment: ListFragment() {
+open class UserPlayedGameFragment: ListFragment() {
private var mUserId = ""
private var mAdapter: UserPlayedGameAdapter? = null
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt
index 0028f12c36..bddaa7d784 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/GameActivity.kt
@@ -2,201 +2,22 @@ package com.gh.gamecenter.qa.editor
import android.content.Context
import android.content.Intent
-import android.os.Bundle
-import android.os.Message
-import android.text.Editable
-import android.text.TextWatcher
-import android.view.View
-import android.view.inputmethod.EditorInfo
-import android.widget.EditText
-import android.widget.TextView
-import androidx.lifecycle.ViewModelProviders
-import androidx.recyclerview.widget.RecyclerView
-import com.gh.common.constant.Config
+import androidx.core.os.bundleOf
import com.gh.common.util.EntranceUtils
-import com.gh.common.view.FixLinearLayoutManager
-import com.gh.common.view.VerticalItemDecoration
-import com.gh.gamecenter.BuildConfig
-import com.gh.gamecenter.R
-import com.gh.gamecenter.baselist.ListActivity
-import com.gh.gamecenter.baselist.NormalListViewModel
-import com.gh.gamecenter.entity.GameEntity
-import com.gh.gamecenter.manager.UserManager
-import com.gh.gamecenter.qa.entity.EditorInsertDefaultEntity
-import com.gh.gamecenter.retrofit.Response
-import com.gh.gamecenter.retrofit.RetrofitManager
-import com.google.android.material.appbar.AppBarLayout
-import com.halo.assistant.HaloApp
-import com.lightgame.utils.Util_System_Keyboard
-import io.reactivex.Observable
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.schedulers.Schedulers
-import kotterknife.bindView
+import com.gh.gamecenter.NormalActivity
-class GameActivity : ListActivity>() {
+class GameActivity : NormalActivity() {
- val searchEt by bindView(R.id.search_input)
- val searchTv by bindView(R.id.search_button)
- val searchBack by bindView(R.id.search_back)
- val appBar by bindView(R.id.list_appbar)
- val noneText by bindView(R.id.reuse_tv_none_data)
- val defaultList by bindView(R.id.default_list)
- val defaultListContainer by bindView(R.id.default_list_container)
-
- private var mAdapter: GameAdapter? = null
-
- private var mSearchKey: String = ""
-
- override fun handleMessage(msg: Message) {
- if (msg.what == 1) {
- if (mSearchKey.isEmpty()) {
- clearPage()
- } else {
- search()
- }
- }
- }
-
- override fun getLayoutId(): Int {
- return R.layout.activity_editor_insert_game
- }
-
- override fun isAutomaticLoad(): Boolean {
- return false
- }
-
- override fun getItemDecoration(): RecyclerView.ItemDecoration {
- return VerticalItemDecoration(this, 8f, false)
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- val title = intent?.getStringExtra(EntranceUtils.KEY_NAVIGATION_TITLE) ?: INSERT_GAME_TITLE
- setNavigationTitle(title)
- noneText.text = "搜索结果为空"
- mListLoading.visibility = View.GONE
- mListRefresh.isEnabled = false
-// appBar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
-// val totalScrollRange = appBarLayout.totalScrollRange
-// if (totalScrollRange == -verticalOffset) {
-// Util_System_Keyboard.hideSoftKeyboard(this)
-// }
-// })
-
- searchEt.setOnEditorActionListener { _, actionId, _ ->
- if (actionId == EditorInfo.IME_ACTION_SEARCH) {
- search()
- }
- false
- }
-
- searchTv.setOnClickListener {
- search()
- Util_System_Keyboard.hideSoftKeyboard(this)
- }
- searchBack.setOnClickListener {
- searchEt.setText("")
- }
-
- searchEt.addTextChangedListener(object : TextWatcher {
- override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
- }
-
- override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
- }
-
- override fun afterTextChanged(s: Editable) {
- val newSearchKey = s.toString().trim()
- if (newSearchKey != mSearchKey) {
- mBaseHandler.removeMessages(1)
- mSearchKey = newSearchKey
- mBaseHandler.sendEmptyMessageDelayed(1, 500)
- }
- searchBack.visibility = if (newSearchKey.isNotEmpty()) View.VISIBLE
- else View.GONE
- }
- })
-
- mListRv.clearOnScrollListeners()
-
- // default open soft keyboard
- searchEt.requestFocus()
- Util_System_Keyboard.showSoftKeyboard(this, searchEt)
-
- if (title == SELECT_GAME_TITLE) initDefaultData()
- }
-
- private fun clearPage() {
- mAdapter?.setListData(ArrayList())
- mListLoading.visibility = View.GONE
- mReuseNoData.visibility = View.GONE
- mReuseNoConn.visibility = View.GONE
- mListRv.visibility = View.GONE
- }
-
- fun search() {
- if (mSearchKey.isEmpty()) {
- toast("请输入搜索关键字")
- } else {
- clearPage()
- onLoadRefresh()
- }
- }
-
- override fun provideListAdapter(): GameAdapter? {
- if (mAdapter == null) {
- mAdapter = GameAdapter(this)
- }
- return mAdapter
- }
-
- override fun provideDataObservable(page: Int): Observable>? {
- return RetrofitManager
- .getInstance(this).api
- .getSearchGame(Config.SENSITIVE_API_HOST + "games:search?keyword=" + searchEt.text + "&view=digest" + "&channel=" + HaloApp.getInstance().channel + "&version" + BuildConfig.VERSION_NAME)
- }
-
- override fun provideListViewModel(): NormalListViewModel {
- val factory = NormalListViewModel.Factory(HaloApp.getInstance().application, this)
- return ViewModelProviders.of(this, factory).get(NormalListViewModel::class.java) as NormalListViewModel
- }
-
- private fun initDefaultData() {
- RetrofitManager.getInstance(this).api
- .getEditorInsertDefaultData(UserManager.getInstance().userId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : Response>() {
- override fun onResponse(response: List?) {
- if (response == null || response.isEmpty()) return
- // init default page
- defaultList.layoutManager = FixLinearLayoutManager(baseContext)
- defaultList.adapter = GameDefaultAdapter(this@GameActivity, response)
- defaultListContainer.visibility = View.VISIBLE
- }
- })
- }
-
- override fun onLoadRefresh() {
- super.onLoadRefresh()
- mListRv.visibility = View.VISIBLE
- }
-
- override fun onLoadEmpty() {
- super.onLoadEmpty()
- mListRv.visibility = View.VISIBLE
- }
-
- override fun onLoadDone() {
- super.onLoadDone()
- mListRv.visibility = View.VISIBLE
+ override fun provideNormalIntent(): Intent {
+ return getTargetIntent(this, GameActivity::class.java, GameFragment::class.java)
}
companion object {
fun getIntent(context: Context, title: String): Intent {
- val intent = Intent(context, GameActivity::class.java)
- intent.putExtra(EntranceUtils.KEY_NAVIGATION_TITLE, title)
- return intent
+ val bundle = bundleOf(
+ EntranceUtils.KEY_NAVIGATION_TITLE to title
+ )
+ return getTargetIntent(context, GameActivity::class.java, GameFragment::class.java, bundle)
}
const val INSERT_GAME_TITLE = "插入游戏"
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt
index 332bd4e242..735ed0b950 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/GameAdapter.kt
@@ -11,7 +11,7 @@ import com.gh.gamecenter.databinding.GameItemBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.game.GameItemViewHolder
-class GameAdapter(context: Context) : ListAdapter(context) {
+open class GameAdapter(context: Context) : ListAdapter(context) {
public override fun setListData(updateData: MutableList?) {
super.setListData(updateData)
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt
new file mode 100644
index 0000000000..8fa0824cef
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/GameFragment.kt
@@ -0,0 +1,190 @@
+package com.gh.gamecenter.qa.editor
+
+import android.os.Bundle
+import android.os.Message
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.View
+import android.view.inputmethod.EditorInfo
+import android.widget.EditText
+import android.widget.TextView
+import androidx.lifecycle.ViewModelProviders
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.constant.Config
+import com.gh.common.util.EntranceUtils
+import com.gh.common.view.FixLinearLayoutManager
+import com.gh.common.view.VerticalItemDecoration
+import com.gh.gamecenter.BuildConfig
+import com.gh.gamecenter.R
+import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.baselist.NormalListViewModel
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.qa.entity.EditorInsertDefaultEntity
+import com.gh.gamecenter.retrofit.Response
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.google.android.material.appbar.AppBarLayout
+import com.halo.assistant.HaloApp
+import com.lightgame.utils.Util_System_Keyboard
+import io.reactivex.Observable
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+import kotterknife.bindView
+
+open class GameFragment : ListFragment>() {
+ val searchEt by bindView(R.id.search_input)
+ val searchTv by bindView(R.id.search_button)
+ val searchBack by bindView(R.id.search_back)
+ val appBar by bindView(R.id.list_appbar)
+ val noneText by bindView(R.id.reuse_tv_none_data)
+ val defaultList by bindView(R.id.default_list)
+ val defaultListContainer by bindView(R.id.default_list_container)
+
+ protected var mAdapter: GameAdapter? = null
+
+ private var mSearchKey: String = ""
+
+ override fun handleMessage(msg: Message) {
+ if (msg.what == 1) {
+ if (mSearchKey.isEmpty()) {
+ clearPage()
+ } else {
+ search()
+ }
+ }
+ }
+
+ override fun getLayoutId(): Int {
+ return R.layout.activity_editor_insert_game
+ }
+
+ override fun isAutomaticLoad(): Boolean {
+ return false
+ }
+
+ override fun getItemDecoration(): RecyclerView.ItemDecoration? {
+ return VerticalItemDecoration(requireContext(), 8f, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val title = arguments?.getString(EntranceUtils.KEY_NAVIGATION_TITLE) ?: ""
+ if (title.isNotEmpty()) {
+ setNavigationTitle(title)
+ }
+ noneText.text = "搜索结果为空"
+ mListLoading?.visibility = View.GONE
+ mListRefresh?.isEnabled = false
+
+ searchEt.setOnEditorActionListener { _, actionId, _ ->
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ search()
+ }
+ false
+ }
+
+ searchTv.setOnClickListener {
+ search()
+ Util_System_Keyboard.hideSoftKeyboard(requireActivity())
+ }
+ searchBack.setOnClickListener {
+ searchEt.setText("")
+ }
+
+ searchEt.addTextChangedListener(object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
+ }
+
+ override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
+ }
+
+ override fun afterTextChanged(s: Editable) {
+ val newSearchKey = s.toString().trim()
+ if (newSearchKey != mSearchKey) {
+ mBaseHandler.removeMessages(1)
+ mSearchKey = newSearchKey
+ mBaseHandler.sendEmptyMessageDelayed(1, 500)
+ }
+ searchBack.visibility = if (newSearchKey.isNotEmpty()) View.VISIBLE else View.GONE
+ }
+ })
+
+ mListRv.clearOnScrollListeners()
+
+ // default open soft keyboard
+ if (isAutoShowKeyboard()) {
+ searchEt.requestFocus()
+ }
+ Util_System_Keyboard.showSoftKeyboard(requireActivity(), searchEt)
+
+ if (title == GameActivity.SELECT_GAME_TITLE) initDefaultData()
+ }
+
+ private fun clearPage() {
+ mAdapter?.setListData(ArrayList())
+ mListLoading?.visibility = View.GONE
+ mReuseNoData?.visibility = View.GONE
+ mReuseNoConn?.visibility = View.GONE
+ mListRv.visibility = View.GONE
+ }
+
+ fun search() {
+ if (mSearchKey.isEmpty()) {
+ toast("请输入搜索关键字")
+ } else {
+ clearPage()
+ onLoadRefresh()
+ }
+ }
+
+ override fun provideListAdapter(): GameAdapter? {
+ if (mAdapter == null) {
+ mAdapter = GameAdapter(requireContext())
+ }
+ return mAdapter
+ }
+
+ override fun provideDataObservable(page: Int): Observable>? {
+ return RetrofitManager
+ .getInstance(requireContext()).api
+ .getSearchGame(Config.SENSITIVE_API_HOST + "games:search?keyword=" + searchEt.text + "&view=digest" + "&channel=" + HaloApp.getInstance().channel + "&version" + BuildConfig.VERSION_NAME)
+ }
+
+ override fun provideListViewModel(): NormalListViewModel {
+ val factory = NormalListViewModel.Factory(HaloApp.getInstance().application, this)
+ return ViewModelProviders.of(this, factory).get(NormalListViewModel::class.java) as NormalListViewModel
+ }
+
+ private fun initDefaultData() {
+ RetrofitManager.getInstance(requireContext()).api
+ .getEditorInsertDefaultData(UserManager.getInstance().userId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Response>() {
+ override fun onResponse(response: List?) {
+ if (response == null || response.isEmpty()) return
+ // init default page
+ defaultList.layoutManager = FixLinearLayoutManager(requireContext())
+ defaultList.adapter = GameDefaultAdapter(requireContext(), response)
+ defaultListContainer.visibility = View.VISIBLE
+ }
+ })
+ }
+
+ override fun onLoadRefresh() {
+ super.onLoadRefresh()
+ mListRv.visibility = View.VISIBLE
+ }
+
+ override fun onLoadEmpty() {
+ super.onLoadEmpty()
+ mListRv.visibility = View.VISIBLE
+ }
+
+ override fun onLoadDone() {
+ super.onLoadDone()
+ mListRv.visibility = View.VISIBLE
+ }
+
+ open fun isAutoShowKeyboard(): Boolean = true
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_choose_games_drag.png b/app/src/main/res/drawable-xxxhdpi/ic_choose_games_drag.png
new file mode 100644
index 0000000000000000000000000000000000000000..c0caeb6fb2c1748dc54b618f2a2f233c5f852e12
GIT binary patch
literal 473
zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdl8)jKx9jP7LeL$-D$|Tv8)E(|mmy
zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-euz(rC1}QXr;NuTe=IrU>7*fIb
z_KqQ6lY;le3Gj9A78m@mhaR
zu*&YHGl>-ee$MAtPAy(JKUZ_YwRrzHm0h!ZwmcVjkQE}9p~5obTMMh*@74E>ZWU+n
z`$%Wq68`sA;O8srH>U+5w!y7MX8e$5+-!I`I@c^M%V>3yS(;e5T8^0-^XHeFZqDdg
zadQTb&jK4crN%WJNX|yq4>7u%dq(d}p?>@9U-xHd`YlN^Q(F{rYDTXnXKlva93Qqz
pK&%!Z$3M{_tOe+8sQ$)smU-FBo15M9Z})?O)zj6_Wt~$(69A4IlMVm?
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_choose_games_top.png b/app/src/main/res/drawable-xxxhdpi/ic_choose_games_top.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b68501e04cfc980c210bc3f719cc3ae7712222d
GIT binary patch
literal 1491
zcmbtU`#aMM82`?eHqzN#%1BL|kwiGunuOdI8wp1`PD~7QNkgk>bDz6XJ*2TB%-zf_
zj@uch;*5@-+~cgYbT*egagglH51sP|ocDP?@8`XIp67kvU*2>#f}@gxh5`TpN;oGw
zcNx3w04gu@IS5Iuj6f83M_Ztde_%nD*adpyg7A32Ko&y*P+AB8*^$VgAp-z_Ss(x`
zW6(~GCHHUFjRpQM-VvJ2xwrzruG2U>8xJZ-{0JMYW}}))$uH7}ozp-x!i!XU3ECQ(
zYIZzFWZX}X7m9I-c<%A_VE2nqg&T-F`snaDR^q~Ix>tsuMl)Qk$j|9G8ok|J<9{(I
zmb4@i&G4EUre_Mxgj>Q63TZ8j$1%ku)8TMATWcs3q>X~e5(XYcG9^-}ZJ|V>;ALN5
zpUHT=8L}xkyzBk7_NnIPW+onw?|veA?ucxdO&aqjcI*jz+su+jSV54Yoqrlp8L3#j~1`F0HVc3
zs}!Ci5bUW63a^rWPu
z>WYerG*DzN{xE&L?b)+uY&ZR_hLsDV@w)(z(19RN#53xQy{LZE9TJJ;>-gg{kV)oj
zd6zs99L%fHJR5}T)hWBVSr#ee$${K=F;b*Z<@i(z-a1XX#+0J3){0AAH-oZz)GJ!q
zfE^K|8w)F(?rlG;TdMa_vB+Ljn!U(c!e;dsoGR6wV(vz&t9xUxSS&qxZwl=1rAnZI
z#R-p$94=g(UcO$>;Yd#Alo(vbHDj0whJ!%l4|@(O&+9y&XlZH5N9XErA0PXT8gSoG
zJ-?A{6O!jvYDVwkgjExc0xkkeMq!LEsgx{K&w2VCQwbH(zrfw1$c>a4o)whjO~+c^
zw0sR>gbKYkS;ov`o6HBabTFiI)CpZ>sCo7er2_lN==7qN(cSUA#kmeI!SIWRbEuQ|
zEcz|b@_Ct9$XmMigCI5S#MG*)s#x6(pNy`LDkf>sQS9`|$~!(Wu~Abhpy!-D=3+23
zt16_P2tFwylFD2+<>}S_aG8RQ8RBz?HBf^bHk-X4zRzovKS%QF8Lm|+dFiNnq1Qk5
zv$$WsC&Gc`T>IKZd`fdP_9%TFWA`A?=@XXkTc8!kAk6z24qOrC(bMnI>}9)`uA_AZ
zO?6+Ocp3s$cAqL9jLpR3C
z*S9Wh-@x?O4G}>Hw6uN?m}yg_G8MEl@$jMj%rECwb0W?|jVcp-DqqYV>_r{8b(#f
zjYt$#>2f1?>GM|$6aE)3*YJCcGdexO6`G=pOkr>uu~Uo33RRrEC$M_cosDz$o0GDS
o=vcNqRl6+s_O!lzu(^VsLjlefKe`$HIt0iJXHT%Jv-L~-2cl}K$N&HU
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_add_games.webp b/app/src/main/res/drawable-xxxhdpi/icon_add_games.webp
new file mode 100644
index 0000000000000000000000000000000000000000..fc412c8bbabb2c3440332bbbbe3d928bf6ed62de
GIT binary patch
literal 3594
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
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_editor_insert_game.xml b/app/src/main/res/layout/activity_editor_insert_game.xml
index 1ed9c790e8..2278b66dfa 100644
--- a/app/src/main/res/layout/activity_editor_insert_game.xml
+++ b/app/src/main/res/layout/activity_editor_insert_game.xml
@@ -5,8 +5,6 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
-
@@ -32,7 +30,6 @@
@@ -104,6 +103,7 @@
android:textColor="@color/text_333333" />
@@ -154,6 +152,7 @@
android:textColor="@color/text_333333" />
diff --git a/app/src/main/res/layout/fragment_add_user_played_game.xml b/app/src/main/res/layout/fragment_add_user_played_game.xml
new file mode 100644
index 0000000000..f53ddaef94
--- /dev/null
+++ b/app/src/main/res/layout/fragment_add_user_played_game.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_choose_games.xml b/app/src/main/res/layout/fragment_choose_games.xml
new file mode 100644
index 0000000000..a51dacfd0e
--- /dev/null
+++ b/app/src/main/res/layout/fragment_choose_games.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_search_game.xml b/app/src/main/res/layout/fragment_search_game.xml
new file mode 100644
index 0000000000..462a6ea270
--- /dev/null
+++ b/app/src/main/res/layout/fragment_search_game.xml
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_choose_games.xml b/app/src/main/res/layout/item_choose_games.xml
new file mode 100644
index 0000000000..3cd59056e4
--- /dev/null
+++ b/app/src/main/res/layout/item_choose_games.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_menu_save.xml b/app/src/main/res/layout/layout_menu_save.xml
new file mode 100644
index 0000000000..e49260fb44
--- /dev/null
+++ b/app/src/main/res/layout/layout_menu_save.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/menu_save.xml b/app/src/main/res/menu/menu_save.xml
new file mode 100644
index 0000000000..5f934c0ac6
--- /dev/null
+++ b/app/src/main/res/menu/menu_save.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
From 9a1266d9d9b9a4cc7b562d239ed48cd573fc8e59 Mon Sep 17 00:00:00 2001
From: leafwai
Date: Mon, 8 Nov 2021 09:24:26 +0800
Subject: [PATCH 05/49] =?UTF-8?q?=E3=80=90=E5=85=89=E7=8E=AF=E5=8A=A9?=
=?UTF-8?q?=E6=89=8BV5.5.0=E3=80=91=E6=B8=B8=E6=88=8F=E5=8D=95=E5=B9=BF?=
=?UTF-8?q?=E5=9C=BA(=E9=80=89=E6=8B=A9=E6=A0=87=E7=AD=BEUI=EF=BC=89https:?=
=?UTF-8?q?//git.ghzs.com/pm/halo-app-issues/-/issues/1598?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../square/GameCollectionTagAdapter.kt | 147 ++++++++++++++++++
1 file changed, 147 insertions(+)
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionTagAdapter.kt
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionTagAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionTagAdapter.kt
new file mode 100644
index 0000000000..65b9c8a3e0
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/square/GameCollectionTagAdapter.kt
@@ -0,0 +1,147 @@
+package com.gh.gamecenter.gamecollection.square
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.DisplayUtils
+import com.gh.common.util.dip2px
+import com.gh.gamecenter.databinding.*
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class GameCollectionTagAdapter(
+ context: Context,
+ val singleChoice: Boolean = true,
+ val data: ArrayList,
+ private val updateCallback: (() -> Unit)
+) :
+ BaseRecyclerAdapter(context) {
+
+ private var mTagViewList = arrayListOf()
+ var singleTagName = ""
+ var multipleTagList = arrayListOf()
+
+
+ override fun getItemViewType(position: Int): Int {
+ return if (singleChoice) {
+ if (position % 2 == 0) TAG_HEADER else TAG_BODY
+ } else {
+ if (position == 0) SELECTED_TAGS else if (position % 2 != 0) TAG_HEADER else TAG_BODY
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType){
+ SELECTED_TAGS -> GameCollectionSelectedTagViewHolder(
+ GameCollectionSelectedTagItemBinding.inflate(mLayoutInflater, parent, false)
+ )
+ TAG_HEADER -> GameCollectionTagHeaderViewHolder(
+ GameCollectionTagHeaderItemBinding.inflate(mLayoutInflater, parent, false)
+ )
+ else -> GameCollectionTagBodyViewHolder(
+ GameCollectionTagBodyItemBinding.inflate(mLayoutInflater, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is GameCollectionSelectedTagViewHolder -> {
+ holder.binding.selectedTagFlexbox.removeAllViews()
+ holder.binding.hintTv.visibility = if (multipleTagList.size == 0) View.VISIBLE else View.GONE
+ for (name in multipleTagList) {
+ val selectedTagView =
+ ItemGameCollectionSelectedTagBinding.inflate(mLayoutInflater)
+ .apply {
+ tagTv.text = name
+ root.setOnClickListener {
+ multipleTagList.remove(name)
+ updateCallback.invoke()
+ notifyDataSetChanged()
+ }
+ }.root
+ holder.binding.selectedTagFlexbox.addView(selectedTagView)
+ }
+ }
+ is GameCollectionTagHeaderViewHolder -> {
+ holder.binding.headerTv.text = data[position]
+ if (position == 0) {
+ holder.binding.root.setPadding(
+ 16F.dip2px(),
+ 40F.dip2px(),
+ 16F.dip2px(),
+ 10F.dip2px()
+ )
+ }
+ }
+ is GameCollectionTagBodyViewHolder -> {
+ val dataList = arrayListOf(
+ "ghgg",
+ "das5555554a44",
+ "dasda54544",
+ "dsdasdasdas",
+ "dasdsa8787",
+ "58748sss"
+ )
+ holder.binding.tagFlexbox.removeAllViews()
+ for (name in dataList) {
+ val tag = if(singleChoice) getSingleTag(name) else getMultipleTag(name)
+ mTagViewList.add(tag)
+ holder.binding.tagFlexbox.addView(tag.root)
+ }
+ if (position == data.size - 1) {
+ holder.binding.root.setPadding(
+ 12F.dip2px(),
+ 5F.dip2px(),
+ 12F.dip2px(),
+ 97F.dip2px()
+ )
+ }
+ }
+ }
+ }
+
+ private fun getSingleTag(name: String) = ItemGameCollectionTagBinding.inflate(mLayoutInflater).apply {
+ tagTv.text = name
+ tagTv.layoutParams = tagTv.layoutParams.apply { width = (DisplayUtils.getScreenWidth() - 56F.dip2px()) / 4 }
+ root.setOnClickListener {
+ for (tag in mTagViewList) {
+ if (tag.tagTv != tagTv) tag.tagTv.isChecked = false
+ }
+ tagTv.isChecked = !tagTv.isChecked
+ if (tagTv.isChecked) singleTagName = tagTv.text.toString()
+ }
+ }
+
+ private fun getMultipleTag(name: String) =
+ ItemGameCollectionTagBinding.inflate(mLayoutInflater).apply {
+ tagTv.layoutParams = tagTv.layoutParams.apply { width = (DisplayUtils.getScreenWidth() - 56F.dip2px()) / 4 }
+ tagTv.text = name
+ if (multipleTagList.contains(name)) tagTv.isChecked = true
+ root.setOnClickListener {
+ tagTv.isChecked = !tagTv.isChecked
+ if (tagTv.isChecked) {
+ multipleTagList.add(name)
+ } else {
+ if (multipleTagList.contains(name)) multipleTagList.remove(name)
+ }
+ updateCallback.invoke()
+ notifyItemChanged(0)
+ }
+ }
+
+ override fun getItemCount() = data.size
+
+ class GameCollectionSelectedTagViewHolder(var binding: GameCollectionSelectedTagItemBinding) :
+ RecyclerView.ViewHolder(binding.root)
+
+ class GameCollectionTagBodyViewHolder(var binding: GameCollectionTagBodyItemBinding) :
+ RecyclerView.ViewHolder(binding.root)
+
+ class GameCollectionTagHeaderViewHolder(var binding: GameCollectionTagHeaderItemBinding) :
+ RecyclerView.ViewHolder(binding.root)
+
+ companion object {
+ const val SELECTED_TAGS = 100
+ const val TAG_HEADER = 101
+ const val TAG_BODY = 102
+ }
+}
\ No newline at end of file
From 42a4210290a92cb76da4acd02582619f365da6a2 Mon Sep 17 00:00:00 2001
From: leafwai
Date: Mon, 8 Nov 2021 09:40:57 +0800
Subject: [PATCH 06/49] =?UTF-8?q?=E3=80=90=E5=85=89=E7=8E=AF=E5=8A=A9?=
=?UTF-8?q?=E6=89=8BV5.5.0=E3=80=91=E6=B8=B8=E6=88=8F=E5=8D=95=E5=B9=BF?=
=?UTF-8?q?=E5=9C=BA(=E9=80=89=E6=8B=A9=E6=A0=87=E7=AD=BEUI=EF=BC=89https:?=
=?UTF-8?q?//git.ghzs.com/pm/halo-app-issues/-/issues/1598?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/src/main/AndroidManifest.xml | 6 +++---
.../square/GameCollectionTagSelectFragment.kt | 14 +++++++-------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index efa5a42661..5b57a4965c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -738,9 +738,9 @@
android:name=".gamecollection.choose.AddGamesActivity"
android:screenOrientation="portrait" />
-
+
+
+
Date: Mon, 8 Nov 2021 18:12:53 +0800
Subject: [PATCH 07/49] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=8E=AF=E5=A2=83api?=
=?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8D=87=E7=BA=A7=E4=B8=BAv5d5d0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
gradle.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gradle.properties b/gradle.properties
index 620ce711ce..c80a20c77a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -65,7 +65,7 @@ QUICK_LOGIN_APPID=300012035775
QUICK_LOGIN_APPKEY=002BAABA2C078342DA33BEAB0A4C6A25
# hosts
-DEV_API_HOST=https\://dev-and-api.ghzs.com/v5d4d0/
+DEV_API_HOST=https\://dev-and-api.ghzs.com/v5d5d0/
API_HOST=https\://and-api.ghzs.com/v5d4d0/
SENSITIVE_API_HOST=https\://and-api.ghzs.com/v5d4d0/
From 831ca71a5843bcc765fa43a96f7b367ffdae5a79 Mon Sep 17 00:00:00 2001
From: jack <1484288157@qq.com>
Date: Wed, 10 Nov 2021 16:52:01 +0800
Subject: [PATCH 08/49] =?UTF-8?q?=E3=80=90=E5=85=89=E7=8E=AF=E5=8A=A9?=
=?UTF-8?q?=E6=89=8BV5.5.0=E3=80=91=E5=88=9B=E5=BB=BA/=E7=BC=96=E8=BE=91?=
=?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=8D=95=20https://git.ghzs.com/pm/halo-app-?=
=?UTF-8?q?issues/-/issues/1604?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/src/main/AndroidManifest.xml | 4 +
.../com/gh/gamecenter/entity/GameEntity.kt | 35 ++-
.../entity/GamesCollectionEntity.kt | 43 ++++
.../MyGameCollectionActivity.kt | 18 ++
.../gamecollection/MyGameCollectionAdapter.kt | 57 +++++
.../MyGameCollectionFragment.kt | 57 +++++
.../MyGameCollectionViewModel.kt | 21 ++
.../choose/AddSearchGameFragment.kt | 2 +-
.../choose/ChooseGamesAdapter.kt | 9 +
.../choose/ChooseGamesFragment.kt | 26 +++
.../publish/GameCollectionEditActivity.kt | 212 ++++++++++++++++--
.../publish/GameCollectionEditViewModel.kt | 119 ++++++++++
.../personal/PersonalFunctionAdapter.kt | 12 +-
.../gamecenter/personal/PersonalViewModel.kt | 3 +-
.../gh/gamecenter/qa/entity/ArticleEntity.kt | 108 ++++-----
.../retrofit/service/ApiService.java | 24 ++
.../com/gh/gamecenter/room/AppDatabase.java | 21 +-
.../room/converter/SimpleGameListConverter.kt | 20 ++
.../room/dao/GameCollectionDraftDao.kt | 21 ++
.../drawable-xxxhdpi/ic_choose_game_del.webp | Bin 0 -> 1202 bytes
.../ic_game_collection_del.webp | Bin 0 -> 782 bytes
.../ic_game_collection_draft.webp | Bin 0 -> 1726 bytes
.../ic_game_collection_edit.webp | Bin 0 -> 972 bytes
.../ic_game_collection_fail.webp | Bin 0 -> 3394 bytes
.../ic_game_collection_pending.webp | Bin 0 -> 3208 bytes
.../ic_game_collection_private.webp | Bin 0 -> 2444 bytes
.../ic_game_collection_publish.webp | Bin 0 -> 744 bytes
.../ic_menu_game_collection_square.webp | Bin 0 -> 2176 bytes
.../drawable/bg_my_game_collection_btn.xml | 8 +
.../layout/activity_game_collection_edit.xml | 6 +-
.../fragment_my_game_collection_list.xml | 97 ++++++++
app/src/main/res/layout/item_choose_games.xml | 2 +-
.../res/layout/item_my_game_collection.xml | 143 ++++++++++++
.../main/res/menu/menu_my_game_collection.xml | 11 +
34 files changed, 998 insertions(+), 81 deletions(-)
create mode 100644 app/src/main/java/com/gh/gamecenter/entity/GamesCollectionEntity.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionActivity.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionAdapter.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionFragment.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionViewModel.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/room/converter/SimpleGameListConverter.kt
create mode 100644 app/src/main/java/com/gh/gamecenter/room/dao/GameCollectionDraftDao.kt
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_choose_game_del.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_del.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_draft.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_edit.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_fail.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_pending.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_private.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_game_collection_publish.webp
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_menu_game_collection_square.webp
create mode 100644 app/src/main/res/drawable/bg_my_game_collection_btn.xml
create mode 100644 app/src/main/res/layout/fragment_my_game_collection_list.xml
create mode 100644 app/src/main/res/layout/item_my_game_collection.xml
create mode 100644 app/src/main/res/menu/menu_my_game_collection.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5b57a4965c..d7c76517d5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -738,6 +738,10 @@
android:name=".gamecollection.choose.AddGamesActivity"
android:screenOrientation="portrait" />
+
+
diff --git a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt
index d9ef421c6f..eaed9e11ed 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/GameEntity.kt
@@ -252,6 +252,13 @@ data class GameEntity(
@SerializedName("bbs_id")
var bbsId: String = "",
+ //游戏单推荐分数
+ @SerializedName("recommend_star")
+ var recommendStar: Int = 5,
+ //游戏单推荐理由
+ @SerializedName("recommend_text")
+ var recommendText: String = "",
+
// 本地字段,使用镜像信息
var useMirrorInfo: Boolean = false,
// 本地字段,曝光用
@@ -549,6 +556,20 @@ data class GameEntity(
&& (useMirrorInfo || RegionSettingHelper.shouldThisGameDisplayMirrorInfo(id)))
}
+ fun toSimpleGame(): SimpleGame {
+ val simpleGame = SimpleGame()
+ simpleGame.id = id
+ simpleGame.mName = mName
+ simpleGame.nameSuffix = nameSuffix
+ simpleGame.mIcon = mIcon
+ simpleGame.mRawIcon = mRawIcon
+ simpleGame.active=active
+ simpleGame.iconSubscript=iconSubscript
+ simpleGame.recommendStar=recommendStar
+ simpleGame.recommendText=recommendText
+ return simpleGame
+ }
+
fun clone(): GameEntity {
val gameEntity = GameEntity()
gameEntity.id = id
@@ -762,12 +783,18 @@ data class SimpleGame(
@SerializedName("name_suffix")
var nameSuffix: String? = null,
@SerializedName("icon")
- private var mIcon: String? = null,
+ var mIcon: String? = null,
@SerializedName("ori_icon")
- private var mRawIcon: String? = null,
+ var mRawIcon: String? = null,
@SerializedName("icon_subscript")
var iconSubscript: String? = null,
- var active: Boolean = false
+ var active: Boolean = false,
+ //游戏单推荐分数
+ @SerializedName("recommend_star")
+ var recommendStar: Int = 5,
+ //游戏单推荐理由
+ @SerializedName("recommend_text")
+ var recommendText: String = "",
) : Parcelable {
@IgnoredOnParcel
@@ -788,6 +815,8 @@ data class SimpleGame(
gameEntity.icon = mIcon
gameEntity.rawIcon = mRawIcon
gameEntity.iconSubscript = iconSubscript
+ gameEntity.recommendStar = recommendStar
+ gameEntity.recommendText = recommendText
return gameEntity
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/entity/GamesCollectionEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/GamesCollectionEntity.kt
new file mode 100644
index 0000000000..2d2e7d4749
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/GamesCollectionEntity.kt
@@ -0,0 +1,43 @@
+package com.gh.gamecenter.entity
+
+import android.os.Parcelable
+import androidx.room.Entity
+import androidx.room.Ignore
+import androidx.room.PrimaryKey
+import androidx.room.TypeConverters
+import com.gh.gamecenter.qa.entity.Count
+import com.gh.gamecenter.qa.entity.TimeEntity
+import com.gh.gamecenter.room.converter.ListStringConverter
+import com.gh.gamecenter.room.converter.SimpleGameListConverter
+import com.google.gson.annotations.SerializedName
+import kotlinx.android.parcel.Parcelize
+
+@Entity(tableName = "GameCollectionDraft")
+@Parcelize
+class GamesCollectionEntity(
+ @Ignore
+ @SerializedName("_id")
+ var id: String = "",
+ @PrimaryKey
+ var primaryKey: String = "", // db key
+ @TypeConverters(ListStringConverter::class)
+ var tags: ArrayList? = null,
+ @TypeConverters(SimpleGameListConverter::class)
+ var games: ArrayList? = null,
+ var title: String = "",
+ var intro: String = "",
+ var cover: String = "",
+ var display: String = "",//self_only: 仅自己可见
+ @Ignore
+ var time: TimeEntity? = null,
+ @Ignore
+ var stamp: String = "",//special_choice: 精选 offical: 官方
+ @Ignore
+ var count: Count? = null,
+ @Ignore
+ var status: String = "",// draft/pending/pass/failed
+ @Ignore
+ var user: User? = null,
+ @Ignore
+ var me: MeEntity? = null,
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionActivity.kt
new file mode 100644
index 0000000000..f894d8df15
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionActivity.kt
@@ -0,0 +1,18 @@
+package com.gh.gamecenter.gamecollection
+
+import android.content.Context
+import android.content.Intent
+import com.gh.gamecenter.NormalActivity
+
+class MyGameCollectionActivity : NormalActivity() {
+
+ override fun provideNormalIntent(): Intent {
+ return getTargetIntent(this, MyGameCollectionActivity::class.java, MyGameCollectionFragment::class.java)
+ }
+
+ companion object {
+ fun getIntent(context: Context): Intent {
+ return getTargetIntent(context, MyGameCollectionActivity::class.java, MyGameCollectionFragment::class.java)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionAdapter.kt
new file mode 100644
index 0000000000..2fee46c81a
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionAdapter.kt
@@ -0,0 +1,57 @@
+package com.gh.gamecenter.gamecollection
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.constant.ItemViewType
+import com.gh.common.util.DisplayUtils
+import com.gh.common.util.toBinding
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.databinding.ItemMyGameCollectionBinding
+import com.gh.gamecenter.entity.GamesCollectionEntity
+
+class MyGameCollectionAdapter(context: Context) : ListAdapter(context) {
+
+ override fun getItemViewType(position: Int): Int {
+ return if (position == itemCount - 1) {
+ ItemViewType.ITEM_FOOTER
+ } else {
+ ItemViewType.ITEM_BODY
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ ItemViewType.ITEM_BODY -> MyGameCollectionViewHolder(parent.toBinding())
+ ItemViewType.ITEM_FOOTER -> FooterViewHolder(parent.toBinding())
+ else -> MyGameCollectionViewHolder(parent.toBinding())
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is MyGameCollectionViewHolder -> {
+
+ }
+ is FooterViewHolder -> {
+ holder.initItemPadding()
+ holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver)
+ holder.hint.setTextColor(ContextCompat.getColor(mContext, R.color.aaaaaa))
+ val lp = holder.itemView.layoutParams as RecyclerView.LayoutParams
+ lp.height = DisplayUtils.dip2px(48F)
+ lp.width = ViewGroup.LayoutParams.MATCH_PARENT
+ holder.itemView.layoutParams = lp
+ }
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
+ }
+
+ class MyGameCollectionViewHolder(val binding: ItemMyGameCollectionBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionFragment.kt
new file mode 100644
index 0000000000..828d06eb37
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionFragment.kt
@@ -0,0 +1,57 @@
+package com.gh.gamecenter.gamecollection
+
+import android.os.Bundle
+import android.view.MenuItem
+import android.view.View
+import com.gh.common.util.showRegulationTestDialogIfNeeded
+import com.gh.gamecenter.R
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.databinding.FragmentMyGameCollectionListBinding
+import com.gh.gamecenter.entity.GamesCollectionEntity
+import com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity
+
+class MyGameCollectionFragment : ListFragment() {
+
+ private var mAdapter: MyGameCollectionAdapter? = null
+ private lateinit var mBinding: FragmentMyGameCollectionListBinding
+
+ override fun getLayoutId(): Int = R.layout.fragment_my_game_collection_list
+
+ override fun getInflatedLayout(): View {
+ return FragmentMyGameCollectionListBinding.inflate(layoutInflater, null, false).apply {
+ mBinding = this
+ }.root
+ }
+
+ override fun onMenuItemClick(menuItem: MenuItem?) {
+ super.onMenuItemClick(menuItem)
+ menuItem?.run {
+ if (itemId == R.id.menu_game_collection_square) {
+
+ }
+ }
+ }
+
+ override fun provideListAdapter(): ListAdapter<*> {
+ return mAdapter ?: MyGameCollectionAdapter(requireContext()).apply {
+ mAdapter = this
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setNavigationTitle("我的游戏单")
+ initMenu(R.menu.menu_my_game_collection)
+
+ mBinding.createBtn.setOnClickListener {
+ showRegulationTestDialogIfNeeded {
+ startActivity(GameCollectionEditActivity.getIntent(requireContext()))
+ }
+ }
+
+ mBinding.reuseNoneDataIv.setOnClickListener {
+ mBinding.createBtn.performClick()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionViewModel.kt
new file mode 100644
index 0000000000..46bc427ca0
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/MyGameCollectionViewModel.kt
@@ -0,0 +1,21 @@
+package com.gh.gamecenter.gamecollection
+
+import android.app.Application
+import com.gh.gamecenter.baselist.ListViewModel
+import com.gh.gamecenter.entity.GamesCollectionEntity
+import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import io.reactivex.Observable
+
+class MyGameCollectionViewModel(application: Application) : ListViewModel(application) {
+
+ override fun provideDataObservable(page: Int): Observable>? {
+ return RetrofitManager.getInstance(HaloApp.getInstance()).api
+ .getGameCollectionList(UserManager.getInstance().userId)
+ }
+
+ override fun mergeResultLiveData() {
+ mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt
index ab0a01cb9c..7f166d03bb 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/AddSearchGameFragment.kt
@@ -21,7 +21,7 @@ class AddSearchGameFragment : GameFragment() {
override fun getLayoutId(): Int = 0
override fun getInflatedLayout(): View {
- return FragmentSearchGameBinding.bind(layoutInflater.inflate(R.layout.fragment_search_game, null, false)).apply {
+ return FragmentSearchGameBinding.inflate(layoutInflater, null, false).apply {
mBinding = this
}.root
}
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt
index 3fcf57c08e..5786168d44 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesAdapter.kt
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.view.MotionEvent
import android.view.ViewGroup
+import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.util.TextHelper
@@ -40,7 +41,15 @@ class ChooseGamesAdapter(context: Context, val dragListener: ItemDragListener) :
val gameEntity = mEntityList[position]
holder.binding.gameNameTv.text = gameEntity.name
holder.binding.gameIcon.displayGameIcon(gameEntity)
+ holder.binding.recommendReasonEt.setText(gameEntity.recommendText)
+ holder.binding.ratingScore.rating = gameEntity.recommendStar.toFloat()
holder.binding.recommendReasonEt.filters = arrayOf(TextHelper.getFilter(45, "最多输入45个字"))
+ holder.binding.recommendReasonEt.doOnTextChanged { text, _, _, _ ->
+ gameEntity.recommendText = text.toString()
+ }
+ holder.binding.ratingScore.setOnRatingChangeListener { _, rating ->
+ gameEntity.recommendStar = rating.toInt()
+ }
holder.binding.deleteIv.setOnClickListener {
dragListener.deleteItem(gameEntity)
}
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt
index 9aed0f7833..d987182fe3 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/choose/ChooseGamesFragment.kt
@@ -1,16 +1,19 @@
package com.gh.gamecenter.gamecollection.choose
import android.os.Bundle
+import android.view.MenuItem
import android.view.View
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.DialogHelper
import com.gh.common.util.goneIf
import com.gh.common.util.viewModelProvider
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.FragmentChooseGamesBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.normal.NormalFragment
+import java.lang.ref.WeakReference
import java.util.*
class ChooseGamesFragment : NormalFragment(), ChooseGamesAdapter.ItemDragListener {
@@ -61,6 +64,15 @@ class ChooseGamesFragment : NormalFragment(), ChooseGamesAdapter.ItemDragListene
mViewModel = viewModelProvider(ChooseGamesViewModel.Factory())
}
+ override fun onMenuItemClick(menuItem: MenuItem?) {
+ super.onMenuItemClick(menuItem)
+ menuItem?.run {
+ if (itemId == R.id.layout_menu_save) {
+ requireActivity().finish()
+ }
+ }
+ }
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mViewModel.chooseGamesLiveData.observe(viewLifecycleOwner) {
@@ -105,4 +117,18 @@ class ChooseGamesFragment : NormalFragment(), ChooseGamesAdapter.ItemDragListene
mViewModel.chooseGamesLiveData.postValue(chooseGames)
}
+ override fun onBackPressed(): Boolean {
+ val games = mViewModel.chooseGamesLiveData.value ?: arrayListOf()
+ if (games.isNotEmpty()) {
+ DialogHelper.showDialog(requireContext(), "提示", "是否保存本次选择的游戏", "保存", "取消", {
+ requireActivity().finish()
+ }, {
+ mViewModel.chooseGamesLiveData.postValue(arrayListOf())
+ requireActivity().finish()
+ }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
+ return true
+ }
+ return super.onBackPressed()
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt
index c85d47a426..bbcf2d5f20 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditActivity.kt
@@ -7,12 +7,17 @@ import android.os.Bundle
import android.view.MenuItem
import androidx.core.widget.doOnTextChanged
import com.gh.base.ToolBarActivity
+import com.gh.base.fragment.WaitingDialogFragment
import com.gh.common.util.*
import com.gh.gamecenter.CropImageActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ActivityGameCollectionEditBinding
+import com.gh.gamecenter.entity.GamesCollectionEntity
+import com.gh.gamecenter.entity.SimpleGame
import com.gh.gamecenter.gamecollection.choose.ChooseGamesActivity
import com.gh.gamecenter.gamecollection.choose.ChooseGamesViewModel
+import com.gh.gamecenter.gamecollection.square.GameCollectionTagSelectActivity
+import com.gh.gamecenter.mvvm.Status
import com.gh.gamecenter.qa.editor.LocalMediaActivity
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
@@ -23,6 +28,7 @@ class GameCollectionEditActivity : ToolBarActivity() {
private lateinit var mBinding: ActivityGameCollectionEditBinding
private lateinit var mViewModel: GameCollectionEditViewModel
private lateinit var mChooseGamesViewModel: ChooseGamesViewModel
+ private var mProcessingDialog: WaitingDialogFragment? = null
override fun getLayoutId(): Int = R.layout.activity_game_collection_edit
@@ -34,6 +40,7 @@ class GameCollectionEditActivity : ToolBarActivity() {
setToolbarMenu(R.menu.menu_game_collection_edit)
mMenuPost = getMenuItem(R.id.menu_game_collection_post)
setNavigationTitle("创建游戏单")
+ mViewModel.gameCollectionPatch = intent.getParcelableExtra(GamesCollectionEntity::class.java.name)
initData()
observeData()
@@ -61,20 +68,42 @@ class GameCollectionEditActivity : ToolBarActivity() {
mBinding.changePosterBtn.setOnClickListener { mBinding.uploadPictureBtn.performClick() }
mBinding.deleteBtn.setOnClickListener {
- initPosterUI("")
+ mViewModel.imageUrl = ""
+ mViewModel.imagePath = ""
+ mBinding.uploadPictureBtn.text = "点击上传图片"
+ initPosterUI()
}
- mBinding.gameCollectionIntroduceEt.doOnTextChanged { text, start, before, count ->
+ mBinding.gameCollectionIntroduceEt.doOnTextChanged { text, _, _, _ ->
mBinding.introduceSizeTv.text = "${text?.length ?: 0}/200"
}
+ mBinding.chooseLabelContainer.setOnClickListener {
+ startActivityForResult(GameCollectionTagSelectActivity.getIntent(this), REQUEST_CHOOSE_TAG)
+ }
+
mBinding.chooseGameContainer.setOnClickListener {
- startActivityForResult(ChooseGamesActivity.getIntent(this), REQUEST_CHOOSE_GAMES)
+ startActivity(ChooseGamesActivity.getIntent(this))
}
}
private fun initData() {
+ mBinding.gameCollectionTitleEt.filters = arrayOf(TextHelper.getFilter(20, "最多输入20个字"))
+ mBinding.gameCollectionIntroduceEt.filters = arrayOf(TextHelper.getFilter(200, "最多输入200个字"))
+ mViewModel.gameCollectionPatch?.run {
+ if (status.isNotEmpty() && status != "draft") {
+ setNavigationTitle("编辑游戏单")
+ }
+ mViewModel.imageUrl = cover
+ initPosterUI()
+ mBinding.gameCollectionTitleEt.setText(title)
+ mBinding.gameCollectionTitleEt.setSelection(title.length)
+ mBinding.gameCollectionIntroduceEt.setText(intro)
+ mBinding.gameCollectionIntroduceEt.setSelection(intro.length)
+ mBinding.selfOnlyCb.isChecked = display == "self_only"
+ mViewModel.getGameCollectionDetail(id)
+ } ?: mViewModel.getDraft()
}
private fun observeData() {
@@ -82,9 +111,59 @@ class GameCollectionEditActivity : ToolBarActivity() {
mBinding.gamesTv.text = if (it.isEmpty()) "选择游戏" else "已选 ${it.size} 款游戏"
mBinding.gamesTipTv.goneIf(it.isNotEmpty())
}
+ mViewModel.processDialog.observe(this) {
+ if (it.isShow) {
+ if (mProcessingDialog?.dialog?.isShowing == true) {
+ mProcessingDialog?.uploadWaitingHint(it.msg)
+ } else {
+ mProcessingDialog = WaitingDialogFragment.newInstance(it.msg, false)
+ mProcessingDialog?.show(supportFragmentManager, null)
+ }
+ } else {
+ mProcessingDialog?.dismiss()
+ }
+ }
+ mViewModel.uploadImageSuccessLiveData.observe(this) {
+ if (it.isNotEmpty()) {
+ initPosterUI()
+ }
+ mBinding.uploadPictureBtn.text = "点击上传图片"
+ }
+ mViewModel.postLiveData.observe(this) {
+ if (it.status == Status.SUCCESS) {
+ toast("提交成功")
+ finish()
+ } else {
+ ErrorHelper.handleError(this, it.exception?.response()?.errorBody()?.string())
+ }
+ }
+ mViewModel.detailLiveData.observe(this) {
+ mViewModel.gameCollectionPatch = it
+ mViewModel.gameCollectionPatch?.run {
+ //TODO:initTags
+ mViewModel.tags = tags ?: arrayListOf()
+ val simpleGames = games?.map { game -> game.toGameEntity() }?.toList()
+ mChooseGamesViewModel.chooseGamesLiveData.postValue(ArrayList(simpleGames))
+ }
+ }
+ mViewModel.draftLiveData.observe(this) {
+ mViewModel.gameCollectionPatch = it
+ mViewModel.gameCollectionPatch?.run {
+ initData()
+ //TODO:initTags
+ mViewModel.tags = tags ?: arrayListOf()
+ val simpleGames = games?.map { game -> game.toGameEntity() }
+ mChooseGamesViewModel.chooseGamesLiveData.postValue(ArrayList(simpleGames))
+ }
+ }
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
+ item?.run {
+ if (itemId == R.id.menu_game_collection_post) {
+ verifyData()
+ }
+ }
return super.onMenuItemClick(item)
}
@@ -102,34 +181,139 @@ class GameCollectionEditActivity : ToolBarActivity() {
}
REQUEST_CODE_IMAGE_CROP -> {
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
- initPosterUI(imagePath)
+ mViewModel.imageUrl = ""
+ mViewModel.imagePath = imagePath
+ if (imagePath.isEmpty()) {
+ mBinding.uploadPictureBtn.text = "点击上传图片"
+ } else {
+ mBinding.uploadPictureBtn.text = "图片上传中..."
+ mViewModel.uploadPoster()
+ }
+ initPosterUI()
}
- REQUEST_CHOOSE_GAMES -> {
+ REQUEST_CHOOSE_TAG -> {
}
}
}
- private fun initPosterUI(imagePath: String) {
- mViewModel.imagePath = imagePath
- mBinding.placeholderView.goneIf(imagePath.isNotEmpty())
- mBinding.uploadPictureBtn.goneIf(imagePath.isNotEmpty())
- mBinding.posterView.goneIf(imagePath.isEmpty())
- mBinding.changePosterBtn.goneIf(imagePath.isEmpty())
- mBinding.deleteBtn.goneIf(imagePath.isEmpty())
- if (imagePath.isNotEmpty()) {
- ImageUtils.display(mBinding.posterView, "file:///$imagePath")
+ private fun initPosterUI() {
+ mBinding.placeholderView.goneIf(mViewModel.imageUrl.isNotEmpty())
+ mBinding.uploadPictureBtn.goneIf(mViewModel.imageUrl.isNotEmpty())
+ mBinding.posterView.goneIf(mViewModel.imageUrl.isEmpty())
+ mBinding.changePosterBtn.goneIf(mViewModel.imageUrl.isEmpty())
+ mBinding.deleteBtn.goneIf(mViewModel.imageUrl.isEmpty())
+ if (mViewModel.imageUrl.isNotEmpty()) {
+ ImageUtils.display(mBinding.posterView, mViewModel.imageUrl)
}
}
+ override fun handleBackPressed(): Boolean {
+ val patch = mViewModel.gameCollectionPatch
+ if (patch != null && patch.status.isNotEmpty() && patch.status != "draft") {
+ DialogHelper.showDialog(this, "温馨提示", "退出将不会保留本次游戏单编辑的内容,是否确定退出", "确定", "取消", {
+ finish()
+ }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
+ return true
+ } else {
+ val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
+ val title = mBinding.gameCollectionTitleEt.text.toString()
+ val introduce = mBinding.gameCollectionIntroduceEt.text.toString()
+ if (mViewModel.imageUrl.isNotEmpty()
+ || mViewModel.tags.isNotEmpty()
+ || games.isNotEmpty()
+ || title.isNotEmpty()
+ || introduce.isNotEmpty()
+ ) {
+ val entity = GamesCollectionEntity()
+ entity.tags = mViewModel.tags
+ entity.title = title
+ entity.intro = introduce
+ entity.cover = mViewModel.imageUrl
+ entity.display = if (mBinding.selfOnlyCb.isChecked) "self_only" else ""
+ entity.games = arrayListOf()
+ entity.games?.addAll(games.map { it.toSimpleGame() }.toList())
+ mViewModel.addDraft(entity)
+ }
+ }
+ return super.handleBackPressed()
+ }
+
+ private fun verifyData() {
+ if (mViewModel.imageUrl.isEmpty()) {
+ toast("请上传游戏单的封面")
+ return
+ }
+ if (mViewModel.tags.isEmpty()) {
+ toast("请选择游戏单的标签")
+ return
+ }
+ val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
+
+ val title = mBinding.gameCollectionTitleEt.text.toString()
+ if (title.isEmpty()) {
+ toast("请填写游戏单的标题")
+ return
+ }
+ val introduce = mBinding.gameCollectionIntroduceEt.text.toString()
+ if (introduce.length < 10) {
+ toast("介绍至少10个字")
+ return
+ }
+
+ val isSelfOnly = mBinding.selfOnlyCb.isChecked
+ val requestMap = hashMapOf(
+ "id" to (mViewModel.gameCollectionPatch?.id ?: ""),
+ "title" to title,
+ "intro" to introduce,
+ "tag_ids" to mViewModel.tags,
+ "cover" to mViewModel.imageUrl,
+ "display" to if (isSelfOnly) "self_only" else "",
+ "games" to games.map {
+ hashMapOf(
+ "_id" to it.id,
+ "recommend_star" to it.recommendStar,
+ "recommend_text" to it.recommendText,
+ )
+ }.toList()
+ )
+
+ if (isSelfOnly) {
+ DialogHelper.showDialog(this, "温馨提示", "游戏单开启“仅自己可见”后,将不会对其他用户展示,是否继续提交", "确定", "取消", {
+ mViewModel.uploadContent(requestMap)
+ }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
+ } else {
+ if (games.size < 8) {
+ DialogHelper.showDialog(this, "温馨提示", "游戏单需要收录至少8个游戏,才可以投稿至游戏单广场,是否在“我的光环-我的游戏单”继续保存为草稿", "继续保存", "添加游戏", {
+ mViewModel.uploadContent(requestMap)
+ }, {
+ startActivity(ChooseGamesActivity.getIntent(this))
+ }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
+ } else {
+ DialogHelper.showDialog(this, "温馨提示", "游戏单会在1-2个工作日内审核完成,您可以在“我的光环-我的游戏单”查看进度", "继续提交", "取消", {
+ mViewModel.uploadContent(requestMap)
+ }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
+ }
+ }
+ }
+
+
companion object {
const val REQUEST_CODE_IMAGE = 100
const val REQUEST_CODE_IMAGE_CROP = 101
const val REQUEST_CHOOSE_GAMES = 102
+ const val REQUEST_CHOOSE_TAG = 103
@JvmStatic
fun getIntent(context: Context): Intent {
return Intent(context, GameCollectionEditActivity::class.java)
}
+
+ @JvmStatic
+ fun getIntent(context: Context, entity: GamesCollectionEntity): Intent {
+ val intent = Intent(context, GameCollectionEditActivity::class.java)
+ intent.putExtra(GamesCollectionEntity::class.java.name, entity)
+ return intent
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt
index 173e63e661..bb97751b11 100644
--- a/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamecollection/publish/GameCollectionEditViewModel.kt
@@ -1,8 +1,127 @@
package com.gh.gamecenter.gamecollection.publish
+import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.MediatorLiveData
+import androidx.lifecycle.MutableLiveData
+import com.gh.base.fragment.WaitingDialogFragment
+import com.gh.common.runOnIoThread
+import com.gh.common.util.*
+import com.gh.gamecenter.entity.GamesCollectionEntity
+import com.gh.gamecenter.mvvm.Resource
+import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.Response
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.gh.gamecenter.room.AppDatabase
+import com.google.gson.JsonObject
+import com.halo.assistant.HaloApp
+import retrofit2.HttpException
class GameCollectionEditViewModel(application: Application) : AndroidViewModel(application) {
var imagePath = ""
+ var imageUrl = ""
+ var tags = ArrayList()
+ var gameCollectionPatch: GamesCollectionEntity? = null
+ var uploadImageSuccessLiveData = MutableLiveData()
+ var detailLiveData = MutableLiveData()
+ var draftLiveData = MutableLiveData()
+ val postLiveData = MutableLiveData>()
+ val processDialog = MediatorLiveData()
+ private val mApi = RetrofitManager.getInstance(HaloApp.getInstance()).api
+ private val mDraftDao = AppDatabase.getInstance(HaloApp.getInstance()).gameCollectionDraftDao()
+
+ fun uploadPoster() {
+ if (imagePath.isEmpty()) return
+ UploadImageUtils.uploadImage(UploadImageUtils.UploadType.poster, imagePath, object : UploadImageUtils.OnUploadImageListener {
+ override fun onSuccess(imageUrl: String) {
+ this@GameCollectionEditViewModel.imageUrl = imageUrl
+ uploadImageSuccessLiveData.postValue(imageUrl)
+ }
+
+ override fun onError(e: Throwable?) {
+ uploadImageSuccessLiveData.postValue("")
+ ToastUtils.showToast("图片上传失败")
+ }
+
+ override fun onProgress(total: Long, progress: Long) {}
+ })
+ }
+
+ fun uploadContent(requestMap: HashMap) {
+ val id = requestMap["id"]?.toString() ?: ""
+ if (id.isNotEmpty()) {
+ requestMap.remove("id")
+ }
+ postContent(requestMap, id)
+ }
+
+ private fun postContent(requestMap: HashMap, gameCollectionId: String) {
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
+ val requestBody = requestMap.toRequestBody()
+ val observable = if (gameCollectionId.isEmpty()) {
+ mApi.createGameCollection(requestBody)
+ } else {
+ mApi.patchGameCollection(requestBody, gameCollectionId)
+ }
+ observable
+ .compose(observableToMain())
+ .subscribe(object : Response() {
+ override fun onResponse(response: JsonObject?) {
+ super.onResponse(response)
+ val id = response?.get("_id")?.asString
+ postLiveData.postValue(Resource.success(id))
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ postLiveData.postValue(Resource.error(e))
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
+ }
+ })
+ }
+
+ fun getGameCollectionDetail(gameCollectionId: String) {
+ if (gameCollectionId.isEmpty()) return
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", true))
+ mApi.getGameCollectionDetail(gameCollectionId)
+ .compose(observableToMain())
+ .subscribe(object : Response() {
+ override fun onResponse(response: GamesCollectionEntity?) {
+ super.onResponse(response)
+ if (response != null) {
+ detailLiveData.postValue(response)
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
+ }
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun getDraft() {
+ mDraftDao.getAllDraft()
+ .compose(singleToMain())
+ .subscribe(object : BiResponse>() {
+ override fun onSuccess(data: List) {
+ if (data.isNotEmpty()) {
+ val draftEntity = data[0]
+ draftLiveData.postValue(draftEntity)
+ }
+ }
+ })
+ }
+
+ fun addDraft(entity: GamesCollectionEntity) {
+ runOnIoThread {
+ val drafts = mDraftDao.getDrafts()
+ mDraftDao.delete(drafts)
+ mDraftDao.addDraft(entity)
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt b/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt
index 56768c49c9..c5c6091b71 100644
--- a/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalFunctionAdapter.kt
@@ -18,6 +18,7 @@ import com.gh.gamecenter.entity.FunctionalGroupEntity
import com.gh.gamecenter.entity.FunctionalLinkEntity
import com.gh.gamecenter.entity.FunctionalMessageType
import com.gh.gamecenter.game.upload.GameSubmissionActivity
+import com.gh.gamecenter.gamecollection.MyGameCollectionActivity
import com.gh.gamecenter.gamedetail.myrating.MyRatingActivity
import com.gh.gamecenter.history.HistoryActivity
import com.gh.gamecenter.manager.UserManager
@@ -32,8 +33,8 @@ import com.gh.gamecenter.video.videomanager.VideoManagerActivity
import com.halo.assistant.HaloApp
import com.lightgame.adapter.BaseRecyclerAdapter
-class PersonalFunctionAdapter(val context: Context, val groupName: String, var mEntityList: ArrayList)
- : BaseRecyclerAdapter(context) {
+class PersonalFunctionAdapter(val context: Context, val groupName: String, var mEntityList: ArrayList) :
+ BaseRecyclerAdapter(context) {
private var mDisplayUpdateHint = false
private val gameTrendsDao = GameTrendsDao(HaloApp.getInstance().application)
@@ -287,6 +288,13 @@ class PersonalFunctionAdapter(val context: Context, val groupName: String, var m
"青少年模式" -> {
context.startActivity(TeenagerModeActivity.getIntent(context))
}
+ "我的游戏单" -> {
+ if (UserManager.getInstance().isLoggedIn) {
+ context.startActivity(MyGameCollectionActivity.getIntent(context))
+ } else {
+ CheckLoginUtils.checkLogin(context, "我的光环-我的游戏单") { }
+ }
+ }
else -> {
DirectUtils.directToLinkPage(context, linkEntity, "", "我的光环")
}
diff --git a/app/src/main/java/com/gh/gamecenter/personal/PersonalViewModel.kt b/app/src/main/java/com/gh/gamecenter/personal/PersonalViewModel.kt
index 66d7b945c4..44086bad67 100644
--- a/app/src/main/java/com/gh/gamecenter/personal/PersonalViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/personal/PersonalViewModel.kt
@@ -44,7 +44,8 @@ class PersonalViewModel(application: Application) : AndroidViewModel(application
Triple("浏览记录", R.drawable.personal_browsing_history, "浏览记录"),
Triple("账号安全", R.drawable.personal_account_security, "账号安全"),
Triple("模拟器游戏", R.drawable.personal_simulator_game, "模拟器游戏"),
- Triple("收货信息", R.drawable.personal_delivery_info, "收货信息")
+ Triple("收货信息", R.drawable.personal_delivery_info, "收货信息"),
+ Triple("我的游戏单", R.drawable.icon_game_collection, "我的游戏单")
)
private val contentCenterFuncs = arrayListOf(
Triple("游戏动态", R.drawable.personal_game_dynamic, "游戏动态"),
diff --git a/app/src/main/java/com/gh/gamecenter/qa/entity/ArticleEntity.kt b/app/src/main/java/com/gh/gamecenter/qa/entity/ArticleEntity.kt
index f7eb8ac1a8..68731fb867 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/entity/ArticleEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/entity/ArticleEntity.kt
@@ -22,47 +22,47 @@ import kotlinx.android.parcel.Parcelize
@Entity
@Parcelize
data class ArticleEntity(
- @PrimaryKey
- @SerializedName("_id")
- var id: String = "",
- var title: String = "",
- var brief: String = "",
- var active: Boolean = true,
- var orderTag: Long = 0,
- @TypeConverters(ListStringConverter::class)
- var images: List = ArrayList(),
- @TypeConverters(ImageInfoConverter::class)
- @SerializedName("images_info")
- var imagesInfo: List = ArrayList(),
- @TypeConverters(CommunityVideoConverter::class)
- var videos: List = ArrayList(),
- var count: Count = Count(),
- var community: CommunityEntity = CommunityEntity(),
- var time: TimeEntity? = TimeEntity(),
- var user: UserEntity = UserEntity(),
- @Ignore
- var read: Boolean = true,
- @Ignore
- var me: MeEntity = MeEntity(),
- @Ignore
- var commentable: Boolean = true,
- @Ignore
- var bbs: CommunityEntity = CommunityEntity(),
- var des: String = "",
- var url: String = "",
- @TypeConverters(VideoInfoConverter::class)
- @SerializedName("video_info")
- var videoInfo: VideoInfo = VideoInfo(),
- var poster: String = "",
- var length: Long = 0,
- @Ignore
- var type: String = "",
- var status: String = "",
- var content: String = "",
- @SyncIgnore // questions里的vote当前entity的vote冲突
- @TypeConverters(QuestionsConverter::class)
- @SerializedName("question")
- var questions: Questions = Questions()
+ @PrimaryKey
+ @SerializedName("_id")
+ var id: String = "",
+ var title: String = "",
+ var brief: String = "",
+ var active: Boolean = true,
+ var orderTag: Long = 0,
+ @TypeConverters(ListStringConverter::class)
+ var images: List = ArrayList(),
+ @TypeConverters(ImageInfoConverter::class)
+ @SerializedName("images_info")
+ var imagesInfo: List = ArrayList(),
+ @TypeConverters(CommunityVideoConverter::class)
+ var videos: List = ArrayList(),
+ var count: Count = Count(),
+ var community: CommunityEntity = CommunityEntity(),
+ var time: TimeEntity? = TimeEntity(),
+ var user: UserEntity = UserEntity(),
+ @Ignore
+ var read: Boolean = true,
+ @Ignore
+ var me: MeEntity = MeEntity(),
+ @Ignore
+ var commentable: Boolean = true,
+ @Ignore
+ var bbs: CommunityEntity = CommunityEntity(),
+ var des: String = "",
+ var url: String = "",
+ @TypeConverters(VideoInfoConverter::class)
+ @SerializedName("video_info")
+ var videoInfo: VideoInfo = VideoInfo(),
+ var poster: String = "",
+ var length: Long = 0,
+ @Ignore
+ var type: String = "",
+ var status: String = "",
+ var content: String = "",
+ @SyncIgnore // questions里的vote当前entity的vote冲突
+ @TypeConverters(QuestionsConverter::class)
+ @SerializedName("question")
+ var questions: Questions = Questions()
) : Parcelable {
fun getPassVideos(): List {
@@ -147,13 +147,15 @@ data class ArticleEntity(
@Parcelize
data class Count(
- @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_COUNT, SyncFieldConstants.ANSWER_COMMENT_COUNT])
- var comment: Int = 0,
- @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_VOTE_COUNT, SyncFieldConstants.ANSWER_VOTE_COUNT])
- var vote: Int = 0,
- var favorite: Int = 0,
- @SyncPage(syncNames = [SyncFieldConstants.ANSWER_COMMENT_REPLY_COUNT])
- var reply: Int = 0) : Parcelable {
+ @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_COUNT, SyncFieldConstants.ANSWER_COMMENT_COUNT])
+ var comment: Int = 0,
+ @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_VOTE_COUNT, SyncFieldConstants.ANSWER_VOTE_COUNT])
+ var vote: Int = 0,
+ var favorite: Int = 0,
+ @SyncPage(syncNames = [SyncFieldConstants.ANSWER_COMMENT_REPLY_COUNT])
+ var reply: Int = 0,
+ var game: Int = 0
+) : Parcelable {
@SyncPage(syncNames = [SyncFieldConstants.ANSWER_COUNT])
var answer: Int = 0
@@ -181,7 +183,9 @@ data class Count(
}
@Parcelize
-data class TimeEntity(var create: Long = 0,
- var update: Long = 0,
- var edit: Long = 0,
- var upload: Long = 0) : Parcelable
\ No newline at end of file
+data class TimeEntity(
+ var create: Long = 0,
+ var update: Long = 0,
+ var edit: Long = 0,
+ var upload: Long = 0
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
index b57d93d3ea..7e1f8cbff5 100644
--- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
+++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java
@@ -3264,4 +3264,28 @@ public interface ApiService {
*/
@PUT("api_go/teen_mode/password")
Single putTeenModePassword(@Body RequestBody body);
+
+ /**
+ * 游戏单列表
+ */
+ @GET("users/{user_id}/game_lists")
+ Observable> getGameCollectionList(@Path("user_id") String userId);
+
+ /**
+ * 创建游戏单
+ */
+ @POST("game_lists")
+ Observable createGameCollection(@Body RequestBody body);
+
+ /**
+ * 编辑游戏单
+ */
+ @PUT("game_lists/{game_list_id}")
+ Observable patchGameCollection(@Body RequestBody body, @Path("game_list_id") String id);
+
+ /**
+ * 游戏单详情(用户编辑自己的游戏单时调用)
+ */
+ @GET("game_lists/{game_list_id}?view=draft")
+ Observable getGameCollectionDetail(@Path("game_list_id") String id);
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java b/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java
index 71e21a83aa..29501bc569 100644
--- a/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java
+++ b/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java
@@ -14,6 +14,7 @@ import com.gh.common.videolog.VideoRecordDao;
import com.gh.common.videolog.VideoRecordEntity;
import com.gh.gamecenter.entity.CommentDraft;
import com.gh.gamecenter.entity.ForumEntity;
+import com.gh.gamecenter.entity.GamesCollectionEntity;
import com.gh.gamecenter.entity.HomePluggableFilterEntity;
import com.gh.gamecenter.entity.SignEntity;
import com.gh.gamecenter.entity.SimulatorGameRecordEntity;
@@ -21,6 +22,7 @@ import com.gh.gamecenter.qa.entity.AnswerEntity;
import com.gh.gamecenter.room.converter.ApkArrayListConverter;
import com.gh.gamecenter.room.converter.MeConverter;
import com.gh.gamecenter.room.converter.SimpleGameConverter;
+import com.gh.gamecenter.room.converter.SimpleGameListConverter;
import com.gh.gamecenter.room.converter.SimulatorConverter;
import com.gh.gamecenter.room.converter.StringArrayListConverter;
import com.gh.gamecenter.room.converter.TagStyleListConverter;
@@ -28,6 +30,7 @@ import com.gh.gamecenter.room.converter.VideoInfoConverter;
import com.gh.gamecenter.room.dao.AnswerDao;
import com.gh.gamecenter.room.dao.CommentDraftDao;
import com.gh.gamecenter.room.dao.ForumDao;
+import com.gh.gamecenter.room.dao.GameCollectionDraftDao;
import com.gh.gamecenter.room.dao.HomePluggableFilterDao;
import com.gh.gamecenter.room.dao.SignDao;
import com.gh.gamecenter.room.dao.SimulatorGameDao;
@@ -45,7 +48,8 @@ import com.gh.gamecenter.video.upload.UploadEntity;
HomePluggableFilterEntity.class,
VideoRecordEntity.class,
SimulatorGameRecordEntity.class,
- ForumEntity.class}, version = 20, exportSchema = false)
+ ForumEntity.class,
+ GamesCollectionEntity.class}, version = 21, exportSchema = false)
@TypeConverters({
StringArrayListConverter.class,
TagStyleListConverter.class,
@@ -53,7 +57,8 @@ import com.gh.gamecenter.video.upload.UploadEntity;
ApkArrayListConverter.class,
SimpleGameConverter.class,
VideoInfoConverter.class,
- MeConverter.class
+ MeConverter.class,
+ SimpleGameListConverter.class
})
public abstract class AppDatabase extends RoomDatabase {
@@ -73,6 +78,8 @@ public abstract class AppDatabase extends RoomDatabase {
public abstract ForumDao forumDao();
+ public abstract GameCollectionDraftDao gameCollectionDraftDao();
+
private static AppDatabase sInstance;
private static final String DATABASE_NAME = "gh-db";
@@ -218,6 +225,13 @@ public abstract class AppDatabase extends RoomDatabase {
}
};
+ static final Migration MIGRATION_20_21 = new Migration(20, 21) {
+ @Override
+ public void migrate(@NonNull SupportSQLiteDatabase database) {
+ database.execSQL("CREATE TABLE GameCollectionDraft(primaryKey TEXT NOT NULL PRIMARY KEY, tags TEXT DEFAULT '', games TEXT DEFAULT '' , title TEXT NOT NULL DEFAULT '', intro TEXT NOT NULL DEFAULT '', cover TEXT NOT NULL DEFAULT '', display TEXT NOT NULL DEFAULT '')");
+ }
+ };
+
private static AppDatabase buildDatabase(Context context) {
return Room.databaseBuilder(context, AppDatabase.class, DATABASE_NAME)
.addMigrations(
@@ -237,7 +251,8 @@ public abstract class AppDatabase extends RoomDatabase {
MIGRATION_16_17,
MIGRATION_17_18,
MIGRATION_18_19,
- MIGRATION_19_20
+ MIGRATION_19_20,
+ MIGRATION_20_21
)
// 不允许主线程查询
.allowMainThreadQueries()
diff --git a/app/src/main/java/com/gh/gamecenter/room/converter/SimpleGameListConverter.kt b/app/src/main/java/com/gh/gamecenter/room/converter/SimpleGameListConverter.kt
new file mode 100644
index 0000000000..e439911df1
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/room/converter/SimpleGameListConverter.kt
@@ -0,0 +1,20 @@
+package com.gh.gamecenter.room.converter
+
+import androidx.room.TypeConverter
+import com.gh.common.util.toJson
+import com.gh.common.util.toObject
+import com.gh.gamecenter.entity.ApkEntity
+import com.gh.gamecenter.entity.SimpleGame
+
+class SimpleGameListConverter {
+ @TypeConverter
+ fun toSimpleGameString(data: ArrayList?): String {
+ return data?.toJson() ?: ""
+ }
+
+ @TypeConverter
+ fun toSimpleGameEntity(data: String?): ArrayList {
+ val apkArray = data?.toObject() ?: arrayOf()
+ return ArrayList(apkArray.toList())
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/room/dao/GameCollectionDraftDao.kt b/app/src/main/java/com/gh/gamecenter/room/dao/GameCollectionDraftDao.kt
new file mode 100644
index 0000000000..657a18f3c6
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/room/dao/GameCollectionDraftDao.kt
@@ -0,0 +1,21 @@
+package com.gh.gamecenter.room.dao
+
+import androidx.room.*
+import com.gh.gamecenter.entity.GamesCollectionEntity
+import io.reactivex.Single
+
+@Dao
+interface GameCollectionDraftDao {
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun addDraft(entity: GamesCollectionEntity)
+
+ @Query("select * from GameCollectionDraft")
+ fun getAllDraft(): Single>
+
+ @Query("select * from GameCollectionDraft")
+ fun getDrafts(): List
+
+ @Delete()
+ fun delete(list: List)
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_choose_game_del.webp b/app/src/main/res/drawable-xxxhdpi/ic_choose_game_del.webp
new file mode 100644
index 0000000000000000000000000000000000000000..1f436ab9ee266ee97c2bc991e3402f555b97f099
GIT binary patch
literal 1202
zcmV;j1Wo%=Nk&Gh1ONb6MM6+kP&il$0000G0000_002(_06|PpNYeoT00B?IIFh8c
zVP+Q(PmotcL?EH2D(aPMIwFzZ&{m^QTxA!lCJYYSNK&M^KZa*!hR#34r`z2Qpf95T
zj@&kKq#|ZE@2yfl!CYm{Xt6n*Z%=jS!)7sRG7Bi_&-O3;_0p`LSO`(QdZ0C}>c~8c
zhbK5XDK?Li$rT=4YeTDCj=<;Yom*oa_Pkg-qm%@KTa4&fZeHz)GVv4nHBCLp1&i*Qfj+oQy{=MnCqe0#F^_ISc`
z2EKC;@txC%?;J^d=Un1DhZEm9p`?N54AsEgm0oMex-c*L-pZ!>=1Vg5(kZS=%%gbd
z+#FAe&9kUpISd$D)scme^k@4PQ{PLoeqsS-&3L&zoNrHc=fie6ZZdNP09H^qAg}@e
z0FV#>odGIP08juvi9D7^r6ZytGd}15pb-gX2yg*}Couk7_|~|mRr>(vp?|*t_W{1o
zpZ`n)c!&2h_X7~ZXr~KZ;NJk(5vT|8A2#n|U$7pK1RMB4h@Of<*p1+&IvDFy5V(AJ
zt~Vz_v9BA-qZQ642HQC-IP9Af!uzxJy8pDZay?`yhSS|j7ytnN@yRkqc|I3I{|3c$
zv@0pIuE+@vKlTbd(QWl$0Ta2Z#_Q1jKRy2&bO?4QJ;i*6yvJ4@#UL;AZ1iWqZqCn%
zjoDE3pKadIah0>7bb7ZNzY`NLh(VS7SoDhi9T*eu*@msKt^$SD8xTiFcT4#iRvClU
zD`@xMQddO3y00C=#w(c{{wP2bPYZeigY!jg)kAuIhm@_%%b9V2ZlLb7RD<)sS-*yv
zu*K8F93pi*WNh2uhX3r8U&8i|Bj3K>BSruVCIn2r?f4uGSs#j_#
z!-7$_=XkdWt?f1|n|_B};Zfn9*^F?1r>&V^`(3SWo2qC{OtDGEXJwY(w}5*L%`*XA
zV0Wan1|a=p@1_2mRSM|Qd)KlhX=7icq4$OQ`FzL)C2T!@Cnu&h4`QVEN>zRG=Fz9)f^pPV?Jg0sCPx1k4Kq5YBO%Dzx34=csdS%esCylI03@GE4FCWD
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_game_collection_del.webp b/app/src/main/res/drawable-xxxhdpi/ic_game_collection_del.webp
new file mode 100644
index 0000000000000000000000000000000000000000..1bc9c423b65892c9a0b9ec539e79654a05a4c3ed
GIT binary patch
literal 782
zcmV+p1M&P)Nk&En0{{S5MM6+kP&il$0000G0000#002J#06|PpNC^P|009@lIFh8c
zS@sOx!_!C+5r$MC-u(~_%uTV1cTNZ=SH=buk|aq|Bq@s-x|qTK|IC!?%;=%rQ$+tK
zK>e#shVACzy$y*hf5zbK3vw5XF0Pyw!>yR`0@l=15505+u24z^9D#Z>IDkq@2Q=#K
z2I!1z?Oct^o@q6}c=L7ezCEMlg*)#176v}!5%*ycp2610II;ZaA4~R~vbuTz0
zc{woZMj)400JCleivRC&VAPF3E-yNv*1h12X|1>6`v{wR?sSarD
zH9%*o0*=5|Z~&F5@B-G