diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5083acb860..9941e0158c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -29,15 +29,15 @@
-
-
+
+
-
+
@@ -76,9 +76,9 @@
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:largeHeap="true"
+ android:networkSecurityConfig="@xml/network_security_config"
android:resizeableActivity="true"
android:theme="@style/AppCompatTheme.APP"
- android:networkSecurityConfig="@xml/network_security_config"
tools:replace="android:allowBackup"
tools:targetApi="n">
@@ -514,6 +514,12 @@
android:theme="@style/Theme.Transparent"
android:windowSoftInputMode="adjustNothing" />
+
+
+ android:launchMode="singleTask"
+ android:screenOrientation="portrait" />
+
+
+
+
-
+ android:theme="@android:style/Theme.Dialog"/>
: ToolBarAct
super.onActivityResult(requestCode, resultCode, data)
DialogUtils.fixWebViewKeyboardNotWorking(this)
if (resultCode != Activity.RESULT_OK) return
- var insertData: EditorInsertEntity?
+ val insertData: EditorInsertEntity?
when (requestCode) {
INSERT_ANSWER_CODE -> {
val answer = data?.getParcelableExtra(AnswerEntity::class.java.simpleName)
@@ -104,11 +106,17 @@ abstract class BaseRichEditorActivity : ToolBarAct
REQUEST_CODE_IMAGE -> {
if (data != null) mViewModel.uploadPic(data)
}
- VideoActivity.INSERT_VIDEO_CODE -> {
- val video = data?.getParcelableExtra(MyVideoEntity::class.java.simpleName)
- if (video != null) {
- mRichEditor.focusEditor()
- mRichEditor.insertCustomVideo(video)
+ INSERT_VIDEO_CODE -> {
+// val video = data?.getParcelableExtra(MyVideoEntity::class.java.simpleName)
+// if (video != null) {
+// mRichEditor.focusEditor()
+// mRichEditor.insertCustomVideo(video)
+// }
+ val localVideoList = data?.getParcelableArrayListExtra(LocalVideoEntity::class.java.name)
+ ?: arrayListOf()
+ if (localVideoList.isNotEmpty()) {
+ mViewModel.localVideoList.addAll(localVideoList)
+ mViewModel.uploadVideo()
}
}
}
@@ -141,7 +149,7 @@ abstract class BaseRichEditorActivity : ToolBarAct
observeData()
}
- private fun observeData(){
+ private fun observeData() {
mViewModel.chooseImagesUpload.observe(this, Observer {
for (key in it.keys) {
mRichEditor.insertPlaceholderImage(key)
@@ -309,7 +317,7 @@ abstract class BaseRichEditorActivity : ToolBarAct
object : EmptyCallback {
override fun onCallback() {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-视频")
- startActivityForResult(VideoActivity.getIntent(this@BaseRichEditorActivity), VideoActivity.INSERT_VIDEO_CODE)
+ startActivityForResult(VideoActivity.getIntent(this@BaseRichEditorActivity, 3), INSERT_VIDEO_CODE)
}
})
}
@@ -426,6 +434,13 @@ abstract class BaseRichEditorActivity : ToolBarAct
return super.handleBackPressed()
}
+ override fun onDestroy() {
+ super.onDestroy()
+ val path = mViewModel.currentUploadingVideo?.filePath
+ if (path != null && UploadManager.isUploading(path)) {
+ UploadManager.cancelTask(path)
+ }
+ }
private inner class OnCursorChangeListener {
@JavascriptInterface
@@ -500,5 +515,6 @@ abstract class BaseRichEditorActivity : ToolBarAct
const val MAX_INPUT_TEXT_NUM = 10000
const val REQUEST_CODE_IMAGE = 120
+ const val INSERT_VIDEO_CODE = 121
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/base/BaseRichEditorViewModel.kt b/app/src/main/java/com/gh/base/BaseRichEditorViewModel.kt
index eebfec6290..fad4da7044 100644
--- a/app/src/main/java/com/gh/base/BaseRichEditorViewModel.kt
+++ b/app/src/main/java/com/gh/base/BaseRichEditorViewModel.kt
@@ -8,9 +8,12 @@ import androidx.lifecycle.MutableLiveData
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.ErrorEntity
+import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.retrofit.service.ApiService
+import com.gh.gamecenter.video.upload.OnUploadListener
+import com.gh.gamecenter.video.upload.UploadManager
import com.lightgame.utils.Utils
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
@@ -27,6 +30,8 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
val chooseImagesUploadSuccess = MutableLiveData>()
var uploadImageSubscription: Disposable? = null
val mapImages = HashMap()
+ val localVideoList = ArrayList()
+ var currentUploadingVideo: LocalVideoEntity? = null
//检查图片是否符合规则并上传图片
fun uploadPic(data: Intent) {
@@ -106,4 +111,26 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
}
})
}
+
+ fun uploadVideo() {
+ if (localVideoList.isEmpty()) return
+ currentUploadingVideo = localVideoList[0]
+ UploadManager.createUploadTask(currentUploadingVideo!!.filePath, object : OnUploadListener {
+ override fun onProgressChanged(uploadFilePath: String, currentSize: Long, totalSize: Long, speed: Long) {
+ val percent = currentSize * 100 / totalSize.toFloat()
+ Utils.log("上传中...${percent.roundTo(1)}%")
+ }
+
+ override fun onUploadSuccess(uploadFilePath: String, url: String) {
+ Utils.log("上传完成:$uploadFilePath--$url")
+ localVideoList.remove(currentUploadingVideo!!)
+ currentUploadingVideo = null
+ uploadVideo()
+ }
+
+ override fun onUploadFailure(uploadFilePath: String, errorMsg: String) {
+
+ }
+ })
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/util/EntranceUtils.java b/app/src/main/java/com/gh/common/util/EntranceUtils.java
index 095ade8041..b8a4044abf 100644
--- a/app/src/main/java/com/gh/common/util/EntranceUtils.java
+++ b/app/src/main/java/com/gh/common/util/EntranceUtils.java
@@ -235,6 +235,9 @@ public class EntranceUtils {
public static final String KEY_IS_QA_FEEDBACK = "is_qa_feedback";
public static final String KEY_IS_CLICK_RECEIVE_BTN = "is_click_receive_btn";
public static final String KEY_SHOW_QUICK_LOGIN = "show_quick_login";
+ public static final String KEY_VIDEO_LIST = "video_list";
+ public static final String KEY_CHOOSE_FORUM_TYPE = "choose_forum_type";
+ public static final String KEY_CHOOSE_MAX_COUNT = "choose_max_count";
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
diff --git a/app/src/main/java/com/gh/gamecenter/entity/LocalVideoEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/LocalVideoEntity.kt
new file mode 100644
index 0000000000..56a46dfb80
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/LocalVideoEntity.kt
@@ -0,0 +1,13 @@
+package com.gh.gamecenter.entity
+
+import android.net.Uri
+import android.os.Parcelable
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+data class LocalVideoEntity(
+ var filePath: String = "",
+ var poster: String = "",
+ var contentUri: Uri? = null,
+ var duration: Long = 0
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumHomeFragment.kt
index 6fb9a95271..fd199c9a78 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumHomeFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumHomeFragment.kt
@@ -39,6 +39,7 @@ import com.gh.gamecenter.qa.CommunityFragment
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
import com.gh.gamecenter.qa.recommends.AskRecommendsSubjectPageAdapter
+import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.gh.gamecenter.user.UserViewModel
import com.google.android.material.appbar.AppBarLayout
import kotterknife.bindView
@@ -330,7 +331,7 @@ class ForumHomeFragment : BaseLazyTabFragment() {
window?.setWindowAnimations(R.style.community_publication_animation)
dialog.setContentView(contentView, params)
dialog.show()
- contentView.findViewById(R.id.community_edit_article).setOnClickListener {
+ contentView.findViewById(R.id.community_edit_article_container).setOnClickListener {
context?.ifLogin("论坛首页", action = {
checkStoragePermissionBeforeAction {
showRegulationTestDialogIfNeeded {
@@ -341,7 +342,7 @@ class ForumHomeFragment : BaseLazyTabFragment() {
}
})
}
- contentView.findViewById(R.id.community_edit_question).setOnClickListener {
+ contentView.findViewById(R.id.community_edit_question_container).setOnClickListener {
context?.ifLogin("论坛首页", action = {
checkStoragePermissionBeforeAction {
showRegulationTestDialogIfNeeded {
@@ -352,6 +353,15 @@ class ForumHomeFragment : BaseLazyTabFragment() {
}
})
}
+ contentView.findViewById(R.id.community_edit_video_container).setOnClickListener {
+ checkStoragePermissionBeforeAction {
+ showRegulationTestDialogIfNeeded {
+ MtaHelper.onEvent("论坛首页", "发布", "发视频")
+ startActivity(VideoPublishActivity.getIntent(requireContext()))
+ dialog.dismiss()
+ }
+ }
+ }
contentView.findViewById(R.id.community_edit_close).setOnClickListener {
dialog.dismiss()
}
diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt
index 0cc778948d..c923e4b623 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/article/edit/ArticleEditActivity.kt
@@ -28,7 +28,7 @@ import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
import com.gh.gamecenter.qa.article.draft.ArticleDraftActivity
-import com.gh.gamecenter.qa.dialog.ChooseForumDialogFragment
+import com.gh.gamecenter.qa.dialog.ChooseForumActivity
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
import com.gh.gamecenter.qa.entity.ArticleDraftEntity
import com.gh.gamecenter.qa.questions.edit.TagsSelectFragment
@@ -79,12 +79,17 @@ class ArticleEditActivity : BaseRichEditorActivity(), Keyb
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
- if (requestCode == ARTICLE_DRAFT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
- val draftEntity = data?.getParcelableExtra(ArticleDraftEntity::class.java.simpleName)
+ if (data == null || resultCode != Activity.RESULT_OK) return
+ if (requestCode == ARTICLE_DRAFT_REQUEST_CODE) {
+ val draftEntity = data.getParcelableExtra(ArticleDraftEntity::class.java.simpleName)
if (draftEntity != null) {
mViewModel.draftEntity = draftEntity
setArticleDraft()
}
+ } else if (requestCode == ChooseForumActivity.CHOOSE_FORUM_REQUEST) {
+ val community = data.getParcelableExtra(EntranceUtils.KEY_COMMUNITY_DATA)
+ mViewModel.mSelectCommunityData = community
+ setGameName()
}
}
@@ -418,10 +423,7 @@ class ArticleEditActivity : BaseRichEditorActivity(), Keyb
}
private fun showSelectGameDialog() {
- ChooseForumDialogFragment.show(this) {
- mViewModel.mSelectCommunityData = it
- setGameName()
- }
+ ChooseForumActivity.startChooseForumActivity(this)
}
private fun setGameName() {
diff --git a/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumActivity.kt
new file mode 100644
index 0000000000..f4cf1d7894
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumActivity.kt
@@ -0,0 +1,111 @@
+package com.gh.gamecenter.qa.dialog
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import androidx.core.widget.doOnTextChanged
+import androidx.fragment.app.Fragment
+import com.gh.base.BaseActivity
+import com.gh.base.adapter.FragmentAdapter
+import com.gh.common.util.DisplayUtils
+import com.gh.common.util.EntranceUtils
+import com.gh.common.util.doOnEnd
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.DialogChooseForumBinding
+import com.gh.gamecenter.entity.CommunityEntity
+
+class ChooseForumActivity : BaseActivity() {
+ private lateinit var binding: DialogChooseForumBinding
+ private var mSearchResultFragment: ChooseForumContainerFragment? = null
+ private val mTabTitleList = arrayListOf("我的关注", "热门论坛")
+ private val mFragmentsList: ArrayList = arrayListOf()
+
+ override fun getLayoutId(): Int = R.layout.dialog_choose_forum
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ DisplayUtils.transparentStatusBar(this)
+ binding = DialogChooseForumBinding.bind(mContentView)
+
+ initViewPager()
+ binding.searchEt.doOnTextChanged { _, _, _, _ ->
+ if (binding.searchEt.text.isNullOrEmpty()) {
+ switchUI(false)
+ } else {
+ switchUI(true)
+ mSearchResultFragment?.setSearchKey(binding.searchEt.text.toString())
+ }
+ }
+ binding.closeIv.setOnClickListener { finish() }
+ binding.maskView.alpha = 0f
+ binding.maskView.animate().alpha(1f).setDuration(300).start()
+ binding.maskView.setOnClickListener { binding.closeIv.performClick() }
+ binding.forumContainer.translationY = (DisplayUtils.getScreenHeight()).toFloat()
+ binding.forumContainer.animate().translationY(0f).setDuration(300).start()
+ }
+
+ private fun initViewPager() {
+ mFragmentsList.clear()
+ mFragmentsList.add(ChooseForumContainerFragment.getInstance(ChooseForumContainerFragment.ChooseForumType.ATTENTION))
+ mFragmentsList.add(ChooseForumContainerFragment.getInstance(ChooseForumContainerFragment.ChooseForumType.HOT))
+ binding.viewPager.offscreenPageLimit = mFragmentsList.size
+ binding.viewPager.adapter = FragmentAdapter(supportFragmentManager, mFragmentsList, mTabTitleList)
+ binding.tabLayout.setupWithViewPager(binding.viewPager)
+ binding.tabIndicator.setupWithTabLayout(binding.tabLayout)
+ binding.tabIndicator.setupWithViewPager(binding.viewPager)
+ binding.tabIndicator.setIndicatorWidth(20)
+ }
+
+ private fun switchUI(isSearch: Boolean) {
+ if (isSearch) {
+ binding.tabContainer.visibility = View.GONE
+ binding.line.visibility = View.GONE
+ binding.viewPager.visibility = View.GONE
+ binding.searchResultContainer.visibility = View.VISIBLE
+
+ if (mSearchResultFragment == null || mSearchResultFragment?.isAdded == false) {
+ val beginTransaction = supportFragmentManager.beginTransaction()
+ mSearchResultFragment = supportFragmentManager.findFragmentByTag(ChooseForumContainerFragment::class.java.simpleName) as? ChooseForumContainerFragment
+ ?: ChooseForumContainerFragment.getInstance(ChooseForumContainerFragment.ChooseForumType.SEARCH) as ChooseForumContainerFragment
+ beginTransaction.replace(binding.searchResultContainer.id, mSearchResultFragment!!, ChooseForumContainerFragment::class.java.simpleName)
+ beginTransaction.commitAllowingStateLoss()
+ }
+ } else {
+ binding.tabContainer.visibility = View.VISIBLE
+ binding.line.visibility = View.VISIBLE
+ binding.viewPager.visibility = View.VISIBLE
+ binding.searchResultContainer.visibility = View.GONE
+ }
+ }
+
+ fun chooseSuccess(community: CommunityEntity) {
+ val intent = Intent()
+ intent.putExtra(EntranceUtils.KEY_COMMUNITY_DATA, community)
+ setResult(Activity.RESULT_OK, intent)
+ finish()
+ }
+
+ override fun finish() {
+ overridePendingTransition(0, 0)
+ binding.maskView.animate().alpha(0f).setDuration(300).start()
+ binding.root.animate()
+ .translationY(DisplayUtils.getScreenHeight().toFloat())
+ .setDuration(300)
+ .doOnEnd {
+ super.finish()
+ }
+ .start()
+ }
+
+ companion object {
+ const val CHOOSE_FORUM_REQUEST = 10
+
+ fun startChooseForumActivity(context: Activity) {
+ val intent = Intent(context, ChooseForumActivity::class.java)
+ context.overridePendingTransition(0, 0)
+ context.startActivityForResult(intent, CHOOSE_FORUM_REQUEST)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerAdapter.kt b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerAdapter.kt
new file mode 100644
index 0000000000..17eb6129c1
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerAdapter.kt
@@ -0,0 +1,39 @@
+package com.gh.gamecenter.qa.dialog
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.MtaHelper
+import com.gh.common.util.goneIf
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.databinding.ForumItemBinding
+import com.gh.gamecenter.entity.CommunityEntity
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.forum.detail.ForumDetailActivity
+import com.gh.gamecenter.qa.entity.CommunitySelectEntity
+
+class ChooseForumContainerAdapter(content: Context, val onSelectCallback: ((entity: CommunityEntity) -> Unit)? = null) : ListAdapter(content) {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return ForumItemViewHolder(ForumItemBinding.inflate(LayoutInflater.from(mContext), parent, false))
+ }
+
+ override fun getItemCount(): Int = mEntityList.size
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder is ForumItemViewHolder) {
+ val forumEntity = mEntityList[position]
+ holder.binding.entity = forumEntity
+ holder.binding.forumIcon.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
+ holder.binding.followTv.visibility = View.GONE
+ holder.itemView.setOnClickListener {
+ onSelectCallback?.invoke(CommunityEntity(forumEntity.id, forumEntity.name, icon = forumEntity.game.getIcon(), iconSubscript = forumEntity.game.iconSubscript))
+ }
+ }
+ }
+
+ class ForumItemViewHolder(val binding: ForumItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerFragment.kt
new file mode 100644
index 0000000000..c08df92906
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerFragment.kt
@@ -0,0 +1,53 @@
+package com.gh.gamecenter.qa.dialog
+
+import android.os.Bundle
+import android.view.View
+import androidx.core.os.bundleOf
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.util.EntranceUtils
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.entity.CommunityEntity
+import com.gh.gamecenter.entity.ForumEntity
+
+class ChooseForumContainerFragment : ListFragment() {
+
+ private var mAdapter: ChooseForumContainerAdapter? = null
+ private var type: String = ""
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ type = arguments?.getString(EntranceUtils.KEY_CHOOSE_FORUM_TYPE) ?: ""
+ }
+
+ override fun provideListAdapter(): ListAdapter<*> {
+ return mAdapter ?: ChooseForumContainerAdapter(requireContext()) {
+ if (requireActivity() is ChooseForumActivity) {
+ (requireActivity() as ChooseForumActivity).chooseSuccess(it)
+ }
+ }.apply {
+ mAdapter = this
+ }
+ }
+
+ fun setSearchKey(key: String) {
+
+ }
+
+ override fun isAutomaticLoad(): Boolean = type != ChooseForumType.SEARCH.value
+
+ override fun getItemDecoration(): RecyclerView.ItemDecoration? = null
+
+ companion object {
+ fun getInstance(type: ChooseForumType): Fragment {
+ return ChooseForumContainerFragment().with(bundleOf(EntranceUtils.KEY_CHOOSE_FORUM_TYPE to type.value))
+ }
+ }
+
+ enum class ChooseForumType(val value: String) {
+ ATTENTION("attention"),
+ HOT("hot"),
+ SEARCH("search")
+ }
+}
diff --git a/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerViewModel.kt
new file mode 100644
index 0000000000..ca56c64108
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumContainerViewModel.kt
@@ -0,0 +1,20 @@
+package com.gh.gamecenter.qa.dialog
+
+import android.app.Application
+import com.gh.gamecenter.baselist.ListViewModel
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.gh.gamecenter.retrofit.service.ApiService
+import io.reactivex.Observable
+
+class ChooseForumContainerViewModel(application: Application) : ListViewModel(application) {
+ private val mApi: ApiService = RetrofitManager.getInstance(getApplication()).api
+ override fun provideDataObservable(page: Int): Observable> {
+ return mApi.getFollowsForum(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/qa/dialog/ChooseForumDialogFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumDialogFragment.kt
deleted file mode 100644
index 492b4e543b..0000000000
--- a/app/src/main/java/com/gh/gamecenter/qa/dialog/ChooseForumDialogFragment.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.gh.gamecenter.qa.dialog
-
-import android.app.Dialog
-import android.os.Bundle
-import android.view.Gravity
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.FragmentTransaction
-import com.gh.base.fragment.BaseDialogFragment
-import com.gh.gamecenter.R
-import com.gh.gamecenter.databinding.DialogChooseForumBinding
-import com.gh.gamecenter.entity.CommunityEntity
-import com.gh.gamecenter.forum.select.ForumSelectFragment
-import com.halo.assistant.HaloApp
-
-class ChooseForumDialogFragment : BaseDialogFragment() {
- private lateinit var binding: DialogChooseForumBinding
- var onSelectCallback: ((entity: CommunityEntity) -> Unit)? = null
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- binding = DialogChooseForumBinding.inflate(inflater, container, false)
- return binding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- val beginTransaction = childFragmentManager.beginTransaction()
- val forumSelectFragment = childFragmentManager.findFragmentByTag(ForumSelectFragment::class.java.simpleName) as? ForumSelectFragment
- ?: ForumSelectFragment()
- forumSelectFragment.onSelectCallback = {
- onSelectCallback?.invoke(it)
- dismissAllowingStateLoss()
- }
- beginTransaction.replace(binding.container.id, forumSelectFragment, ForumSelectFragment::class.java.simpleName)
- beginTransaction.commitAllowingStateLoss()
- binding.closeIv.setOnClickListener { dismissAllowingStateLoss() }
- }
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val createDialog = super.onCreateDialog(savedInstanceState)
- createDialog.setCanceledOnTouchOutside(true)
-
- val window = createDialog.window
- window?.setGravity(Gravity.BOTTOM)
- window?.setWindowAnimations(R.style.community_publication_animation)
- return createDialog
- }
-
- override fun onStart() {
- super.onStart()
- val width = HaloApp.getInstance().application.resources.displayMetrics.widthPixels
- val height = dialog?.window?.attributes?.height ?: ViewGroup.LayoutParams.WRAP_CONTENT
- dialog?.window?.setLayout(width, height)
- }
-
-
- companion object {
- fun show(activity: AppCompatActivity, onSelectCallback: ((entity: CommunityEntity) -> Unit)) {
- var fragment = activity.supportFragmentManager.findFragmentByTag(ChooseForumDialogFragment::class.java.name) as? ChooseForumDialogFragment
- if (fragment == null) {
- fragment = ChooseForumDialogFragment()
- fragment.onSelectCallback = onSelectCallback
- fragment.show(activity.supportFragmentManager, ChooseForumDialogFragment::class.java.name)
- } else {
- fragment.onSelectCallback = onSelectCallback
- val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
- transaction.show(fragment)
- transaction.commit()
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoAdapter.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoAdapter.kt
index 146aeff7fa..d0851e313e 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoAdapter.kt
@@ -1,25 +1,23 @@
package com.gh.gamecenter.qa.editor
+import android.content.Context
import android.database.Cursor
import android.view.LayoutInflater
-import android.view.View
import android.view.ViewGroup
-import androidx.appcompat.app.AppCompatActivity
import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.ImageUtils
import com.gh.common.util.TimeUtils
+import com.gh.common.util.ToastUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.LocalVideoItemBinding
-import com.gh.gamecenter.databinding.PhotoPosterItemBinding
-import com.gh.gamecenter.video.upload.view.UploadVideoActivity
-import com.gh.gamecenter.video.videomanager.VideoManagerActivity
import com.halo.assistant.HaloApp
import com.zhihu.matisse.internal.entity.Item
import com.zhihu.matisse.internal.entity.SelectionSpec
import com.zhihu.matisse.internal.ui.adapter.RecyclerViewCursorAdapter
import com.zhihu.matisse.internal.utils.PathUtils
-class LocalVideoAdapter : RecyclerViewCursorAdapter(null) {
- private val mImageResize = HaloApp.getInstance().application.resources.displayMetrics.widthPixels / 3
+class LocalVideoAdapter(val context: Context, val maxChooseSize: Int, val callback: (ArrayList- ) -> Unit) : RecyclerViewCursorAdapter(null) {
+ private val mSelectedVideoList = arrayListOf
- ()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocalVideoPreviewViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.local_video_item, parent, false)
@@ -27,22 +25,34 @@ class LocalVideoAdapter : RecyclerViewCursorAdapter
}
override fun onBindViewHolder(holder: LocalVideoPreviewViewHolder, cursor: Cursor?, position: Int) {
-
val item = Item.valueOf(cursor)
- SelectionSpec.getInstance().imageEngine.loadThumbnail(
- HaloApp.getInstance().application, mImageResize, null,
- holder.binding.preview, item.contentUri)
+ ImageUtils.display(holder.binding.preview, "file:///${PathUtils.getPath(context, item.contentUri)}")
holder.binding.durationTv.text = TimeUtils.formatVideoDuration(item.duration / 1000)
+ holder.binding.checkImageView.isChecked = mSelectedVideoList.contains(item)
holder.itemView.setOnClickListener {
- val path = PathUtils.getPath(holder.itemView.context, item.contentUri)
- val intent = UploadVideoActivity.getIntent(holder.itemView.context, path, "本地视频", "", "")
- (holder.itemView.context as AppCompatActivity).startActivityForResult(intent, VideoActivity.INSERT_VIDEO_CODE)
+ if (mSelectedVideoList.contains(item)) {
+ mSelectedVideoList.remove(item)
+ notifyItemChanged(position)
+ callback.invoke(mSelectedVideoList)
+ } else {
+ if (mSelectedVideoList.size < maxChooseSize) {
+ mSelectedVideoList.add(item)
+ notifyItemChanged(position)
+ callback.invoke(mSelectedVideoList)
+ } else {
+ ToastUtils.showToast("至多选择${maxChooseSize}条视频")
+ }
+ }
}
}
override fun getItemViewType(position: Int, cursor: Cursor?): Int {
return 0
}
+
+ fun getSelectedVideoList(): ArrayList
- {
+ return mSelectedVideoList
+ }
}
class LocalVideoPreviewViewHolder(val binding: LocalVideoItemBinding) : BaseRecyclerViewHolder(binding.root)
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoFragment.kt
index abefa8c9f3..a8f59a1bcb 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/LocalVideoFragment.kt
@@ -8,12 +8,19 @@ import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import com.gh.base.fragment.BaseFragment
+import com.gh.common.util.EntranceUtils
import com.gh.common.util.dip2px
+import com.gh.common.util.toColor
+import com.gh.common.util.toDrawable
import com.gh.common.view.GridSpacingItemDecoration
+import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.ActivityEditorVideoBinding
+import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.video.upload.view.UploadVideoActivity
+import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.zhihu.matisse.internal.entity.Album
import com.zhihu.matisse.internal.model.AlbumMediaCollection
+import com.zhihu.matisse.internal.utils.PathUtils
class LocalVideoFragment : BaseFragment(), AlbumMediaCollection.AlbumMediaCallbacks {
lateinit var binding: ActivityEditorVideoBinding
@@ -31,10 +38,38 @@ class LocalVideoFragment : BaseFragment(), AlbumMediaCollection.AlbumMediaC
super.onCreate(savedInstanceState)
binding.reuseTvNoneData.text = "暂无数据~"
binding.listRv.layoutManager = GridLayoutManager(requireContext(), 3)
- binding.listRv.addItemDecoration(GridSpacingItemDecoration(3, 1F.dip2px(), false))
- mAdapter = LocalVideoAdapter()
+ binding.listRv.addItemDecoration(GridSpacingItemDecoration(3, 4F.dip2px(), false))
+ val maxChooseCount = arguments?.getInt(EntranceUtils.KEY_CHOOSE_MAX_COUNT, 1)
+ mAdapter = LocalVideoAdapter(requireContext(), maxChooseCount ?: 1) {
+ binding.previewTv.isEnabled = it.isNotEmpty()
+ binding.confirmTv.isEnabled = it.isNotEmpty()
+ if (it.isEmpty()) {
+ binding.previewTv.setTextColor(R.color.text_cccccc.toColor())
+ binding.confirmTv.alpha = 0.6f
+ } else {
+ binding.previewTv.setTextColor(R.color.text_666666.toColor())
+ binding.confirmTv.alpha = 1f
+ }
+ binding.numTv.text = "${it.size}/${mAdapter.maxChooseSize}"
+ }
+ binding.numTv.text = "0/${mAdapter.maxChooseSize}"
binding.listRv.adapter = mAdapter
binding.listRefresh.isEnabled = false
+
+ binding.previewTv.setOnClickListener {
+ val intent = PreviewVideoActivity.getIntent(requireContext(), mAdapter.getSelectedVideoList())
+ requireActivity().startActivityForResult(intent, PREVIEW_VIDEO)
+ }
+ binding.confirmTv.setOnClickListener {
+ val localVideoList = arrayListOf()
+ mAdapter.getSelectedVideoList().forEach {
+ localVideoList.add(LocalVideoEntity(PathUtils.getPath(requireContext(), it.uri)))
+ }
+ val intent = Intent()
+ intent.putExtra(LocalVideoEntity::class.java.name, localVideoList)
+ requireActivity().setResult(Activity.RESULT_OK, intent)
+ requireActivity().finish()
+ }
}
override fun onAlbumMediaReset() {
@@ -60,11 +95,9 @@ class LocalVideoFragment : BaseFragment(), AlbumMediaCollection.AlbumMediaC
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
- if (data != null && requestCode == VideoActivity.INSERT_VIDEO_CODE) {
- if (resultCode == UploadVideoActivity.RESULT_CODE_VIDEO) {
- requireActivity().setResult(Activity.RESULT_OK, data)
- requireActivity().finish()
- }
+ if (data != null) {
+ requireActivity().setResult(Activity.RESULT_OK, data)
+ requireActivity().finish()
}
}
@@ -73,4 +106,8 @@ class LocalVideoFragment : BaseFragment(), AlbumMediaCollection.AlbumMediaC
mAlbumMediaCollection?.onDestroy()
}
+ companion object {
+ const val PREVIEW_VIDEO = 100
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/PreviewVideoActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/PreviewVideoActivity.kt
new file mode 100644
index 0000000000..45421caa37
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/PreviewVideoActivity.kt
@@ -0,0 +1,34 @@
+package com.gh.gamecenter.qa.editor
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.base.BaseActivity
+import com.gh.common.util.DisplayUtils
+import com.gh.common.util.EntranceUtils
+import com.gh.gamecenter.R
+import com.zhihu.matisse.internal.entity.Item
+
+class PreviewVideoActivity : BaseActivity() {
+ override fun getLayoutId(): Int {
+ return R.layout.activity_amway
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ DisplayUtils.transparentStatusBar(this)
+
+ val containerFragment = supportFragmentManager.findFragmentByTag(PreviewVideoFragment::class.java.simpleName)
+ ?: PreviewVideoFragment().with(intent.extras)
+ // 若 placeholder 外层为 RelativeLayout 的话,会出现莫名的偏移
+ supportFragmentManager.beginTransaction().replace(R.id.placeholder, containerFragment, PreviewVideoFragment::class.java.simpleName).commitAllowingStateLoss()
+ }
+
+ companion object {
+ fun getIntent(context: Context,videos:ArrayList
- ): Intent {
+ val intent = Intent(context, PreviewVideoActivity::class.java)
+ intent.putExtra(EntranceUtils.KEY_VIDEO_LIST,videos)
+ return intent
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/PreviewVideoFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/PreviewVideoFragment.kt
new file mode 100644
index 0000000000..7ccf0c0972
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/PreviewVideoFragment.kt
@@ -0,0 +1,180 @@
+package com.gh.gamecenter.qa.editor
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
+import com.facebook.drawee.generic.RoundingParams
+import com.facebook.drawee.view.SimpleDraweeView
+import com.gh.base.fragment.BaseFragment
+import com.gh.base.fragment.WaitingDialogFragment
+import com.gh.common.util.*
+import com.gh.common.view.GridSpacingItemColorDecoration
+import com.gh.gamecenter.CropImageActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.FragmentPreviewVideoBinding
+import com.gh.gamecenter.databinding.ItemVideoSelectorBinding
+import com.gh.gamecenter.entity.LocalVideoEntity
+import com.gh.gamecenter.video.poster.PosterEditActivity
+import com.gh.gamecenter.video.upload.view.UploadVideoActivity
+import com.lightgame.adapter.BaseRecyclerAdapter
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.zhihu.matisse.internal.entity.Item
+import com.zhihu.matisse.internal.utils.PathUtils
+
+class PreviewVideoFragment : BaseFragment() {
+ private lateinit var mBinding: FragmentPreviewVideoBinding
+ private var mVideoItems: ArrayList
- = arrayListOf()
+ private var mProcessingDialog: WaitingDialogFragment? = null
+ private lateinit var mVideoSelectorAdapter: VideoSelectorAdapter
+ private val mLocalVideoList = arrayListOf()
+ override fun getLayoutId(): Int = 0
+
+ override fun getInflatedLayout(): View {
+ mBinding = FragmentPreviewVideoBinding.inflate(LayoutInflater.from(requireContext()), null, false)
+ return mBinding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mVideoItems = arguments?.getParcelableArrayList
- (EntranceUtils.KEY_VIDEO_LIST)
+ ?: arrayListOf()
+ if (mVideoItems.isNotEmpty()) {
+ mVideoItems.forEach {
+ val localVideoEntity = LocalVideoEntity(
+ PathUtils.getPath(requireContext(), it.uri),
+ contentUri = it.contentUri,
+ duration = it.duration
+ )
+ mLocalVideoList.add(localVideoEntity)
+ }
+ initVideo(mLocalVideoList[0])
+ }
+ mBinding.numTv.text = "(1/${mVideoItems.size})"
+ mVideoSelectorAdapter = VideoSelectorAdapter(requireContext(), mLocalVideoList) { entity, position ->
+ mBinding.videoView.release()
+ mBinding.numTv.text = "(${position + 1}/${mVideoItems.size})"
+ initVideo(entity)
+ }
+ mBinding.videoSelectorRv.adapter = mVideoSelectorAdapter
+ mBinding.videoSelectorRv.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
+ mBinding.videoSelectorRv.addItemDecoration(GridSpacingItemColorDecoration(requireContext(), 8, 0, R.color.transparent))
+ mBinding.confirmTv.setOnClickListener {
+ val intent = Intent()
+ intent.putExtra(LocalVideoEntity::class.java.name, mLocalVideoList)
+ requireActivity().setResult(Activity.RESULT_OK, intent)
+ requireActivity().finish()
+ }
+
+ mBinding.changeCoverTv.setOnClickListener {
+ val item = mVideoItems[mVideoSelectorAdapter.selectPosition]
+ val intent = PosterEditActivity.getIntentByPath(requireContext(), PathUtils.getPath(requireContext(), item.uri))
+ startActivityForResult(intent, UploadVideoActivity.REQUEST_CODE_IMAGE_CROP)
+ }
+ mBinding.backBtn.setOnClickListener { requireActivity().finish() }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (data == null || resultCode != Activity.RESULT_OK) return
+ if (requestCode == UploadVideoActivity.REQUEST_CODE_IMAGE_CROP) {
+ val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
+ if (imagePath.isNotEmpty()) {
+ uploadImage(imagePath)
+ }
+ }
+ }
+
+ private fun uploadImage(imagePath: String) {
+ mProcessingDialog = WaitingDialogFragment.newInstance("图片上传中...", false)
+ mProcessingDialog?.show(requireActivity().supportFragmentManager, WaitingDialogFragment::class.java.name)
+ UploadImageUtils.uploadImage(UploadImageUtils.UploadType.poster, imagePath, object : UploadImageUtils.OnUploadImageListener {
+ override fun onSuccess(imageUrl: String) {
+ mProcessingDialog?.dismiss()
+ mLocalVideoList[mVideoSelectorAdapter.selectPosition].poster = imageUrl
+ mBinding.videoView.updateThumb(imageUrl)
+ }
+
+ override fun onError(e: Throwable?) {
+ mProcessingDialog?.dismiss()
+ ToastUtils.showToast("上传失败")
+ }
+
+ override fun onProgress(total: Long, progress: Long) {}
+ })
+ }
+
+ private fun initVideo(entity: LocalVideoEntity) {
+ GSYVideoOptionBuilder()
+ .setIsTouchWiget(false)
+ .setUrl(entity.filePath)
+ .setRotateViewAuto(false)
+ .setCacheWithPlay(false)
+ .setRotateWithSystem(false)
+ .setReleaseWhenLossAudio(true)
+ .setLooping(false)
+ .setShowFullAnimation(false)
+ .build(mBinding.videoView)
+ if (entity.poster.isNotEmpty()) {
+ mBinding.videoView.updateThumb(entity.poster)
+ } else {
+ mBinding.videoView.updateThumb("file:///${PathUtils.getPath(requireContext(), entity.contentUri)}")
+ }
+ }
+
+ class VideoSelectorAdapter(context: Context, val localVideoList: ArrayList, val callback: (LocalVideoEntity, Int) -> Unit) : BaseRecyclerAdapter(context) {
+ var selectPosition: Int = 0
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return VideoSelectorViewHolder(ItemVideoSelectorBinding.inflate(LayoutInflater.from(mContext), parent, false))
+ }
+
+ override fun getItemCount(): Int = localVideoList.size
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ if (holder is VideoSelectorViewHolder) {
+ val item = localVideoList[position]
+ setPreviewBorder(holder.binding.preview, selectPosition == position)
+ ImageUtils.display(holder.binding.preview, "file:///${PathUtils.getPath(mContext, item.contentUri)}")
+ holder.binding.root.setOnClickListener {
+ selectPosition = position
+ callback.invoke(localVideoList[selectPosition], selectPosition)
+ notifyDataSetChanged()
+ }
+ }
+ }
+
+ private fun setPreviewBorder(view: SimpleDraweeView, isSelected: Boolean) {
+ val params = RoundingParams()
+ params.setBorder(if (isSelected) R.color.white.toColor() else R.color.transparent.toColor(), 1f.dip2px().toFloat())
+ params.setCornersRadius(4f.dip2px().toFloat())
+ val build = GenericDraweeHierarchyBuilder.newInstance(mContext.resources)
+ .setRoundingParams(params)
+ .build()
+ view.hierarchy = build
+ }
+ }
+
+ class VideoSelectorViewHolder(val binding: ItemVideoSelectorBinding) : RecyclerView.ViewHolder(binding.root)
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/editor/VideoActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/editor/VideoActivity.kt
index d4034d8471..584b3d3e8e 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/editor/VideoActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/editor/VideoActivity.kt
@@ -17,6 +17,7 @@ import androidx.viewpager.widget.ViewPager
import com.gh.base.ToolBarActivity
import com.gh.base.adapter.FragmentAdapter
import com.gh.base.fragment.BaseFragment_TabLayout
+import com.gh.common.util.EntranceUtils
import com.gh.common.util.viewModelProvider
import com.gh.common.view.TabIndicatorView
import com.gh.gamecenter.R
@@ -48,6 +49,7 @@ class VideoActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks {
private lateinit var mAlbumsSpinner: VideoAlbumsSpanner
private lateinit var mAlbumsAdapter: VideoAlbumsAdapter
private val mAlbumCollection = AlbumCollection()
+ private var mIsFirstAlbumLoad = true
override fun getLayoutId(): Int = R.layout.activity_video_tablayout_viewpager
@@ -55,11 +57,13 @@ class VideoActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks {
super.onCreate(savedInstanceState)
mViewModel = viewModelProvider()
- mViewModel.obsListData.observe(this, Observer {
- initViewPager()
- initAlbumsSpinner()
- })
- mViewModel.load(LoadType.REFRESH)
+// mViewModel.obsListData.observe(this, Observer {
+// initViewPager()
+// initAlbumsSpinner()
+// })
+// mViewModel.load(LoadType.REFRESH)
+ initViewPager()
+ initAlbumsSpinner()
}
private fun initAlbumsSpinner() {
@@ -95,19 +99,22 @@ class VideoActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks {
mAlbumCollection.loadAlbums()
}
-
override fun onAlbumLoad(cursor: Cursor?) {
- mAlbumsAdapter.swapCursor(cursor)
- mBaseHandler.post {
- cursor?.moveToPosition(mAlbumCollection.currentSelection)
- val album = Album.valueOf(cursor)
- if (album.isAll && SelectionSpec.getInstance().capture) {
- album.addCaptureCount()
- }
- if (mLocalVideoFragment?.isAdded == true) {
- mLocalVideoFragment?.loadVideos(album)
+ if (mIsFirstAlbumLoad) {
+ mIsFirstAlbumLoad = false
+ mAlbumsAdapter.swapCursor(cursor)
+ mBaseHandler.post {
+ cursor?.moveToPosition(mAlbumCollection.currentSelection)
+ val album = Album.valueOf(cursor)
+ if (album.isAll && SelectionSpec.getInstance().capture) {
+ album.addCaptureCount()
+ }
+ if (mLocalVideoFragment?.isAdded == true) {
+ mLocalVideoFragment?.loadVideos(album)
+ }
}
}
+
}
override fun onAlbumReset() {
@@ -115,14 +122,15 @@ class VideoActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks {
}
private fun initViewPager() {
- if (!mViewModel.obsListData.value.isNullOrEmpty()) {
+ /*if (!mViewModel.obsListData.value.isNullOrEmpty()) {
mTabTitleList.add("视频库")
mFragmentsList.add(OnlineVideoFragment())
} else {
mTabIndicatorView.visibility = View.GONE
- }
+ }*/
+ mTabIndicatorView.visibility = View.GONE
mTabTitleList.add("本地视频")
- mLocalVideoFragment = LocalVideoFragment()
+ mLocalVideoFragment = LocalVideoFragment().apply { arguments = intent.extras }
mFragmentsList.add(mLocalVideoFragment!!)
mViewPager.offscreenPageLimit = mFragmentsList.size
mViewPager.adapter = FragmentAdapter(supportFragmentManager, mFragmentsList, mTabTitleList)
@@ -146,9 +154,11 @@ class VideoActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks {
private fun provideTabView(tabTitle: String): View {
val binding = TabItemChooseVideoBinding.inflate(LayoutInflater.from(this), null, false)
binding.tabTitle.text = tabTitle
- if (mViewModel.obsListData.value.isNullOrEmpty()) {
- binding.tabTitle.setTextColor(ContextCompat.getColor(this, R.color.text_333333))
- }
+// if (mViewModel.obsListData.value.isNullOrEmpty()) {
+// binding.tabTitle.setTextColor(ContextCompat.getColor(this, R.color.text_333333))
+// }
+ binding.tabTitle.setTextColor(ContextCompat.getColor(this, R.color.text_333333))
+ binding.tabTitle.textSize = 16f
if (tabTitle == "本地视频") {
binding.tabArrow.visibility = View.VISIBLE
binding.root.setOnTouchListener { _, _ ->
@@ -169,10 +179,10 @@ class VideoActivity : ToolBarActivity(), AlbumCollection.AlbumCallbacks {
}
companion object {
- const val INSERT_VIDEO_CODE = 414
-
- fun getIntent(context: Context): Intent {
- return Intent(context, VideoActivity::class.java)
+ fun getIntent(context: Context, maxChooseCount: Int = 1): Intent {
+ return Intent(context, VideoActivity::class.java).apply {
+ putExtra(EntranceUtils.KEY_CHOOSE_MAX_COUNT, maxChooseCount)
+ }
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt
index 60a988cb5a..df9294cf9e 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/questions/edit/QuestionEditActivity.kt
@@ -20,6 +20,7 @@ import androidx.core.widget.addTextChangedListener
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
+import com.gh.base.BaseRichEditorActivity.Companion.INSERT_VIDEO_CODE
import com.gh.base.ToolBarActivity
import com.gh.base.fragment.WaitingDialogFragment
import com.gh.common.AppExecutor
@@ -38,7 +39,7 @@ import com.gh.gamecenter.mvvm.Status
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
import com.gh.gamecenter.qa.article.draft.ArticleDraftActivity
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
-import com.gh.gamecenter.qa.dialog.ChooseForumDialogFragment
+import com.gh.gamecenter.qa.dialog.ChooseForumActivity
import com.gh.gamecenter.qa.editor.VideoActivity
import com.gh.gamecenter.qa.entity.CommunityVideoEntity
import com.gh.gamecenter.qa.entity.QuestionDraftEntity
@@ -84,12 +85,12 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
@SuppressLint("Recycle")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
-
- if (requestCode == MEDIA_STORE_REQUEST && resultCode == RESULT_OK) {
+ if (data == null || resultCode != Activity.RESULT_OK) return
+ if (requestCode == MEDIA_STORE_REQUEST) {
val selectedPics = Matisse.obtainResult(data)
mViewModel.validatePic(selectedPics)
- } else if (requestCode == VideoActivity.INSERT_VIDEO_CODE && resultCode == RESULT_OK) {
- val videoEntity = data?.getParcelableExtra(MyVideoEntity::class.java.simpleName)
+ } else if (requestCode == INSERT_VIDEO_CODE) {
+ val videoEntity = data.getParcelableExtra(MyVideoEntity::class.java.simpleName)
if (videoEntity != null) {
mViewModel.videoLiveData.postValue(CommunityVideoEntity(
id = videoEntity.id,
@@ -98,13 +99,22 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
duration = RichEditor.formatVideoDuration(videoEntity.length),
status = videoEntity.status))
}
- } else if (requestCode == QUESTION_DRAFT_REQUEST_CODE && resultCode == RESULT_OK) {
- val draftEntity = data?.getParcelableExtra(QuestionDraftEntity::class.java.simpleName)
+ } else if (requestCode == QUESTION_DRAFT_REQUEST_CODE) {
+ val draftEntity = data.getParcelableExtra(QuestionDraftEntity::class.java.simpleName)
if (draftEntity != null) {
mViewModel.questionDraftEntity = draftEntity
setQuestionDraft(draftEntity)
mViewModel.getQuestionDraftContent(draftEntity.id)
}
+ } else if (requestCode == ChooseForumActivity.CHOOSE_FORUM_REQUEST) {
+ val community = data.getParcelableExtra(EntranceUtils.KEY_COMMUNITY_DATA)
+ mViewModel.communityEntity = community
+ if (mViewModel.questionEntity != null) {
+ mViewModel.questionEntity?.community?.id = community?.id ?: ""
+ mViewModel.questionEntity?.community?.name = community?.name ?: ""
+ }
+ setForumName()
+ mBinding.vm = mViewModel
}
}
@@ -494,7 +504,7 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
object : EmptyCallback {
override fun onCallback() {
MtaHelper.onEvent("发表问题", "插入链接", "插入视频")
- startActivityForResult(VideoActivity.getIntent(this@QuestionEditActivity), VideoActivity.INSERT_VIDEO_CODE)
+ startActivityForResult(VideoActivity.getIntent(this@QuestionEditActivity), INSERT_VIDEO_CODE)
}
})
}
@@ -574,15 +584,7 @@ class QuestionEditActivity : ToolBarActivity(), KeyboardHeightObserver {
}
private fun showSelectGameDialog() {
- ChooseForumDialogFragment.show(this) {
- mViewModel.communityEntity = it
- if (mViewModel.questionEntity != null) {
- mViewModel.questionEntity?.community?.id = it.id
- mViewModel.questionEntity?.community?.name = it.name
- }
- setForumName()
- mBinding.vm = mViewModel
- }
+ ChooseForumActivity.startChooseForumActivity(this)
}
// Limits of EditText
diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/PreviewVideoView.kt b/app/src/main/java/com/gh/gamecenter/qa/video/PreviewVideoView.kt
new file mode 100644
index 0000000000..71e8e94f15
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/video/PreviewVideoView.kt
@@ -0,0 +1,59 @@
+package com.gh.gamecenter.qa.video
+
+import android.content.Context
+import android.net.Uri
+import android.util.AttributeSet
+import android.view.Surface
+import android.view.View
+import android.widget.ImageView
+import com.facebook.drawee.view.SimpleDraweeView
+import com.gh.common.util.ImageUtils
+import com.gh.gamecenter.R
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import com.squareup.picasso.Picasso
+
+class PreviewVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : StandardGSYVideoPlayer(context, attrs) {
+
+ var thumbImage: SimpleDraweeView = findViewById(R.id.thumbImage)
+
+ override fun getLayoutId(): Int {
+ return R.layout.layout_preview_video
+ }
+
+
+ /******************* 下方两个重载方法,在播放开始前不屏蔽封面,不需要可屏蔽 ********************/
+
+ override fun onSurfaceUpdated(surface: Surface) {
+ super.onSurfaceUpdated(surface)
+ if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
+ mThumbImageViewLayout.visibility = View.INVISIBLE
+ }
+ }
+
+ fun updateThumb(url: String) {
+ ImageUtils.display(thumbImage, url)
+ }
+
+ override fun setViewShowState(view: View?, visibility: Int) {
+ if (view === mThumbImageViewLayout && visibility != View.VISIBLE) {
+ return
+ }
+ super.setViewShowState(view, visibility)
+ }
+
+ /********************************各类UI的状态显示*********************************************/
+
+ override fun touchSurfaceMoveFullLogic(absDeltaX: Float, absDeltaY: Float) {
+ super.touchSurfaceMoveFullLogic(absDeltaX, absDeltaY)
+ //不给触摸快进,如果需要,屏蔽下方代码即可
+ mChangePosition = false
+ //不给触摸音量,如果需要,屏蔽下方代码即可
+ mChangeVolume = false
+ //不给触摸亮度,如果需要,屏蔽下方代码即可
+ mBrightness = false
+ }
+
+ override fun touchDoubleUp() {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishActivity.kt
new file mode 100644
index 0000000000..adf1a5b69f
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishActivity.kt
@@ -0,0 +1,26 @@
+package com.gh.gamecenter.qa.video.publish
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import com.gh.gamecenter.NormalActivity
+import com.gh.gamecenter.R
+
+class VideoPublishActivity : NormalActivity() {
+ override fun getLayoutId(): Int = R.layout.activity_video_publish
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mToolbar.navigationIcon = null
+ findViewById(R.id.backBtn).setOnClickListener { finish() }
+ }
+
+ companion object {
+ @JvmStatic
+ fun getIntent(context: Context): Intent {
+ return getTargetIntent(context, VideoPublishActivity::class.java, VideoPublishFragment::class.java)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishFragment.kt
new file mode 100644
index 0000000000..8c32d62cd7
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishFragment.kt
@@ -0,0 +1,293 @@
+package com.gh.gamecenter.qa.video.publish
+
+import android.app.Activity
+import android.content.Intent
+import android.media.MediaMetadataRetriever
+import android.media.ThumbnailUtils
+import android.net.Uri
+import android.os.Bundle
+import android.provider.MediaStore
+import android.view.LayoutInflater
+import android.view.MenuItem
+import android.view.View
+import androidx.core.content.ContextCompat
+import androidx.core.widget.doOnTextChanged
+import com.gh.base.BaseRichEditorActivity
+import com.gh.common.runOnUiThread
+import com.gh.common.util.*
+import com.gh.gamecenter.CropImageActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.FragmentVideoPublishBinding
+import com.gh.gamecenter.entity.CommunityEntity
+import com.gh.gamecenter.entity.LocalVideoEntity
+import com.gh.gamecenter.entity.VideoEntity
+import com.gh.gamecenter.normal.NormalFragment
+import com.gh.gamecenter.qa.dialog.ChooseForumActivity
+import com.gh.gamecenter.qa.editor.VideoActivity
+import com.gh.gamecenter.video.poster.PosterEditActivity
+import com.gh.gamecenter.video.upload.OnUploadListener
+import com.gh.gamecenter.video.upload.UploadManager
+import com.gh.gamecenter.video.upload.view.VideoFileEntity
+import com.lightgame.download.FileUtils
+import java.io.File
+
+class VideoPublishFragment : NormalFragment() {
+
+ private lateinit var mBinding: FragmentVideoPublishBinding
+ private lateinit var mViewModel: VideoPublishViewModel
+ private var mVideoFileEntity: VideoFileEntity? = null
+ private lateinit var mMenuDraft: MenuItem
+ private lateinit var mMenuPost: MenuItem
+
+ override fun getLayoutId(): Int = 0
+
+ override fun getInflatedLayout(): View {
+ mBinding = FragmentVideoPublishBinding.inflate(LayoutInflater.from(requireContext()), null, false)
+ return mBinding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setNavigationTitle("发视频")
+ initMenu(R.menu.menu_answer_post)
+ mMenuDraft = getItemMenu(R.id.menu_draft)
+ mMenuPost = getItemMenu(R.id.menu_answer_post)
+ mViewModel = viewModelProvider()
+
+ mBinding.title.filters = arrayOf(TextHelper.getFilter(50, "标题最多50个字"))
+ mBinding.title.doOnTextChanged { text, start, count, after ->
+ if (text?.contains("\n") == true) {
+ mBinding.title.setText(text.toString().replace("\n", ""))
+ mBinding.title.setSelection(start)
+ return@doOnTextChanged
+ }
+ if (PatternUtils.isHasSpace(text.toString())) {
+ mBinding.title.setText(PatternUtils.replaceSpace(text.toString()))
+ mBinding.title.setSelection(start)
+ return@doOnTextChanged
+ }
+ checkPostButtonEnable()
+ }
+
+ mBinding.uploadButton.setOnClickListener {
+ PermissionHelper.checkStoragePermissionBeforeAction(requireActivity(), object : EmptyCallback {
+ override fun onCallback() {
+ startActivityForResult(VideoActivity.getIntent(requireContext(), 1), BaseRichEditorActivity.INSERT_VIDEO_CODE)
+ }
+ })
+ }
+ mBinding.videoPosterPatchHint.setOnClickListener { startMediaStore() }
+ mBinding.forumContainer.setOnClickListener {
+ ChooseForumActivity.startChooseForumActivity(requireActivity())
+ }
+ mBinding.chooseActivityContainer.setOnClickListener {
+ //选择活动
+ }
+ mBinding.deleteVideoIv.setOnClickListener {
+
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (data == null || resultCode != Activity.RESULT_OK) return
+ if (requestCode == BaseRichEditorActivity.INSERT_VIDEO_CODE) {
+ val localVideoList = data.getParcelableArrayListExtra(LocalVideoEntity::class.java.name)
+ ?: arrayListOf()
+ if (localVideoList.isNotEmpty()) {
+ initUpload(localVideoList[0])
+ }
+ } else if (requestCode == REQUEST_CODE_IMAGE_CROP) {
+ val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
+ mBinding.videoPoster.setImageURI("file://$imagePath")
+ mVideoFileEntity?.poster = imagePath ?: ""
+ } else if (requestCode == ChooseForumActivity.CHOOSE_FORUM_REQUEST) {
+ val community = data.getParcelableExtra(EntranceUtils.KEY_COMMUNITY_DATA)
+ mViewModel.communityEntity = community
+ setForumName()
+ }
+ }
+
+ private fun initUpload(localVideoEntity: LocalVideoEntity) {
+ val videoPath = localVideoEntity.filePath
+ if (videoPath.isEmpty() || !File(videoPath).exists()) {
+ handleFileNotFound()
+ return
+ }
+ if (localVideoEntity.poster.isNotEmpty()) {
+ ImageUtils.display(mBinding.videoPoster, localVideoEntity.poster)
+ } else {
+ val thumbnail = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.MINI_KIND)
+ mBinding.videoPoster.setImageBitmap(thumbnail)
+ }
+
+ mBinding.uploadButton.visibility = View.GONE
+ mBinding.videoPosterMask.visibility = View.GONE
+ mBinding.pauseButton.setOnClickListener {
+ when {
+ UploadManager.isUploading(videoPath) -> {
+ mBinding.uploadStatus.text = "上传已暂停"
+ mBinding.uploadInfoContainer.visibility = View.VISIBLE
+ mBinding.uploadSpeed.visibility = View.GONE
+ mBinding.pauseButton.setImageResource(R.drawable.upload_resume)
+ mBinding.pauseButton.visibility = View.VISIBLE
+ UploadManager.cancelTask(videoPath)
+ }
+ File(videoPath).exists() -> {
+ mBinding.uploadStatus.text = "视频上传中..."
+ mBinding.uploadInfoContainer.visibility = View.VISIBLE
+ mBinding.pauseButton.setImageResource(R.drawable.upload_pause)
+ mBinding.pauseButton.visibility = View.VISIBLE
+ createUploadTask(videoPath)
+ }
+ else -> {
+ handleFileNotFound()
+ toast("上传失败,视频文件不存在")
+ }
+ }
+ }
+ val videoFile = File(videoPath)
+ val retriever = MediaMetadataRetriever()
+ val fileUri = Uri.fromFile(videoFile)
+ retriever.setDataSource(requireContext(), fileUri)
+ val time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) ?: "0"
+ val timeInSecond = java.lang.Long.parseLong(time) / 1000
+ retriever.release()
+
+ var format = ""
+ tryWithDefaultCatch {
+ val mimeType = FileUtils.getFileMimeType(requireContext(), videoPath)
+ if (mimeType != null) {
+ val split = mimeType.split("/")
+ format = if (split.count() >= 2) {
+ split[1]
+ } else {
+ mimeType
+ }
+ }
+ }
+
+ mVideoFileEntity = VideoFileEntity(videoPath, null, localVideoEntity.poster, timeInSecond, videoFile.length(), format)
+ createUploadTask(videoPath)
+ }
+
+ private fun createUploadTask(videoPath: String) {
+ mBinding.uploadStatus.text = "视频上传中..."
+ UploadManager.createUploadTask(videoPath, object : OnUploadListener {
+ override fun onProgressChanged(uploadFilePath: String, currentSize: Long, totalSize: Long, speed: Long) {
+ runOnUiThread {
+ mBinding.uploadInfoContainer.visibility = View.VISIBLE
+ mBinding.uploadStatus.text = "视频上传中..."
+ mBinding.uploadSpeed.visibility = View.VISIBLE
+ mBinding.pauseButton.visibility = View.VISIBLE
+ mBinding.uploadSpeed.text = (SpeedUtils.getSpeed(speed) + "预计还需" + SpeedUtils.getRemainTime(totalSize, currentSize, speed))
+ mBinding.uploadProgress.update(((360 * currentSize) / totalSize).toInt(), "")
+ }
+ }
+
+ override fun onUploadSuccess(uploadFilePath: String, url: String) {
+ runOnUiThread {
+ handleUploadSuccess(url)
+ }
+ }
+
+ override fun onUploadFailure(uploadFilePath: String, errorMsg: String) {
+ runOnUiThread {
+ if (!File(uploadFilePath).exists()) {
+ handleFileNotFound()
+ toast("上传失败,视频文件不存在")
+ } else {
+ mBinding.uploadStatus.text = "网络错误,中断上传"
+ mBinding.pauseButton.setImageResource(R.drawable.upload_resume)
+ mBinding.pauseButton.visibility = View.VISIBLE
+ toast("网络错误,请检查网络正常后再重试")
+ }
+ mBinding.uploadSpeed.visibility = View.GONE
+ }
+ }
+ })
+ }
+
+ private fun handleFileNotFound() {
+ mBinding.uploadButton.visibility = View.VISIBLE
+ mBinding.uploadInfoContainer.visibility = View.GONE
+ mBinding.videoPosterMask.visibility = View.VISIBLE
+ }
+
+ private fun handleUploadSuccess(url: String) {
+ mBinding.uploadButton.visibility = View.GONE
+ mBinding.uploadInfoContainer.visibility = View.GONE
+ mBinding.videoPosterMask.visibility = View.GONE
+ mBinding.videoPosterPatchHint.visibility = View.VISIBLE
+ mBinding.uploadProgress.update(360, "")
+ mVideoFileEntity?.url = url
+ }
+
+ private fun setForumName() {
+ if (mViewModel.communityEntity != null) {
+ mBinding.chooseForumTv.text = mViewModel.communityEntity?.name
+ mBinding.forumIconView.visibility = View.VISIBLE
+ mBinding.forumIconView.displayGameIcon(mViewModel.communityEntity?.icon, mViewModel.communityEntity?.iconSubscript)
+ mBinding.forumContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.bg_shape_f8_radius_4)
+ mBinding.chooseForumTv.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(requireContext(), R.drawable.ic_article_edit_choose_forum_arrow_gray), null)
+ mBinding.chooseForumTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.text_333333))
+ }
+ }
+
+ private fun checkPostButtonEnable() {
+
+ }
+
+ override fun onMenuItemClick(menuItem: MenuItem?) {
+ super.onMenuItemClick(menuItem)
+ when (menuItem?.itemId) {
+ R.id.menu_answer_post -> {
+
+ }
+ R.id.menu_draft -> {
+
+ }
+ }
+ }
+
+ private fun startMediaStore() {
+ try {
+ PermissionHelper.checkStoragePermissionBeforeAction(requireContext(), object : EmptyCallback {
+ override fun onCallback() {
+ var intent: Intent? = null
+ when {
+ mVideoFileEntity?.url?.isNotEmpty() == true -> {
+ val videoEntity = VideoEntity(length = mVideoFileEntity?.length
+ ?: 0, url = mVideoFileEntity?.url ?: "")
+ intent = PosterEditActivity.getIntentByVideo(requireContext(), videoEntity)
+ }
+ mVideoFileEntity?.path?.isNotEmpty() == true -> {
+ intent = PosterEditActivity.getIntentByPath(requireContext(), mVideoFileEntity?.url
+ ?: "")
+ }
+ else -> {
+ throwExceptionInDebug("video not found")
+ }
+ }
+ startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
+ }
+ })
+ } catch (e: Exception) {
+ toast(R.string.media_image_hint)
+ e.printStackTrace()
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ val path = mVideoFileEntity?.path
+ if (path != null && UploadManager.isUploading(path)) {
+ UploadManager.cancelTask(path)
+ }
+ }
+
+ companion object {
+ const val REQUEST_CODE_IMAGE_CROP = 101
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishViewModel.kt
new file mode 100644
index 0000000000..41a3cd9508
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/video/publish/VideoPublishViewModel.kt
@@ -0,0 +1,9 @@
+package com.gh.gamecenter.qa.video.publish
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import com.gh.gamecenter.entity.CommunityEntity
+
+class VideoPublishViewModel(application: Application) : AndroidViewModel(application) {
+ var communityEntity: CommunityEntity? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/video/upload/view/UploadVideoActivity.kt b/app/src/main/java/com/gh/gamecenter/video/upload/view/UploadVideoActivity.kt
index 927256cc0f..2f7a74b5b4 100644
--- a/app/src/main/java/com/gh/gamecenter/video/upload/view/UploadVideoActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/video/upload/view/UploadVideoActivity.kt
@@ -584,7 +584,8 @@ class UploadVideoActivity : ToolBarActivity() {
} else {
val localVideoPoster = application.cacheDir.absolutePath + File.separator + System.currentTimeMillis() + ".jpg"
try {
- val bmp = ThumbnailUtils.createVideoThumbnail(mVideoFileEntity?.path ?: "", MediaStore.Images.Thumbnails.MINI_KIND)
+ val bmp = ThumbnailUtils.createVideoThumbnail(mVideoFileEntity?.path
+ ?: "", MediaStore.Images.Thumbnails.MINI_KIND)
// bmp 可能为空
FileOutputStream(localVideoPoster).use { out ->
bmp?.compress(Bitmap.CompressFormat.PNG, 100, out)
@@ -728,7 +729,7 @@ class UploadVideoActivity : ToolBarActivity() {
}
}
}
- mVideoFileEntity = VideoFileEntity(videoPath, null, timeInSecond, videoFile.length(), format)
+ mVideoFileEntity = VideoFileEntity(videoPath, null, "", timeInSecond, videoFile.length(), format)
createUploadTask(videoPath)
}
diff --git a/app/src/main/java/com/gh/gamecenter/video/upload/view/VideoFileEntity.kt b/app/src/main/java/com/gh/gamecenter/video/upload/view/VideoFileEntity.kt
index 58dc296f92..0161bb4d02 100644
--- a/app/src/main/java/com/gh/gamecenter/video/upload/view/VideoFileEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/video/upload/view/VideoFileEntity.kt
@@ -3,7 +3,8 @@ package com.gh.gamecenter.video.upload.view
data class VideoFileEntity(
val path: String,
var url: String?,
- val length: Long,
- val size: Long,
+ var poster: String,
+ var length: Long = 0,
+ var size: Long = 0,
val format: String
)
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_article.webp b/app/src/main/res/drawable-xxhdpi/community_edit_article.webp
index 05d8cfd60d..5fb8624587 100644
Binary files a/app/src/main/res/drawable-xxhdpi/community_edit_article.webp and b/app/src/main/res/drawable-xxhdpi/community_edit_article.webp differ
diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_close.png b/app/src/main/res/drawable-xxhdpi/community_edit_close.png
new file mode 100644
index 0000000000..8383082598
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/community_edit_close.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_close.webp b/app/src/main/res/drawable-xxhdpi/community_edit_close.webp
deleted file mode 100644
index 2bd31942fc..0000000000
Binary files a/app/src/main/res/drawable-xxhdpi/community_edit_close.webp and /dev/null differ
diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_question.webp b/app/src/main/res/drawable-xxhdpi/community_edit_question.webp
index d312d27892..c093c8cfa8 100644
Binary files a/app/src/main/res/drawable-xxhdpi/community_edit_question.webp and b/app/src/main/res/drawable-xxhdpi/community_edit_question.webp differ
diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_video.webp b/app/src/main/res/drawable-xxhdpi/community_edit_video.webp
new file mode 100644
index 0000000000..2a7459bff8
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/community_edit_video.webp differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_choose_activity.webp b/app/src/main/res/drawable-xxhdpi/ic_choose_activity.webp
new file mode 100644
index 0000000000..38af24a83d
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_choose_activity.webp differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_del_video.png b/app/src/main/res/drawable-xxhdpi/ic_del_video.png
new file mode 100644
index 0000000000..f37d1eeb97
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_del_video.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/icon_upload_video_btn.webp b/app/src/main/res/drawable-xxhdpi/icon_upload_video_btn.webp
new file mode 100644
index 0000000000..1a9d18b696
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_upload_video_btn.webp differ
diff --git a/app/src/main/res/drawable/bg_change_cover_btn.xml b/app/src/main/res/drawable/bg_change_cover_btn.xml
new file mode 100644
index 0000000000..1d2e5fd0e9
--- /dev/null
+++ b/app/src/main/res/drawable/bg_change_cover_btn.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/border_round_stroke_0dot5_eee_999.xml b/app/src/main/res/drawable/border_round_stroke_0dot5_eee_999.xml
new file mode 100644
index 0000000000..2e24f2006c
--- /dev/null
+++ b/app/src/main/res/drawable/border_round_stroke_0dot5_eee_999.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_editor_video.xml b/app/src/main/res/layout/activity_editor_video.xml
index fbf97bbd5c..7eface2233 100644
--- a/app/src/main/res/layout/activity_editor_video.xml
+++ b/app/src/main/res/layout/activity_editor_video.xml
@@ -6,22 +6,71 @@
android:background="@color/white"
android:orientation="vertical">
-
-
+ android:layout_marginLeft="2dp"
+ android:layout_marginRight="2dp">
-
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/community_edit_window.xml b/app/src/main/res/layout/community_edit_window.xml
index 857ab0022d..590c50dbf9 100644
--- a/app/src/main/res/layout/community_edit_window.xml
+++ b/app/src/main/res/layout/community_edit_window.xml
@@ -6,87 +6,103 @@
-
+ app:layout_constraintTop_toTopOf="parent">
-
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
-
-
+ app:layout_constraintStart_toEndOf="@+id/community_edit_question_container"
+ app:layout_constraintTop_toTopOf="parent">
+
+
+
+
+
+
-
-
-
+ app:layout_constraintRight_toRightOf="parent" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_choose_forum.xml b/app/src/main/res/layout/dialog_choose_forum.xml
index 30b893105c..29dbff9d52 100644
--- a/app/src/main/res/layout/dialog_choose_forum.xml
+++ b/app/src/main/res/layout/dialog_choose_forum.xml
@@ -2,14 +2,23 @@
+ android:layout_height="match_parent"
+ android:background="@color/transparent"
+ android:focusable="true"
+ android:focusableInTouchMode="true">
+
+
+ android:background="@drawable/game_detail_more_dialog_background">
-
+
+
+
+
+
+
+
+
+
+
+
+ app:layout_constraintTop_toBottomOf="@+id/line" />
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_preview_video.xml b/app/src/main/res/layout/fragment_preview_video.xml
new file mode 100644
index 0000000000..53ee8687d7
--- /dev/null
+++ b/app/src/main/res/layout/fragment_preview_video.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_video_publish.xml b/app/src/main/res/layout/fragment_video_publish.xml
new file mode 100644
index 0000000000..bfe9e6002e
--- /dev/null
+++ b/app/src/main/res/layout/fragment_video_publish.xml
@@ -0,0 +1,278 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_video_selector.xml b/app/src/main/res/layout/item_video_selector.xml
new file mode 100644
index 0000000000..34fa87a15e
--- /dev/null
+++ b/app/src/main/res/layout/item_video_selector.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_preview_video.xml b/app/src/main/res/layout/layout_preview_video.xml
new file mode 100644
index 0000000000..333348787d
--- /dev/null
+++ b/app/src/main/res/layout/layout_preview_video.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/local_video_item.xml b/app/src/main/res/layout/local_video_item.xml
index e5b3c1bd23..4819f1391d 100644
--- a/app/src/main/res/layout/local_video_item.xml
+++ b/app/src/main/res/layout/local_video_item.xml
@@ -8,20 +8,33 @@
+ app:roundingBorderColor="@color/black_alpha_10"
+ app:roundingBorderWidth="0.5dp" />
+
#0D000000
#1A000000
#4D000000
+ #99000000
#66000000
#80000000
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 417428d210..06a72e0c7f 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -69,6 +69,13 @@
+
+