diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7654d829c4..26d6515b04 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -26,12 +26,16 @@
+
+
+
+
-
+
@@ -70,9 +74,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">
@@ -475,7 +479,7 @@
android:screenOrientation="portrait" />
+
+
-
-
@@ -585,10 +591,6 @@
android:screenOrientation="portrait"
android:theme="@style/TransparentStatusBarAndNavigationBar" />
-
-
@@ -611,8 +613,8 @@
+ android:launchMode="singleTask"
+ android:screenOrientation="portrait" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ android:theme="@android:style/Theme.Dialog" />
: ToolBarActivity(), KeyboardHeightObserver, UploadVideoListener {
val mRichEditor by bindView(R.id.rich_editor)
@@ -55,21 +62,21 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
private val mEditorParagraphContainer by bindView(R.id.editor_paragraph_container)
private val mEditorLinkContainer by bindView(R.id.editor_link_container)
private val mEditorInsertDetailContainer by bindView(R.id.editor_insert_detail_container)
- val mAddLabelContainer by bindView(R.id.add_label_container)
- val mAddLabelTv by bindView(R.id.add_label_tv)
- val mLabelNumTv by bindView(R.id.label_num_tv)
- val mLabelArrowIv by bindView(R.id.label_arrow)
- val mTagsContainer by bindView(R.id.tagsContainer)
+ private val mTagsContainer by bindView(R.id.tagsContainer)
private var mCurrentParagraphStyle = ""
private var mIsExtendedKeyboardShow = false
-
+ private var mAgreePostPic: Boolean = false
+ protected lateinit var mViewModel: VM
+ protected var mIsKeyBoardShow = false
+ protected var mKeyboardHeightProvider: KeyboardHeightProvider? = null
+ val FILE_HOST = "file:///"
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
DialogUtils.fixWebViewKeyboardNotWorking(this)
if (resultCode != Activity.RESULT_OK) return
- var insertData: EditorInsertEntity? = null
+ val insertData: EditorInsertEntity?
when (requestCode) {
INSERT_ANSWER_CODE -> {
val answer = data?.getParcelableExtra(AnswerEntity::class.java.simpleName)
@@ -95,11 +102,20 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
mRichEditor.insertCustomStyleLink(insertData)
}
}
- VideoActivity.INSERT_VIDEO_CODE -> {
- val video = data?.getParcelableExtra(MyVideoEntity::class.java.simpleName)
- if (video != null) {
- mRichEditor.focusEditor()
- mRichEditor.insertCustomVideo(video)
+ REQUEST_CODE_IMAGE -> {
+ if (data != null) mViewModel.uploadPic(data)
+ }
+ INSERT_VIDEO_CODE -> {
+ val localVideoList = data?.getParcelableArrayListExtra(LocalVideoEntity::class.java.name)
+ ?: arrayListOf()
+ if (localVideoList.isNotEmpty()) {
+ uploadVideo(localVideoList)
+ }
+ }
+ REQUEST_CODE_IMAGE_CROP -> {
+ val imagePath = data?.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
+ if (!imagePath.isNullOrEmpty()) {
+ mViewModel.uploadPoster(imagePath)
}
}
}
@@ -107,19 +123,48 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
AppExecutor.uiExecutor.executeWithDelay(Runnable {
Util_System_Keyboard.showSoftKeyboard(this)
}, 100)
+ }
+
+ private fun uploadVideo(localVideoList: ArrayList) {
+ mViewModel.localVideoList.addAll(localVideoList)
+ runOnIoThread {
+ localVideoList.forEach {
+ if (it.poster.startsWith("http")) {
+ runOnUiThread {
+ mRichEditor.focusEditor()
+ mRichEditor.insertPlaceholderVideo(it.id, it.poster)
+ }
+ } else {
+ val videoThumbnail = BitmapUtils.getVideoThumbnail(it.filePath)
+ val filePath = "${cacheDir.absolutePath}${File.separator}${it.id}.webp"
+ BitmapUtils.saveBitmap(videoThumbnail, filePath)
+ it.poster = filePath
+ runOnUiThread {
+ mRichEditor.focusEditor()
+ mRichEditor.insertPlaceholderVideo(it.id, "$FILE_HOST${it.poster}")
+ }
+ }
+ }
+ mViewModel.uploadVideo()
+ }
}
@SuppressLint("AddJavascriptInterface", "ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- mAddLabelContainer.visibility = if (this is ArticleEditActivity) View.VISIBLE else View.GONE
+ mViewModel = provideViewModel()
+ mViewModel.setUploadVideoListener(this)
+ mKeyboardHeightProvider = KeyboardHeightProvider(this)
+ mRichEditor.post { mKeyboardHeightProvider?.start() }
mRichEditor.setPadding(20, 15, 20, 15)
// 防止个别手机在Js里无法获取粘贴内容
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
mRichEditor.addJavascriptInterface(OnCursorChangeListener(), "OnCursorChangeListener")
mRichEditor.addJavascriptInterface(OnEditorTextChangeListener(), "OnEditorTextChangeListener")
+ mRichEditor.addJavascriptInterface(OnVideoListener(), "onVideoListener")
mRichEditor.setInputEnabled(true)
+ mRichEditor.setPadding(16, 15, 16, 15)
mRichEditor.setOnTouchListener { _, _ ->
if (mIsExtendedKeyboardShow) {
@@ -129,14 +174,41 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
mRichEditor.hasFocus()
} else false
}
+ observeData()
}
+ private fun observeData() {
+ mViewModel.chooseImagesUpload.observe(this, Observer {
+ for (key in it.keys) {
+ mRichEditor.insertPlaceholderImage(key)
+ }
+ })
+ mViewModel.chooseImagesUploadSuccess.observe(this, Observer {
+ val jsonArray = JSONArray()
+ for (key in it.keys) {
+ val jsonObject = JSONObject()
+ jsonObject.put("id", key)
+ jsonObject.put("url", it[key])
+ jsonArray.put(jsonObject)
+ }
+ mRichEditor.replacePlaceholderImage(jsonArray.toString())
+ AppExecutor.uiExecutor.executeWithDelay(Runnable {
+ Util_System_Keyboard.showSoftKeyboard(this)
+ }, 100)
+ })
+ }
+
+ override fun onKeyboardHeightChanged(height: Int, orientation: Int) {
+ mIsKeyBoardShow = height > 0
+ if (height > 0) {
+ closeExtendedKeyboard()
+ }
+ }
fun closeExtendedKeyboard() {
mEditorInsertDetailContainer.visibility = View.GONE
mEditorFont.isChecked = false
mEditorLink.isChecked = false
- mAddLabelContainer.isSelected = false
mIsExtendedKeyboardShow = false
}
@@ -144,36 +216,7 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
mEditorFont.isEnabled = isEnabled
}
- fun changeAddLabel(isLabelContainerShow: Boolean) {
- if (isLabelContainerShow) {
- mLabelNumTv.visibility = View.GONE
- mLabelArrowIv.visibility = View.VISIBLE
- mAddLabelTv.setTextColor(ContextCompat.getColor(this, R.color.theme_font))
- mAddLabelTv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
- mAddLabelContainer.background = ContextCompat.getDrawable(this, R.drawable.bg_editor_insert_add_label)
- } else {
- val selectedLabel = getSelectedLabel()
- if (selectedLabel == 0) {
- mAddLabelTv.text = "添加标签"
- mLabelNumTv.visibility = View.GONE
- mAddLabelTv.setTextColor(ContextCompat.getColor(this, R.color.text_666666))
- mAddLabelTv.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(this, R.drawable.ic_add_label), null, null, null)
- } else {
- mAddLabelTv.text = "标签"
- mLabelNumTv.visibility = View.VISIBLE
- mLabelNumTv.text = selectedLabel.toString()
- mAddLabelTv.setTextColor(ContextCompat.getColor(this, R.color.theme_font))
- mAddLabelTv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
- }
- mLabelArrowIv.visibility = View.GONE
- mAddLabelContainer.background = ContextCompat.getDrawable(this, R.drawable.border_round_stroke_eee_999)
- }
- }
-
- open fun getSelectedLabel(): Int = 0
-
-
- @OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.add_label_container, R.id.editor_font_underline,
+ @OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.editor_font_underline,
R.id.editor_font_bold, R.id.editor_font_italic, R.id.editor_font_strikethrough,
R.id.editor_paragraph_h1, R.id.editor_paragraph_h2, R.id.editor_paragraph_h3,
R.id.editor_paragraph_h4, R.id.editor_font_container, R.id.editor_paragraph_container,
@@ -187,9 +230,6 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
R.id.editor_link -> {
controlEditorLinkContainer()
}
- R.id.add_label_container -> {
- controlAddLabelContainer()
- }
R.id.editor_font_bold -> {
mEditorFontBold.isChecked = !mEditorFontBold.isChecked
mRichEditor.setBold()
@@ -282,17 +322,46 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
object : EmptyCallback {
override fun onCallback() {
MtaHelper.onEvent(mtaEventName(), "插入链接", "插入链接-视频")
- startActivityForResult(VideoActivity.getIntent(this@BaseRichEditorActivity), VideoActivity.INSERT_VIDEO_CODE)
+ startActivityForResult(LocalMediaActivity.getIntent(this@BaseRichEditorActivity, LocalMediaActivity.ChooseType.VIDEO, 3), INSERT_VIDEO_CODE)
}
})
}
+ R.id.editor_image -> {
+ if (!mAgreePostPic && !NetworkUtils.isWifiOr4GOr3GConnected(this)) {
+ mAgreePostPic = true
+ DialogUtils.showAlertDialog(this,
+ "警告",
+ "当前使用移动网络,上传图片会消耗手机流量",
+ "我知道了", "", { startMediaStore() }, null)
+ return
+ }
+ startMediaStore()
+ }
+ }
+ }
+
+ private fun startMediaStore() {
+ MtaHelper.onEvent(mtaEventName(), "插入图片", "插入图片")
+ if (mViewModel.mapImages.size >= 50) {
+ toast(R.string.answer_edit_max_img_hint)
+ return
+ }
+ try {
+ PermissionHelper.checkStoragePermissionBeforeAction(this, object : EmptyCallback {
+ override fun onCallback() {
+ val intent = LocalMediaActivity.getIntent(this@BaseRichEditorActivity, LocalMediaActivity.ChooseType.IMAGE, 10)
+ startActivityForResult(intent, REQUEST_CODE_IMAGE)
+ }
+ })
+ } catch (e: Exception) {
+ toast(R.string.media_image_hint)
+ e.printStackTrace()
}
}
private fun controlEditorFontContainer() {
mEditorFont.isChecked = !mEditorFont.isChecked
mEditorLink.isChecked = false
- mAddLabelContainer.isSelected = false
val isShouldDelay = if (mEditorFont.isChecked) {
Util_System_Keyboard.hideSoftKeyboard(this)
true
@@ -307,14 +376,12 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
mEditorLinkContainer.visibility = View.GONE
mTagsContainer.visibility = View.GONE
mIsExtendedKeyboardShow = mEditorFont.isChecked
- changeAddLabel(false)
}, if (isShouldDelay) 200 else 0L)
}
private fun controlEditorLinkContainer() {
mEditorLink.isChecked = !mEditorLink.isChecked
mEditorFont.isChecked = false
- mAddLabelContainer.isSelected = false
val isShouldDelay = if (mEditorLink.isChecked) {
Util_System_Keyboard.hideSoftKeyboard(this)
true
@@ -329,32 +396,9 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
mEditorParagraphContainer.visibility = View.GONE
mTagsContainer.visibility = View.GONE
mIsExtendedKeyboardShow = mEditorLink.isChecked
- changeAddLabel(false)
}, if (isShouldDelay) 200 else 0L)
}
- fun controlAddLabelContainer() {
- mEditorLink.isChecked = false
- mEditorFont.isChecked = false
- mAddLabelContainer.isSelected = !mAddLabelContainer.isSelected
- val isShouldDelay = if (mAddLabelContainer.isSelected) {
- Util_System_Keyboard.hideSoftKeyboard(this)
- changeAddLabel(true)
- true
- } else {
- Util_System_Keyboard.showSoftKeyboard(this)
- changeAddLabel(false)
- false
- }
- mEditorInsertDetailContainer.postDelayed({
- mEditorInsertDetailContainer.visibility = if (mAddLabelContainer.isSelected) View.VISIBLE else View.GONE
- mTagsContainer.visibility = if (mAddLabelContainer.isSelected) View.VISIBLE else View.GONE
- mEditorLinkContainer.visibility = View.GONE
- mEditorFontContainer.visibility = View.GONE
- mEditorParagraphContainer.visibility = View.GONE
- mIsExtendedKeyboardShow = mAddLabelContainer.isSelected
- }, if (isShouldDelay) 200 else 0L)
- }
override fun handleBackPressed(): Boolean {
if (mIsExtendedKeyboardShow) {
@@ -364,6 +408,24 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
return super.handleBackPressed()
}
+ override fun onResume() {
+ super.onResume()
+ mKeyboardHeightProvider?.setKeyboardHeightObserver(this)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ mKeyboardHeightProvider?.setKeyboardHeightObserver(null)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mKeyboardHeightProvider?.close()
+ val path = mViewModel.currentUploadingVideo?.filePath
+ if (path != null && UploadManager.isUploading(path)) {
+ UploadManager.cancelTask(path)
+ }
+ }
private inner class OnCursorChangeListener {
@JavascriptInterface
@@ -417,7 +479,75 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
}
}
+ private inner class OnVideoListener {
+ @JavascriptInterface
+ fun showDeleteDialog(id: String) {
+ DialogHelper.showDialog(this@BaseRichEditorActivity, "提示", "确定删除吗?", "确定", "取消", {
+ runOnUiThread {
+ mRichEditor.delPlaceholderVideo(id)
+ mViewModel.deleteVideo(id)
+ }
+ })
+ }
+
+ @JavascriptInterface
+ fun updatePoster(id: String, videoId: String, url: String) {
+ mViewModel.id = id
+ mViewModel.videoId = videoId
+ val videoEntity = VideoEntity(url = url)
+ val intent = PosterEditActivity.getIntentByVideo(this@BaseRichEditorActivity, videoEntity)
+ startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
+ }
+
+ @JavascriptInterface
+ fun deleteUploadingVideo(id: String) {
+ mViewModel.deleteVideo(id)
+ }
+
+ @JavascriptInterface
+ fun reUploadVideo(id: String) {
+ val video = mViewModel.uploadVideoErrorList.find { it.id == id }
+ if (video != null) {
+ mViewModel.localVideoList.add(video)
+ mViewModel.uploadVideoErrorList.remove(video)
+ mViewModel.uploadVideo()
+ }
+ }
+ }
+
+ override fun insertPlaceholderVideo(id: String, poster: String) {
+ mRichEditor.insertPlaceholderVideo(id, poster)
+ }
+
+ override fun updateVideoProgress(id: String, progress: String) {
+ mRichEditor.updateVideoProgress(id, progress)
+ }
+
+ override fun videoUploadFinished(id: String, url: String, msg: JsonObject) {
+ try {
+ val obj = JSONObject()
+ obj.put("poster", msg.get("poster").asString)
+ obj.put("url", msg.get("url").asString)
+ obj.put("duration", RichEditor.formatVideoDuration(msg.get("length").asLong / 1000))
+ obj.put("id", msg.get("_id").asString)
+ obj.put("status", "pending")
+ mRichEditor.videoUploadFinished(id, url, obj.toString())
+ } catch (e: java.lang.Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun changePoster(id: String, poster: String) {
+ mRichEditor.changePoster(id, poster)
+ }
+
+ override fun videoUploadFailed(id: String) {
+ mRichEditor.videoUploadFailed(id)
+ }
+
+ open fun getSelectedLabel(): Int = 0
abstract fun mtaEventName(): String
+ abstract fun provideViewModel(): VM
companion object {
const val ELEMENT_NAME_BOLD = " b "
@@ -434,5 +564,9 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
const val INSERT_ARTICLE_CODE = 412
const val INSERT_GAME_CODE = 413
const val MAX_INPUT_TEXT_NUM = 10000
+
+ const val REQUEST_CODE_IMAGE = 120
+ const val INSERT_VIDEO_CODE = 121
+ const val REQUEST_CODE_IMAGE_CROP = 122
}
}
\ 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
new file mode 100644
index 0000000000..b5720bb6d1
--- /dev/null
+++ b/app/src/main/java/com/gh/base/BaseRichEditorViewModel.kt
@@ -0,0 +1,349 @@
+package com.gh.base
+
+import android.app.Application
+import android.content.Intent
+import android.text.TextUtils
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.MediatorLiveData
+import androidx.lifecycle.MutableLiveData
+import com.gh.base.fragment.WaitingDialogFragment
+import com.gh.common.runOnUiThread
+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.BbsType
+import com.gh.gamecenter.retrofit.Response
+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.google.gson.JsonObject
+import com.lightgame.utils.Utils
+import com.zhihu.matisse.Matisse
+import com.zhihu.matisse.internal.utils.PathUtils
+import io.reactivex.disposables.Disposable
+import okhttp3.ResponseBody
+import retrofit2.HttpException
+import java.io.File
+import java.util.*
+import kotlin.collections.HashMap
+import kotlin.collections.List
+import kotlin.collections.Map
+import kotlin.collections.find
+import kotlin.collections.forEach
+import kotlin.collections.set
+
+abstract class BaseRichEditorViewModel(application: Application) : AndroidViewModel(application) {
+ val mApi: ApiService = RetrofitManager.getInstance(application).api
+ val processDialog = MediatorLiveData()
+ val uploadingImage = ArrayList>()
+ val chooseImagesUpload = MutableLiveData>()
+ val chooseImagesUploadSuccess = MutableLiveData>()
+ var uploadImageSubscription: Disposable? = null
+ val mapImages = HashMap()
+ val localVideoList = ArrayList()
+ val uploadVideoErrorList = ArrayList()
+ var currentUploadingVideo: LocalVideoEntity? = null
+ var type: String = "" //游戏论坛:game_bbs 官方论坛:official_bbs
+ private var mUploadVideoListener: UploadVideoListener? = null
+ val TITLE_MIN_LENGTH = 6
+ val MIN_TEXT_LENGTH = 6
+ val MAX_TEXT_LENGTH = 10000
+ val FILE_HOST = "file:///"
+ var id = ""//视频标记
+ var videoId = ""//更改封面视频id
+
+ fun setUploadVideoListener(uploadVideoListener: UploadVideoListener) {
+ this.mUploadVideoListener = uploadVideoListener
+ }
+
+ //检查图片是否符合规则并上传图片
+ fun uploadPic(data: Intent) {
+ val uris = Matisse.obtainResult(data)
+ val pictureList = ArrayList()
+ for (uri in uris) {
+ val picturePath = PathUtils.getPath(getApplication(), uri)
+ if (picturePath != null) {
+ if (File(picturePath).length() > ImageUtils.getUploadFileMaxSize()) {
+ val count = ImageUtils.getUploadFileMaxSize() / 1024 / 1024
+ val application: Application = getApplication()
+ Utils.toast(getApplication(), application.getString(R.string.pic_max_hint, count))
+ continue
+ }
+ Utils.log("picturePath = $picturePath")
+ pictureList.add(picturePath)
+ } else {
+ Utils.log("picturePath is null")
+ }
+ }
+ if (pictureList.size == 0) return
+
+ uploadImageSubscription = UploadImageUtils.compressAndUploadImageList(UploadImageUtils.UploadType.answer, pictureList
+ , false, object : UploadImageUtils.OnUploadImageListListener {
+ override fun onProgress(total: Long, progress: Long) {}
+
+ override fun onCompressSuccess(imageUrls: List) {
+ val chooseImageMd5Map = LinkedHashMap()
+ imageUrls.forEach {
+ chooseImageMd5Map[MD5Utils.getUrlMD5(it)] = ""
+ }
+ uploadingImage.add(chooseImageMd5Map)
+ chooseImagesUpload.postValue(chooseImageMd5Map)
+ }
+
+ override fun onSuccess(imageUrl: LinkedHashMap, errorMap: Map) {
+ val uploadMap = uploadingImage.find { it.containsKey(MD5Utils.getUrlMD5(imageUrl.entries.iterator().next().key)) }
+ uploadMap?.let {
+ for (key in imageUrl.keys) {
+ uploadMap[MD5Utils.getUrlMD5(key)] = FILE_HOST + key.decodeURI()
+ mapImages[TextUtils.htmlEncode(key).decodeURI()] = imageUrl[key] ?: ""
+ }
+ chooseImagesUploadSuccess.postValue(uploadMap)
+ uploadingImage.remove(uploadMap)
+ }
+ val errorSize = pictureList.size - imageUrl.size
+ if (errorSize > 0) {
+ for (error in errorMap.values) {
+ if (error is HttpException && error.code() == 403) {
+ Utils.toast(getApplication(), errorSize.toString() + "张违规图片上传失败")
+ return
+ }
+ }
+ Utils.toast(getApplication(), errorSize.toString() + "张图片上传失败")
+ }
+ }
+
+ override fun onError(errorMap: Map) {
+ val errorSize = pictureList.size
+
+ for (error in errorMap.values) {
+ if (error is HttpException && error.code() == 403) {
+ val e = error.response()?.errorBody()?.string()?.toObject()
+ if (e != null && e.code == 403017) {
+ Utils.toast(getApplication(), errorSize.toString() + "张图片的宽或高超过限制,请裁剪后上传")
+ } else {
+ Utils.toast(getApplication(), errorSize.toString() + "张违规图片上传失败")
+ }
+ return
+ }
+ }
+ if (errorSize == 1) {
+ Utils.toast(getApplication(), "图片上传失败")
+ } else {
+ Utils.toast(getApplication(), errorSize.toString() + "张图片上传失败")
+ }
+ }
+ })
+ }
+
+ fun uploadPoster(picturePath: String) {
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("图片上传中...", true))
+ uploadImageSubscription = UploadImageUtils.compressAndUploadImage(UploadImageUtils.UploadType.poster, picturePath, false,
+ object : UploadImageUtils.OnUploadImageListener {
+ override fun onSuccess(imageUrl: String) {
+ patchVideoPoster(imageUrl)
+ }
+
+ override fun onError(e: Throwable?) {
+ handleUploadPosterResult(true)
+ }
+
+ override fun onProgress(total: Long, progress: Long) {
+
+ }
+ })
+ }
+
+ private fun patchVideoPoster(poster: String) {
+ if (id.isEmpty() || videoId.isEmpty()) return
+ val map = hashMapOf("poster" to poster)
+ mApi.patchBbsVideo(videoId, map.toRequestBody())
+ .compose(observableToMain())
+ .subscribe(object : Response() {
+ override fun onResponse(response: ResponseBody?) {
+ super.onResponse(response)
+ mUploadVideoListener?.changePoster(id, poster)
+ handleUploadPosterResult(false)
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ handleUploadPosterResult(true)
+ }
+ })
+ }
+
+ private fun handleUploadPosterResult(isFailure: Boolean = false) {
+ processDialog.postValue(WaitingDialogFragment.WaitingDialogData("图片上传中...", false))
+ if (isFailure) {
+ ToastUtils.showToast("封面更改失败")
+ }
+ id = ""
+ videoId = ""
+ }
+
+ fun deleteVideo(id: String) {
+ if (localVideoList.isNotEmpty()) {
+ val video = localVideoList.find { it.id == id }
+ if (video != null) {
+ if (UploadManager.isUploading(video.filePath)) {
+ UploadManager.cancelTask(video.filePath)
+ }
+ localVideoList.remove(video)
+ }
+ }
+ if (uploadVideoErrorList.isNotEmpty()) {
+ val video = uploadVideoErrorList.find { it.id == id }
+ if (video != null) {
+ uploadVideoErrorList.remove(video)
+ }
+ }
+ if (currentUploadingVideo?.id == id) {
+ currentUploadingVideo = null
+ uploadVideo()
+ }
+ }
+
+ fun uploadVideo() {
+ if (currentUploadingVideo != null) return
+ if (localVideoList.isEmpty()) return
+ currentUploadingVideo = localVideoList[0]
+ UploadManager.createUploadTask(currentUploadingVideo?.filePath
+ ?: "", object : OnUploadListener {
+ override fun onProgressChanged(uploadFilePath: String, currentSize: Long, totalSize: Long, speed: Long) {
+ runOnUiThread {
+ val percent = (currentSize * 100 / totalSize.toFloat()).roundTo(1)
+ currentUploadingVideo?.id?.let {
+ mUploadVideoListener?.updateVideoProgress(it, percent.toString())
+ }
+ }
+ }
+
+ override fun onUploadSuccess(uploadFilePath: String, url: String) {
+ if (currentUploadingVideo != null) {
+ val newPoster = ImageUtils.getVideoSnapshot(url, 0)
+ postVideoInfo(url, newPoster)
+ }
+ }
+
+ override fun onUploadFailure(uploadFilePath: String, errorMsg: String) {
+ uploadFailure()
+ }
+ })
+ }
+
+ private fun getVideoType(): String {
+ return when (type) {
+ BbsType.GAME_BBS.value -> {
+ when (getRichType()) {
+ RichType.ARTICLE -> BbsType.GAME_BBS_ARTICLE_INSERT.value
+ RichType.QUESTION -> BbsType.GAME_BBS_QUESTION_INSERT.value
+ else -> ""
+ }
+ }
+ BbsType.OFFICIAL_BBS.value -> {
+ when (getRichType()) {
+ RichType.ARTICLE -> BbsType.OFFICIAL_BBS_ARTICLE_INSERT.value
+ RichType.QUESTION -> BbsType.OFFICIAL_BBS_QUESTION_INSERT.value
+ else -> ""
+ }
+ }
+ else -> ""
+ }
+ }
+
+ fun postVideoInfo(url: String, poster: String) {
+ val map = HashMap().apply {
+ put("poster", poster)
+ put("url", url)
+ put("format", currentUploadingVideo?.format ?: "")
+ put("size", currentUploadingVideo?.size ?: 0)
+ put("length", currentUploadingVideo?.duration ?: 0)
+ put("type", getVideoType())
+ }
+ val requestBody = map.toRequestBody()
+ mApi.postBbsVideo(requestBody)
+ .compose(observableToMain())
+ .subscribe(object : Response() {
+ override fun onResponse(response: JsonObject?) {
+ super.onResponse(response)
+ if (response != null) {
+ uploadSuccess(poster, url, response)
+ }
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ uploadFailure()
+ }
+ })
+ }
+
+ private fun uploadSuccess(poster: String, url: String, data: JsonObject) {
+ currentUploadingVideo?.let {
+ mUploadVideoListener?.changePoster(it.id, poster)
+ mUploadVideoListener?.videoUploadFinished(it.id, url, data)
+ UploadManager.cancelTask(it.filePath)
+ localVideoList.remove(it)
+ }
+ currentUploadingVideo = null
+ uploadVideo()
+ }
+
+ private fun uploadFailure() {
+ currentUploadingVideo?.let {
+ runOnUiThread {
+ mUploadVideoListener?.videoUploadFailed(it.id)
+ }
+ uploadVideoErrorList.add(it)
+ localVideoList.remove(it)
+ UploadManager.cancelTask(it.filePath)
+ }
+ currentUploadingVideo = null
+ uploadVideo()
+ }
+
+ fun checkIsAllUploadedAndToast(): Boolean {
+ if (localVideoList.isNotEmpty() || uploadVideoErrorList.isNotEmpty()) {
+ ToastUtils.showToast("视频未上传完成,视频内容保存失败")
+ return false
+ }
+ return true
+ }
+
+ abstract fun getRichType(): RichType
+}
+
+interface UploadVideoListener {
+ /**
+ * 插入视频占位图
+ */
+ fun insertPlaceholderVideo(id: String, poster: String)
+
+ /**
+ * 更新视频进度条
+ */
+ fun updateVideoProgress(id: String, progress: String)
+
+ /**
+ * 上传视频完成
+ */
+ fun videoUploadFinished(id: String, url: String, msg: JsonObject)
+
+ /**
+ * 更换封面图
+ */
+ fun changePoster(id: String, poster: String)
+
+ /**
+ * 上传失败
+ */
+ fun videoUploadFailed(id: String)
+}
+
+enum class RichType {
+ ARTICLE,
+ QUESTION,
+ ANSWER
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/constant/Constants.java b/app/src/main/java/com/gh/common/constant/Constants.java
index 485f734ece..79a994615f 100644
--- a/app/src/main/java/com/gh/common/constant/Constants.java
+++ b/app/src/main/java/com/gh/common/constant/Constants.java
@@ -1,6 +1,7 @@
package com.gh.common.constant;
import com.gh.common.util.PackageUtils;
+import com.gh.common.util.TimeUtils;
import com.halo.assistant.HaloApp;
public class Constants {
@@ -170,6 +171,9 @@ public class Constants {
//首页视频播放进度
public static final String SP_HOME_VIDEO_PLAY_RECORD = "home_video_play_record";
+ // 论坛内容视频播放进度
+ public static final String SP_CONTENT_VIDEO_PLAY_RECORD = "content_video_play_record";
+
// 用户是否曾经永久拒绝过存储权限
public static final String SP_USER_HAS_PERMANENTLY_DENIED_STORAGE_PERMISSION = "user_has_permanently_denied_storage_permission";
@@ -193,6 +197,19 @@ public class Constants {
// 是否成功取过号
public static final String SP_HAS_GET_PHONE_INFO = "has_get_phone_info";
+ // 是否点击过更换背景按钮
+ public static final String SP_HAS_CLICK_CHANGE_BG = "has_click_change_bg";
+ // 是否显示更换背景提示
+ public static final String SP_SHOW_CHANGE_BG_TIPS = "show_change_bg_tips" + TimeUtils.getStartTimeOfToday();
+
+
+ // 内容视频播放选项
+ public static final String SP_CONTENT_VIDEO_OPTION = "content_video_option";
+ // 首页/游戏详情页视频播放选项
+ public static final String SP_HOME_OR_DETAIL_VIDEO_OPTION = "home_or_detail_video_option";
+ // 是否默认静音播放视频
+ public static final String SP_VIDEO_PLAY_MUTE = "video_play_mute";
+
//手机号码匹配规则
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
public static final String REGEX_ACCOUNT = "^[a-zA-Z_]\\w{5,17}$";
@@ -298,6 +315,10 @@ public class Constants {
public static final String WITHDRAW_INFO_ADDRESS_DEV = "https://static-web.ghzs.com/shop-dev/index.html#/cash?from=ghzs";
public static final String WITHDRAW_INFO_ADDRESS = "https://static-web.ghzs.com/shop/index.html#/cash?from=ghzs";
+ // 活动详情
+ public static final String ACTIVITY_DETAIL_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_activity_dev/common.html?from=ghzs";
+ public static final String ACTIVITY_DETAIL_ADDRESS = "https://static-web.ghzs.com/ghzs_activity_prod/common.html?from=ghzs";
+
//最少需要多少数据才能上传
public static final int DATA_AMOUNT = 20;
diff --git a/app/src/main/java/com/gh/common/databind/BindingAdapters.java b/app/src/main/java/com/gh/common/databind/BindingAdapters.java
index 9cd5aa0f33..bb165a6414 100644
--- a/app/src/main/java/com/gh/common/databind/BindingAdapters.java
+++ b/app/src/main/java/com/gh/common/databind/BindingAdapters.java
@@ -336,6 +336,13 @@ public class BindingAdapters {
}
}
+ @BindingAdapter("gameIcon")
+ public static void setGameIcon(View view, GameEntity gameEntity) {
+ if (gameEntity != null && view instanceof GameIconView) {
+ ((GameIconView) view).displayGameIcon(gameEntity.getIcon(), gameEntity.getIconSubscript());
+ }
+ }
+
@BindingAdapter("articleType")
public static void setArticleType(TextView view, String articleType) {
NewsUtils.setNewsType(view, articleType, 0, 0);
diff --git a/app/src/main/java/com/gh/common/history/HistoryDatabase.kt b/app/src/main/java/com/gh/common/history/HistoryDatabase.kt
index 33e51e8f7f..e6e5683771 100644
--- a/app/src/main/java/com/gh/common/history/HistoryDatabase.kt
+++ b/app/src/main/java/com/gh/common/history/HistoryDatabase.kt
@@ -26,7 +26,8 @@ import com.halo.assistant.HaloApp
ListStringConverter::class,
CommunityVideoConverter::class,
UserConverter::class,
- ImageInfoConverter::class)
+ ImageInfoConverter::class,
+ VideoInfoConverter::class)
abstract class HistoryDatabase : RoomDatabase() {
@@ -79,6 +80,21 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
+ val MIGRATION_8_9: Migration = object : Migration(8, 9) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("Alter TABLE ArticleEntity add des TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE ArticleEntity add url TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE ArticleEntity add videoInfo TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE ArticleEntity add poster TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE ArticleEntity add length INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("Alter TABLE AnswerEntity add des TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE AnswerEntity add url TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE AnswerEntity add videoInfo TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE AnswerEntity add poster TEXT NOT NULL DEFAULT ''")
+ database.execSQL("Alter TABLE AnswerEntity add length INTEGER NOT NULL DEFAULT 0")
+ }
+ }
+
val instance by lazy {
Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
.addMigrations(MIGRATION_2_3)
@@ -87,6 +103,7 @@ abstract class HistoryDatabase : RoomDatabase() {
.addMigrations(MIGRATION_5_6)
.addMigrations(MIGRATION_6_7)
.addMigrations(MIGRATION_7_8)
+ .addMigrations(MIGRATION_8_9)
.build()
}
}
diff --git a/app/src/main/java/com/gh/common/syncpage/SyncFieldConstants.kt b/app/src/main/java/com/gh/common/syncpage/SyncFieldConstants.kt
index 033fd8b95c..672c517793 100644
--- a/app/src/main/java/com/gh/common/syncpage/SyncFieldConstants.kt
+++ b/app/src/main/java/com/gh/common/syncpage/SyncFieldConstants.kt
@@ -20,4 +20,7 @@ object SyncFieldConstants {
// 回答数量
const val ANSWER_COUNT = "ANSWER_COUNT"
+ // 是否关注
+ const val IS_FOLLOWER = "IS_FOLLOWER"
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/util/BitmapUtils.java b/app/src/main/java/com/gh/common/util/BitmapUtils.java
index 99077eeef7..28d834fa37 100644
--- a/app/src/main/java/com/gh/common/util/BitmapUtils.java
+++ b/app/src/main/java/com/gh/common/util/BitmapUtils.java
@@ -8,6 +8,7 @@ import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
+import android.media.MediaMetadataRetriever;
import android.os.Build;
import com.halo.assistant.HaloApp;
@@ -354,4 +355,25 @@ public class BitmapUtils {
return result;
}
+
+ // 获取视频缩略图(比较耗时,建议在子线程中调用)
+ public static Bitmap getVideoThumbnail(String filePath) {
+ Bitmap bitmap = null;
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ try {
+ retriever.setDataSource(filePath);
+ bitmap = retriever.getFrameAtTime();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ retriever.release();
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ }
+ }
+ return bitmap;
+ }
}
diff --git a/app/src/main/java/com/gh/common/util/CommentHelper.kt b/app/src/main/java/com/gh/common/util/CommentHelper.kt
index 2aa48589d8..0ef998a1ed 100644
--- a/app/src/main/java/com/gh/common/util/CommentHelper.kt
+++ b/app/src/main/java/com/gh/common/util/CommentHelper.kt
@@ -74,12 +74,26 @@ object CommentHelper {
listener = listener)
}
+ fun showQuestionCommentOption(view: View,
+ commentEntity: CommentEntity,
+ questionId: String,
+ listener: OnCommentOptionClickListener?) {
+ showCommentOptions(view = view,
+ commentEntity = commentEntity,
+ showConversation = false,
+ questionId = questionId,
+ isShowTop = true,
+ ignoreModerator = true,
+ listener = listener)
+ }
+
private fun showCommentOptions(view: View,
commentEntity: CommentEntity,
showConversation: Boolean,
articleId: String? = null,
communityId: String? = null,
answerId: String? = null,
+ questionId: String? = null,
videoId: String? = null,
isShowTop: Boolean = false,
ignoreModerator: Boolean = false,
@@ -87,7 +101,7 @@ object CommentHelper {
listener: OnCommentOptionClickListener? = null) {
val context = view.context
val dialogOptions = ArrayList()
- if (isShowTop && articleId != null && commentEntity.me?.isArticleOrAnswerAuthor == true) {
+ if (isShowTop && (articleId != null || questionId != null) && commentEntity.me?.isArticleOrAnswerAuthor == true) {
dialogOptions.add(if (commentEntity.isTop) "取消置顶" else "置顶")
}
@@ -97,7 +111,7 @@ object CommentHelper {
}
if (isVideoAuthor || (videoId != null && commentEntity.user.id == UserManager.getInstance().userId)) {
dialogOptions.add("删除评论")
- } else if (articleId != null && (commentEntity.user.id == UserManager.getInstance().userId ||
+ } else if ((articleId != null || questionId != null) && (commentEntity.user.id == UserManager.getInstance().userId ||
commentEntity.me?.isModerator == true || commentEntity.me?.isArticleOrAnswerAuthor == true)) {
dialogOptions.add("删除评论")
}
@@ -156,12 +170,19 @@ object CommentHelper {
}
}
- if (answerId != null) {
- PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType, commentListener)
- } else if (articleId != null) {
- PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
- } else {
- PostCommentUtils.reportVideoComment(context, videoId, commentEntity.id, reportType, commentListener)
+ when {
+ answerId != null -> {
+ PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType, commentListener)
+ }
+ articleId != null -> {
+ PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
+ }
+ questionId != null -> {
+ PostCommentUtils.reportQuestionComment(context, questionId, commentEntity.id, reportType, commentListener)
+ }
+ else -> {
+ PostCommentUtils.reportVideoComment(context, videoId, commentEntity.id, reportType, commentListener)
+ }
}
}
}
diff --git a/app/src/main/java/com/gh/common/util/CommentUtils.java b/app/src/main/java/com/gh/common/util/CommentUtils.java
index 5471cfe04b..57e84b47ac 100644
--- a/app/src/main/java/com/gh/common/util/CommentUtils.java
+++ b/app/src/main/java/com/gh/common/util/CommentUtils.java
@@ -271,6 +271,7 @@ public class CommentUtils {
String articleId,
String articleCommunityId,
String videoId,
+ String questionId,
final CommentEntity commentEntity,
final TextView commentLikeCountTv,
final ImageView commentLikeIv,
@@ -294,7 +295,7 @@ public class CommentUtils {
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
commentLikeCountTv.setVisibility(View.VISIBLE);
- PostCommentUtils.likeComment(context, answerId, articleId, articleCommunityId, videoId, commentEntity.getId(),
+ PostCommentUtils.likeComment(context, answerId, articleId, articleCommunityId, videoId, questionId, commentEntity.getId(),
new PostCommentUtils.PostCommentListener() {
@Override
public void postSuccess(JSONObject response) {
@@ -348,7 +349,7 @@ public class CommentUtils {
String entrance = "视频流-评论-点赞";
CheckLoginUtils.checkLogin(context, entrance, () -> {
- PostCommentUtils.likeComment(context, answerId, articleId, articleCommunityId, videoId, commentEntity.getId(),
+ PostCommentUtils.likeComment(context, answerId, articleId, articleCommunityId, videoId, "", commentEntity.getId(),
new PostCommentUtils.PostCommentListener() {
@Override
public void postSuccess(JSONObject response) {
diff --git a/app/src/main/java/com/gh/common/util/DialogUtils.java b/app/src/main/java/com/gh/common/util/DialogUtils.java
index 35d845943c..411572e341 100644
--- a/app/src/main/java/com/gh/common/util/DialogUtils.java
+++ b/app/src/main/java/com/gh/common/util/DialogUtils.java
@@ -80,6 +80,7 @@ import com.gh.gamecenter.entity.PrivacyPolicyEntity;
import com.gh.gamecenter.entity.SettingsEntity;
import com.gh.gamecenter.entity.SimpleGameEntity;
import com.gh.gamecenter.entity.TrackableEntity;
+import com.gh.gamecenter.setting.GameDownloadSettingFragment;
import com.gh.gamecenter.suggest.SuggestType;
import com.halo.assistant.HaloApp;
import com.halo.assistant.fragment.SettingsFragment;
@@ -221,7 +222,7 @@ public class DialogUtils {
} else if (NetworkUtils.isWifiConnected(context)
|| filter4GorSize(context, size)) {
callBack.onResponse(false);
- } else if (!preferences.getBoolean(SettingsFragment.getTrafficDownloadHintKey(), true)) {
+ } else if (!preferences.getBoolean(GameDownloadSettingFragment.getTrafficDownloadHintKey(), true)) {
AppExecutor.getUiExecutor().executeWithDelay(() -> Utils.toast(context, "当前使用移动网络下载,请注意流量消耗"), 500);
callBack.onResponse(false);
} else {
@@ -296,7 +297,7 @@ public class DialogUtils {
PreferenceManager
.getDefaultSharedPreferences(finalContext)
.edit()
- .putBoolean(SettingsFragment.getTrafficDownloadHintKey(), false)
+ .putBoolean(GameDownloadSettingFragment.getTrafficDownloadHintKey(), false)
.apply();
AppExecutor.getUiExecutor().executeWithDelay(() -> {
// 显示了弹窗以后,即便下面这个 toast 放在 listener.onConfirm 后调用也是显示 listener.onConfirm 里的 toast
diff --git a/app/src/main/java/com/gh/common/util/DirectUtils.kt b/app/src/main/java/com/gh/common/util/DirectUtils.kt
index 061dadacd5..ed928a9990 100644
--- a/app/src/main/java/com/gh/common/util/DirectUtils.kt
+++ b/app/src/main/java/com/gh/common/util/DirectUtils.kt
@@ -50,6 +50,7 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
+import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.security.BindPhoneActivity
@@ -766,7 +767,7 @@ object DirectUtils {
// 这里换个线程操作是为了做一点延时
AppExecutor.ioExecutor.execute {
- EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK))
+ EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS))
EventBus.getDefault().post(EBReuse(CommunityFragment.EB_RETRY_PAGE))
}
}
@@ -781,7 +782,7 @@ object DirectUtils {
// 这里换个线程操作是为了做一点延时
AppExecutor.ioExecutor.execute {
- EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK))
+ EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS))
EventBus.getDefault().post(EBReuse(CommunityFragment.EB_RETRY_PAGE))
}
}
@@ -833,7 +834,8 @@ object DirectUtils {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
- bundle.putString(KEY_TO, VideoDetailActivity::class.java.name)
+ bundle.putString(KEY_TO, ForumVideoDetailActivity::class.java.name)
+ bundle.putString(KEY_VIDEO_ID, videoId);
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_ID, videoId)
bundle.putString(KEY_GAMEID, gameId)
@@ -1177,10 +1179,10 @@ object DirectUtils {
// 这里换个线程操作是为了做一点延时
AppExecutor.ioExecutor.execute {
- EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK))
+ EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS))
}
} else {
- jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_ASK) })
+ jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_BBS) })
}
}
@@ -1461,4 +1463,19 @@ object DirectUtils {
url = String.format(Locale.CHINA, "%s×tamp=%d", url, (Date().time / 1000 / 1000.toFloat()).roundToInt())
directToFullScreenWebPage(context, url, true)
}
+
+ /**
+ * 跳转至活动详情
+ */
+ @JvmStatic
+ fun directToActivityDetail(context: Context, activityId: String, entrance: String) {
+ var url: String = if (isPublishEnv()) {
+ Constants.ACTIVITY_DETAIL_ADDRESS
+ } else {
+ Constants.ACTIVITY_DETAIL_ADDRESS
+ }
+
+ url = String.format(Locale.CHINA, "%s&id=%s×tamp=%d", url, activityId, (Date().time / 1000 / 1000.toFloat()).roundToInt())
+ directToWebView(context, url, entrance)
+ }
}
\ 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 982e02238d..04a853c131 100644
--- a/app/src/main/java/com/gh/common/util/EntranceUtils.java
+++ b/app/src/main/java/com/gh/common/util/EntranceUtils.java
@@ -236,6 +236,11 @@ 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 final String KEY_COMMENT_COUNT = "comment_count";
+ public static final String KEY_IS_COMMENT_CONVERSATION = "is_comment_conversation";
public static void jumpActivity(Context context, Bundle bundle) {
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
diff --git a/app/src/main/java/com/gh/common/util/ImageUtils.kt b/app/src/main/java/com/gh/common/util/ImageUtils.kt
index 356fd00b82..29d2e03e5f 100644
--- a/app/src/main/java/com/gh/common/util/ImageUtils.kt
+++ b/app/src/main/java/com/gh/common/util/ImageUtils.kt
@@ -19,6 +19,7 @@ import com.facebook.drawee.controller.ControllerListener
import com.facebook.drawee.drawable.ScalingUtils
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
import com.facebook.drawee.view.SimpleDraweeView
+import com.facebook.imagepipeline.common.ResizeOptions
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.ImageInfo
@@ -90,7 +91,7 @@ object ImageUtils {
val jpegConfig = Config.getSettings()?.image?.oss?.jpeg
val webpConfig = Config.getSettings()?.image?.oss?.webp
?: Config.getSettings()?.image?.oss?.gif
- if (jpegConfig != null) {
+ if (imageUrl?.contains("?x-oss-process") == false && jpegConfig != null) {
return if (width == 0 || width == null) {
"$imageUrl$webpConfig"
} else {
@@ -452,6 +453,19 @@ object ImageUtils {
draweeView.setImageURI("res:///" + res)
}
+ @JvmStatic
+ fun displayResizeMedia(draweeView: SimpleDraweeView, url: String, resizeWidthDp: Int, resizeHeightDp: Int) {
+ val request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
+ .setResizeOptions(ResizeOptions(resizeWidthDp, resizeHeightDp))
+ .build()
+ val controller = Fresco.newDraweeControllerBuilder()
+ .setImageRequest(request)
+ .setOldController(draweeView.controller)
+ .setControllerListener(BaseControllerListener())
+ .build()
+ draweeView.controller = controller
+ }
+
//预加载图片
@JvmStatic
fun prefetchToDiskCache(url: String) {
diff --git a/app/src/main/java/com/gh/common/util/NewLogUtils.kt b/app/src/main/java/com/gh/common/util/NewLogUtils.kt
index 2338bf2d5a..7870f789e9 100644
--- a/app/src/main/java/com/gh/common/util/NewLogUtils.kt
+++ b/app/src/main/java/com/gh/common/util/NewLogUtils.kt
@@ -3,7 +3,10 @@ package com.gh.common.util
import com.gh.common.json.json
import com.gh.common.loghub.LoghubUtils
import com.gh.gamecenter.entity.LinkEntity
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
+import io.reactivex.schedulers.Schedulers
import org.json.JSONObject
object NewLogUtils {
@@ -25,6 +28,19 @@ object NewLogUtils {
log(json, "event", false)
}
+ fun logForumContentBrowser(contentId: String, contentType: String) {
+ val requestBody = hashMapOf(
+ Pair("content_id", contentId),
+ Pair("content_type", contentType)
+ ).createRequestBody()
+
+ RetrofitManager.getInstance(HaloApp.getInstance())
+ .api
+ .postBrowses(requestBody)
+ .subscribeOn(Schedulers.io())
+ .subscribe()
+ }
+
private fun log(jsonObject: JSONObject, logStore: String, uploadImmediately: Boolean) {
Utils.log("NewLogUtils", jsonObject.toString(4))
LoghubUtils.log(jsonObject, logStore, uploadImmediately)
diff --git a/app/src/main/java/com/gh/common/util/PostCommentUtils.java b/app/src/main/java/com/gh/common/util/PostCommentUtils.java
index 63e6a96544..dec59ec097 100644
--- a/app/src/main/java/com/gh/common/util/PostCommentUtils.java
+++ b/app/src/main/java/com/gh/common/util/PostCommentUtils.java
@@ -117,6 +117,7 @@ public class PostCommentUtils {
String articleId,
String articleCommunityId,
String videoId,
+ String questionId,
final String commentId,
final PostCommentListener listener) {
@@ -126,6 +127,8 @@ public class PostCommentUtils {
observable = RetrofitManager.getInstance(context).getApi().postVoteAnswerComment(answerId, commentId);
} else if (!TextUtils.isEmpty(articleId)) {
observable = RetrofitManager.getInstance(context).getApi().postVoteCommunityArticleComment(articleCommunityId, articleId, commentId);
+ } else if (!TextUtils.isEmpty(questionId)) {
+ observable = RetrofitManager.getInstance(context).getApi().postVoteQuestionComment(questionId, commentId);
} else {
observable = RetrofitManager.getInstance(context).getApi().postVoteToVideo(videoId, commentId);
}
@@ -258,6 +261,28 @@ public class PostCommentUtils {
}
});
}
+ public static void reportQuestionComment(final Context context,
+ final String questionId,
+ final String commentId,
+ final String reportData,
+ final PostCommentListener listener) {
+ RequestBody body = RequestBody.create(MediaType.parse("application/json"), reportData);
+ RetrofitManager.getInstance(context).getApi()
+ .postQuestionCommentReport(questionId, commentId, body)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Response() {
+ @Override
+ public void onResponse(ResponseBody response) {
+ listener.postSuccess(null);
+ }
+
+ @Override
+ public void onFailure(HttpException e) {
+ listener.postFailed(e);
+ }
+ });
+ }
public interface PostCommentListener {
void postSuccess(JSONObject response);
diff --git a/app/src/main/java/com/gh/common/util/ShareUtils.java b/app/src/main/java/com/gh/common/util/ShareUtils.java
index af3e522e63..667eb403e4 100644
--- a/app/src/main/java/com/gh/common/util/ShareUtils.java
+++ b/app/src/main/java/com/gh/common/util/ShareUtils.java
@@ -409,6 +409,11 @@ public class ShareUtils {
//QQ分享
public void qqShare() {
Utils.toast(mContext, R.string.share_skip);
+
+ mShareType = ShareType.qq;
+ shareType = "qq_friend";
+ LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+
Bundle params = new Bundle();
switch (mShareEntrance) {
@@ -445,6 +450,10 @@ public class ShareUtils {
public void wechatShare() {
Utils.toast(mContext, R.string.share_skip);
+ shareType = "wechat_friend";
+ mShareType = ShareType.wechat;
+ LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
Utils.toast(mContext, "没安装微信,分享失败");
return;
@@ -561,6 +570,12 @@ public class ShareUtils {
//QQ空间分享
public void qZoneShare() {
Utils.toast(mContext, R.string.share_skip);
+
+ mShareType = ShareType.qqZone;
+ shareType = "qq_zone";
+ MtaHelper.onEvent("内容分享", "QQ空间", mTitle);
+ LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+
Bundle params = new Bundle();
switch (mShareEntrance) {
@@ -601,6 +616,10 @@ public class ShareUtils {
public void wechatMomentsShare() {
Utils.toast(mContext, R.string.share_skip);
+ mShareType = ShareType.wechatMoments;
+ shareType = "wechat_moment";
+ LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+
if (!PackageHelper.INSTANCE.getLocalPackageNameSet().contains("com.tencent.mm")) {
Utils.toast(mContext, "没安装微信,分享失败");
return;
@@ -642,6 +661,10 @@ public class ShareUtils {
//新浪微博分享
public void sinaWeiboShare() {
+ mShareType = ShareType.weibo;
+ shareType = "sina_weibo";
+ LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+
WbSdk.install(mContext, new AuthInfo(mContext, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
if (mShareEntrance == ShareEntrance.qaDetail) {
@@ -668,6 +691,10 @@ public class ShareUtils {
//短信分享
public void shortMessageShare() {
+ mShareType = ShareType.weibo;
+ shareType = "sms";
+ LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+
String smsBody;
switch (mShareEntrance) {
case news:
@@ -714,6 +741,7 @@ public class ShareUtils {
public void copyLink(String copyContent) {
shareType = "copy_link";
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+ LogUtils.uploadShareResult(shareType, shareEntrance.getName(), "success", shareUrl, mTitle, mSummary, resourceId);
if (mShareEntrance != ShareEntrance.shareGh) {
ExtensionsKt.copyTextAndToast(copyContent, "复制成功");
safelyDismiss();
@@ -749,50 +777,34 @@ public class ShareUtils {
holder.shareLogo.setImageResource(arrLogo[position]);
holder.shareLabel.setText(arrLabel[position]);
holder.itemView.setOnClickListener(v -> {
- if (mShareEntrance == ShareEntrance.shareGh) {
- MtaHelper.onEvent("我的光环_新", "分享光环", arrLabel[position]);
- }
if (listener != null) {
listener.onItemClick(holder.getAdapterPosition());
}
switch (holder.getPosition()) {
case 0:
- shareType = "wechat_friend";
- MtaHelper.onEvent("内容分享", "微信好友", mTitle);
- LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
wechatShare();
break;
case 1:
- shareType = "wechat_moment";
- MtaHelper.onEvent("内容分享", "微信朋友圈", mTitle);
- LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
wechatMomentsShare();
break;
case 2:
- shareType = "qq_friend";
- MtaHelper.onEvent("内容分享", "QQ好友", mTitle);
- LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
qqShare();
break;
case 3:
- shareType = "qq_zone";
- MtaHelper.onEvent("内容分享", "QQ空间", mTitle);
- LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
qZoneShare();
break;
case 4:
- shareType = "sina_weibo";
- MtaHelper.onEvent("内容分享", "新浪微博", mTitle);
- LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
sinaWeiboShare();
break;
case 5:
- MtaHelper.onEvent("内容分享", "短信", mTitle);
shortMessageShare();
break;
case 6:
- MtaHelper.onEvent("内容分享", "复制链接", mTitle);
+ shareType = "copy_link";
+ LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+ LogUtils.uploadShareResult(shareType, shareEntrance.getName(), "success", shareUrl, mTitle, mSummary, resourceId);
+
if (mShareEntrance == ShareEntrance.askInvite) {
copyLink(mTitle + " - 光环助手" + shareUrl);
} else if (mShareEntrance == ShareEntrance.askNormal || mShareEntrance == ShareEntrance.answerNormal) {
@@ -815,6 +827,7 @@ public class ShareUtils {
} else {
shareType = "copy_link";
LogUtils.uploadShareType(shareType, shareEntrance.getName(), shareUrl, mTitle, mSummary, resourceId);
+ LogUtils.uploadShareResult(shareType, shareEntrance.getName(), "success", shareUrl, mTitle, mSummary, resourceId);
}
break;
}
diff --git a/app/src/main/java/com/gh/common/view/CustomDividerItemDecoration.kt b/app/src/main/java/com/gh/common/view/CustomDividerItemDecoration.kt
index 8e7e30d323..060fd1d0b6 100644
--- a/app/src/main/java/com/gh/common/view/CustomDividerItemDecoration.kt
+++ b/app/src/main/java/com/gh/common/view/CustomDividerItemDecoration.kt
@@ -1,11 +1,13 @@
package com.gh.common.view
import android.content.Context
+import android.graphics.Canvas
import android.graphics.Rect
import android.view.View
import android.widget.LinearLayout
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
+import kotlin.math.roundToInt
class CustomDividerItemDecoration(
context: Context,
@@ -13,6 +15,7 @@ class CustomDividerItemDecoration(
var notDecorateTheFirstItem: Boolean = false,
var notDecorateTheLastItem: Boolean = false,
var notDecorateTheFirstTwoItems: Boolean = false) : DividerItemDecoration(context, LinearLayout.VERTICAL) {
+ private val mBounds = Rect()
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
if (onlyDecorateTheFirstItem) {
@@ -31,4 +34,42 @@ class CustomDividerItemDecoration(
}
}
+ override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
+ if (parent.layoutManager == null || drawable == null) {
+ return
+ }
+ drawVertical(c, parent)
+ }
+
+ private fun drawVertical(canvas: Canvas, parent: RecyclerView) {
+ canvas.save()
+ val left: Int
+ val right: Int
+ if (parent.clipToPadding) {
+ left = parent.paddingLeft
+ right = parent.width - parent.paddingRight
+ canvas.clipRect(left, parent.paddingTop, right,
+ parent.height - parent.paddingBottom)
+ } else {
+ left = 0
+ right = parent.width
+ }
+ val childCount = parent.childCount
+ for (i in 0 until childCount) {
+ val child = parent.getChildAt(i)
+ parent.getDecoratedBoundsWithMargins(child, mBounds)
+ var bottom = mBounds.bottom + child.translationY.roundToInt()
+ val rect = Rect()
+ getItemOffsets(rect, child, parent, RecyclerView.State())
+ val top = if (rect.bottom > 0) {
+ bottom - (drawable?.intrinsicHeight ?: 0)
+ } else {
+ bottom = 0
+ 0
+ }
+ drawable?.setBounds(left, top, right, bottom)
+ drawable?.draw(canvas)
+ }
+ canvas.restore()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/common/view/FlexLinearLayout.kt b/app/src/main/java/com/gh/common/view/FlexLinearLayout.kt
index 80d210e70c..a4a96b9e4c 100644
--- a/app/src/main/java/com/gh/common/view/FlexLinearLayout.kt
+++ b/app/src/main/java/com/gh/common/view/FlexLinearLayout.kt
@@ -12,6 +12,8 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.gh.common.util.DisplayUtils
+import com.gh.common.util.dip2px
+import com.gh.common.util.sp2px
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.TagStyleEntity
import kotlin.math.ceil
@@ -23,16 +25,27 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
private var mTotalCount = 0
private var mTags = ArrayList()
- private var mItemHeight = DisplayUtils.dip2px(20F)
- private var mPadding = DisplayUtils.dip2px(5F)
- private var mMargin = DisplayUtils.dip2px(4F)
+ private var mItemHeight = 0
+ private var mPadding = 0
+ private var mMargin = 0
private var mTextSize = 10F
- private var mLastItemWidth = DisplayUtils.dip2px(18F)//最后更多按钮宽度
+ private var mLastItemWidth = 0//最后更多按钮宽度
private var mTotalWidth = 0
+ private var mStrokeWidth = 0
var onClickListener: OnItemClickListener? = null
init {
gravity = Gravity.CENTER_VERTICAL
+
+ val ta = context.obtainStyledAttributes(attrs, R.styleable.FlexLinearLayout)
+ mItemHeight = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemHeight, 20f.dip2px())
+ mPadding = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemPadding, 5f.dip2px())
+ mMargin = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemMargin, 4f.dip2px())
+ mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10f.sp2px().toFloat())
+ mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18f.dip2px())
+ mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 1f.dip2px())
+
+ ta.recycle()
}
fun setTags(tags: ArrayList) {
@@ -40,7 +53,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
mTotalCount = tags.size
mTotalWidth = measuredWidth
val paint = Paint()
- paint.textSize = DisplayUtils.sp2px(context, mTextSize).toFloat()
+ paint.textSize = mTextSize
var currentWidth = mLastItemWidth.toFloat()
tags.forEach {
@@ -79,7 +92,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
layoutParams = params
setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_game_detail_label_more))
background = createBackgroundDrawable()
- scaleType=ImageView.ScaleType.CENTER
+ scaleType = ImageView.ScaleType.CENTER
}
imageView.setOnClickListener {
onClickListener?.onMoreClickListener()
@@ -92,7 +105,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
return TextView(context).apply {
text = tag.name
includeFontPadding = false
- textSize = mTextSize
+ textSize = DisplayUtils.px2sp(context, mTextSize).toFloat()
gravity = Gravity.CENTER
setTextColor(Color.parseColor("#333333"))
@@ -112,7 +125,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
private fun createBackgroundDrawable(): GradientDrawable {
val gradientDrawable = GradientDrawable()
gradientDrawable.setColor(Color.TRANSPARENT)
- gradientDrawable.setStroke(DisplayUtils.dip2px(context, 1f), Color.parseColor("#C2C6CC"))
+ gradientDrawable.setStroke(mStrokeWidth, Color.parseColor("#C2C6CC"))
gradientDrawable.cornerRadius = DisplayUtils.dip2px(2f).toFloat()
return gradientDrawable
}
diff --git a/app/src/main/java/com/gh/common/view/ImageContainerView.kt b/app/src/main/java/com/gh/common/view/ImageContainerView.kt
index b464df5bd3..77133eba0f 100644
--- a/app/src/main/java/com/gh/common/view/ImageContainerView.kt
+++ b/app/src/main/java/com/gh/common/view/ImageContainerView.kt
@@ -72,7 +72,7 @@ class ImageContainerView : LinearLayout {
mPath = path
index = 0
removeAllViews()
- if (entity.getPassVideos().isNullOrEmpty() && entity.images.isNullOrEmpty()) {
+ if (entity.getPassVideos().isNotEmpty() || entity.images.isNullOrEmpty()) {
visibility = View.GONE
return
}
diff --git a/app/src/main/java/com/gh/common/view/RichEditor.java b/app/src/main/java/com/gh/common/view/RichEditor.java
index eeacb3755b..0a80e4b6c7 100644
--- a/app/src/main/java/com/gh/common/view/RichEditor.java
+++ b/app/src/main/java/com/gh/common/view/RichEditor.java
@@ -11,6 +11,7 @@ import android.util.AttributeSet;
import android.view.Gravity;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
+import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -463,6 +464,49 @@ public class RichEditor extends WebView {
exec("javascript:RE.replacePlaceholderImage('" + list + "');");
}
+ /**
+ * 插入视频占位图
+ */
+ public void insertPlaceholderVideo(String id, String poster) {
+ exec("javascript:RE.insertPlaceholderVideo('" + id + "','" + poster + "');");
+ }
+
+ /**
+ * 更新视频进度条
+ */
+ public void updateVideoProgress(String id, String progress) {
+ exec("javascript:RE.updateVideoProgress('" + id + "','" + progress + "');");
+ }
+
+
+ /**
+ * 上传视频完成
+ */
+ public void videoUploadFinished(String id, String url, String msg) {
+ exec("javascript:RE.videoUploadFinished('" + id + "','" + url + "','" + msg + "');");
+ }
+
+ /**
+ * 更换封面图
+ */
+ public void changePoster(String id, String poster) {
+ exec("javascript:RE.changePoster('" + id + "','" + poster + "');");
+ }
+
+ /**
+ * 删除视频
+ */
+ public void delPlaceholderVideo(String id) {
+ exec("javascript:RE.delPlaceholderVideo('" + id + "');");
+ }
+
+ /**
+ * 上传失败
+ */
+ public void videoUploadFailed(String id) {
+ exec("javascript:RE.videoUploadFailed('" + id + "');");
+ }
+
public void removeFormat() {
exec("javascript:RE.removeFormat();");
}
diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java
index ca67c05302..ff2b3e7641 100644
--- a/app/src/main/java/com/gh/gamecenter/MainActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java
@@ -307,8 +307,6 @@ public class MainActivity extends BaseActivity {
}
});
- //恢复顶部视频默认静音状态
- SPUtils.setBoolean(Constants.SP_TOP_VIDEO_VOICE, true);
//恢复视频流非Wifi提醒
SPUtils.setBoolean(Constants.SP_NON_WIFI_TIPS, true);
//重置首页视频播放进度
@@ -749,7 +747,7 @@ public class MainActivity extends BaseActivity {
private void switchToCommunityTabAndRefresh() {
getIntent().putExtra(SWITCH_TO_COMMUNITY, false);
Log.e("Switch", "true");
- EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK));
+ EventBus.getDefault().post(new EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_BBS));
EventBus.getDefault().post(new EBReuse(CommunityFragment.EB_RETRY_PAGE));
}
@@ -882,7 +880,7 @@ public class MainActivity extends BaseActivity {
if (info != null) {
if (EntranceUtils.HOST_COMMUNITY.equals(info.getType())) {
UserManager.getInstance().setCommunityData(new CommunityEntity(info.getLink(), info.getText()));
- runOnUiThread(() -> mMainWrapperFragment.setCurrentItem(MainWrapperFragment.INDEX_ASK));
+ runOnUiThread(() -> mMainWrapperFragment.setCurrentItem(MainWrapperFragment.INDEX_BBS));
} else {
DirectUtils.directToSpecificPage(this,
info.getType(),
diff --git a/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java b/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java
index 60a75ca6e5..8bb30e0383 100644
--- a/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/baselist/ListFragment.java
@@ -145,6 +145,7 @@ public abstract class ListFragment extends Ba
loadStatusControl(response.size());
}
+ public MutableLiveData> getListLiveData(){
+ return mListLiveData;
+ }
+
private void handleFailure(Exception exception) {
if (exception instanceof HttpException && ((HttpException) exception).code() == 404) {
loadStatusControl(0);
diff --git a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt
index 4fbd87807d..aa410163f5 100644
--- a/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/category/NewCategoryListFragment.kt
@@ -8,10 +8,7 @@ import butterknife.BindView
import com.ethanhua.skeleton.Skeleton
import com.gh.common.constant.Constants
import com.gh.common.exposure.ExposureListener
-import com.gh.common.util.DialogUtils
-import com.gh.common.util.EntranceUtils
-import com.gh.common.util.observeNonNull
-import com.gh.common.util.viewModelProvider
+import com.gh.common.util.*
import com.gh.common.view.ConfigFilterView
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
@@ -139,7 +136,7 @@ class NewCategoryListFragment : ListFragment implements ISyncAda
holder.itemView.setOnClickListener(v -> {
if (entity.getActive()) {
- mContext.startActivity(AnswerDetailActivity.getIntent(mContext, entity.getId(), mEntrance, path));
+// mContext.startActivity(AnswerDetailActivity.getIntent(mContext, entity.getId(), mEntrance, path));
+ mContext.startActivity(NewQuestionDetailActivity.getCommentIntent(mContext, entity.getQuestions().getId(), entity.getId(), mEntrance, path));
} else {
showDeleteDialog(entity.getId());
}
@@ -112,7 +115,8 @@ public class AnswerAdapter extends ListAdapter implements ISyncAda
});
viewHolder.getBinding().title.setOnClickListener(v -> {
Questions questions = entity.getQuestions();
- mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, questions.getId(), mEntrance, path));
+// mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, questions.getId(), mEntrance, path));
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, questions.getId(), mEntrance, path));
});
break;
case ItemViewType.ITEM_FOOTER:
diff --git a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleAdapter.kt b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleAdapter.kt
index cdd6e931dc..abf9d03cb2 100644
--- a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleAdapter.kt
@@ -13,9 +13,11 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
+import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.qa.answer.CommunityAnswerItemViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.ArticleEntity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
class CommunityArticleAdapter(context: Context,
private val mViewModel: CommunityArticleViewModel,
@@ -68,14 +70,21 @@ class CommunityArticleAdapter(context: Context,
}
}
+ if (entity.bbs == CommunityEntity()) {
+ entity.bbs = entity.community
+ }
holder.bindArticleItem(entity, mEntrance, path)
holder.itemView.setOnClickListener {
- if (entity.active) {
- mContext.startActivity(ArticleDetailActivity.getIntent(mContext, entity.community, entity.id, mEntrance, path))
+ if (entity.type == "question") {
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, entity.id, mEntrance, path))
} else {
- DialogUtils.showCancelAlertDialog(mContext, "提示", "内容已被删除,是否取消收藏?", "取消收藏", "暂不", {
- mViewModel.deleteCollection(entity.community.id, entity.id)
- }, null)
+ if (entity.active) {
+ mContext.startActivity(ArticleDetailActivity.getIntent(mContext, entity.community, entity.id, mEntrance, path))
+ } else {
+ DialogUtils.showCancelAlertDialog(mContext, "提示", "内容已被删除,是否取消收藏?", "取消收藏", "暂不", {
+ mViewModel.deleteCollection(entity.community.id, entity.id)
+ }, null)
+ }
}
if (!entity.read) {
diff --git a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt
index 28e125a946..41d3df7963 100644
--- a/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/collection/CommunityArticleViewModel.kt
@@ -9,6 +9,7 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.baselist.LoadType
import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.Response
@@ -17,11 +18,11 @@ import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.functions.Function
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.HttpException
-
class CommunityArticleViewModel(application: Application) : ListViewModel(application) {
var type: String = CommunityArticleFragment.Type.COLLECTION.value
@@ -32,7 +33,17 @@ class CommunityArticleViewModel(application: Application) : ListViewModel> {
return if (type == CommunityArticleFragment.Type.COLLECTION.value) {
- Single.fromObservable(RetrofitManager.getInstance(getApplication()).api.getCollectionCommunityArticle(UserManager.getInstance().userId, page))
+ Single.fromObservable(
+ RetrofitManager.getInstance(getApplication()).api
+ .getCollectionArticleAndQuestion(UserManager.getInstance().userId, page)
+ .flatMap(Function, Observable>> { list ->
+ Observable.create { emitter->
+ val articleList = list.map { it.transformArticleEntity() }.toList()
+ emitter.onNext(articleList)
+ emitter.onComplete()
+ }
+ })
+ )
} else {
if (page > 5) {
Single.create { it.onSuccess(arrayListOf()) }
diff --git a/app/src/main/java/com/gh/gamecenter/energy/TaskFragment.kt b/app/src/main/java/com/gh/gamecenter/energy/TaskFragment.kt
index 4bf5c9e315..f47ebd9e65 100644
--- a/app/src/main/java/com/gh/gamecenter/energy/TaskFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/energy/TaskFragment.kt
@@ -10,7 +10,7 @@ class TaskFragment: ListFragment() {
private var mAdapter: TaskAdapter? = null
- override fun provideListAdapter()= mAdapter
+ override fun provideListAdapter() = mAdapter
?: TaskAdapter(requireContext()).apply { mAdapter = this }
override fun provideListViewModel(): TaskViewModel = viewModelProvider()
diff --git a/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt
index 96024b077b..92f57b65af 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/CommentEntity.kt
@@ -7,30 +7,33 @@ import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
-data class CommentEntity(@SerializedName("_id")
- var id: String? = null,
- var user: UserEntity = UserEntity(),
- var parent: ArticleCommentParent? = null,
- @SerializedName("parent_user")
- var parentUser: CommentParentEntity? = null,
- var content: String? = null,
- @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_VOTE_COUNT])
- var vote: Int = 0,
- @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_REPLY_COUNT])
- var reply: Int = 0,
- var time: Long = 0,
- var priority: Int = 0,
- @SerializedName("me")
- var me: MeEntity? = null,
- @SerializedName("is_top")
- var isTop: Boolean = false,//是否置顶
- // 楼数,本地字段
- var floor: Int = 0,
- @SerializedName("attached") // 楼中楼
- var subCommentList: ArrayList? = null) : Parcelable {
+data class CommentEntity(
+ @SerializedName("_id")
+ var id: String? = null,
+ var user: UserEntity = UserEntity(),
+ var parent: ArticleCommentParent? = null,
+ @SerializedName("parent_user")
+ var parentUser: CommentParentEntity? = null,
+ var content: String? = null,
+ @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_VOTE_COUNT])
+ var vote: Int = 0,
+ @SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_REPLY_COUNT])
+ var reply: Int = 0,
+ var time: Long = 0,
+ var priority: Int = 0,
+ @SerializedName("me")
+ var me: MeEntity? = null,
+ @SerializedName("is_top")
+ var isTop: Boolean = false,//是否置顶
+ var type: String = "comment",//comment/answer,区分问题评论旧数据,answer表示旧数据(回答)
+
+ // 楼数,本地字段
+ var floor: Int = 0,
+ @SerializedName("attached") // 楼中楼
+ var subCommentList: ArrayList? = null) : Parcelable {
fun clone(): CommentEntity {
- return CommentEntity(id, user, parent, parentUser, content, vote, reply, time, priority, me, isTop, floor, subCommentList)
+ return CommentEntity(id, user, parent, parentUser, content, vote, reply, time, priority, me, isTop, type, floor, subCommentList)
}
companion object {
diff --git a/app/src/main/java/com/gh/gamecenter/entity/CommunityEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/CommunityEntity.kt
index 7158d242d9..8bde53e686 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/CommunityEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/CommunityEntity.kt
@@ -14,6 +14,7 @@ data class CommunityEntity(
var icon: String? = "",
@SerializedName("icon_subscript")
var iconSubscript: String? = null,
+ var type: String = "game_bbs",//game_bbs/official_bbs
var game: SimpleGame? = null) : Parcelable {
constructor(id: String = "", name: String = "") : this(id, name, "choiceness")
diff --git a/app/src/main/java/com/gh/gamecenter/entity/ForumActivityEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ForumActivityEntity.kt
new file mode 100644
index 0000000000..56f361d081
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/ForumActivityEntity.kt
@@ -0,0 +1,40 @@
+package com.gh.gamecenter.entity
+
+import com.google.gson.annotations.SerializedName
+
+data class ForumActivityCategoryEntity(
+ @SerializedName("_id")
+ var id: String = "",
+ var name: String = ""
+)
+
+data class ForumActivityEntity(
+ @SerializedName("_id")
+ val id: String = "",
+ val title: String = "",
+ @SerializedName("tag_activity_id")
+ val activityId: String = "", //活动标签ID
+ @SerializedName("tag_activity_name")
+ val activityName: String = "", //活动标签名
+ @SerializedName("game_id")
+ val gameId: String = "",
+ @SerializedName("game_name")
+ val gameName: String = "",
+ @SerializedName("effect_time")
+ val effectTime: ActivityTime = ActivityTime(),
+ @SerializedName("award_time")
+ val awardTime: ActivityTime = ActivityTime(),
+ val image: ActivityImage = ActivityImage(),
+ val name: String = "",
+ val unread: Boolean = false
+) {
+
+ data class ActivityTime(
+ val start: Long = 0,
+ val end: Long = 0
+ )
+
+ data class ActivityImage(
+ val cover: String = ""
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/ForumDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ForumDetailEntity.kt
index 6e8e72c3be..d94d423282 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/ForumDetailEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/ForumDetailEntity.kt
@@ -9,10 +9,24 @@ data class ForumDetailEntity(
var game: SimpleGame = SimpleGame(),
var background: String = "",
var name: String = "",
+ var icon: String = "",
var moderator: ArrayList = arrayListOf(),
@SerializedName("top")
var topLink: ArrayList = arrayListOf(),
@SerializedName("zone_tab")
var zone: ZoneEntity? = null,
- var me: MeEntity = MeEntity()
-)
\ No newline at end of file
+ var me: MeEntity = MeEntity(),
+ var type: String = "" //game_bbs/official_bbs
+) {
+ fun convertForumDetailEntityToForumEntity(): ForumEntity {
+ val forumEntity = ForumEntity()
+ forumEntity.id = id
+ forumEntity.name = name
+ forumEntity.icon = icon
+ forumEntity.game = game
+ forumEntity.orderTag = System.currentTimeMillis()
+ forumEntity.unread = false
+ forumEntity.type = type
+ return forumEntity
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/ForumEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ForumEntity.kt
index 2761bfc5f5..bd408090f5 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/ForumEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/ForumEntity.kt
@@ -1,17 +1,33 @@
package com.gh.gamecenter.entity
+import androidx.room.Entity
+import androidx.room.PrimaryKey
import com.google.gson.annotations.SerializedName
+@Entity
data class ForumEntity(
+ @PrimaryKey
@SerializedName("_id")
var id: String = "",
var game: SimpleGame = SimpleGame(),
var name: String = "",
+ var icon: String = "",
@SerializedName("is_follow")
var isFollow: Boolean = false,
//本地字段,判断是否是推荐论坛
- var isRecommend: Boolean = false
-)
+ var isRecommend: Boolean = false,
+ var orderTag: Long = 0,
+ var unread: Boolean = false,
+ var type: String = "" //game_bbs/official_bbs
+) {
+ fun transformUnreadEntity(): ForumUnreadEntity {
+ val forumUnreadEntity = ForumUnreadEntity()
+ forumUnreadEntity.id = id
+ forumUnreadEntity.name = name
+ forumUnreadEntity.unread = unread
+ return forumUnreadEntity
+ }
+}
data class ForumCategoryEntity(
@SerializedName("_id")
diff --git a/app/src/main/java/com/gh/gamecenter/entity/ForumUnreadEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ForumUnreadEntity.kt
new file mode 100644
index 0000000000..03eee93be7
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/ForumUnreadEntity.kt
@@ -0,0 +1,13 @@
+package com.gh.gamecenter.entity
+
+import android.os.Parcelable
+import com.google.gson.annotations.SerializedName
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+data class ForumUnreadEntity(
+ @SerializedName("_id")
+ var id: String = "",
+ var name: String = "",
+ var unread: Boolean = false
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/ForumVideoEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ForumVideoEntity.kt
new file mode 100644
index 0000000000..dd4bb6a4c5
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/ForumVideoEntity.kt
@@ -0,0 +1,50 @@
+package com.gh.gamecenter.entity
+
+import android.os.Parcelable
+import com.gh.gamecenter.qa.entity.Count
+import com.google.gson.annotations.SerializedName
+import kotlinx.android.parcel.IgnoredOnParcel
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+open class ForumVideoEntity(
+ @SerializedName("_id")
+ var id: String = "",
+ var title: String = "",
+ var des: String = "",
+ var poster: String = "",
+ var url: String = "",
+ val user: PersonalEntity = PersonalEntity(),
+ val me: MeEntity = MeEntity(),
+ val size: Long = 0,
+ var length: Long = 0,
+ // 有三种状态 pass通过,fail未通过,pending审核中
+ var status: String = "",
+ val format: String = "Mp4",
+ var game: GameEntity? = null,
+ @SerializedName("tag_activity_id")
+ var tagActivityId: String = "",//活动标签的id
+ @SerializedName("tag_activity_name")
+ var tagActivityName: String = "",
+ @SerializedName("bbs_id")
+ var bbsId: String = "",
+ @SerializedName("game_id")
+ var gameId: String = "",
+ var type: String = "",
+ var share: Int = 0,
+ var time: Time = Time(),
+ @SerializedName("video_info")
+ var videoInfo: VideoInfo = VideoInfo(),
+ @SerializedName("is_jx")
+ var isHighlighted: Boolean = true,
+ var bbs: CommunityEntity? = null,
+ var count: Count = Count(),
+ @IgnoredOnParcel
+ var videoIsMuted: Boolean = false //是否静音标记
+) : Parcelable
+
+@Parcelize
+data class Time(val upload: Long = 0, val audit: Long = 0, val update: Long = 0) : Parcelable
+
+@Parcelize
+data class VideoInfo(var width: Int = 0, var height: Int = 0) : Parcelable
\ No newline at end of file
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..d02178a2dc
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/LocalVideoEntity.kt
@@ -0,0 +1,16 @@
+package com.gh.gamecenter.entity
+
+import android.net.Uri
+import android.os.Parcelable
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+data class LocalVideoEntity(
+ var id: String = "",
+ var filePath: String = "",
+ var poster: String = "",
+ var contentUri: Uri? = null,
+ var duration: Long = 0,
+ var format: String = "",
+ var size: Long = 0
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/MeEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/MeEntity.kt
index 78c673a3b8..9726c7979b 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/MeEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/MeEntity.kt
@@ -52,19 +52,23 @@ class MeEntity(@SerializedName("is_community_voted")
@SerializedName("is_article_favorite")
var isArticleFavorite: Boolean = false,
+ @SerializedName("is_question_favorite")
+ var isQuestionFavorite: Boolean = false,
+
@SerializedName("is_toolkit_favorite")
var isToolkitFavorite: Boolean = false,
- @SerializedName("is_comment_own", alternate = ["is_answer_commented", "is_community_article_commented", "is_video_commented"])
+ @SerializedName("is_comment_own", alternate = ["is_answer_commented", "is_community_article_commented", "is_video_commented", "is_question_commented"])
var isCommentOwner: Boolean = false, // 是否是当前评论的拥有者
@SyncPage(syncNames = [SyncFieldConstants.ARTICLE_COMMENT_VOTE])
- @SerializedName("is_comment_voted", alternate = ["is_answer_comment_voted", "is_video_comment_voted", "is_community_article_comment_voted"])
+ @SerializedName("is_comment_voted", alternate = ["is_answer_comment_voted", "is_video_comment_voted", "is_community_article_comment_voted", "is_question_comment_voted"])
var isCommentVoted: Boolean = false, // 是否已经点赞过当前评论
@SerializedName("is_version_requested")
var isVersionRequested: Boolean = false,
+ @SyncPage(syncNames = [SyncFieldConstants.IS_FOLLOWER])
@SerializedName("is_follower", alternate = ["is_follow"])
var isFollower: Boolean = false, // 是否已经关注该用户
@@ -102,8 +106,8 @@ class MeEntity(@SerializedName("is_community_voted")
@SerializedName("permissions")
val moderatorPermissions: Permissions = Permissions(),
- @SerializedName("is_answer_author", alternate = ["is_community_article_author"])
- val isArticleOrAnswerAuthor: Boolean = false, //用于判断是否是当前评论关联的回答或文章的作者
+ @SerializedName("is_answer_author", alternate = ["is_community_article_author", "is_question_author"])
+ val isArticleOrAnswerAuthor: Boolean = false, //用于判断是否是当前评论关联的回答/文章/问题的作者
@SerializedName("article_draft")
var articleDraft: ArticleDraftEntity? = null,//帖子详情可能返回草稿
@@ -159,8 +163,11 @@ data class Permissions(
var topCommunityArticleComment: Int = GUEST, // 置顶文章评论
@SerializedName("hide-community-article-comment")
- var hideCommunityArticleComment: Int = GUEST // 隐藏文章评论
+ var hideCommunityArticleComment: Int = GUEST, // 隐藏文章评论
+ //视频相关
+ @SerializedName("choiceness-video")
+ var highlightVideo: Int = GUEST // 加精视频帖
) : Parcelable {
companion object {
// -1 为无权限,0 为初级权限,1 为高级权限
diff --git a/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt
index 064dc16061..30d11efd49 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/PersonalEntity.kt
@@ -41,7 +41,7 @@ data class PersonalEntity(
@SerializedName("today_visit")
val todayVisit: Int? = 0) : Parcelable {
- fun getQaCount() = answer + question + communityArticle
+ fun getTotalCount() = video + answer + question + communityArticle
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt
index f7f80ffadc..6ba18307ab 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/PersonalHistoryEntity.kt
@@ -3,10 +3,7 @@ package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.common.annotation.SyncPage
import com.gh.common.syncpage.SyncFieldConstants
-import com.gh.gamecenter.qa.entity.AnswerEntity
-import com.gh.gamecenter.qa.entity.CommunityVideoEntity
-import com.gh.gamecenter.qa.entity.ImageInfo
-import com.gh.gamecenter.qa.entity.Questions
+import com.gh.gamecenter.qa.entity.*
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.IgnoredOnParcel
import kotlinx.android.parcel.Parcelize
@@ -18,6 +15,12 @@ data class PersonalHistoryEntity(
val type: String = "",
var question: Question = Question(),
var brief: String = "",
+ var des: String = "",
+ var url: String = "",
+ @SerializedName("video_info")
+ var videoInfo: VideoInfo = VideoInfo(),
+ var poster: String = "",
+ var length: Long = 0,
var count: Count = Count(),
val time: Long = 0,
var title: String = "",
@@ -60,7 +63,16 @@ data class PersonalHistoryEntity(
var vote: Int = -1,
@SyncPage(syncNames = [SyncFieldConstants.ANSWER_COUNT])
var answer: Int = -1,
- var reply: Int = -1) : Parcelable
+ var reply: Int = -1) : Parcelable {
+
+ fun transformForumCount(): com.gh.gamecenter.qa.entity.Count {
+ val count = com.gh.gamecenter.qa.entity.Count()
+ count.comment = comment
+ count.vote = vote
+ count.answer = answer
+ return count
+ }
+ }
@Parcelize
data class Comment(
@@ -88,7 +100,10 @@ data class PersonalHistoryEntity(
@SerializedName("ori_icon")
var rawIcon: String? = null,
@SerializedName("icon_subscript")
- var iconSubscript: String? = null
+ var iconSubscript: String? = null,
+
+ @SerializedName("played_time")
+ val playedTime: Long = 0
) : Parcelable {
@IgnoredOnParcel
var name: String
@@ -113,14 +128,11 @@ data class PersonalHistoryEntity(
answer.images = images
answer.videos = videos
answer.time = time
- answer.vote = count.vote
- answer.commentCount = count.comment
+ answer.count = count.transformForumCount()
answer.me = me
answer.commentable = commentable
answer.articleCommunityId = community.id
- if (type.contains("article")) {
- answer.type = "community_article"
- }
+ answer.type = type
return answer
}
@@ -133,4 +145,27 @@ data class PersonalHistoryEntity(
question.communityName = community.name
return question
}
+
+ fun transformForumVideoEntity(): ForumVideoEntity {
+ val forumVideoEntity = ForumVideoEntity()
+ if (type == "video") {
+ forumVideoEntity.id = id
+ forumVideoEntity.title = title
+ forumVideoEntity.des = des
+ forumVideoEntity.url = url
+ forumVideoEntity.poster = poster
+ forumVideoEntity.length = length
+ forumVideoEntity.videoInfo = videoInfo
+ } else {
+ forumVideoEntity.title = title
+ forumVideoEntity.des = brief
+ if (getPassVideos().isNotEmpty()) {
+ forumVideoEntity.id = getPassVideos()[0].id
+ forumVideoEntity.url = getPassVideos()[0].url
+ forumVideoEntity.poster = getPassVideos()[0].poster
+ forumVideoEntity.videoInfo = VideoInfo(width = getPassVideos()[0].width, height = getPassVideos()[0].height)
+ }
+ }
+ return forumVideoEntity
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/VideoDescItemEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/VideoDescItemEntity.kt
new file mode 100644
index 0000000000..3670d1afbe
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/entity/VideoDescItemEntity.kt
@@ -0,0 +1,6 @@
+package com.gh.gamecenter.entity
+
+data class VideoDescItemEntity(
+ var topVideoInfo: ForumVideoEntity? = null,
+ var recommendVideo: ForumVideoEntity? = null
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/entity/VideoDraftEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/VideoDraftEntity.kt
index 96e0f97163..d6f0d06189 100644
--- a/app/src/main/java/com/gh/gamecenter/entity/VideoDraftEntity.kt
+++ b/app/src/main/java/com/gh/gamecenter/entity/VideoDraftEntity.kt
@@ -8,6 +8,7 @@ import kotlinx.android.parcel.Parcelize
class VideoDraftEntity(@SerializedName("_id")
val id: String = "",
val title: String = "",
+ val des: String = "",
var poster: String = "",
val url: String = "",
@SerializedName("game_id")
@@ -15,21 +16,26 @@ class VideoDraftEntity(@SerializedName("_id")
@SerializedName("game_name")
val gameName: String = "",
@SerializedName("category_id")
- val categoryId: String = "",
+ val categoryId: String? = "",
val size: Long = 0,
val length: Long = 0,
@SerializedName("tag_id")
- val tagsId: List = ArrayList(),
+ val tagsId: List? = ArrayList(),
val user: UserEntity = UserEntity(),
val time: VideoTimeEntity = VideoTimeEntity(),
@SerializedName("local_path")
- var localPath: String = "",
+ var localPath: String? = "",
val original: String = "",//是否原创 //是否原创 yes/no 默认为空字符串
val source: String = "",//转载来源, 当 original=yes
@SerializedName("tag_activity_name")
val tagActivityName: String = "",
@SerializedName("tag_activity_id")
- var tagActivityId: String = "") : Parcelable
+ var tagActivityId: String = "",
+ var type: String = "",
+ var game: GameEntity? = null,
+ @SerializedName("bbs_id")
+ var bbsId: String = "",
+ var bbs: CommunityEntity? = null) : Parcelable
@Parcelize
class VideoTimeEntity(val create: Long = 0,
diff --git a/app/src/main/java/com/gh/gamecenter/eventbus/EBForumRecordChange.java b/app/src/main/java/com/gh/gamecenter/eventbus/EBForumRecordChange.java
new file mode 100644
index 0000000000..1d8f86c241
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/eventbus/EBForumRecordChange.java
@@ -0,0 +1,20 @@
+package com.gh.gamecenter.eventbus;
+
+import com.gh.gamecenter.entity.ForumEntity;
+
+public class EBForumRecordChange {
+
+ ForumEntity forumEntity;
+
+ public EBForumRecordChange(ForumEntity forumEntity) {
+ this.forumEntity = forumEntity;
+ }
+
+ public ForumEntity getForumEntity() {
+ return forumEntity;
+ }
+
+ public void setForumEntity(ForumEntity forumEntity) {
+ this.forumEntity = forumEntity;
+ }
+}
diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListAdapter.kt
index 12441cc748..291c7c8bfd 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListAdapter.kt
@@ -10,7 +10,6 @@ import com.gh.base.BaseActivity
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.MtaHelper
-import com.gh.common.util.dip2px
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
@@ -20,7 +19,8 @@ import com.gh.gamecenter.forum.home.ForumArticleAskItemViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.Questions
-import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
+import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntrance: String, val path: String) : ListAdapter(context), ISyncAdapterHandler {
@@ -56,10 +56,11 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
questions.id = answer.id ?: ""
questions.title = answer.articleTitle
questions.description = answer.description
- questions.answerCount = answer.answerCount
+ questions.answerCount = answer.count.answer
answer.questions = questions
if (path == "精华") answer.type = "community_article"
if (path == "问答") answer.type = "question"
+ if (path == "视频") answer.type = "video"
if (answer.bbs.id.isEmpty()) answer.bbs.id = bbsId
@@ -76,12 +77,20 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
answerViewHolder.bindForumAnswerItem(answer, mEntrance, path)
answerViewHolder.itemView.setOnClickListener {
val entrance = BaseActivity.mergeEntranceAndPath(mEntrance, path)
- if ("community_article" == answer.type) {
- MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
- mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(bbsId), answer.id!!, mEntrance, path))
- } else {
- MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
- mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, answer.id, mEntrance, path))
+ when (answer.type) {
+ "community_article" -> {
+ MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
+ mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(bbsId), answer.id!!, mEntrance, path))
+ }
+ "video" -> {
+ MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
+ mContext.startActivity(ForumVideoDetailActivity.getIntent(mContext, answer.id ?:""))
+ }
+ else -> {
+ MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, answer.id
+ ?: "", mEntrance, path))
+ }
}
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
index 8ce88b45c4..f6332492df 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListFragment.kt
@@ -4,15 +4,16 @@ import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
-import com.gh.common.util.EntranceUtils
-import com.gh.common.util.dip2px
-import com.gh.common.util.viewModelProvider
+import com.gh.common.AppExecutor
+import com.gh.common.constant.Constants
+import com.gh.common.util.*
import com.gh.common.view.divider.HorizontalDividerItemDecoration
import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.baselist.ListFragment
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.eventbus.EBTypeChange
+import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper
import com.gh.gamecenter.qa.CommunityFragment
import com.gh.gamecenter.qa.entity.AnswerEntity
import org.greenrobot.eventbus.EventBus
@@ -23,52 +24,16 @@ class ForumArticleAskListFragment : ListFragment CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
- EventBus.getDefault().post(EBTypeChange(ForumDetailFragment.EB_HIDE_QUESTION_BUTTON, 0))
- } else if (dy < -CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
- EventBus.getDefault().post(EBTypeChange(ForumDetailFragment.EB_SHOW_QUESTION_BUTTON, 0))
- }
- }
- })
- }
-
- fun refresh() {
- onLoadRefresh()
- }
-
- override fun hideRefreshingLayout() {
- (parentFragment as? ForumDetailFragment)?.hideRefreshingLayout()
- }
-
- fun onRefresh(filter: String) {
- mViewModel?.sort = if (filter == "最新发布") "time.create" else "time.reply"
- onRefresh()
- }
-
-
override fun provideListAdapter(): ListAdapter<*> {
if (!::mAdapter.isInitialized) {
mAdapter = ForumArticleAskListAdapter(requireContext(), bbsId, mEntrance, mPath)
@@ -83,6 +48,124 @@ class ForumArticleAskListFragment : ListFragment CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
+ EventBus.getDefault().post(EBTypeChange(ForumDetailFragment.EB_HIDE_QUESTION_BUTTON, 0))
+ } else if (dy < -CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
+ EventBus.getDefault().post(EBTypeChange(ForumDetailFragment.EB_SHOW_QUESTION_BUTTON, 0))
+ }
+ scroll()
+ }
+ })
+ }
+
+ override fun onResume() {
+ resumeVideo()
+ super.onResume()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ pauseVideo()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mScrollCalculatorHelper?.currentPlayer?.release()
+ }
+
+ override fun onLoadDone() {
+ super.onLoadDone()
+ AppExecutor.uiExecutor.executeWithDelay(Runnable {
+ scroll()
+ mScrollCalculatorHelper?.onScrollStateChanged(mListRv, RecyclerView.SCROLL_STATE_IDLE)
+ }, 100)
+ }
+
+ fun refresh() {
+ onLoadRefresh()
+ }
+
+ override fun hideRefreshingLayout() {
+ (parentFragment as? ForumDetailFragment)?.hideRefreshingLayout()
+ }
+
+ fun onRefresh(filter: String) {
+ if (mPath == "全部") {
+ mViewModel?.sort = if (filter == "最新发布") "time.create" else "time.reply"
+ }
+ if (mPath == "视频") {
+ mViewModel?.videoSort = if (filter == "推荐") "recommend" else "time.upload"
+ }
+ onRefresh()
+ }
+
+ private fun scroll() {
+ val firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition()
+ val lastVisibleItem = mLayoutManager.findLastVisibleItemPosition()
+ mScrollCalculatorHelper?.onScroll(mViewModel?.videoList, firstVisibleItem, lastVisibleItem)
+ }
+
+ private fun resumeVideo() {
+ mScrollCalculatorHelper?.run {
+ if (currentPlayer != null) {
+ val video = mViewModel?.videoList?.safelyGetInRelease(currentPosition)
+ if (video != null) {
+ val position = ForumScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(video.url))
+ //这里必须要延迟操作,否则会白屏
+ mBaseHandler.postDelayed({
+ if (position != 0L) {
+ currentPlayer?.seekTo(position)
+ currentPlayer?.onVideoResume(false)
+ val videoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
+ if (videoVoiceStatus) {
+ currentPlayer?.mute()
+ } else {
+ currentPlayer?.unMute()
+ }
+ } else {
+ currentPlayer?.release()
+ }
+
+ }, 50)
+ }
+ }
+ }
+ }
+
+ private fun pauseVideo() {
+ mScrollCalculatorHelper?.run {
+ if (currentPosition >= 0) {
+ currentPlayer?.onVideoPause()
+ val position = currentPlayer?.getCurrentPosition() ?: 0L
+ val video = mViewModel?.videoList?.safelyGetInRelease(currentPosition)
+ if (video != null) {
+ ForumScrollCalculatorHelper.savePlaySchedule(MD5Utils.getContentMD5(video.url), position)
+ }
+ }
+ }
+ }
+
override fun addSyncPageObserver(): Boolean = true
override fun provideSyncAdapter(): ForumArticleAskListAdapter = mAdapter
diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt
index b06b8752ec..de270e6933 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumArticleAskListViewModel.kt
@@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.UrlFilterUtils
import com.gh.gamecenter.baselist.ListViewModel
-import com.gh.gamecenter.forum.home.ForumArticleListViewModel
+import com.gh.gamecenter.entity.ForumVideoEntity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
@@ -14,6 +14,8 @@ import io.reactivex.Observable
class ForumArticleAskListViewModel(application: Application, val bbsId: String = "", val mPath: String = "") : ListViewModel(application) {
var sort: String = "time.reply"
+ var videoSort: String = "recommend"
+ var videoList = listOf()
override fun provideDataObservable(page: Int): Observable> {
return when (mPath) {
@@ -23,14 +25,25 @@ class ForumArticleAskListViewModel(application: Application, val bbsId: String =
"精华" -> {
RetrofitManager.getInstance(getApplication()).api.getEssenceForumList(bbsId, page)
}
- else -> {
+ "问答" -> {
RetrofitManager.getInstance(getApplication()).api.getAskForumList(bbsId, page)
}
+ else -> {
+ RetrofitManager.getInstance(getApplication()).api.getVideoForumList(bbsId, UrlFilterUtils.getFilterQuery(videoSort, "-1"), page)
+ }
}
}
override fun mergeResultLiveData() {
- mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
+ mResultLiveData.addSource(mListLiveData) { list ->
+
+ videoList = list.map {
+ if (mPath == "视频") it.type = "video"
+ it.transformForumVideoEntity()
+ }
+
+ mResultLiveData.postValue(list)
+ }
}
class Factory(private val bbsId: String, val path: String) : ViewModelProvider.NewInstanceFactory() {
diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt
index 7b3d09ea38..7c7e8706d4 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailFragment.kt
@@ -1,6 +1,8 @@
package com.gh.gamecenter.forum.detail
+import android.graphics.Bitmap
import android.graphics.drawable.ColorDrawable
+import android.os.Build
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
@@ -10,7 +12,7 @@ import android.view.animation.AnimationUtils
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
-import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.view.ViewCompat
@@ -24,9 +26,11 @@ import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
import com.facebook.drawee.generic.RoundingParams
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.base.fragment.BaseLazyTabFragment
+import com.gh.common.constant.Constants
import com.gh.common.dialog.TrackableDialog
import com.gh.common.util.*
import com.gh.gamecenter.GameDetailActivity
+import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.FragmentForumDetailBinding
import com.gh.gamecenter.entity.CommunityEntity
@@ -40,8 +44,10 @@ import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.mvvm.Status
+import com.gh.gamecenter.qa.BbsType
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
+import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.google.android.material.appbar.AppBarLayout
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@@ -53,12 +59,14 @@ class ForumDetailFragment : BaseLazyTabFragment() {
private var mAllForumArticleAskListFragment: ForumArticleAskListFragment? = null
private var mEssenceForumArticleAskListFragment: ForumArticleAskListFragment? = null
private var mAskForumArticleAskListFragment: ForumArticleAskListFragment? = null
+ private var mVideoForumArticleAskListFragment: ForumArticleAskListFragment? = null
private var bbsId: String = ""
private var mViewModel: ForumDetailViewModel? = null
private var mForumDetail: ForumDetailEntity? = null
private lateinit var mBinding: FragmentForumDetailBinding
private var mFilter = "最新回复"
+ private var mVideoFilter = "推荐"
private var mLastPosition = 0
override fun initFragmentList(fragments: MutableList) {
@@ -68,15 +76,19 @@ class ForumDetailFragment : BaseLazyTabFragment() {
EntranceUtils.KEY_PATH to "精华", EntranceUtils.KEY_BBS_ID to bbsId)) as ForumArticleAskListFragment?
mAskForumArticleAskListFragment = ForumArticleAskListFragment().with(bundleOf(EntranceUtils.KEY_ENTRANCE to "论坛详情",
EntranceUtils.KEY_PATH to "问答", EntranceUtils.KEY_BBS_ID to bbsId)) as ForumArticleAskListFragment?
+ mVideoForumArticleAskListFragment = ForumArticleAskListFragment().with(bundleOf(EntranceUtils.KEY_ENTRANCE to "论坛详情",
+ EntranceUtils.KEY_PATH to "视频", EntranceUtils.KEY_BBS_ID to bbsId)) as ForumArticleAskListFragment?
fragments.add(mAllForumArticleAskListFragment!!)
fragments.add(mEssenceForumArticleAskListFragment!!)
fragments.add(mAskForumArticleAskListFragment!!)
+ fragments.add(mVideoForumArticleAskListFragment!!)
}
override fun initTabTitleList(tabTitleList: MutableList) {
tabTitleList.add(TAB_TITLE_ALL)
tabTitleList.add(TAB_TITLE_ESSENCE)
tabTitleList.add(TAB_TITLE_ASK)
+ tabTitleList.add(TAB_TITLE_VIDEO)
}
override fun getInflatedLayout(): View {
@@ -158,6 +170,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
})
mViewPager.doOnPageSelected {
mBinding.filterContainer.goneIf(it != 0)
+ mBinding.videoFilterContainer.goneIf(it != 3)
MtaHelper.onEvent("论坛详情", getKeyValue(mLastPosition), getKeyValue(it))
mLastPosition = it
}
@@ -171,6 +184,9 @@ class ForumDetailFragment : BaseLazyTabFragment() {
if (mAskForumArticleAskListFragment != null && mViewPager.currentItem == 2) {
mAskForumArticleAskListFragment?.refresh()
}
+ if (mVideoForumArticleAskListFragment != null && mViewPager.currentItem == 3) {
+ mVideoForumArticleAskListFragment?.refresh()
+ }
}
LogUtils.uploadAccessToBbs(bbsId, "论坛详情")
}
@@ -190,8 +206,14 @@ class ForumDetailFragment : BaseLazyTabFragment() {
private fun initUI() {
mForumDetail?.apply {
mBinding.entity = this
- mBinding.forumThumbSmall.displayGameIcon(game.getIcon(), game.iconSubscript)
- mBinding.forumThumbBig.displayGameIcon(game.getIcon(), game.iconSubscript)
+ if (type == "official_bbs") {
+ mBinding.forumThumbSmall.displayGameIcon(icon, null)
+ mBinding.forumThumbBig.displayGameIcon(icon, null)
+ } else {
+ mBinding.forumThumbSmall.displayGameIcon(game.getIcon(), game.iconSubscript)
+ mBinding.forumThumbBig.displayGameIcon(game.getIcon(), game.iconSubscript)
+ }
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
initModeratorHeadView(moderator)
if (topLink.isNotEmpty()) {
mBinding.forumTopContentRv.visibility = View.VISIBLE
@@ -200,38 +222,32 @@ class ForumDetailFragment : BaseLazyTabFragment() {
adapter = ForumTopLinkAdapter(requireContext(), topLink)
}
} else {
- if (background.isNotEmpty()) {
- val params = mBinding.tabContainer.layoutParams as LinearLayout.LayoutParams
- params.topMargin = DisplayUtils.dip2px(-8f)
- mBinding.tabContainer.layoutParams = params
- mBinding.tabContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.background_shape_white_radius_5_top_only)
- }
+ val params = mBinding.tabContainer.layoutParams as LinearLayout.LayoutParams
+ params.topMargin = DisplayUtils.dip2px(-8f)
+ mBinding.tabContainer.layoutParams = params
+ mBinding.tabContainer.background = ContextCompat.getDrawable(requireContext(), R.drawable.background_shape_white_radius_5_top_only)
}
+
if (background.isEmpty()) {
- mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back)
- mBinding.forumBackground.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
- mBinding.forumNameTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.text_333333))
- mBinding.followTv.background = ContextCompat.getDrawable(requireContext(), if (me.isFollower) R.drawable.bg_shape_f5_radius_999 else R.drawable.bg_forum_follow)
- mBinding.followTv.setTextColor(ContextCompat.getColor(requireContext(), if (me.isFollower) R.color.text_999999 else R.color.theme_font))
+ ImageUtils.getBitmap(game.getIcon(), object : BiCallback {
+ @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+ override fun onFirst(first: Bitmap) {
+ var blurBitmap = BitmapUtils.getBlurBitmap(requireContext(), first, 25)
+ mBinding.forumDefaultBackground.setImageBitmap(blurBitmap)
+ }
- val params = mBinding.forumThumbBig.layoutParams as ConstraintLayout.LayoutParams
- params.bottomMargin = DisplayUtils.dip2px(20f)
- mBinding.forumThumbBig.layoutParams = params
-
- val headContainerParams = mBinding.headContainer.layoutParams as LinearLayout.LayoutParams
- headContainerParams.height = DisplayUtils.dip2px(186f)
- mBinding.headContainer.layoutParams = headContainerParams
+ override fun onSecond(second: Boolean) {}
+ })
} else {
- mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
ImageUtils.display(mBinding.forumBackground, background)
- mBinding.forumNameTv.setTextColor(ContextCompat.getColor(requireContext(), R.color.white))
- mBinding.followTv.setTextColor(ContextCompat.getColor(requireContext(), if (me.isFollower) R.color.white_alpha_40 else R.color.white_alpha_90))
- mBinding.followTv.background = ContextCompat.getDrawable(requireContext(), R.drawable.bg_forum_detail_follow)
}
+ mBinding.followTv.setTextColor(ContextCompat.getColor(requireContext(), if (me.isFollower) R.color.text_999999 else R.color.white))
+ mBinding.followTv.background = ContextCompat.getDrawable(requireContext(), if (me.isFollower) R.drawable.bg_shape_f5_radius_999 else R.drawable.login_btn_bg)
}
}
- @OnClick(R.id.filterContainer, R.id.community_edit, R.id.moderatorTv, R.id.reuse_no_connection, R.id.gameZoneTv, R.id.followTv, R.id.forumThumbBig, R.id.searchIv)
+ @OnClick(R.id.filterContainer, R.id.videoFilterContainer, R.id.community_edit, R.id.moderatorTv, R.id.reuse_no_connection, R.id.gameZoneTv,
+ R.id.followTv, R.id.forumThumbBig, R.id.searchIv, R.id.forumRuleContainer)
fun onViewClick(view: View) {
when (view.id) {
R.id.searchIv -> {
@@ -239,7 +255,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
}
R.id.filterContainer -> {
MtaHelper.onEvent("论坛详情", "全部Tab", "过滤选项")
- showFilterPopupWindow {
+ showFilterPopupWindow(arrayListOf("最新发布", "最新回复")) {
mFilter = it
mBinding.forumFilter.text = mFilter
if (mAllForumArticleAskListFragment != null && mViewPager.currentItem == 0) {
@@ -247,6 +263,16 @@ class ForumDetailFragment : BaseLazyTabFragment() {
}
}
}
+ R.id.videoFilterContainer -> {
+ MtaHelper.onEvent("论坛详情", "视频Tab", "过滤选项")
+ showFilterPopupWindow(arrayListOf("推荐", "最新发布")) {
+ mVideoFilter = it
+ mBinding.videoForumFilter.text = mVideoFilter
+ if (mVideoForumArticleAskListFragment != null && mViewPager.currentItem == 3) {
+ mVideoForumArticleAskListFragment?.onRefresh(mVideoFilter)
+ }
+ }
+ }
R.id.community_edit -> {
showCommunityEditWindow()
}
@@ -297,6 +323,10 @@ class ForumDetailFragment : BaseLazyTabFragment() {
}
}
}
+
+ R.id.forumRuleContainer -> {
+ startActivity(NewsDetailActivity.getIntentById(requireContext(), Constants.FORUM_REGULATIONS_NEWS_ID, "论坛详情"))
+ }
}
}
@@ -304,16 +334,14 @@ class ForumDetailFragment : BaseLazyTabFragment() {
mBinding.titleTv.setTextColor(ContextCompat.getColor(requireContext(), if (isToolbarWhite) R.color.black else R.color.white))
mBinding.toolbar.setBackgroundColor(ContextCompat.getColor(requireContext(), if (isToolbarWhite) R.color.white else R.color.transparent))
DisplayUtils.setStatusBarColor(requireActivity(), if (isToolbarWhite) R.color.white else R.color.transparent, true)
- if (mForumDetail?.background?.isEmpty() == false) {
- if (isToolbarWhite) {
- DisplayUtils.setLightStatusBar(requireActivity(), true)
- mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back)
- mBinding.searchIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_forum_detail_search))
- } else {
- DisplayUtils.setLightStatusBar(requireActivity(), false)
- mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
- mBinding.searchIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_forum_detail_search_light))
- }
+ if (isToolbarWhite) {
+ DisplayUtils.setLightStatusBar(requireActivity(), true)
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back)
+ mBinding.searchIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_forum_detail_search))
+ } else {
+ DisplayUtils.setLightStatusBar(requireActivity(), false)
+ mBinding.toolbar.setNavigationIcon(R.drawable.ic_bar_back_light)
+ mBinding.searchIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_forum_detail_search_light))
}
}
@@ -333,7 +361,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
.setBackground(ColorDrawable(ContextCompat.getColor(requireContext(), R.color.placeholder_bg)))
.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP)
.build()
- val params = LinearLayout.LayoutParams(24f.dip2px(), 24f.dip2px())
+ val params = LinearLayout.LayoutParams(20f.dip2px(), 20f.dip2px())
headView.layoutParams = params
if (index != 0) {
params.leftMargin = (-8f).dip2px()
@@ -349,8 +377,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
}
- private fun showFilterPopupWindow(clickListener: (String) -> Unit) {
- val contentList = arrayListOf("最新发布", "最新回复")
+ private fun showFilterPopupWindow(contentList: ArrayList, clickListener: (String) -> Unit) {
val inflater = LayoutInflater.from(requireContext())
val layout = inflater.inflate(R.layout.layout_popup_container, null)
val popupWindow = PopupWindow(
@@ -368,7 +395,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
val container = layout.findViewById(R.id.container)
for (text in contentList) {
val item = inflater.inflate(R.layout.layout_popup_option_item, container, false)
- if (mFilter == text) {
+ if (mVideoFilter == text) {
(item as TextView).setTextColor(ContextCompat.getColor(requireContext(), R.color.theme_font))
} else {
(item as TextView).setTextColor(ContextCompat.getColor(requireContext(), R.color.text_999999))
@@ -408,24 +435,39 @@ class ForumDetailFragment : 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 {
MtaHelper.onEvent("论坛详情", "发布", "发帖子")
startActivity(ArticleEditActivity.getIntent(requireContext(), CommunityEntity(mForumDetail?.id
?: "", mForumDetail?.name
- ?: "", icon = mForumDetail?.game?.getIcon(), iconSubscript = mForumDetail?.game?.iconSubscript)))
+ ?: "", icon = mForumDetail?.game?.getIcon(), iconSubscript = mForumDetail?.game?.iconSubscript), mForumDetail?.type
+ ?: ""))
dialog.dismiss()
}
})
}
- contentView.findViewById(R.id.community_edit_question).setOnClickListener {
+ contentView.findViewById(R.id.community_edit_question_container).setOnClickListener {
context?.ifLogin("论坛详情", action = {
checkStoragePermissionBeforeAction {
MtaHelper.onEvent("论坛详情", "发布", "提问")
startActivity(QuestionEditActivity.getIntent(requireContext(), CommunityEntity(mForumDetail?.id
?: "", mForumDetail?.name
- ?: "", icon = mForumDetail?.game?.getIcon(), iconSubscript = mForumDetail?.game?.iconSubscript)))
+ ?: "", icon = mForumDetail?.game?.getIcon(), iconSubscript = mForumDetail?.game?.iconSubscript), mForumDetail?.type
+ ?: ""))
+ dialog.dismiss()
+ }
+ })
+ }
+ contentView.findViewById(R.id.community_edit_video_container).setOnClickListener {
+ context?.ifLogin("论坛详情", action = {
+ checkStoragePermissionBeforeAction {
+ MtaHelper.onEvent("论坛详情", "发布", "发视频")
+ val communityEntity = CommunityEntity(mForumDetail?.id
+ ?: "", mForumDetail?.name
+ ?: "", icon = mForumDetail?.game?.getIcon(), iconSubscript = mForumDetail?.game?.iconSubscript)
+ startActivity(VideoPublishActivity.getIntent(requireContext(), communityEntity, mForumDetail?.type
+ ?: "", mEntrance, "论坛详情"))
dialog.dismiss()
}
})
@@ -461,6 +503,7 @@ class ForumDetailFragment : BaseLazyTabFragment() {
const val TAB_TITLE_ALL = "全部"
const val TAB_TITLE_ESSENCE = "精华"
const val TAB_TITLE_ASK = "问答"
+ const val TAB_TITLE_VIDEO = "视频"
const val EB_SHOW_QUESTION_BUTTON = "EB_SHOW_QUESTION_BUTTON"
const val EB_HIDE_QUESTION_BUTTON = "EB_HIDE_QUESTION_BUTTON"
}
diff --git a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt
index 1de25fe3ff..e6600f6948 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt
@@ -6,26 +6,40 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import com.gh.common.util.singleToMain
import com.gh.gamecenter.entity.ForumDetailEntity
+import com.gh.gamecenter.eventbus.EBForumRecordChange
import com.gh.gamecenter.mvvm.Resource
import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.EmptyResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
+import com.gh.gamecenter.room.AppDatabase
import com.halo.assistant.HaloApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
+import org.greenrobot.eventbus.EventBus
import retrofit2.HttpException
class ForumDetailViewModel(application: Application, val bbsId: String) : AndroidViewModel(application) {
private val mApi = RetrofitManager.getInstance(application).api
+ private val mForumDao = AppDatabase.getInstance(HaloApp.getInstance()).forumDao()
var forumDetail = MutableLiveData>()
init {
+ postForumRead()
getForumDetail()
}
+ @SuppressLint("CheckResult")
+ fun postForumRead() {
+ mApi.postForumRead(bbsId)
+ .compose(singleToMain())
+ .subscribe(EmptyResponse())
+ }
+
fun getForumDetail() {
mApi.getForumDetail(bbsId)
.subscribeOn(Schedulers.io())
@@ -34,6 +48,10 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi
override fun onResponse(response: ForumDetailEntity?) {
super.onResponse(response)
forumDetail.postValue(Resource.success(response))
+ response?.run {
+ mForumDao.addForum(convertForumDetailEntityToForumEntity())
+ EventBus.getDefault().post(EBForumRecordChange(convertForumDetailEntityToForumEntity()))
+ }
}
override fun onFailure(e: HttpException?) {
diff --git a/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowAdapter.kt
deleted file mode 100644
index 8c493c522d..0000000000
--- a/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowAdapter.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.gh.gamecenter.forum.follow
-
-import android.content.Context
-import android.view.Gravity
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-import com.gh.base.BaseRecyclerViewHolder
-import com.gh.common.util.*
-import com.gh.common.view.BugFixedPopupWindow
-import com.gh.gamecenter.R
-import com.gh.gamecenter.databinding.ForumMyFollowBinding
-import com.gh.gamecenter.entity.ForumEntity
-import com.gh.gamecenter.eventbus.EBForumFollowChange
-import com.gh.gamecenter.forum.detail.ForumDetailActivity
-import com.gh.gamecenter.qa.entity.CommunitySelectEntity
-import com.lightgame.adapter.BaseRecyclerAdapter
-import org.greenrobot.eventbus.EventBus
-
-class ForumMyFollowAdapter(context: Context, val mViewModel: ForumMyFollowViewModel) : BaseRecyclerAdapter(context) {
- val entityList = ArrayList()
-
- fun setListData(updateData: List) {
- entityList.clear()
- entityList.addAll(updateData)
- notifyDataSetChanged()
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- return ForumMyFollowViewHolder(ForumMyFollowBinding.bind(mLayoutInflater.inflate(R.layout.forum_my_follow, parent, false)))
- }
-
- override fun getItemCount(): Int = entityList.size
-
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- val forumEntity = entityList[position]
- val followViewHolder = holder as ForumMyFollowViewHolder
- followViewHolder.binding.entity = forumEntity
- followViewHolder.binding.forumIcon.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
- followViewHolder.binding.moreActionIv.setOnClickListener {
- MtaHelper.onEvent("论坛首页", "我关注的论坛", "更多")
- showMoreWindow(it, forumEntity)
- }
- followViewHolder.itemView.setOnClickListener {
- MtaHelper.onEvent("论坛首页", "我关注的论坛", forumEntity.name)
- mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, "我的关注"))
- }
- }
-
- private fun showMoreWindow(view: View, entity: ForumEntity) {
- val inflater = LayoutInflater.from(mContext)
- val layout = inflater.inflate(R.layout.layout_popup_container, null)
- val popupWindow = BugFixedPopupWindow(layout,
- LinearLayout.LayoutParams.WRAP_CONTENT,
- LinearLayout.LayoutParams.WRAP_CONTENT)
- val container = layout.findViewById(R.id.container)
- val dialogOptions = arrayListOf("取消关注")
- for (text in dialogOptions) {
- val item = inflater.inflate(R.layout.layout_popup_option_item, container, false)
- container.addView(item)
-
- val hitText = item.findViewById(R.id.hint_text)
- hitText.text = text
-
- item.setOnClickListener {
- popupWindow.dismiss()
- when (text) {
- "取消关注" -> {
- DialogUtils.showNewAlertDialog(mContext, "提示", "确定取消关注", "暂不", "确定", null, Gravity.CENTER, false, {}, {
- MtaHelper.onEvent("论坛首页", "我关注的论坛", "取消关注")
- mViewModel.unFollowForum(entity.id) {
- EventBus.getDefault().post(EBForumFollowChange(entity, false))
- }
- })
- }
- }
- }
- }
- popupWindow.isTouchable = true
- popupWindow.isFocusable = true
-
- popupWindow.showAutoOrientation(view)
- }
-
- class ForumMyFollowViewHolder(val binding: ForumMyFollowBinding) : BaseRecyclerViewHolder(binding.root)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowFragment.kt
deleted file mode 100644
index ef0538645e..0000000000
--- a/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowFragment.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.gh.gamecenter.forum.follow
-
-import android.os.Bundle
-import android.view.View
-import android.widget.LinearLayout
-import androidx.lifecycle.Observer
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-import com.gh.common.AppExecutor
-import com.gh.common.util.viewModelProvider
-import com.gh.gamecenter.R
-import com.gh.gamecenter.eventbus.EBForumFollowChange
-import com.gh.gamecenter.normal.NormalFragment
-import kotterknife.bindView
-import org.greenrobot.eventbus.Subscribe
-import org.greenrobot.eventbus.ThreadMode
-
-class ForumMyFollowFragment : NormalFragment() {
-
- val mRefresh by bindView(R.id.list_refresh)
- val mListRv by bindView(R.id.list_rv)
- val mReuseLoading by bindView(R.id.reuse_ll_loading)
- val mNoConnection by bindView(R.id.reuse_no_connection)
- val mNoneData by bindView(R.id.reuse_none_data)
-
- private var mAdapter: ForumMyFollowAdapter? = null
- private var mViewModel: ForumMyFollowViewModel? = null
-
- override fun getLayoutId(): Int = R.layout.fragment_list_base
-
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- mViewModel = viewModelProvider()
- mListRv.apply {
- layoutManager = LinearLayoutManager(requireContext())
- mAdapter = ForumMyFollowAdapter(requireContext(), mViewModel!!)
- adapter = mAdapter
- }
- mViewModel?.forumData?.observe(viewLifecycleOwner, Observer {
- mRefresh.isRefreshing = false
- mReuseLoading.visibility = View.GONE
- if (it != null) {
- mNoConnection.visibility = View.GONE
- if (it.isNotEmpty()) {
- mNoneData.visibility = View.GONE
- mAdapter?.setListData(it)
- } else {
- mNoneData.visibility = View.VISIBLE
- }
- } else {
- mNoneData.visibility = View.GONE
- mNoConnection.visibility = View.VISIBLE
- }
- })
- mNoConnection.setOnClickListener {
- mViewModel?.loadFollowsForum()
- }
- mRefresh.setOnRefreshListener {
- mViewModel?.loadFollowsForum()
- }
- }
-
- @Subscribe(threadMode = ThreadMode.MAIN)
- fun onFollowForumChange(forumFollowChange: EBForumFollowChange) {
- val entityList = mAdapter?.entityList ?: arrayListOf()
- val index = entityList.indexOfFirst { it.id == forumFollowChange.forumEntity.id }
- val findEntity = entityList.find { it.id == forumFollowChange.forumEntity.id }
- if (!forumFollowChange.isFollow) {
- entityList.remove(findEntity)
- mAdapter?.notifyItemRangeRemoved(index, 1)
- }
- if (mAdapter?.entityList?.isEmpty() == true) {
- mListRv.visibility = View.GONE
- mNoneData.visibility = View.VISIBLE
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowViewModel.kt
deleted file mode 100644
index 2876855c76..0000000000
--- a/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowViewModel.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.gh.gamecenter.forum.follow
-
-import android.annotation.SuppressLint
-import android.app.Application
-import androidx.lifecycle.AndroidViewModel
-import androidx.lifecycle.MediatorLiveData
-import com.gh.gamecenter.baselist.ListViewModel
-import com.gh.gamecenter.entity.ForumEntity
-import com.gh.gamecenter.manager.UserManager
-import com.gh.gamecenter.qa.entity.CommunitySelectEntity
-import com.gh.gamecenter.retrofit.BiResponse
-import com.gh.gamecenter.retrofit.Response
-import com.gh.gamecenter.retrofit.RetrofitManager
-import io.reactivex.Observable
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.schedulers.Schedulers
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-
-class ForumMyFollowViewModel(application: Application) : AndroidViewModel(application) {
-
- val forumData = MediatorLiveData>()
- init {
- loadFollowsForum()
- }
-
- fun loadFollowsForum(){
- RetrofitManager.getInstance(getApplication()).api
- .getFollowsForum(UserManager.getInstance().userId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : Response>() {
- override fun onResponse(response: List?) {
- super.onResponse(response)
- forumData.postValue(response)
- }
-
- override fun onFailure(e: HttpException?) {
- super.onFailure(e)
- forumData.postValue(null)
- }
- })
- }
-
- @SuppressLint("CheckResult")
- fun unFollowForum(bbsId: String, onSuccess: () -> Unit) {
- RetrofitManager.getInstance(getApplication()).api
- .unFollowForum(bbsId)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : BiResponse() {
- override fun onSuccess(data: ResponseBody) {
- onSuccess.invoke()
- }
- })
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ArticleItemVideoView.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ArticleItemVideoView.kt
new file mode 100644
index 0000000000..826479818d
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ArticleItemVideoView.kt
@@ -0,0 +1,353 @@
+package com.gh.gamecenter.forum.home
+
+import android.app.Activity
+import android.content.Context
+import android.util.AttributeSet
+import android.view.Surface
+import android.view.View
+import android.widget.ImageView
+import android.widget.SeekBar
+import android.widget.TextView
+import androidx.core.content.ContextCompat
+import com.facebook.drawee.view.SimpleDraweeView
+import com.gh.common.util.*
+import com.gh.gamecenter.R
+import com.gh.gamecenter.entity.ForumVideoEntity
+import com.gh.gamecenter.video.detail.CustomManager
+import com.lightgame.utils.Utils
+import com.shuyu.gsyvideoplayer.utils.CommonUtil
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
+import com.shuyu.gsyvideoplayer.video.base.GSYVideoViewBridge
+import io.reactivex.disposables.Disposable
+import java.util.*
+
+class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : StandardGSYVideoPlayer(context, attrs) {
+
+ private var mVideoEntity: ForumVideoEntity? = null
+ private var mMuteDisposable: Disposable? = null
+ private var mIsAutoPlay = false
+ var uuid = UUID.randomUUID().toString()
+
+ var thumbImage: SimpleDraweeView = findViewById(R.id.thumbImage)
+ var durationTv: TextView = findViewById(R.id.durationTv)
+ var completeContainer: View = findViewById(R.id.completeContainer)
+ var replayTv: TextView = findViewById(R.id.replayTv)
+ var shareTv: TextView = findViewById(R.id.shareTv)
+ var volume: ImageView = findViewById(R.id.volume)
+ var remainingTv: TextView = findViewById(R.id.remainingTv)
+ var back: ImageView = findViewById(R.id.back)
+
+ override fun getLayoutId(): Int {
+ return R.layout.layout_article_item_video
+ }
+
+ init {
+ post {
+ volume.setOnClickListener { toggleMute() }
+ }
+
+ if (mIfCurrentIsFullscreen) {
+ showBackBtn()
+ } else {
+ hideBackBtn()
+ }
+
+ setBackFromFullScreenListener {
+ clearFullscreenLayout()
+ }
+ }
+
+ override fun getGSYVideoManager(): GSYVideoViewBridge {
+ CustomManager.getCustomManager(getKey()).initContext(context.applicationContext)
+ return CustomManager.getCustomManager(getKey())
+ }
+
+ fun startPlayLogic(isAutoPlay: Boolean) {
+ mIsAutoPlay = isAutoPlay
+ startPlayLogic()
+ }
+
+ override fun prepareVideo() {
+ super.prepareVideo()
+ violenceUpdateMuteStatus()
+ }
+
+ fun violenceUpdateMuteStatus() {
+ if (mMuteDisposable != null) {
+ mMuteDisposable?.dispose()
+ mMuteDisposable = null
+ }
+ mMuteDisposable = rxTimer(25) {
+ if (it >= 400) {
+ mMuteDisposable?.dispose()
+ mMuteDisposable = null
+ }
+ updateMuteStatus()
+ }
+ }
+
+ // 不需要弹弹窗,直接播放
+ override fun showWifiDialog() {
+ startPlayLogic(false)
+ //val trafficVideo = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(SettingsFragment.TRAFFIC_VIDEO_SP_KEY, false)
+ //if (trafficVideo) {
+ // 不延迟的话 isCacheFile 可能直接返回 false
+ postDelayed({
+ tryCatchInRelease {
+ // 这个库的 NetworkUtils.isWifiConnected 可能会触发空指针,这里换为我们自己的
+ if (!com.shuyu.gsyvideoplayer.utils.NetworkUtils.isAvailable(mContext) && !gsyVideoManager.isCacheFile) {
+ Utils.toast(context, "网络异常,请检查手机网络状态")
+ } else if (!NetworkUtils.isWifiConnected(mContext) && !gsyVideoManager.isCacheFile) {
+ Utils.toast(context, "当前为非Wi-Fi环境,请注意流量消耗")
+ }
+ }
+ }, 100)
+ // }
+ }
+
+ override fun updateStartImage() {
+ if (mStartButton is ImageView) {
+ val imageView = mStartButton as ImageView
+ when (mCurrentState) {
+ GSYVideoView.CURRENT_STATE_PLAYING -> imageView.setImageResource(R.drawable.icon_preview_video_pause)
+ GSYVideoView.CURRENT_STATE_ERROR -> imageView.setImageResource(R.drawable.icon_preview_video_play)
+ else -> imageView.setImageResource(R.drawable.icon_preview_video_play)
+ }
+ }
+ }
+
+ override fun onClickUiToggle() {
+ if (mCurrentState == CURRENT_STATE_PLAYING) {
+ if (mStartButton.visibility == View.VISIBLE) {
+ changeUiToPlayingClear()
+ } else {
+ changeUiToPlayingShow()
+ }
+ } else {
+ super.onClickUiToggle()
+ }
+ }
+
+ /******************* 下方两个重载方法,在播放开始前不屏蔽封面,不需要可屏蔽 ********************/
+
+ override fun onSurfaceUpdated(surface: Surface) {
+ super.onSurfaceUpdated(surface)
+ if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
+ mThumbImageViewLayout.visibility = View.INVISIBLE
+ uploadVideoStreamingPlaying("开始播放")
+ }
+ }
+
+ //监控播放错误
+// override fun onError(what: Int, extra: Int) {
+// super.onError(what, extra)
+// Utils.toast(context, "网络错误,视频播放失败")
+// setViewShowState(mStartButton, View.INVISIBLE)
+//// errorContainer.visibility = View.VISIBLE
+// }
+
+ override fun releaseVideos() {
+ uploadVideoStreamingPlaying("结束播放")
+ CustomManager.releaseAllVideos(getKey())
+ }
+
+ override fun onVideoPause() {
+ super.onVideoPause()
+ uploadVideoStreamingPlaying("暂停播放")
+ }
+
+ // 重载以减少横竖屏切换的时间
+ override fun checkoutState() {
+ removeCallbacks(mCheckoutTask)
+ postDelayed(mCheckoutTask, 300)
+ }
+
+ override fun clearFullscreenLayout() {
+ super.clearFullscreenLayout()
+ updateMuteStatus()
+ hideBackBtn()
+ }
+
+ override fun setProgressAndTime(progress: Int, secProgress: Int, currentTime: Int, totalTime: Int, forceChange: Boolean) {
+ super.setProgressAndTime(progress, secProgress, currentTime, totalTime, forceChange)
+ if (remainingTv.visibility == View.VISIBLE) {
+ remainingTv.text = CommonUtil.stringForTime(totalTime - currentTime)
+ }
+ }
+
+ private fun showBackBtn() {
+ mTopContainer.background = ContextCompat.getDrawable(context, R.drawable.video_title_bg)
+ back.visibility = View.VISIBLE
+ }
+
+ private fun hideBackBtn() {
+ mTopContainer?.setBackgroundResource(0)
+ back.visibility = View.GONE
+ }
+
+ fun updateThumb(url: String) {
+ ImageUtils.display(thumbImage, url)
+ }
+
+ fun updateDurationTv(duration: String) {
+ durationTv.text = duration
+ }
+
+ fun updateVideoData(video: ForumVideoEntity) {
+ mVideoEntity = video
+ }
+
+ 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() {
+
+ }
+
+ override fun setStateAndUi(state: Int) {
+ super.setStateAndUi(state)
+ if (currentState == GSYVideoView.CURRENT_STATE_PREPAREING) {
+ setViewShowState(durationTv, View.GONE)
+ }
+
+// if (currentState == GSYVideoView.CURRENT_STATE_PLAYING) {
+// setViewShowState(mBottomProgressBar, View.VISIBLE)
+// }
+
+ if (currentState == GSYVideoView.CURRENT_STATE_AUTO_COMPLETE) {
+ hideAllWidget()
+ setViewShowState(completeContainer, View.VISIBLE)
+ mTopContainer.visibility = View.VISIBLE
+ replayTv.setOnClickListener {
+ startButton.performClick()
+ violenceUpdateMuteStatus()
+ uploadVideoStreamingPlaying("重新播放")
+ }
+ shareTv.setOnClickListener {
+ share()
+ }
+ } else {
+ setViewShowState(completeContainer, View.GONE)
+ }
+ }
+
+ override fun changeUiToPlayingShow() {
+ super.changeUiToPlayingShow()
+ if (!mIfCurrentIsFullscreen) setViewShowState(mBottomProgressBar, View.VISIBLE)
+ }
+
+ override fun changeUiToPlayingClear() {
+ super.changeUiToPlayingClear()
+ if (mIfCurrentIsFullscreen) setViewShowState(mBottomProgressBar, View.GONE)
+ }
+
+ private fun toggleMute() {
+ if (mVideoEntity?.videoIsMuted == true) {
+ unMute(true)
+ } else {
+ mute(true)
+ }
+ }
+
+ fun updateMuteStatus() {
+ if (mVideoEntity?.videoIsMuted == true) {
+ mute()
+ } else {
+ unMute()
+ }
+ }
+
+ fun mute(isManual: Boolean = false) {
+ mVideoEntity?.videoIsMuted = true
+ volume.setImageResource(R.drawable.ic_article_video_volume_off)
+ CustomManager.getCustomManager(getKey()).isNeedMute = true
+ if (isManual) {
+// Utils.toast(context, "当前处于静音状态")
+ uploadVideoStreamingPlaying("点击静音")
+ }
+ }
+
+ fun unMute(isManual: Boolean = false) {
+ mVideoEntity?.videoIsMuted = false
+ volume.setImageResource(R.drawable.ic_article_video_volume_on)
+ CustomManager.getCustomManager(getKey()).isNeedMute = false
+ if (isManual) {
+ uploadVideoStreamingPlaying("取消静音")
+ }
+ }
+
+ override fun onAutoCompletion() {
+ super.onAutoCompletion()
+ uploadVideoStreamingPlaying("播放完毕")
+ }
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ super.onStopTrackingTouch(seekBar)
+ uploadVideoStreamingPlaying("拖动")
+ }
+
+ private fun share() {
+ mVideoEntity?.let {
+ val shareIcon = it.poster
+ val shareUrl = if (isPublishEnv()) {
+ "https://m.ghzs666.com/video/${it.id}"
+ } else {
+ "https://resource.ghzs.com/page/video_play/video/video.html?video=${it.id}"
+ }
+ ShareUtils.getInstance(context).showShareWindowsCallback(context as Activity,
+ this,
+ shareUrl,
+ shareIcon,
+ it.title,
+ it.des,
+ ShareUtils.ShareEntrance.video, it.id, object : ShareUtils.ShareCallBack {
+ override fun onSuccess(label: String) {
+// if ("短信" == label || "复制链接" == label) viewModel?.shareVideoStatistics(it)
+ }
+
+ override fun onCancel() {
+ uploadVideoStreamingPlaying("取消分享")
+ }
+ })
+ }
+ }
+
+ fun uploadVideoStreamingPlaying(action: String) {
+
+ }
+
+ fun setFullViewStatus() {
+ mProgressBar.visibility = View.VISIBLE
+ mCurrentTimeTextView.visibility = View.VISIBLE
+ mTotalTimeTextView.visibility = View.VISIBLE
+ mBottomProgressBar.visibility = View.GONE
+ remainingTv.visibility = View.GONE
+ durationTv.visibility = View.GONE
+ }
+
+ fun getKey(): String {
+ return uuid
+ }
+
+ fun getCurrentPosition(): Long {
+ return mCurrentPosition
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt
new file mode 100644
index 0000000000..209dd4e804
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/CommunityHomeFragment.kt
@@ -0,0 +1,258 @@
+package com.gh.gamecenter.forum.home
+
+import android.graphics.Typeface
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.AnimationUtils
+import android.widget.*
+import androidx.core.graphics.ColorUtils
+import androidx.core.os.bundleOf
+import androidx.fragment.app.Fragment
+import com.gh.base.adapter.FragmentAdapter
+import com.gh.base.fragment.LazyFragment
+import com.gh.common.dialog.TrackableDialog
+import com.gh.common.util.*
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.FragmentCommunityHomeBinding
+import com.gh.gamecenter.databinding.TabItemMainBinding
+import com.gh.gamecenter.eventbus.EBTypeChange
+import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
+import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.qa.CommunityFragment
+import com.gh.gamecenter.qa.BbsType
+import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
+import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
+import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import kotlin.math.abs
+
+class CommunityHomeFragment : LazyFragment() {
+
+ private var mBinding: FragmentCommunityHomeBinding? = null
+ private var mFragmentList = arrayListOf()
+ private var mTitleList = arrayListOf("推荐", "论坛", "活动")
+ private var mTabList = arrayListOf()
+
+ override fun getRealLayoutId(): Int {
+ return R.layout.fragment_community_home
+ }
+
+ override fun onRealLayoutInflated(inflatedView: View) {
+ mBinding = FragmentCommunityHomeBinding.bind(inflatedView)
+ }
+
+ override fun onFragmentFirstVisible() {
+ super.onFragmentFirstVisible()
+
+ initViewPager()
+ }
+
+ override fun initRealView() {
+ super.initRealView()
+ mBinding?.run {
+ searchContainer.setOnClickListener {
+ requireContext().startActivity(ForumOrUserSearchActivity.getIntent(requireContext(), "", "论坛首页"))
+ }
+
+ communityEditBtn.setOnClickListener {
+ showCommunityEditWindow()
+ }
+ }
+ }
+
+ override fun onFragmentResume() {
+ super.onFragmentResume()
+
+ DisplayUtils.setLightStatusBar(requireActivity(), true)
+ }
+
+ fun setCurrentItem(index: Int) {
+ mBinding?.viewPager?.currentItem = index
+ }
+
+ private fun initViewPager() {
+ mBinding?.run {
+ mFragmentList.clear()
+ val tag = "android:switcher:${viewPager.id}:"
+ val forumArticleListFragment = childFragmentManager.findFragmentByTag("${tag}0")
+ ?: ForumArticleListFragment().with(bundleOf(EntranceUtils.KEY_ENTRANCE to "社区", EntranceUtils.KEY_PATH to "推荐"))
+ mFragmentList.add(forumArticleListFragment)
+
+ val forumFragment = childFragmentManager.findFragmentByTag("${tag}1")
+ ?: ForumFragment().with(bundleOf(EntranceUtils.KEY_ENTRANCE to "社区"))
+ mFragmentList.add(forumFragment)
+
+ val activityFragment = childFragmentManager.findFragmentByTag("${tag}2")
+ ?: ForumActivityFragment().with(bundleOf(EntranceUtils.KEY_ENTRANCE to "活动"))
+ mFragmentList.add(activityFragment)
+
+ viewPager.run {
+ offscreenPageLimit = mFragmentList.size
+ adapter = FragmentAdapter(childFragmentManager, mFragmentList, mTitleList)
+ viewPager.doOnScroll(
+ onPageSelected = { position ->
+ updateTabTextStyle(position, 0F)
+ },
+ onPageScrolled = { position, positionOffset, _ ->
+ if (position + 1 != mTabList.size) {
+ mTabList[position].run {
+ textSize = (DEFAULT_TAB_TEXT_SIZE + ((1 - positionOffset) * 4)).roundTo(1)
+ setTextColor(ColorUtils.blendARGB(TAB_DEFAULT_COLOR, TAB_SELECTED_COLOR, 1 - positionOffset))
+ }
+ mTabList[position + 1].run {
+ textSize = (DEFAULT_TAB_TEXT_SIZE + ((positionOffset) * 4)).roundTo(1)
+ setTextColor(ColorUtils.blendARGB(TAB_DEFAULT_COLOR, TAB_SELECTED_COLOR, positionOffset))
+ }
+
+ // 多 tab 切换的时候可能会出现某些 tab 的文字没有回归到原始大小的问题的问题 (positionOffset 不保证连续)
+ for ((index, tabTv) in mTabList.withIndex()) {
+ if (abs(index - position) >= 2) {
+ if (tabTv.textSize != DEFAULT_TAB_TEXT_SIZE) {
+ tabTv.textSize = DEFAULT_TAB_TEXT_SIZE
+ tabTv.setTextColor(TAB_DEFAULT_COLOR)
+ }
+ }
+ }
+ }
+
+ updateTabTextStyle(position, positionOffset)
+ }
+ )
+ }
+
+ tabLayout.setupWithViewPager(viewPager)
+ indicatorView.run {
+ setupWithTabLayout(tabLayout)
+ setupWithViewPager(viewPager)
+ setIndicatorWidth(18)
+ }
+ for (i in 0 until tabLayout.tabCount) {
+ val tab = tabLayout.getTabAt(i) ?: continue
+ val tabTitle = if (tab.text != null) tab.text.toString() else ""
+ val tabViewBinding = generateTabView(tabTitle)
+ mTabList.add(tabViewBinding.tabTitle)
+ tab.customView = tabViewBinding.root
+ tab.view.setPadding(0, 0, 0, 0)
+ }
+ }
+ }
+
+ private fun updateTabTextStyle(selectedPosition: Int, positionOffset: Float) {
+ for ((index, titleTv) in mTabList.withIndex()) {
+ if (index == selectedPosition) {
+ titleTv.setTextColor(TAB_SELECTED_COLOR)
+ if (positionOffset == 0F) {
+ titleTv.setTypeface(null, Typeface.NORMAL)
+ titleTv.setTypeface(titleTv.typeface, Typeface.BOLD)
+ }
+ } else {
+ titleTv.setTextColor(TAB_DEFAULT_COLOR)
+ if (positionOffset == 0F) {
+ titleTv.setTypeface(null, Typeface.NORMAL)
+ }
+ }
+ }
+ }
+
+ private fun generateTabView(title: String): TabItemMainBinding {
+ val binding = TabItemMainBinding.inflate(LayoutInflater.from(requireContext()))
+ binding.tabTitle.run {
+ text = title
+ textSize = DEFAULT_TAB_TEXT_SIZE
+ setTextColor(TAB_DEFAULT_COLOR)
+ }
+ binding.invisibleTabTitle.run {
+ text = title
+ textSize = DEFAULT_TAB_TEXT_SIZE
+ }
+ return binding
+ }
+
+ private fun showCommunityEditWindow() {
+ val contentView = LayoutInflater.from(context).inflate(R.layout.community_edit_window, null)
+ val params = ViewGroup.LayoutParams(resources.displayMetrics.widthPixels, ViewGroup.LayoutParams.WRAP_CONTENT)
+ val dialog = TrackableDialog(
+ requireContext(),
+ R.style.DialogWindowTransparent,
+ "社区",
+ UserManager.getInstance().community.name,
+ null,
+ "发布-空白",
+ "发布-返回",
+ false)
+ val window = dialog.window
+ window?.setGravity(Gravity.BOTTOM)
+ window?.setWindowAnimations(R.style.community_publication_animation)
+ dialog.setContentView(contentView, params)
+ dialog.show()
+ contentView.findViewById(R.id.community_edit_article_container).setOnClickListener {
+ context?.ifLogin("论坛首页", action = {
+ checkStoragePermissionBeforeAction {
+ showRegulationTestDialogIfNeeded {
+ MtaHelper.onEvent("论坛首页", "发布", "发帖子")
+ startActivity(ArticleEditActivity.getIntent(requireContext(), null))
+ dialog.dismiss()
+ }
+ }
+ })
+ }
+ contentView.findViewById(R.id.community_edit_question_container).setOnClickListener {
+ context?.ifLogin("论坛首页", action = {
+ checkStoragePermissionBeforeAction {
+ showRegulationTestDialogIfNeeded {
+ MtaHelper.onEvent("论坛首页", "发布", "提问")
+ startActivity(QuestionEditActivity.getIntent(requireContext()))
+ dialog.dismiss()
+ }
+ }
+ })
+ }
+ contentView.findViewById(R.id.community_edit_video_container).setOnClickListener {
+ checkStoragePermissionBeforeAction {
+ showRegulationTestDialogIfNeeded {
+ MtaHelper.onEvent("论坛首页", "发布", "发视频")
+ startActivity(VideoPublishActivity.getIntent(requireContext(), null, "", mEntrance, "论坛首页"))
+ dialog.dismiss()
+ }
+ }
+ }
+ contentView.findViewById(R.id.community_edit_close).setOnClickListener {
+ dialog.dismiss()
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(status: EBTypeChange) {
+ if (status.type == CommunityFragment.EB_SHOW_QUESTION_BUTTON) {
+ setPutQuestionButtonStatus(View.VISIBLE)
+ } else if (status.type == CommunityFragment.EB_HIDE_QUESTION_BUTTON) {
+ setPutQuestionButtonStatus(View.GONE)
+ }
+ }
+
+ private fun setPutQuestionButtonStatus(visibility: Int) {
+ mBinding?.run {
+ if (communityEditBtn.visibility == visibility) return
+ if (visibility == View.GONE) {
+ val animation = AnimationUtils.loadAnimation(context, R.anim.button_anim_exit)
+ communityEditBtn.startAnimation(animation)
+ } else {
+ val animation = AnimationUtils.loadAnimation(context, R.anim.button_anim_enter)
+ communityEditBtn.startAnimation(animation)
+ }
+ communityEditBtn.visibility = visibility
+ }
+ }
+
+ companion object {
+ var TAB_SELECTED_COLOR: Int = R.color.text_333333.toColor()
+ var TAB_DEFAULT_COLOR: Int = R.color.text_666666.toColor()
+ var DEFAULT_TAB_TEXT_SIZE = 16F
+ const val TAB_RECOMMEND_INDEX = 0
+ const val TAB_FORUM_INDEX = 1
+ const val TAB_ACTIVITY_INDEX = 2
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityAdapter.kt
new file mode 100644
index 0000000000..8769eac174
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityAdapter.kt
@@ -0,0 +1,113 @@
+package com.gh.gamecenter.forum.home
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.constant.ItemViewType
+import com.gh.common.exposure.time.TimeUtil
+import com.gh.common.util.*
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.databinding.ForumActivityItemBinding
+import com.gh.gamecenter.entity.ForumActivityEntity
+
+class ForumActivityAdapter(context: Context,
+ val mViewModel: ForumActivityViewModel,
+ val mEntrance: String) : ListAdapter(context) {
+
+ override fun getItemViewType(position: Int): Int {
+ if (position == itemCount - 1) return ItemViewType.ITEM_FOOTER
+ return ItemViewType.ITEM_BODY
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ ItemViewType.ITEM_FOOTER -> {
+ val view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
+ FooterViewHolder(view)
+ }
+
+ else -> {
+ ForumActivityViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.forum_activity_item, parent, false))
+ }
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return if (mEntityList.isNotEmpty()) mEntityList.size + FOOTER_ITEM_COUNT else 0
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is ForumActivityViewHolder -> {
+ holder.binding.run {
+ val activityEntity = mEntityList[position]
+ entity = activityEntity
+ executePendingBindings()
+
+ line.goneIf(position == 0)
+
+ var status = ""
+ val currentTime = TimeUtil.currentTime()
+ when {
+ // 进行中
+ currentTime > activityEntity.effectTime.start
+ && (currentTime < activityEntity.effectTime.end
+ || activityEntity.effectTime.end == null
+ || activityEntity.effectTime.end == 0L) -> {
+ status = "进行中"
+ statusTv.text = "进行中"
+ statusTv.setTextColor(R.color.theme_font.toColor())
+ statusTv.setBackgroundResource(R.drawable.bg_forum_activity_status_blue)
+ if (activityEntity.effectTime.end == null || activityEntity.effectTime.end == 0L) {
+ timeTv.text = "长期有效"
+ } else {
+ val startTime = TimeUtils.getFormatTime(activityEntity.effectTime.start, "yyyy.MM.dd")
+ val endTime = TimeUtils.getFormatTime(activityEntity.effectTime.end, "yyyy.MM.dd")
+ timeTv.text = "$startTime 至 $endTime"
+ }
+ }
+
+ // 奖励发放中
+ currentTime > activityEntity.awardTime.start
+ && currentTime < activityEntity.awardTime.end -> {
+ status = "发放中"
+ statusTv.text = "发放中"
+ statusTv.setTextColor(R.color.theme_font.toColor())
+ statusTv.setBackgroundResource(R.drawable.bg_forum_activity_status_blue)
+ val startTime = TimeUtils.getFormatTime(activityEntity.awardTime.start, "yyyy.MM.dd")
+ val endTime = TimeUtils.getFormatTime(activityEntity.awardTime.end, "yyyy.MM.dd")
+ timeTv.text = "$startTime 至 $endTime"
+ }
+
+ // 已结束
+ else -> {
+ status = "已结束"
+ statusTv.text = "已结束"
+ statusTv.setTextColor(R.color.white.toColor())
+ statusTv.setBackgroundResource(R.drawable.bg_forum_activity_status_gray)
+ val startTime = TimeUtils.getFormatTime(activityEntity.effectTime.start, "yyyy.MM.dd")
+ val endTime = TimeUtils.getFormatTime(activityEntity.effectTime.end, "yyyy.MM.dd")
+ timeTv.text = "$startTime 至 $endTime"
+ }
+ }
+
+ root.setOnClickListener {
+ if (status == "发放中") ToastUtils.toast("活动奖励发放中~")
+ if (status == "已结束") ToastUtils.toast("活动已结束~")
+ DirectUtils.directToActivityDetail(mContext, activityEntity.id, mEntrance)
+ }
+ }
+ }
+
+ is FooterViewHolder -> {
+ holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
+ }
+ }
+ }
+
+ inner class ForumActivityViewHolder(val binding: ForumActivityItemBinding): BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityFragment.kt
new file mode 100644
index 0000000000..1a0d16496b
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityFragment.kt
@@ -0,0 +1,83 @@
+package com.gh.gamecenter.forum.home
+
+import android.view.View
+import android.view.ViewGroup
+import android.widget.CheckedTextView
+import com.gh.common.util.dip2px
+import com.gh.common.util.observeNonNull
+import com.gh.common.util.viewModelProvider
+import com.gh.gamecenter.R
+import com.gh.gamecenter.baselist.LazyListFragment
+import com.gh.gamecenter.databinding.FragmentForumActivityBinding
+import com.gh.gamecenter.databinding.LayoutForumActivityCategoryItemBinding
+import com.gh.gamecenter.entity.ForumActivityCategoryEntity
+import com.gh.gamecenter.entity.ForumActivityEntity
+import com.google.android.flexbox.FlexboxLayout
+
+class ForumActivityFragment: LazyListFragment() {
+
+ private var mBinding: FragmentForumActivityBinding? = null
+ private var mAdapter: ForumActivityAdapter? = null
+
+ override fun getRealLayoutId() = R.layout.fragment_forum_activity
+
+ override fun provideListAdapter() =
+ mAdapter ?: ForumActivityAdapter(requireContext(), mListViewModel, "论坛-活动").apply { mAdapter = this }
+
+ override fun provideListViewModel(): ForumActivityViewModel {
+ return viewModelProvider()
+ }
+
+ override fun onRealLayoutInflated(inflatedView: View) {
+ mBinding = FragmentForumActivityBinding.bind(inflatedView)
+ }
+
+ override fun initRealView() {
+ super.initRealView()
+
+ mListViewModel.categories.observeNonNull(viewLifecycleOwner) {
+ initCategoryView(ArrayList(it))
+ }
+ }
+
+ override fun getItemDecoration() = null
+
+ private fun initCategoryView(list: ArrayList) {
+ if (list.isEmpty()) return
+
+ mBinding?.categoryContainer?.visibility = View.VISIBLE
+
+ list.add(0, ForumActivityCategoryEntity(id = "all", name = "全部"))
+ list.forEachIndexed { index, entity ->
+ val binding = LayoutForumActivityCategoryItemBinding.inflate(layoutInflater).apply {
+ val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ params.setMargins(0, 8F.dip2px(), 8F.dip2px(), 0)
+ params.height = 24F.dip2px()
+ root.layoutParams = params
+
+ name.text = entity.name
+ name.isChecked = index == 0
+ root.setOnClickListener {
+ updateCategory(index, entity)
+ }
+ }
+
+ mBinding?.categoryContainer?.addView(binding.root)
+ }
+ }
+
+ private fun updateCategory(index: Int, entity: ForumActivityCategoryEntity) {
+ updateCategoryView(index)
+ mListViewModel.categoryId = entity.id
+ onRefresh()
+ }
+
+ private fun updateCategoryView(index: Int) {
+ mBinding?.categoryContainer?.run {
+ for (i in 0 until childCount) {
+ val categoryView = getChildAt(i) as CheckedTextView
+ categoryView.isChecked = index == i
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityViewModel.kt
new file mode 100644
index 0000000000..dc5fb1af9e
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumActivityViewModel.kt
@@ -0,0 +1,48 @@
+package com.gh.gamecenter.forum.home
+
+import android.annotation.SuppressLint
+import android.app.Application
+import androidx.lifecycle.MutableLiveData
+import com.gh.common.util.UrlFilterUtils
+import com.gh.common.util.singleToMain
+import com.gh.gamecenter.baselist.ListViewModel
+import com.gh.gamecenter.entity.ForumActivityCategoryEntity
+import com.gh.gamecenter.entity.ForumActivityEntity
+import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.RetrofitManager
+import io.reactivex.Single
+
+class ForumActivityViewModel(application: Application) : ListViewModel(application) {
+
+ var categoryId = "all"
+ var categories = MutableLiveData>()
+
+ init {
+ getActivityCategories()
+ }
+
+ @SuppressLint("CheckResult")
+ fun getActivityCategories() {
+ RetrofitManager.getInstance(getApplication())
+ .api
+ .forumActivityCategories
+ .compose(singleToMain())
+ .subscribe(object : BiResponse>() {
+ override fun onSuccess(data: List) {
+ categories.postValue(data)
+ }
+ })
+ }
+
+ override fun provideDataObservable(page: Int) = null
+
+ override fun provideDataSingle(page: Int): Single> {
+ return RetrofitManager.getInstance(getApplication())
+ .api.getForumActivities(UrlFilterUtils.getFilterQuery("category_id", categoryId), page)
+ }
+
+ 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/forum/home/ForumArticleAskItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleAskItemViewHolder.kt
index 9397b83b88..958cdac5a1 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleAskItemViewHolder.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleAskItemViewHolder.kt
@@ -1,27 +1,29 @@
package com.gh.gamecenter.forum.home
+import android.app.Activity
import android.text.SpannableStringBuilder
-import android.text.Spanned
import android.view.View
import androidx.core.content.ContextCompat
-import androidx.core.text.set
import com.gh.base.BaseActivity
import com.gh.common.util.*
-import com.gh.common.view.CenterImageSpan
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.entity.CommunityEntity
+import com.gh.gamecenter.entity.ForumVideoEntity
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.answer.BaseAnswerOrArticleItemViewHolder
-import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
-import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
import com.gh.gamecenter.qa.questions.invite.QuestionsInviteActivity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
+import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : BaseAnswerOrArticleItemViewHolder(binding.root) {
@@ -48,6 +50,11 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
binding.title.text = SpanBuilder(title).image(0, 1, R.drawable.ic_ask_label).build()
} else {
binding.content.visibility = View.VISIBLE
+ if (entity.type == "video") {
+ binding.content.goneIf(entity.des.isEmpty())
+ } else {
+ binding.content.visibility = View.VISIBLE
+ }
//若文章内有图片和视频,标题后增加‘有视频’标签 issues-1052
if (entity.getPassVideos().isNotEmpty() && entity.images.isNotEmpty()) {
val videoSpan = SpanBuilder(" ").image(1, " ".length, R.drawable.ic_article_video_label).build()
@@ -60,6 +67,12 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
}
binding.imageContainer.bindData(entity, entrance, path)
+ if (entity.type == "video") {
+ bindVideoData(entity.transformForumVideoEntity())
+ } else {
+ bindArticleVideoData(entity)
+ }
+
val user = entity.user
binding.userBadgeName.setOnClickListener { binding.userBadgeIcon.performClick() }
binding.userBadgeIcon.setOnClickListener {
@@ -78,11 +91,149 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
MtaHelper.onEvent(getEventId(BaseActivity.mergeEntranceAndPath(entrance, path)), getKey(BaseActivity.mergeEntranceAndPath(entrance, path)), "用户名字")
DirectUtils.directToHomeActivity(binding.root.context, entity.user.id, 1, entrance, path)
}
+ binding.concernBtn.setOnClickListener {
+ debounceActionWithInterval(R.id.concernBtn, 1000) {
+ CheckLoginUtils.checkLogin(itemView.context, entrance) {
+ followUser(entity, object : EmptyCallback {
+ override fun onCallback() {
+ entity.me.isFollower = true
+ binding.concernBtn.visibility = View.GONE
+ binding.followedUserTv.visibility = View.VISIBLE
+ }
+ })
+ }
+ }
+ }
binding.executePendingBindings()
}
+ private fun bindVideoData(entity: ForumVideoEntity) {
+ binding.run {
+ if (entity.url.isEmpty()) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.GONE
+ } else {
+ val videoInfo = entity.videoInfo
+ val visibleView = if (videoInfo.height > videoInfo.width) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.VISIBLE
+ verticalVideoView
+ } else {
+ horizontalVideoView.visibility = View.VISIBLE
+ verticalVideoView.visibility = View.GONE
+ horizontalVideoView
+ }
+
+ val orientationUtils = OrientationUtils(itemView.context as Activity, visibleView)
+ orientationUtils.isEnable = false
+ GSYVideoOptionBuilder()
+ .setIsTouchWiget(false)
+ .setUrl(entity.url)
+ .setRotateViewAuto(false)
+ .setCacheWithPlay(true)
+ .setRotateWithSystem(false)
+ .setReleaseWhenLossAudio(true)
+ .setLooping(false)
+ .setShowFullAnimation(false)
+ .setEnlargeImageRes(R.drawable.ic_game_detail_enter_full_screen)
+ .setShrinkImageRes(R.drawable.ic_game_detail_exit_full_screen)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onQuitFullscreen(url: String?, vararg objects: Any) {
+ orientationUtils.backToProtVideo()
+ visibleView.uploadVideoStreamingPlaying("退出全屏")
+ }
+ })
+ .build(visibleView)
+ visibleView.run {
+ updateVideoData(entity)
+ updateThumb(entity.poster)
+ updateDurationTv(TimeUtils.formatDuration(entity.length))
+
+ fullscreenButton.setOnClickListener {
+ val horizontalVideoView = startWindowFullscreen(itemView.context, true, true) as? ArticleItemVideoView
+ if (horizontalVideoView == null) {
+ toastInInternalRelease("全屏失败,请向技术人员提供具体的操作步骤")
+ return@setOnClickListener
+ }
+ orientationUtils.resolveByClick()
+ horizontalVideoView.uuid = uuid
+ horizontalVideoView.updateVideoData(entity)
+ horizontalVideoView.updateThumb(entity.poster)
+ horizontalVideoView.violenceUpdateMuteStatus()
+ horizontalVideoView.setFullViewStatus()
+ uploadVideoStreamingPlaying("开始播放")
+ uploadVideoStreamingPlaying("点击全屏")
+ }
+ }
+ }
+ }
+ }
+
+ private fun bindArticleVideoData(entity: AnswerEntity) {
+ binding.run {
+ if (entity.getPassVideos().isNullOrEmpty()) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.GONE
+ } else {
+ val video = entity.getPassVideos()[0]
+ val visibleView = if (video.height > video.width) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.VISIBLE
+ verticalVideoView
+ } else {
+ horizontalVideoView.visibility = View.VISIBLE
+ verticalVideoView.visibility = View.GONE
+ horizontalVideoView
+ }
+
+ val orientationUtils = OrientationUtils(itemView.context as Activity, visibleView)
+ orientationUtils.isEnable = false
+ GSYVideoOptionBuilder()
+ .setIsTouchWiget(false)
+ .setUrl(video.url)
+ .setRotateViewAuto(false)
+ .setCacheWithPlay(true)
+ .setRotateWithSystem(false)
+ .setReleaseWhenLossAudio(true)
+ .setLooping(false)
+ .setShowFullAnimation(false)
+ .setEnlargeImageRes(R.drawable.ic_game_detail_enter_full_screen)
+ .setShrinkImageRes(R.drawable.ic_game_detail_exit_full_screen)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onQuitFullscreen(url: String?, vararg objects: Any) {
+ orientationUtils.backToProtVideo()
+ visibleView.uploadVideoStreamingPlaying("退出全屏")
+ }
+ })
+ .build(visibleView)
+ visibleView.run {
+ val forumVideoEntity = entity.transformForumVideoEntity()
+ updateVideoData(forumVideoEntity)
+ updateThumb(video.poster)
+ updateDurationTv(video.duration)
+
+ fullscreenButton.setOnClickListener {
+ val horizontalVideoView = startWindowFullscreen(itemView.context, true, true) as? ArticleItemVideoView
+ if (horizontalVideoView == null) {
+ toastInInternalRelease("全屏失败,请向技术人员提供具体的操作步骤")
+ return@setOnClickListener
+ }
+ orientationUtils.resolveByClick()
+ horizontalVideoView.uuid = uuid
+ horizontalVideoView.updateVideoData(forumVideoEntity)
+ horizontalVideoView.updateThumb(video.poster)
+ horizontalVideoView.violenceUpdateMuteStatus()
+ horizontalVideoView.setFullViewStatus()
+ uploadVideoStreamingPlaying("开始播放")
+ uploadVideoStreamingPlaying("点击全屏")
+ }
+ }
+ }
+ }
+ }
+
override fun bindCommendAndVote(entity: AnswerEntity, entrance: String) {
- if (entity.type == "community_article") {
+ if (entity.type == "community_article" || entity.type == "video") {
binNormalView(entity)
} else {
if (entity.questions.answerCount > 0) {
@@ -95,12 +246,23 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
voteCount.text = "邀请回答"
voteIcon.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.community_invite_follow))
}
+
+ if (entity.bbs.type == "official_bbs") {
+ forumIcon?.displayGameIcon(entity.bbs.icon, null)
+ } else {
+ forumIcon?.displayGameIcon(entity.bbs.game?.getIcon(), entity.bbs.game?.iconSubscript)
+ }
+
forumNameTv.setOnClickListener {
MtaHelper.onEvent(getEventId(entrance), getKey(entrance), if (entity.bbs.name.isEmpty()) entity.bbs.name else entity.bbs.name)
itemView.context.startActivity(ForumDetailActivity.getIntent(itemView.context, entity.bbs.id, entrance))
LogUtils.uploadAccessToBbs(entity.bbs.id, "文章外所属论坛")
}
+ forumNameContainer?.setOnClickListener {
+ forumNameTv.performClick()
+ }
+
commentCountContainer.setOnClickListener {
if (filterIllegalCommentStatus(entity.commentable, entity.active)) return@setOnClickListener
if (entity.type == "community_article") {
@@ -111,14 +273,14 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
entrance, "")
itemView.context.startActivity(intent)
MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "评论图标")
+ } else if (entity.type == "video") {
+ itemView.context.startActivity(ForumVideoDetailActivity.getIntent(itemView.context, entity.id
+ ?: ""))
} else {
- val intent = if (entity.questions.answerCount > 0) {
- QuestionsDetailActivity.getIntent(it.context, entity.questions.id, entrance, "")
- } else {
+ if (entity.questions.answerCount == 0) {
MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "我来回答")
- AnswerEditActivity.getIntent(it.context, entity.questions, entity.communityName)
}
- itemView.context.startActivity(intent)
+ itemView.context.startActivity(NewQuestionDetailActivity.getCommentIntent(it.context, entity.questions.id, entrance, ""))
}
}
@@ -127,7 +289,7 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B
debounceActionWithInterval(R.id.container_like, 1000) {
CheckLoginUtils.checkLogin(itemView.context, entrance) {
- if (entity.type == "community_article") {
+ if (entity.type == "community_article" || entity.type == "video") {
MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "点赞图标")
if (!voteIcon.isChecked) voteAnswer(entity)
else cancelAnswerVote(entity)
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListAdapter.kt
index 4e5fb646db..e3ccfba756 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListAdapter.kt
@@ -1,8 +1,10 @@
package com.gh.gamecenter.forum.home
import android.content.Context
+import android.graphics.Color
import android.view.View
import android.view.ViewGroup
+import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.base.BaseActivity
@@ -10,18 +12,19 @@ import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.MtaHelper
import com.gh.common.util.dip2px
+import com.gh.common.util.goneIf
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.entity.CommunityEntity
-import com.gh.gamecenter.forum.detail.ForumDetailActivity
-import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.ArticleEntity
-import com.gh.gamecenter.qa.entity.Questions
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
+import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
class ForumArticleListAdapter(context: Context, val mEntrance: String, val path: String) : ListAdapter(context), ISyncAdapterHandler {
+
override fun areItemsTheSame(oldItem: ArticleEntity?, newItem: ArticleEntity?): Boolean {
return oldItem?.id == newItem?.id
}
@@ -38,6 +41,7 @@ class ForumArticleListAdapter(context: Context, val mEntrance: String, val path:
view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
FooterViewHolder(view)
}
+
else -> {
view = mLayoutInflater.inflate(R.layout.community_answer_item, parent, false)
ForumArticleAskItemViewHolder(CommunityAnswerItemBinding.bind(view))
@@ -55,12 +59,57 @@ class ForumArticleListAdapter(context: Context, val mEntrance: String, val path:
val viewHolder = holder as ForumArticleAskItemViewHolder
val articleEntity = mEntityList[position]
articleEntity.community = CommunityEntity(articleEntity.bbs.id, articleEntity.bbs.name)
+
+ if (articleEntity.type == "bbs_article") articleEntity.type = "community_article"
+ if (articleEntity.type == "bbs_question") articleEntity.type = "question"
+ if (articleEntity.type == "bbs_video") articleEntity.type = "video"
+
+ viewHolder.binding.run {
+ topLine.goneIf(position == 0)
+ contentContainer.setBackgroundColor(Color.TRANSPARENT)
+ bottomContainer.setBackgroundColor(Color.TRANSPARENT)
+ includeVoteAndComment.commentCountContainer.setBackgroundColor(Color.TRANSPARENT)
+ includeVoteAndComment.voteCountContainer.setBackgroundColor(Color.TRANSPARENT)
+ }
viewHolder.bindForumArticleItem(articleEntity, mEntrance, path)
+
+ if (articleEntity.type == "question") {
+ if (articleEntity.count.answer > 0) {
+ viewHolder.commentCount.text = articleEntity.count.answer.toString()
+ } else {
+ viewHolder.commentCount.text = "回答"
+ }
+ viewHolder.commentCount.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(mContext, R.drawable.community_comment_count), null, null, null)
+ viewHolder.voteCountContainer.visibility = View.GONE
+ val params = viewHolder.binding.includeVoteAndComment.root.layoutParams as LinearLayout.LayoutParams
+ params.width = 80f.dip2px()
+ viewHolder.binding.includeVoteAndComment.root.layoutParams = params
+ } else {
+ viewHolder.voteCountContainer.visibility = View.VISIBLE
+ val params = viewHolder.binding.includeVoteAndComment.root.layoutParams as LinearLayout.LayoutParams
+ params.width = 160f.dip2px()
+ viewHolder.binding.includeVoteAndComment.root.layoutParams = params
+ }
+
viewHolder.itemView.setOnClickListener {
- MtaHelper.onEvent("论坛首页", viewHolder.getKey(BaseActivity.mergeEntranceAndPath(mEntrance, path)), "${articleEntity.title}(${articleEntity.id})")
- mContext.startActivity(ArticleDetailActivity.getIntent(mContext, articleEntity.community, articleEntity.id, "", path))
+ when (articleEntity.type) {
+ "community_article" -> {
+ MtaHelper.onEvent("论坛首页", viewHolder.getKey(BaseActivity.mergeEntranceAndPath(mEntrance, path)), "${articleEntity.title}(${articleEntity.id})")
+ mContext.startActivity(ArticleDetailActivity.getIntent(mContext, articleEntity.community, articleEntity.id, "", path))
+ }
+ "video" -> {
+ MtaHelper.onEvent("论坛首页", viewHolder.getKey(BaseActivity.mergeEntranceAndPath(mEntrance, path)), "${articleEntity.title}(${articleEntity.id})")
+ mContext.startActivity(ForumVideoDetailActivity.getIntent(mContext, articleEntity.id ?:""))
+ }
+ else -> {
+ MtaHelper.onEvent("论坛首页", viewHolder.getKey(BaseActivity.mergeEntranceAndPath(mEntrance, path)), "${articleEntity.title}(${articleEntity.id})")
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, articleEntity.id
+ ?: "", mEntrance, path))
+ }
+ }
}
}
+
ItemViewType.ITEM_FOOTER -> {
val footerViewHolder = holder as FooterViewHolder
footerViewHolder.initItemPadding()
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListFragment.kt
index fbac34bc7e..5b8a736ac5 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListFragment.kt
@@ -1,103 +1,167 @@
package com.gh.gamecenter.forum.home
-import android.os.Bundle
import android.view.View
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.core.content.ContextCompat
-import androidx.core.widget.NestedScrollView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
+import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.AppExecutor
+import com.gh.common.constant.Constants
import com.gh.common.iinterface.IScrollable
import com.gh.common.util.*
-import com.gh.common.view.DumbRefreshLayout
-import com.gh.common.view.divider.HorizontalDividerItemDecoration
import com.gh.gamecenter.R
-import com.gh.gamecenter.baselist.ListAdapter
-import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.baselist.LazyListFragment
+import com.gh.gamecenter.databinding.FragmentForumListBinding
+import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.eventbus.EBDeleteDetail
+import com.gh.gamecenter.eventbus.EBForumRecordChange
import com.gh.gamecenter.eventbus.EBTypeChange
-import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper.Companion.getPlaySchedule
+import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper.Companion.savePlaySchedule
import com.gh.gamecenter.qa.CommunityFragment
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.user.UserViewModel
-import kotterknife.bindView
+import com.google.android.material.appbar.AppBarLayout
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
+import kotlin.math.abs
-class ForumArticleListFragment : ListFragment(), IScrollable {
-
- private val mNoLoginView by bindView(R.id.reuse_no_login)
- private val mNoFollowView by bindView(R.id.reuse_no_follow)
- private val mLoginTv by bindView(R.id.loginTv)
+class ForumArticleListFragment : LazyListFragment(), IScrollable {
private var mViewModel: ForumArticleListViewModel? = null
private var mUserViewModel: UserViewModel? = null
- private lateinit var mAdapter: ForumArticleListAdapter
+ private var mBinding: FragmentForumListBinding? = null
+ private var mAdapter: ForumArticleListAdapter? = null
+ private var mScrollCalculatorHelper: ForumScrollCalculatorHelper? = null
private var mPath = ""
+ private var mIsFirst = true
+ private var mHaveLoadLoginData = false
+ private var mIsLogin = false
- override fun onCreate(savedInstanceState: Bundle?) {
+ override fun getRealLayoutId() = R.layout.fragment_forum_list
+
+ override fun onFragmentFirstVisible() {
mPath = arguments?.getString(EntranceUtils.KEY_PATH) ?: ""
- super.onCreate(savedInstanceState)
val factory = UserViewModel.Factory(requireActivity().application)
mUserViewModel = ViewModelProviders.of(this, factory)[UserViewModel::class.java]
mUserViewModel?.loginObsUserinfo?.observe(this, Observer {
- if (mPath != "关注") return@Observer
- if (it?.data != null) {
- mNoLoginView.visibility = View.GONE
- onLoadRefresh()
- } else {
- mNoLoginView.visibility = View.VISIBLE
+ if (it?.data != null && !mHaveLoadLoginData && !mIsLogin) {
+ onRefresh()
+ }
+ })
+
+ super.onFragmentFirstVisible()
+ mScrollCalculatorHelper = ForumScrollCalculatorHelper(R.id.horizontalVideoView, R.id.verticalVideoView, 0)
+ }
+
+ override fun initRealView() {
+ super.initRealView()
+
+ mViewModel?.recordForumsLiveData?.observeNonNull(viewLifecycleOwner) {
+ initRecordForums(it)
+ }
+
+ mBinding?.run {
+ appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
+ mListRefresh?.isEnabled = abs(verticalOffset) <= 2
+ })
+
+ mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ if (dy > CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
+ EventBus.getDefault().post(EBTypeChange(CommunityFragment.EB_HIDE_QUESTION_BUTTON, 0))
+ } else if (dy < -CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
+ EventBus.getDefault().post(EBTypeChange(CommunityFragment.EB_SHOW_QUESTION_BUTTON, 0))
+ }
+ }
+ })
+ }
+
+ mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ super.onScrollStateChanged(recyclerView, newState)
+ mScrollCalculatorHelper?.onScrollStateChanged(mListRv, newState)
+ }
+
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+ scroll()
}
})
}
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- mListRv.overScrollMode = View.OVER_SCROLL_NEVER
- mListRefresh?.isEnabled = false
- if (mPath == "关注" && !UserManager.getInstance().isLoggedIn) {
- mNoLoginView.visibility = View.VISIBLE
+ override fun onRealLayoutInflated(inflatedView: View) {
+ super.onRealLayoutInflated(inflatedView)
+ mBinding = FragmentForumListBinding.bind(inflatedView)
+ }
+
+ override fun onFragmentResume() {
+ super.onFragmentResume()
+ mIsLogin = CheckLoginUtils.isLogin()
+ if (mIsFirst) {
+ mIsFirst = false
} else {
- mNoLoginView.visibility = View.GONE
- onLoadRefresh()
+ mViewModel?.getForumUnreadStatus()
}
- mLoginTv.setOnClickListener {
- CheckLoginUtils.checkLogin(requireContext(), mEntrance, null)
- }
- mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
- override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
- super.onScrolled(recyclerView, dx, dy)
- if (dy > CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
- EventBus.getDefault().post(EBTypeChange(CommunityFragment.EB_HIDE_QUESTION_BUTTON, 0))
- } else if (dy < -CommunityFragment.FOLLOW_HINT_TRIGGER_HEIGHT) {
- EventBus.getDefault().post(EBTypeChange(CommunityFragment.EB_SHOW_QUESTION_BUTTON, 0))
- }
- }
- })
+ }
+
+ override fun onResume() {
+ resumeVideo()
+ super.onResume()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ pauseVideo()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mScrollCalculatorHelper?.currentPlayer?.release()
}
override fun provideListViewModel(): ForumArticleListViewModel {
- mViewModel = viewModelProvider(ForumArticleListViewModel.Factory(mPath))
+ mViewModel = viewModelProvider()
return mViewModel!!
}
- override fun getLayoutId(): Int = R.layout.fragment_forum_list
+ override fun getItemDecoration() = null
- override fun getItemDecoration(): RecyclerView.ItemDecoration {
- return HorizontalDividerItemDecoration.Builder(requireContext())
- .size(0.5f.dip2px())
- .margin(20f.dip2px())
- .color(ContextCompat.getColor(requireContext(), R.color.text_eeeeee)).build()
+ override fun provideListAdapter() = mAdapter ?: ForumArticleListAdapter(requireContext(), mEntrance, mPath).apply { mAdapter = this }
+
+ override fun onRefresh() {
+ super.onRefresh()
+ mBinding?.recordForumsContainer?.visibility = View.GONE
+ mBaseHandler.postDelayed({
+ tryCatchInRelease { mViewModel?.getRecordForums() }
+ }, 500)
}
- override fun provideListAdapter(): ListAdapter<*> {
- if (!::mAdapter.isInitialized) {
- mAdapter = ForumArticleListAdapter(requireContext(), mEntrance, mPath)
+ override fun onLoadDone() {
+ super.onLoadDone()
+ if (CheckLoginUtils.isLogin()) mHaveLoadLoginData = true
+ AppExecutor.uiExecutor.executeWithDelay(Runnable {
+ scroll()
+ mScrollCalculatorHelper?.onScrollStateChanged(mListRv, RecyclerView.SCROLL_STATE_IDLE)
+ }, 100)
+ }
+
+ private fun initRecordForums(list: List) {
+ mBinding?.run {
+ recordForumsContainer.visibility = View.VISIBLE
+ recordForumsMore.setOnClickListener {
+ (parentFragment as? CommunityHomeFragment)?.run {
+ setCurrentItem(CommunityHomeFragment.TAB_FORUM_INDEX)
+ }
+ }
+ if (recordForumsRv.adapter != null) {
+ (recordForumsRv.adapter as? ForumRecordsAdapter)?.setListData(list)
+ } else {
+ recordForumsRv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
+ recordForumsRv.adapter = ForumRecordsAdapter(requireContext(), "社区-论坛-关注论坛", list)
+ }
}
- return mAdapter
}
fun onRefresh(filter: String) {
@@ -105,53 +169,92 @@ class ForumArticleListFragment : ListFragment= 0) {
+ currentPlayer?.onVideoPause()
+ val position = currentPlayer?.getCurrentPosition() ?: 0L
+ val video = mViewModel?.videoList?.safelyGetInRelease(currentPosition)
+ if (video != null) {
+ savePlaySchedule(MD5Utils.getContentMD5(video.url), position)
+ }
+ }
+ }
+ }
+
override fun addSyncPageObserver(): Boolean = true
- override fun provideSyncAdapter(): ForumArticleListAdapter = mAdapter
+ override fun provideSyncAdapter(): ForumArticleListAdapter = provideListAdapter()
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEvent(detail: EBDeleteDetail){
- val currentEntity = mAdapter.entityList?.find { it.id == detail.id }
- val indexOf = mAdapter.entityList?.indexOf(currentEntity) ?: 0
- mAdapter.entityList?.remove(currentEntity)
- mAdapter.notifyItemRemoved(indexOf)
+ mAdapter?.run {
+ val currentEntity = entityList?.find { it.id == detail.id }
+ val indexOf = entityList?.indexOf(currentEntity) ?: 0
+ entityList?.remove(currentEntity)
+ notifyItemRemoved(indexOf)
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onForumRecordChange(change: EBForumRecordChange) {
+ mBinding?.run {
+ if (recordForumsContainer.visibility == View.VISIBLE) {
+ mViewModel?.run {
+ val firstEntity = recordForums.safelyGetInRelease(0)
+ if (firstEntity?.id == change.forumEntity.id) {
+ if (firstEntity.unread) {
+ firstEntity.unread = false
+ }
+ return
+ }
+
+ val findEntity = recordForums.find { it.id == change.forumEntity.id }
+ if (findEntity != null) {
+ recordForums.remove(findEntity)
+ }
+ recordForums.add(0, change.forumEntity)
+ }
+ } else {
+ mViewModel?.recordForums = arrayListOf(change.forumEntity)
+ }
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListViewModel.kt
index e8ea4d7c9f..d0f000e752 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumArticleListViewModel.kt
@@ -1,44 +1,100 @@
package com.gh.gamecenter.forum.home
+import android.annotation.SuppressLint
import android.app.Application
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.MutableLiveData
import com.gh.common.util.UrlFilterUtils
+import com.gh.common.util.createRequestBodyAny
+import com.gh.common.util.singleToMain
import com.gh.gamecenter.baselist.ListViewModel
-import com.gh.gamecenter.baselist.LoadStatus
-import com.gh.gamecenter.baselist.LoadType
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.entity.ForumUnreadEntity
+import com.gh.gamecenter.entity.ForumVideoEntity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.entity.ArticleEntity
+import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
+import com.gh.gamecenter.room.AppDatabase
import com.halo.assistant.HaloApp
import io.reactivex.Observable
-class ForumArticleListViewModel(application: Application, val path: String) : ListViewModel(application) {
+class ForumArticleListViewModel(application: Application) : ListViewModel(application) {
+ private val mForumDao = AppDatabase.getInstance(HaloApp.getInstance()).forumDao()
+ val recordForumsLiveData = MutableLiveData>()
+ var recordForums = arrayListOf()
+ var recordStatusForums = arrayListOf()
var sort: String = "time.comment"//排序 time.edit 最新发布 time.comment 最新回复
+ var videoList = listOf()
- override fun provideDataObservable(page: Int): Observable>? {
- return if (path == "关注") {
- RetrofitManager.getInstance(getApplication())
- .api.getForumFollowArticle(UserManager.getInstance().userId, UrlFilterUtils.getFilterQuery(sort, "-1"), page)
- } else {
- RetrofitManager.getInstance(getApplication())
- .api.getForumRecommendsArticle(UrlFilterUtils.getFilterQuery(sort, "-1"), page)
- }
+ init {
+ setOverLimitSize(0)
+ getRecordForums()
}
- override fun load(loadType: LoadType?) {
- if (path == "关注" && !UserManager.getInstance().isLoggedIn) return
- super.load(loadType)
+ override fun provideDataObservable(page: Int): Observable>? {
+ return RetrofitManager.getInstance(getApplication())
+ .api.getForumRecommends(UrlFilterUtils.getFilterQuery(sort, "-1"), page)
}
override fun mergeResultLiveData() {
- mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
- }
+ mResultLiveData.addSource(mListLiveData) { list ->
- class Factory(val path: String) : ViewModelProvider.NewInstanceFactory() {
- override fun create(modelClass: Class): T {
- return ForumArticleListViewModel(HaloApp.getInstance().application, path) as T
+ videoList = list.map { it.transformForumVideoEntity() }
+
+ mResultLiveData.postValue(list)
}
}
+
+ @SuppressLint("CheckResult")
+ fun getRecordForums() {
+ mForumDao.getForum()
+ .subscribe({
+ it?.run {
+ if (it.isNotEmpty()) {
+ recordForums = ArrayList(it)
+ getForumUnreadStatus()
+ }
+ }
+ }, { })
+ }
+
+ @SuppressLint("CheckResult")
+ fun getForumUnreadStatus() {
+ if (recordForums.isEmpty()) return
+
+ if (!UserManager.getInstance().isLoggedIn) {
+ recordForumsLiveData.postValue(recordForums)
+ return
+ }
+
+ val requestMap = hashMapOf()
+ recordStatusForums.clear()
+ recordForums.forEach {
+ recordStatusForums.add(it.transformUnreadEntity())
+ }
+ requestMap["bbs"] = recordStatusForums
+ val body = requestMap.createRequestBodyAny()
+ RetrofitManager.getInstance(getApplication())
+ .api
+ .getForumUnreadStatus(body)
+ .compose(singleToMain())
+ .subscribe(object : BiResponse>() {
+
+ override fun onSuccess(data: List) {
+ if (data.isNotEmpty() && data.size == recordForums.size) {
+ data.forEachIndexed { index, unreadEntity ->
+ recordForums[index].unread = unreadEntity.unread
+ recordStatusForums[index].unread = unreadEntity.unread
+ }
+ }
+ recordForumsLiveData.postValue(recordForums)
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ recordForumsLiveData.postValue(recordForums)
+ }
+ })
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt
new file mode 100644
index 0000000000..2961b72fb0
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt
@@ -0,0 +1,214 @@
+package com.gh.gamecenter.forum.home
+
+import android.view.View
+import androidx.lifecycle.Observer
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.base.fragment.LazyFragment
+import com.gh.common.util.observeNonNull
+import com.gh.common.util.viewModelProvider
+import com.gh.common.view.GridSpacingItemColorDecoration
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.FragmentForumBinding
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.eventbus.EBForumFollowChange
+import com.gh.gamecenter.eventbus.EBForumRecordChange
+import com.gh.gamecenter.forum.list.ForumListActivity
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class ForumFragment: LazyFragment() {
+
+ private var mBinding: FragmentForumBinding? = null
+ private var mViewModel: ForumViewModel? = null
+ private var mHaveFollowForum = false
+ private var mHaveHotForum = false
+ private var mIsFirst = true
+
+ override fun getRealLayoutId(): Int {
+ return R.layout.fragment_forum
+ }
+
+ override fun onRealLayoutInflated(inflatedView: View) {
+ mBinding = FragmentForumBinding.bind(inflatedView)
+ }
+
+ override fun onFragmentFirstVisible() {
+ mViewModel = viewModelProvider()
+ super.onFragmentFirstVisible()
+ }
+
+ override fun initRealView() {
+ super.initRealView()
+
+ mViewModel?.followForumsLiveData?.observe(viewLifecycleOwner, Observer {
+ mBinding?.run {
+ reuseLoading.root.visibility = View.GONE
+ if (it != null) {
+ reuseNoConnection.root.visibility = View.GONE
+ if (it.isNotEmpty()) {
+ mHaveFollowForum = true
+ initFollowForums(it)
+ }
+ if (!mHaveHotForum) mViewModel?.getHotForum()
+ } else {
+ reuseNoneData.root.visibility = View.GONE
+ reuseNoConnection.root.visibility = View.VISIBLE
+ reuseNoConnection.root.setOnClickListener {
+ reuseLoading.root.visibility = View.VISIBLE
+ mViewModel?.getData()
+ }
+ }
+ }
+ })
+
+ mViewModel?.hotForums?.observe(viewLifecycleOwner, Observer {
+ mBinding?.run {
+ if (mHaveFollowForum) {
+ if (it != null && it.isNotEmpty()) {
+ mHaveHotForum = true
+ initHotForums(it)
+ }
+ } else {
+ reuseLoading.root.visibility = View.GONE
+ if (it != null) {
+ reuseNoConnection.root.visibility = View.GONE
+ if (it.isNotEmpty()) {
+ initHotForums(it)
+ }
+ } else {
+ reuseNoneData.root.visibility = View.GONE
+ reuseNoConnection.root.visibility = View.VISIBLE
+ reuseNoConnection.root.setOnClickListener {
+ reuseLoading.root.visibility = View.VISIBLE
+ mViewModel?.getData()
+ }
+ }
+ }
+ }
+ })
+
+ mViewModel?.officialForums?.observeNonNull(viewLifecycleOwner) {
+ if (it.isNotEmpty()) initOfficialForums(it)
+ }
+
+ initWelfare()
+ }
+
+ override fun onFragmentResume() {
+ super.onFragmentResume()
+
+ if (mIsFirst) {
+ mIsFirst = false
+ } else {
+ mViewModel?.getForumUnreadStatus()
+ }
+ }
+
+ private fun initFollowForums(list: List) {
+ mBinding?.run {
+ followForumContainer.visibility = View.VISIBLE
+ followMore.setOnClickListener { startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_FOLLOW)) }
+ if (followForumRv.adapter != null) {
+ (followForumRv.adapter as? ForumRecordsAdapter)?.setListData(list)
+ } else {
+ followForumRv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
+ followForumRv.adapter = ForumRecordsAdapter(requireContext(), "社区-论坛-关注论坛", ArrayList(list))
+ }
+ }
+ }
+
+ private fun initHotForums(list: List) {
+ mBinding?.run {
+ hotForumContainer.visibility = View.VISIBLE
+ hotMore.setOnClickListener { startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_HOT)) }
+ hotForumRv.layoutManager = LinearLayoutManager(requireContext())
+ val newList = if (mHaveFollowForum) {
+ if (list.size > 5) {
+ list.subList(0, 5)
+ } else {
+ list
+ }
+ } else {
+ if (list.size > 10) {
+ list.subList(0, 10)
+ } else {
+ list
+ }
+ }
+ hotForumRv.adapter = HotForumsAdapter(requireContext(), "社区-论坛-热门论坛", mViewModel, newList)
+ }
+ }
+
+ private fun initOfficialForums(list: List) {
+ mBinding?.run {
+ officialForumContainer.visibility = View.VISIBLE
+ officialMore.setOnClickListener { startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_OFFICIAL)) }
+ officialForumRv.layoutManager = GridLayoutManager(requireContext(), 2)
+ val newList = if (list.size > 6) list.subList(0, 6) else list
+ officialForumRv.adapter = OfficialForumAdapter(requireContext(), "社区-论坛-热门论坛", newList)
+ officialForumRv.addItemDecoration(GridSpacingItemColorDecoration(requireContext(), 0, 16, R.color.transparent))
+ }
+ }
+
+ private fun initWelfare() {
+ val welfareLists = arrayListOf>()
+ welfareLists.run {
+ add(Pair(R.drawable.ic_forum_tool_box, "工具箱"))
+ add(Pair(R.drawable.ic_forum_libao_center, "礼包中心"))
+ add(Pair(R.drawable.ic_forum_game_moment, "游戏动态"))
+ add(Pair(R.drawable.ic_forum_news, "资讯中心"))
+ add(Pair(R.drawable.ic_forum_accelerator, "万能加速器"))
+ }
+
+ mBinding?.run {
+ otherWelfareContainer.visibility = View.VISIBLE
+ otherWelfareRv.layoutManager = GridLayoutManager(requireContext(), 2)
+ otherWelfareRv.adapter = WelfaresAdapter(requireContext(), welfareLists)
+ otherWelfareRv.addItemDecoration(GridSpacingItemColorDecoration(requireContext(), 0, 16, R.color.transparent))
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onFollowForumChange(forumFollowChange: EBForumFollowChange) {
+ mBinding?.run {
+ if (forumFollowChange.isFollow) {
+ if (followForumContainer.visibility == View.VISIBLE) {
+ mViewModel?.run {
+ followForums.add(0, forumFollowChange.forumEntity)
+ (followForumRv.adapter as? ForumRecordsAdapter)?.setListData(followForums)
+ }
+ } else {
+ mViewModel?.followForums = arrayListOf(forumFollowChange.forumEntity)
+ initFollowForums(listOf(forumFollowChange.forumEntity))
+ }
+ } else {
+ mViewModel?.run {
+ val findEntity = followForums.find { it.id == forumFollowChange.forumEntity.id }
+ followForums.remove(findEntity)
+ if (followForums.isEmpty()) {
+ followForumContainer.visibility = View.GONE
+ } else{
+ (followForumRv.adapter as? ForumRecordsAdapter)?.setListData(followForums)
+ }
+ }
+ }
+
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onForumRecordChange(change: EBForumRecordChange) {
+ mBinding?.run {
+ if (followForumContainer.visibility == View.VISIBLE) {
+ mViewModel?.run {
+ val findIndex = followForums.indexOfFirst { it.id == change.forumEntity.id }
+ if (findIndex != -1 && followForums[findIndex].unread) {
+ followForums[findIndex].unread = false
+ }
+ }
+ }
+ }
+ }
+}
\ 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..117fb3026f 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
@@ -30,15 +30,17 @@ import com.gh.gamecenter.entity.LinkEntity
import com.gh.gamecenter.eventbus.EBForumFollowChange
import com.gh.gamecenter.eventbus.EBTypeChange
import com.gh.gamecenter.eventbus.EBUISwitch
-import com.gh.gamecenter.forum.follow.ForumMyFollowActivity
+import com.gh.gamecenter.forum.list.ForumListActivity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
import com.gh.gamecenter.forum.select.ForumSelectActivity
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.CommunityFragment
+import com.gh.gamecenter.qa.BbsType
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
@@ -247,7 +249,7 @@ class ForumHomeFragment : BaseLazyTabFragment() {
R.id.forumFollowTv -> {
CheckLoginUtils.checkLogin(requireContext(), "论坛") {
MtaHelper.onEvent("论坛首页", "关注的论坛", "更多论坛")
- requireContext().startActivity(ForumMyFollowActivity.getIntent(requireContext()))
+ requireContext().startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_FOLLOW))
}
}
}
@@ -330,7 +332,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 +343,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 +354,15 @@ class ForumHomeFragment : BaseLazyTabFragment() {
}
})
}
+ contentView.findViewById(R.id.community_edit_video_container).setOnClickListener {
+ checkStoragePermissionBeforeAction {
+ showRegulationTestDialogIfNeeded {
+ MtaHelper.onEvent("论坛首页", "发布", "发视频")
+ startActivity(VideoPublishActivity.getIntent(requireContext(), null, "", mEntrance, "论坛首页"))
+ dialog.dismiss()
+ }
+ }
+ }
contentView.findViewById(R.id.community_edit_close).setOnClickListener {
dialog.dismiss()
}
@@ -398,7 +409,7 @@ class ForumHomeFragment : BaseLazyTabFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busNine: EBUISwitch) {
- if (busNine.position == MainWrapperFragment.INDEX_ASK) {
+ if (busNine.position == MainWrapperFragment.INDEX_BBS) {
mFollowForumArticleListFragment?.scrollToTop()
mRecommendForumArticleListFragment?.scrollToTop()
appbar.setExpanded(true)
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordDao.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordDao.kt
new file mode 100644
index 0000000000..35ec1e0875
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordDao.kt
@@ -0,0 +1,80 @@
+package com.gh.gamecenter.forum.home
+
+import com.gh.common.util.SPUtils
+import com.gh.gamecenter.entity.ForumEntity
+
+class ForumRecordDao {
+ fun add(id: String) {
+ val originString = SPUtils.getString(SP_KEY)
+
+ if (originString.isEmpty()) {
+ SPUtils.setString(SP_KEY, id)
+ } else {
+ getAll()?.let {
+ if (it.contains(id)) {
+ it.remove(id)
+ }
+ it.add(0, id)
+ save(it)
+ }
+ }
+ }
+
+ fun delete(id: String) {
+ val originString = SPUtils.getString(SP_KEY)
+ if (originString.isNotEmpty()) {
+ getAll()?.let {
+ if (it.contains(id)) {
+ it.remove(id)
+ }
+ save(it)
+ }
+ }
+ }
+
+ private fun save(it: ArrayList) {
+ val builder = StringBuilder()
+ for ((index, key) in it.withIndex()) {
+ builder.append(key)
+ if (index != it.size - 1) {
+ builder.append(DIVIDER)
+ }
+ }
+ SPUtils.setString(SP_KEY, builder.toString())
+ }
+
+ fun sortForumList(originalForums: ArrayList?) {
+ if (originalForums.isNullOrEmpty()) return
+ val visitRecords = getAll()
+ val tempList = arrayListOf()
+ visitRecords?.forEach { id ->
+ val index = originalForums.indexOfFirst { it.id == id }
+ if (index >= 0) {
+ tempList.add(originalForums.removeAt(index))
+ }
+ }
+ tempList.addAll(originalForums)
+ originalForums.clear()
+ originalForums.addAll(tempList)
+ }
+
+ fun getAll(): ArrayList? {
+ val list = SPUtils.getString(SP_KEY).split(DIVIDER)
+
+ return if (list.size == 1 && list[0].isEmpty()) null else ArrayList(list)
+ }
+
+ companion object {
+ private const val SP_KEY = "forum_recoed_key"
+ private const val DIVIDER = "<-||->"
+
+ @Volatile
+ private var instance: ForumRecordDao? = null
+
+ fun getInstance(): ForumRecordDao {
+ return instance ?: synchronized(this) {
+ instance ?: ForumRecordDao().also { instance = it }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt
new file mode 100644
index 0000000000..d033ff6ec3
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt
@@ -0,0 +1,53 @@
+package com.gh.gamecenter.forum.home
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.*
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.ForumRecordItemBinding
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.forum.detail.ForumDetailActivity
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class ForumRecordsAdapter(context: Context,
+ private val entrance: String,
+ private var mList: List)
+ : BaseRecyclerAdapter(context) {
+
+ fun setListData(list: List) {
+ mList = list
+ notifyDataSetChanged()
+ }
+
+ override fun getItemCount() = mList.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
+ = ForumRecordViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.forum_record_item, parent, false))
+
+
+ override fun onBindViewHolder(holder: ForumRecordViewHolder, position: Int) {
+ holder.binding.run {
+ root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
+ leftMargin = if (position == 0) 16F.dip2px() else 0
+ }
+
+ val forumEntity = mList[position]
+ entity = forumEntity
+ executePendingBindings()
+
+ if (forumEntity.type == "official_bbs") {
+ forumIv.displayGameIcon(forumEntity.icon, null)
+ } else {
+ forumIv.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
+ }
+
+ root.setOnClickListener {
+ mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, entrance))
+ }
+ }
+ }
+
+ class ForumRecordViewHolder(val binding: ForumRecordItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumScrollCalculatorHelper.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumScrollCalculatorHelper.kt
new file mode 100644
index 0000000000..9554fc834a
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumScrollCalculatorHelper.kt
@@ -0,0 +1,167 @@
+package com.gh.gamecenter.forum.home
+
+import android.graphics.Rect
+import android.os.Handler
+import android.os.Looper
+import android.text.TextUtils
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.constant.Constants
+import com.gh.common.util.MD5Utils
+import com.gh.common.util.NetworkUtils
+import com.gh.common.util.SPUtils
+import com.gh.common.util.safelyGetInRelease
+import com.gh.gamecenter.entity.ForumVideoEntity
+import com.gh.gamecenter.setting.VideoSettingFragment
+import com.gh.gamecenter.video.detail.CustomManager
+import com.halo.assistant.HaloApp
+import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer
+
+class ForumScrollCalculatorHelper(private val horizontalId: Int,
+ private val verticalId: Int,
+ private val rangeTop: Int) {
+ private var firstVisible = -1
+ private var lastVisible = 0
+ private var visibleCount = 0
+ private var runnable: PlayRunnable? = null
+ var mItemData: List? = null
+ var currentPlayer: ArticleItemVideoView? = null
+ var currentPosition = -1
+ var mListRv: RecyclerView? = null
+
+ private val playHandler = Handler(Looper.getMainLooper())
+
+ fun onScrollStateChanged(view: RecyclerView?, scrollState: Int) {
+ mListRv = view
+ if (scrollState == RecyclerView.SCROLL_STATE_IDLE) {
+ playVideo(view)
+ }
+ }
+
+ fun onScroll(itemData: List?, firstVisibleItem: Int, lastVisibleItem: Int) {
+ mItemData = itemData
+ firstVisible = firstVisibleItem
+ lastVisible = lastVisibleItem
+ visibleCount = lastVisibleItem - firstVisibleItem
+ releaseIfNeeded()
+ }
+
+ //判断player是否划出了屏幕,划出了屏幕则需要释放
+ private fun releaseIfNeeded() {
+ val rect = Rect()
+ if (currentPlayer != null) {
+ currentPlayer?.getLocalVisibleRect(rect)
+ val height = currentPlayer?.height
+ if (rect.top != 0 || rect.bottom != height) {
+ //保存进度
+ val currentScheduler = currentPlayer?.currentPositionWhenPlaying?.toLong() ?: 0L
+ val video = mItemData?.safelyGetInRelease(currentPosition)
+ if (video != null) {
+ savePlaySchedule(MD5Utils.getContentMD5(video.url), currentScheduler)
+ }
+ CustomManager.releaseAllVideos(currentPlayer?.getKey())
+// currentPlayer?.resetDetailMask()
+ currentPlayer = null
+ currentPosition = -1
+ }
+ }
+ }
+
+ private fun playVideo(view: RecyclerView?) {
+ if (view == null) return
+ val layoutManager = view.layoutManager
+ var gsyBaseVideoPlayer: ArticleItemVideoView
+ for (i in firstVisible until lastVisible + 1) {
+ if (layoutManager == null || mItemData.isNullOrEmpty()) return
+
+ val child = mListRv?.findViewHolderForAdapterPosition(i)?.itemView
+ val horizontalPlayer: View? = child?.findViewById(horizontalId)
+ val verticalPlayer: View? = child?.findViewById(verticalId)
+ val player = when {
+ horizontalPlayer?.visibility == View.VISIBLE -> horizontalPlayer
+ verticalPlayer?.visibility == View.VISIBLE -> verticalPlayer
+ else -> null
+ }
+ if (player == null || player !is ArticleItemVideoView) continue
+
+ val video = mItemData?.safelyGetInRelease(i)
+ if (video == null || TextUtils.isEmpty(video.url)) continue
+
+ val rect = Rect()
+ player.getLocalVisibleRect(rect)
+ val height = player.height
+ if (rect.top == 0 && rect.bottom == height) {
+ gsyBaseVideoPlayer = player
+ if (runnable != null) {
+ playHandler.removeCallbacks(runnable!!)
+ runnable = null
+ }
+ if (currentPlayer == gsyBaseVideoPlayer) return
+ val screenPosition = IntArray(2)
+ gsyBaseVideoPlayer.getLocationInWindow(screenPosition)
+ val rangePosition = screenPosition[1]
+ if (rangePosition >= rangeTop) {
+ runnable = PlayRunnable(gsyBaseVideoPlayer)
+ if (currentPlayer != null) {
+ CustomManager.releaseAllVideos(currentPlayer?.getKey())
+// currentPlayer?.resetDetailMask()
+ }
+ currentPlayer = gsyBaseVideoPlayer
+ currentPosition = i
+ //降低频率
+ playHandler.postDelayed(runnable!!, 100)
+ break
+ }
+ }
+
+ }
+ }
+
+ private inner class PlayRunnable(var gsyBaseVideoPlayer: GSYBaseVideoPlayer?) : Runnable {
+ override fun run() {
+ if (gsyBaseVideoPlayer != null && !gsyBaseVideoPlayer!!.isInPlayingState) {
+
+ val videoOption = SPUtils.getString(Constants.SP_CONTENT_VIDEO_OPTION, VideoSettingFragment.VIDEO_OPTION_WIFI)
+ ?: VideoSettingFragment.VIDEO_OPTION_WIFI
+
+ when (videoOption) {
+ VideoSettingFragment.VIDEO_OPTION_ALL -> {
+ startPlayLogic(gsyBaseVideoPlayer)
+ }
+
+ VideoSettingFragment.VIDEO_OPTION_WIFI -> {
+ if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
+ startPlayLogic(gsyBaseVideoPlayer)
+ }
+ }
+
+ else -> {}
+ }
+ }
+ }
+ }
+
+ private fun startPlayLogic(gsyBaseVideoPlayer: GSYBaseVideoPlayer?) {
+ val videoView = gsyBaseVideoPlayer as? ArticleItemVideoView
+// val position = getPlaySchedule(MD5Utils.getContentMD5(topVideo.url))
+// if (position > 0) {
+// videoView?.seekOnStart = position
+// }
+ videoView?.startPlayLogic()
+ }
+
+ companion object {
+
+ fun savePlaySchedule(key: String, schedule: Long) {
+ val record = SPUtils.getMap(Constants.SP_HOME_VIDEO_PLAY_RECORD)
+ record[key] = schedule.toString()
+ SPUtils.setMap(Constants.SP_CONTENT_VIDEO_PLAY_RECORD, record)
+ }
+
+ fun getPlaySchedule(key: String): Long {
+ val record = SPUtils.getMap(Constants.SP_CONTENT_VIDEO_PLAY_RECORD)
+ return record[key]?.toLong() ?: 0L
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/ForumViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumViewModel.kt
new file mode 100644
index 0000000000..ca2198944c
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumViewModel.kt
@@ -0,0 +1,164 @@
+package com.gh.gamecenter.forum.home
+
+import android.annotation.SuppressLint
+import android.app.Application
+import androidx.lifecycle.*
+import com.gh.common.util.CheckLoginUtils
+import com.gh.common.util.createRequestBodyAny
+import com.gh.common.util.singleToMain
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.entity.ForumUnreadEntity
+import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.Response
+import com.gh.gamecenter.retrofit.RetrofitManager
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+import okhttp3.ResponseBody
+import retrofit2.HttpException
+
+class ForumViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val api = RetrofitManager.getInstance(getApplication()).api
+ val followForumsLiveData = MediatorLiveData>()
+ val hotForums = MediatorLiveData>()
+ val officialForums = MediatorLiveData>()
+ var followForums = arrayListOf()
+ var followStatusForums = arrayListOf()
+
+ init {
+ getData()
+ }
+
+ fun getData() {
+ if (CheckLoginUtils.isLogin()) {
+ getFollowForum()
+ } else {
+ getHotForum()
+ }
+ getOfficialForum()
+ }
+
+ @SuppressLint("CheckResult")
+ fun getFollowForum() {
+ api.getFollowsForum(UserManager.getInstance().userId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Response>() {
+ override fun onResponse(response: List?) {
+ super.onResponse(response)
+ if (response?.isNotEmpty() == true) {
+ followForums = ArrayList(response)
+ getForumUnreadStatus()
+ } else {
+ followForumsLiveData.postValue(response)
+ }
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ followForumsLiveData.postValue(null)
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun getForumUnreadStatus() {
+ if (followForums.isEmpty()) return
+
+ if (!UserManager.getInstance().isLoggedIn) {
+ followForumsLiveData.postValue(followForums)
+ return
+ }
+
+ val requestMap = hashMapOf()
+ followStatusForums.clear()
+ followForums.forEach {
+ followStatusForums.add(it.transformUnreadEntity())
+ }
+ requestMap["bbs"] = followStatusForums
+ val body = requestMap.createRequestBodyAny()
+ RetrofitManager.getInstance(getApplication())
+ .api
+ .getForumUnreadStatus(body)
+ .compose(singleToMain())
+ .subscribe(object : BiResponse>() {
+
+ override fun onSuccess(data: List) {
+ if (data.isNotEmpty() && data.size == followForums.size) {
+ data.forEachIndexed { index, unreadEntity ->
+ followForums[index].unread = unreadEntity.unread
+ }
+ }
+ followForumsLiveData.postValue(followForums)
+ }
+
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ followForumsLiveData.postValue(followForums)
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun getHotForum() {
+ api.getHotForumWithPage(1)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Response>() {
+ override fun onResponse(response: List?) {
+ super.onResponse(response)
+ hotForums.postValue(response)
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ hotForums.postValue(null)
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun getOfficialForum() {
+ api.getOfficialForum(1)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Response>() {
+ override fun onResponse(response: List?) {
+ super.onResponse(response)
+ officialForums.postValue(response)
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ officialForums.postValue(null)
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun followForum(bbsId: String, onSuccess: () -> Unit) {
+ RetrofitManager.getInstance(getApplication()).api
+ .followForum(bbsId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ onSuccess.invoke()
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun unFollowForum(bbsId: String, onSuccess: () -> Unit) {
+ RetrofitManager.getInstance(getApplication()).api
+ .unFollowForum(bbsId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ onSuccess.invoke()
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/HotForumsAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/HotForumsAdapter.kt
new file mode 100644
index 0000000000..45ed048e48
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/HotForumsAdapter.kt
@@ -0,0 +1,81 @@
+package com.gh.gamecenter.forum.home
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.*
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.HotForumItemBinding
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.eventbus.EBForumFollowChange
+import com.gh.gamecenter.forum.detail.ForumDetailActivity
+import com.lightgame.adapter.BaseRecyclerAdapter
+import org.greenrobot.eventbus.EventBus
+
+class HotForumsAdapter(context: Context,
+ private val entrance: String,
+ private val mViewModel: ForumViewModel?,
+ private var mList: List)
+ : BaseRecyclerAdapter(context) {
+
+
+ override fun getItemCount() = mList.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
+ = HotForumViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.hot_forum_item, parent, false))
+
+
+ override fun onBindViewHolder(holder: HotForumViewHolder, position: Int) {
+ holder.binding.run {
+ val forumEntity = mList[position]
+ entity = forumEntity
+ executePendingBindings()
+
+ forumIv.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
+
+ followTv.run {
+ text = if (forumEntity.isFollow) {
+ setBackgroundResource(R.drawable.button_round_fafafa)
+ setTextColor(R.color.text_C0C6CC.toColor())
+ "已关注"
+ } else {
+ setBackgroundResource(R.drawable.button_round_f0f8fa)
+ setTextColor(R.color.theme_font.toColor())
+ "关注"
+ }
+ }
+
+ followTv.setOnClickListener {
+ debounceActionWithInterval(R.id.followTv) {
+ CheckLoginUtils.checkLogin(mContext, entrance) {
+ if (forumEntity.isFollow) {
+ mViewModel?.unFollowForum(forumEntity.id) {
+ forumEntity.isFollow = false
+ followTv.setBackgroundResource(R.drawable.button_round_f0f8fa)
+ followTv.setTextColor(R.color.theme_font.toColor())
+ followTv.text = "关注"
+ EventBus.getDefault().post(EBForumFollowChange(forumEntity, false))
+ }
+ } else {
+ mViewModel?.followForum(forumEntity.id) {
+ forumEntity.isFollow = true
+ followTv.setBackgroundResource(R.drawable.button_round_fafafa)
+ followTv.setTextColor(R.color.text_C0C6CC.toColor())
+ followTv.text = "已关注"
+ ToastUtils.showToast("关注成功")
+ EventBus.getDefault().post(EBForumFollowChange(forumEntity, true))
+ }
+ }
+ }
+ }
+ }
+
+ root.setOnClickListener {
+ mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, entrance))
+ }
+ }
+ }
+
+ class HotForumViewHolder(val binding: HotForumItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/OfficialForumAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/OfficialForumAdapter.kt
new file mode 100644
index 0000000000..e48ea70c16
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/OfficialForumAdapter.kt
@@ -0,0 +1,46 @@
+package com.gh.gamecenter.forum.home
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.CheckLoginUtils
+import com.gh.common.util.DataCollectionUtils
+import com.gh.common.util.MtaHelper
+import com.gh.common.util.ifLogin
+import com.gh.gamecenter.*
+import com.gh.gamecenter.databinding.ForumWelfareItemBinding
+import com.gh.gamecenter.databinding.HotForumItemBinding
+import com.gh.gamecenter.databinding.OfficialForumItemBinding
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.forum.detail.ForumDetailActivity
+import com.gh.gamecenter.manager.UserManager
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class OfficialForumAdapter(context: Context,
+ private val entrance: String,
+ private var mList: List)
+ : BaseRecyclerAdapter(context) {
+
+
+ override fun getItemCount() = mList.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
+ = OfficialForumViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.official_forum_item, parent, false))
+
+
+ override fun onBindViewHolder(holder: OfficialForumViewHolder, position: Int) {
+ holder.binding.run {
+
+ val forumEntity = mList[position]
+ entity = forumEntity
+ executePendingBindings()
+
+ root.setOnClickListener {
+ mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, entrance))
+ }
+ }
+ }
+
+ class OfficialForumViewHolder(val binding: OfficialForumItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/home/WelfaresAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/home/WelfaresAdapter.kt
new file mode 100644
index 0000000000..b080a9f15b
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/home/WelfaresAdapter.kt
@@ -0,0 +1,70 @@
+package com.gh.gamecenter.forum.home
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.util.CheckLoginUtils
+import com.gh.common.util.DataCollectionUtils
+import com.gh.common.util.MtaHelper
+import com.gh.common.util.ifLogin
+import com.gh.gamecenter.*
+import com.gh.gamecenter.databinding.ForumWelfareItemBinding
+import com.gh.gamecenter.databinding.HotForumItemBinding
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.forum.detail.ForumDetailActivity
+import com.gh.gamecenter.manager.UserManager
+import com.lightgame.adapter.BaseRecyclerAdapter
+
+class WelfaresAdapter(context: Context,
+ private var mList: List>)
+ : BaseRecyclerAdapter(context) {
+
+
+ override fun getItemCount() = mList.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
+ = WelfareViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.forum_welfare_item, parent, false))
+
+
+ override fun onBindViewHolder(holder: WelfareViewHolder, position: Int) {
+ holder.binding.run {
+// root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
+// leftMargin = if (position == 0) 16F.dip2px() else 0
+// }
+
+ val entity = mList[position]
+ welfareIv.setImageResource(entity.first)
+ welfareName.text = entity.second
+
+
+ root.setOnClickListener {
+ when (entity.second) {
+ "工具箱" -> {
+ mContext.startActivity(ToolBoxActivity.getIntent(mContext, "(社区-论坛:工具箱)"))
+ }
+
+ "礼包中心" -> {
+ mContext.startActivity(LibaoActivity.getIntent(mContext, "(社区-论坛:礼包中心)"))
+ }
+
+ "游戏动态" -> {
+ CheckLoginUtils.checkLogin(mContext, "社区-论坛:游戏动态") {
+ mContext.startActivity(ConcernInfoActivity.getIntent(mContext))
+ }
+ }
+
+ "资讯中心" -> {
+ mContext.startActivity(InfoActivity.getIntent(mContext))
+ }
+
+ "万能加速器" -> {
+ GameDetailActivity.startGameDetailActivity(mContext, "5c9456576b90b400137cc6a6", "社区-论坛:万能加速器")
+ }
+ }
+ }
+ }
+ }
+
+ class WelfareViewHolder(val binding: ForumWelfareItemBinding) : BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListActivity.kt
new file mode 100644
index 0000000000..bb19f73862
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListActivity.kt
@@ -0,0 +1,22 @@
+package com.gh.gamecenter.forum.list
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.common.util.EntranceUtils
+import com.gh.gamecenter.NormalActivity
+
+class ForumListActivity : NormalActivity() {
+
+ companion object {
+ const val TYPE_FOLLOW = "follow"
+ const val TYPE_HOT = "hot"
+ const val TYPE_OFFICIAL = "official"
+
+ fun getIntent(context: Context, type: String): Intent {
+ val bundle = Bundle()
+ bundle.putString(EntranceUtils.KEY_TYPE, type)
+ return getTargetIntent(context, ForumListActivity::class.java, ForumListFragment::class.java, bundle)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt
new file mode 100644
index 0000000000..1a00d7d358
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt
@@ -0,0 +1,117 @@
+package com.gh.gamecenter.forum.list
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import androidx.databinding.DataBindingUtil
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.base.BaseRecyclerViewHolder
+import com.gh.common.constant.ItemViewType
+import com.gh.common.util.CheckLoginUtils
+import com.gh.common.util.ToastUtils
+import com.gh.common.util.debounceActionWithInterval
+import com.gh.common.util.toColor
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.databinding.ForumMyFollowBinding
+import com.gh.gamecenter.entity.ForumEntity
+import com.gh.gamecenter.eventbus.EBForumFollowChange
+import com.gh.gamecenter.forum.detail.ForumDetailActivity
+import org.greenrobot.eventbus.EventBus
+
+class ForumListAdapter(context: Context,
+ val entrance: String,
+ val mViewModel: ForumListViewModel?): ListAdapter(context) {
+
+ override fun getItemCount(): Int {
+ return if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return when (position) {
+ itemCount - 1 -> ItemViewType.ITEM_FOOTER
+ else -> ItemViewType.ITEM_BODY
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ ItemViewType.ITEM_FOOTER -> FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
+
+ else -> ForumItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.forum_my_follow, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is ForumItemViewHolder -> {
+ holder.binding.run {
+ val forumEntity = mEntityList[position]
+ entity = forumEntity
+ executePendingBindings()
+
+ if (mViewModel?.type == ForumListActivity.TYPE_OFFICIAL) {
+ forumIcon.displayGameIcon(forumEntity.icon, null)
+ } else {
+ forumIcon.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
+ }
+ topLine.visibility = if (position == 0) View.GONE else View.VISIBLE
+
+ if (mViewModel?.type == ForumListActivity.TYPE_FOLLOW) {
+ moreIv.visibility = View.VISIBLE
+ followTv.visibility = View.GONE
+ } else {
+ moreIv.visibility = View.GONE
+ followTv.visibility = View.VISIBLE
+
+ followTv.run {
+ text = if (forumEntity.isFollow) {
+ setBackgroundResource(R.drawable.button_round_fafafa)
+ setTextColor(R.color.text_C0C6CC.toColor())
+ "已关注"
+ } else {
+ setBackgroundResource(R.drawable.button_round_f0f8fa)
+ setTextColor(R.color.theme_font.toColor())
+ "关注"
+ }
+ }
+
+ followTv.setOnClickListener {
+ debounceActionWithInterval(R.id.followTv) {
+ CheckLoginUtils.checkLogin(mContext, entrance) {
+ if (forumEntity.isFollow) {
+ mViewModel?.unFollowForum(forumEntity.id) {
+ forumEntity.isFollow = false
+ followTv.setBackgroundResource(R.drawable.button_round_f0f8fa)
+ followTv.setTextColor(R.color.theme_font.toColor())
+ followTv.text = "关注"
+ EventBus.getDefault().post(EBForumFollowChange(forumEntity, false))
+ }
+ } else {
+ mViewModel?.followForum(forumEntity.id) {
+ forumEntity.isFollow = true
+ followTv.setBackgroundResource(R.drawable.button_round_fafafa)
+ followTv.setTextColor(R.color.text_C0C6CC.toColor())
+ followTv.text = "已关注"
+ ToastUtils.showToast("关注成功")
+ EventBus.getDefault().post(EBForumFollowChange(forumEntity, true))
+ }
+ }
+ }
+ }
+ }
+ }
+
+ root.setOnClickListener { mContext.startActivity(ForumDetailActivity.getIntent(mContext, forumEntity.id, entrance)) }
+ }
+ }
+
+ is FooterViewHolder -> {
+ holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
+ }
+ }
+ }
+
+ inner class ForumItemViewHolder(val binding: ForumMyFollowBinding): BaseRecyclerViewHolder(binding.root)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListFragment.kt
new file mode 100644
index 0000000000..c989ff5952
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListFragment.kt
@@ -0,0 +1,41 @@
+package com.gh.gamecenter.forum.list
+
+import android.os.Bundle
+import com.gh.common.util.EntranceUtils
+import com.gh.common.util.dip2px
+import com.gh.common.util.toColor
+import com.gh.common.util.viewModelProvider
+import com.gh.common.view.SpacingItemDecoration
+import com.gh.gamecenter.R
+import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.entity.ForumEntity
+
+class ForumListFragment: ListFragment() {
+
+ private var mAdapter: ForumListAdapter? = null
+ private var mViewModel: ForumListViewModel? = null
+
+
+ override fun provideListAdapter() = mAdapter
+ ?: ForumListAdapter(requireContext(), mEntrance, provideListViewModel()).apply { mAdapter = this }
+
+ override fun provideListViewModel() = viewModelProvider()
+
+ override fun getItemDecoration()= SpacingItemDecoration(onlyDecorateTheFirstItem = true, top = 8F.dip2px())
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ val type = arguments?.getString(EntranceUtils.KEY_TYPE) ?: ""
+ mViewModel = provideListViewModel()
+ mViewModel?.type = type
+ when (type) {
+ ForumListActivity.TYPE_FOLLOW -> {
+ setNavigationTitle("关注论坛")
+ mViewModel?.setOverLimitSize(1000)
+ }
+ ForumListActivity.TYPE_HOT -> setNavigationTitle("热门论坛")
+ ForumListActivity.TYPE_OFFICIAL -> setNavigationTitle("综合论坛")
+ }
+
+ super.onCreate(savedInstanceState)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/list/ForumListVIewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListVIewModel.kt
new file mode 100644
index 0000000000..fce7c1e799
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListVIewModel.kt
@@ -0,0 +1,57 @@
+package com.gh.gamecenter.forum.list
+
+import android.annotation.SuppressLint
+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.BiResponse
+import com.gh.gamecenter.retrofit.RetrofitManager
+import io.reactivex.Observable
+import io.reactivex.Single
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+import okhttp3.ResponseBody
+
+class ForumListViewModel(application: Application): ListViewModel(application) {
+
+ private val mApi = RetrofitManager.getInstance(getApplication()).api
+ var type = ForumListActivity.TYPE_FOLLOW
+
+ override fun mergeResultLiveData() {
+ mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) }
+ }
+
+ override fun provideDataObservable(page: Int): Observable> {
+ return when (type) {
+ ForumListActivity.TYPE_FOLLOW -> mApi.getFollowsForum(UserManager.getInstance().userId)
+ ForumListActivity.TYPE_HOT -> mApi.getHotForumWithPage(page)
+ ForumListActivity.TYPE_OFFICIAL -> mApi.getOfficialForum(page)
+ else -> mApi.getHotForumWithPage(page)
+ }
+ }
+
+ @SuppressLint("CheckResult")
+ fun followForum(bbsId: String, onSuccess: () -> Unit) {
+ mApi.followForum(bbsId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ onSuccess.invoke()
+ }
+ })
+ }
+
+ @SuppressLint("CheckResult")
+ fun unFollowForum(bbsId: String, onSuccess: () -> Unit) {
+ mApi.unFollowForum(bbsId)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ onSuccess.invoke()
+ }
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt
index 1f236f8bbd..cace5649a3 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumContentSearchListAdapter.kt
@@ -20,12 +20,12 @@ import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.databinding.ForumSearchContentListBinding
import com.gh.gamecenter.entity.CommunityEntity
-import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.forum.home.ForumArticleAskItemViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.Questions
-import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
+import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
class ForumContentSearchListAdapter(context: Context, val mListViewModel: ForumContentSearchListViewModel, val mEntrance: String) : ListAdapter(context), ISyncAdapterHandler {
@@ -73,7 +73,7 @@ class ForumContentSearchListAdapter(context: Context, val mListViewModel: ForumC
val questions = Questions()
questions.id = answer.id ?: ""
questions.title = answer.articleTitle
- questions.answerCount = answer.answerCount
+ questions.answerCount = answer.count.answer
answer.questions = questions
if (mEntrance == "论坛首页+(搜索)") {
@@ -101,61 +101,93 @@ class ForumContentSearchListAdapter(context: Context, val mListViewModel: ForumC
answerViewHolder.binding.content.text = answer.brief?.fromHtml()
answerViewHolder.itemView.setOnClickListener {
val entrance = BaseActivity.mergeEntranceAndPath(mEntrance, "")
- if ("community_article" == answer.type) {
- MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
- mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(answer.bbs.id), answer.id!!, mEntrance, ""))
- } else {
- MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
- mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, answer.id, mEntrance, ""))
+ when (answer.type) {
+ "community_article" -> {
+ MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
+ mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(answer.bbs.id), answer.id!!, mEntrance, ""))
+ }
+ "video" -> {
+ MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
+ mContext.startActivity(ForumVideoDetailActivity.getIntent(mContext, answer.id ?:""))
+ }
+ else -> {
+ MtaHelper.onEvent(holder.getEventId(entrance), holder.getKey(entrance), "${answer.articleTitle}(${answer.id})")
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, answer.id?:"", mEntrance, ""))
+ }
}
}
- if (answer.type != "community_article") {
+ if (answer.type == "question") {
if (answer.questions.answerCount > 0) {
answerViewHolder.commentCount.text = answer.questions.answerCount.toString()
} else {
answerViewHolder.commentCount.text = "回答"
}
+ answerViewHolder.commentCount.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(mContext, R.drawable.community_comment_count), null, null, null)
answerViewHolder.voteCountContainer.visibility = View.GONE
val params = answerViewHolder.binding.includeVoteAndComment.root.layoutParams as LinearLayout.LayoutParams
params.width = 80f.dip2px()
answerViewHolder.binding.includeVoteAndComment.root.layoutParams = params
+ } else {
+ answerViewHolder.voteCountContainer.visibility = View.VISIBLE
+ val params = answerViewHolder.binding.includeVoteAndComment.root.layoutParams as LinearLayout.LayoutParams
+ params.width = 160f.dip2px()
+ answerViewHolder.binding.includeVoteAndComment.root.layoutParams = params
}
-
} else {
val forumSearchHolder = holder as ForumSearchContentListViewHolder
- forumSearchHolder.binding.entity = answer
- if (answer.type == "question") {
- forumSearchHolder.binding.content.visibility = View.GONE
- val title = answer.questions.title ?: ""
- val spannableStringBuilder = SpannableStringBuilder(" ")
- spannableStringBuilder.setSpan(CenterImageSpan(mContext, R.drawable.ic_ask_label), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
- spannableStringBuilder.append(title.fromHtml())
- forumSearchHolder.binding.title.text = spannableStringBuilder
- } else {
- forumSearchHolder.binding.content.visibility = View.VISIBLE
- forumSearchHolder.binding.title.text = answer.questions.title?.fromHtml()
- }
- when {
- answer.getPassVideos().isNotEmpty() -> {
- val poster = answer.getPassVideos()[0].poster
- ImageUtils.display(forumSearchHolder.binding.image, poster, false)
- forumSearchHolder.binding.image.visibility = View.VISIBLE
- }
- answer.images.isNotEmpty() -> {
- forumSearchHolder.binding.image.visibility = View.VISIBLE
- ImageUtils.display(forumSearchHolder.binding.image, answer.images[0], false)
- }
- else -> {
- forumSearchHolder.binding.image.visibility = View.GONE
- }
- }
+ if (answer.type == "video") {
+ forumSearchHolder.binding.run {
+ normalContainer.visibility = View.GONE
+ includedAnswerItem.root.visibility = View.VISIBLE
- forumSearchHolder.binding.content.text = answer.brief?.fromHtml()
- forumSearchHolder.itemView.setOnClickListener {
- if ("community_article" == answer.type) {
- mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(answer.bbs.id), answer.id!!, mEntrance, ""))
+ includedAnswerItem.entity = answer
+ includedAnswerItem.executePendingBindings()
+
+ val answerViewHolder = ForumArticleAskItemViewHolder(includedAnswerItem)
+ answerViewHolder.bindForumAnswerItem(answer, mEntrance, "")
+ answerViewHolder.itemView.setOnClickListener {
+ mContext.startActivity(ForumVideoDetailActivity.getIntent(mContext, answer.id ?:""))
+ }
+ }
+ } else {
+ forumSearchHolder.binding.includedAnswerItem.root.visibility = View.GONE
+ forumSearchHolder.binding.normalContainer.visibility = View.VISIBLE
+
+ forumSearchHolder.binding.entity = answer
+ if (answer.type == "question") {
+ forumSearchHolder.binding.content.visibility = View.GONE
+ val title = answer.questions.title ?: ""
+ val spannableStringBuilder = SpannableStringBuilder(" ")
+ spannableStringBuilder.setSpan(CenterImageSpan(mContext, R.drawable.ic_ask_label), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ spannableStringBuilder.append(title.fromHtml())
+ forumSearchHolder.binding.title.text = spannableStringBuilder
} else {
- mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, answer.id, mEntrance, ""))
+ forumSearchHolder.binding.content.visibility = View.VISIBLE
+ forumSearchHolder.binding.title.text = answer.questions.title?.fromHtml()
+ }
+ when {
+ answer.getPassVideos().isNotEmpty() -> {
+ val poster = answer.getPassVideos()[0].poster
+ ImageUtils.display(forumSearchHolder.binding.image, poster, false)
+ forumSearchHolder.binding.image.visibility = View.VISIBLE
+ }
+ answer.images.isNotEmpty() -> {
+ forumSearchHolder.binding.image.visibility = View.VISIBLE
+ ImageUtils.display(forumSearchHolder.binding.image, answer.images[0], false)
+ }
+ else -> {
+ forumSearchHolder.binding.image.visibility = View.GONE
+ }
+ }
+
+ forumSearchHolder.binding.content.text = answer.brief?.fromHtml()
+ forumSearchHolder.itemView.setOnClickListener {
+ if ("community_article" == answer.type) {
+ mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(answer.bbs.id), answer.id!!, mEntrance, ""))
+ } else {
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, answer.id
+ ?: "", mEntrance, ""))
+ }
}
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt
index 6b3945f73b..32c8641018 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchActivity.kt
@@ -9,6 +9,7 @@ import com.gh.common.constant.Constants
import com.gh.common.util.DirectUtils
import com.gh.common.util.EntranceUtils
import com.gh.common.util.showKeyBoard
+import com.gh.common.util.toColor
import com.gh.gamecenter.DisplayType
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
@@ -28,6 +29,7 @@ class ForumOrUserSearchActivity : SearchActivity() {
"搜索此论坛中的内容"
}
searchEt.showKeyBoard()
+ searchBtn.setTextColor(R.color.theme_font.toColor())
}
override fun search(type: SearchType, key: String?) {
diff --git a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchFragment.kt
index 5fbdfd8520..5252a4def9 100644
--- a/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchFragment.kt
@@ -18,7 +18,7 @@ class ForumOrUserSearchFragment : BaseFragment_TabLayout() {
}
override fun initTabTitleList(tabTitleList: MutableList) {
- tabTitleList.add("帖子")
+ tabTitleList.add("内容")
tabTitleList.add("用户")
}
@@ -42,10 +42,7 @@ class ForumOrUserSearchFragment : BaseFragment_TabLayout() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- mTabLayout.tabMode = TabLayout.MODE_AUTO
- val tabLayoutParams = mTabLayout.layoutParams as RelativeLayout.LayoutParams
- tabLayoutParams.width = RelativeLayout.LayoutParams.WRAP_CONTENT
- mTabLayout.layoutParams = tabLayoutParams
+ mTabLayout.tabMode = TabLayout.MODE_FIXED
val viewpagerParams = mViewPager.layoutParams as LinearLayout.LayoutParams
viewpagerParams.topMargin = 0.5f.dip2px()
diff --git a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java b/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java
index 5ca3cc8a52..73075ce82d 100644
--- a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java
+++ b/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java
@@ -49,7 +49,7 @@ import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.eventbus.EBReuse;
import com.gh.gamecenter.eventbus.EBSkip;
import com.gh.gamecenter.eventbus.EBUISwitch;
-import com.gh.gamecenter.forum.home.ForumHomeFragment;
+import com.gh.gamecenter.forum.home.CommunityHomeFragment;
import com.gh.gamecenter.game.GameFragment;
import com.gh.gamecenter.message.MessageUnreadRepository;
import com.gh.gamecenter.message.MessageUnreadViewModel;
@@ -57,7 +57,6 @@ import com.gh.gamecenter.personal.PersonalFragment;
import com.gh.gamecenter.video.detail.HomeVideoFragment;
import com.halo.assistant.HaloApp;
import com.lightgame.listeners.OnBackPressedListener;
-import com.lightgame.utils.Utils;
import com.lightgame.view.CheckableImageView;
import com.lightgame.view.CheckableLinearLayout;
import com.lightgame.view.NoScrollableViewPager;
@@ -95,7 +94,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
@BindView(R.id.lottieVideo)
LottieAnimationView mLottieVideo;
@BindView(R.id.lottieCommunity)
- LottieAnimationView mLottieCommunity;
+ LottieAnimationView mLottieBBS;
@BindView(R.id.lottieMine)
SimpleDraweeView mLottieMine;
@BindView(R.id.main_tab_game_name)
@@ -103,8 +102,8 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
public static final int INDEX_HOME = 0;
public static final int INDEX_GAME = 1;
- public static final int INDEX_VIDEO = 2;
- public static final int INDEX_ASK = 3;
+ public static final int INDEX_BBS = 2;
+ public static final int INDEX_VIDEO = 3;
public static final int INDEX_PERSONAL = 4;
public static final String EB_MAIN_SCROLL_TOP = "main_scroll_top";
@@ -114,7 +113,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
private MainWrapperViewModel mViewModel;
private MessageUnreadViewModel mMessageUnreadViewModel;
private HomeVideoFragment homeVideoFragment;
- private String[] resAssets = {"lottie/tab_home.json", "lottie/tab_game.json", "lottie/tab_video.json", "lottie/tab_forum.json", "tab_mine.gif"};
+ private String[] resAssets = {"lottie/tab_home.json", "lottie/tab_game.json", "lottie/tab_forum.json", "lottie/tab_video.json", "tab_mine.gif"};
@Override
protected int getLayoutId() {
@@ -147,12 +146,13 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
Bundle videoArgs = new Bundle();
videoArgs.putBoolean(EntranceUtils.KEY_IS_HOME_VIDEO, true);
homeVideoFragment.setArguments(videoArgs);
+
+ fragments.add(new CommunityHomeFragment());
fragments.add(homeVideoFragment);
if (mViewModel.shouldHideVideoTab()) {
mTabVideo.setVisibility(View.GONE);
}
- fragments.add(new ForumHomeFragment());
fragments.add(new PersonalFragment());
}
@@ -292,7 +292,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
case INDEX_VIDEO:
DataUtils.onMtaEvent(getContext(), "顶级页面", "BottomBar_双击", "视频");
break;
- case INDEX_ASK:
+ case INDEX_BBS:
DataUtils.onMtaEvent(getContext(), "顶级页面", "BottomBar_双击", "问答");
break;
case INDEX_PERSONAL:
@@ -328,42 +328,42 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
private void playTabAnimation(int toCheck) {
switch (toCheck) {
- case 0:
+ case INDEX_HOME:
stopAnimation(mLottieGame, INDEX_GAME);
stopAnimation(mLottieVideo, INDEX_VIDEO);
- stopAnimation(mLottieCommunity, INDEX_ASK);
+ stopAnimation(mLottieBBS, INDEX_BBS);
stopAnimation(mLottieMine, INDEX_PERSONAL);
playAnimation(mLottieHome, toCheck);
break;
- case 1:
+ case INDEX_GAME:
SubjectRecommendEntity value = mViewModel.getNavBar().getValue();
if (value != null && !TextUtils.isEmpty(value.getAnimationCode())) {
stopAnimation(mLottieHome, INDEX_HOME);
stopAnimation(mLottieVideo, INDEX_VIDEO);
- stopAnimation(mLottieCommunity, INDEX_ASK);
+ stopAnimation(mLottieBBS, INDEX_BBS);
stopAnimation(mLottieMine, INDEX_PERSONAL);
playGameAnimation(value, toCheck);
}
break;
- case 2:
+ case INDEX_BBS:
stopAnimation(mLottieHome, INDEX_HOME);
stopAnimation(mLottieGame, INDEX_GAME);
- stopAnimation(mLottieCommunity, INDEX_ASK);
+ stopAnimation(mLottieVideo, INDEX_VIDEO);
+ stopAnimation(mLottieMine, INDEX_PERSONAL);
+ playAnimation(mLottieBBS, toCheck);
+ break;
+ case INDEX_VIDEO:
+ stopAnimation(mLottieHome, INDEX_HOME);
+ stopAnimation(mLottieGame, INDEX_GAME);
+ stopAnimation(mLottieBBS, INDEX_BBS);
stopAnimation(mLottieMine, INDEX_PERSONAL);
playAnimation(mLottieVideo, toCheck);
break;
- case 3:
+ case INDEX_PERSONAL:
stopAnimation(mLottieHome, INDEX_HOME);
stopAnimation(mLottieGame, INDEX_GAME);
stopAnimation(mLottieVideo, INDEX_VIDEO);
- stopAnimation(mLottieMine, INDEX_PERSONAL);
- playAnimation(mLottieCommunity, toCheck);
- break;
- case 4:
- stopAnimation(mLottieHome, INDEX_HOME);
- stopAnimation(mLottieGame, INDEX_GAME);
- stopAnimation(mLottieVideo, INDEX_VIDEO);
- stopAnimation(mLottieCommunity, INDEX_ASK);
+ stopAnimation(mLottieBBS, INDEX_BBS);
playAnimation(mLottieMine, toCheck);
break;
default:
@@ -477,7 +477,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
case INDEX_GAME:
tabText = "游戏库";
break;
- case INDEX_ASK:
+ case INDEX_BBS:
tabText = "论坛";
LogUtils.uploadAccessBbsTab();
break;
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt
index 9b19f67ccb..dbdc1bd0e3 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailFragment.kt
@@ -60,6 +60,7 @@ import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.gh.gamecenter.mvvm.Status
import com.gh.gamecenter.normal.NormalFragment
import com.gh.gamecenter.packagehelper.PackageViewModel
+import com.gh.gamecenter.setting.VideoSettingFragment
import com.gh.gamecenter.simulatorgame.SimulatorGameActivity
import com.gh.gamecenter.tag.TagsActivity
import com.gh.gamecenter.user.UserViewModel
@@ -850,17 +851,29 @@ class GameDetailFragment : NormalFragment() {
mTopVideoView.updateThumb(topVideo.poster)
//val trafficVideo = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(SettingsFragment.TRAFFIC_VIDEO_SP_KEY, false)
- if (NetworkUtils.isWifiConnected(requireContext()) /*|| !trafficVideo*/) {
- if (mViewModel.isTopVideoPartlyCached(topVideo.url)) {
+ val videoOption = SPUtils.getString(Constants.SP_HOME_OR_DETAIL_VIDEO_OPTION, VideoSettingFragment.VIDEO_OPTION_WIFI)
+ ?:VideoSettingFragment.VIDEO_OPTION_WIFI
+ when (videoOption) {
+ VideoSettingFragment.VIDEO_OPTION_ALL -> {
mTopVideoView.startPlayLogic(isAutoPlay = true)
- } else {
- // 未有缓存时,为避免影响页面加载,延迟自动播放视频
- postDelayedRunnable({
- if (activity != null && activity?.isFinishing != true) {
- mTopVideoView.startPlayLogic(isAutoPlay = true)
- }
- }, INITIAL_DELAY)
}
+
+ VideoSettingFragment.VIDEO_OPTION_WIFI -> {
+ if (NetworkUtils.isWifiConnected(requireContext()) /*|| !trafficVideo*/) {
+ if (mViewModel.isTopVideoPartlyCached(topVideo.url)) {
+ mTopVideoView.startPlayLogic(isAutoPlay = true)
+ } else {
+ // 未有缓存时,为避免影响页面加载,延迟自动播放视频
+ postDelayedRunnable({
+ if (activity != null && activity?.isFinishing != true) {
+ mTopVideoView.startPlayLogic(isAutoPlay = true)
+ }
+ }, INITIAL_DELAY)
+ }
+ }
+ }
+
+ else -> {}
}
mTopVideoView.fullscreenButton.setOnClickListener {
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt
index 105fa9ec46..60a0855635 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/GameDetailViewModel.kt
@@ -51,7 +51,7 @@ class GameDetailViewModel(application: Application,
// 供被包裹 fragment (如 FuliFragment) 用的合并用户数据后的游戏数据 liveData
val unifiedGameDetailWithUserRelatedInfoForChildLiveData = MutableLiveData()
- var videoIsMuted = true
+ var videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
var displayTopVideo: Boolean = false
fun loadData() {
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/answer/GameDetailAnswerAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/answer/GameDetailAnswerAdapter.kt
index 9d8c82f45a..e9a460eb14 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/answer/GameDetailAnswerAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/fuli/answer/GameDetailAnswerAdapter.kt
@@ -18,7 +18,7 @@ import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.Questions
-import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
import com.halo.assistant.HaloApp
import com.lightgame.adapter.BaseRecyclerAdapter
@@ -59,7 +59,7 @@ class GameDetailAnswerAdapter(context: Context,
mContext.startActivity(ArticleDetailActivity.getIntent(mContext, CommunityEntity(entity.articleCommunityId, ""), entity.id!!, mEntrance, path))
} else {
MtaHelper.onEvent("游戏详情_新", "点击问题", mViewModel.game?.name + "+" + entity.questions.title)
- mContext.startActivity(QuestionsDetailActivity.getIntent(mContext, entity.questions.id, mEntrance, path))
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, entity.questions.id, mEntrance, path))
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt
index 681d40e623..667e49fe40 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/video/TopVideoView.kt
@@ -173,8 +173,6 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
}
fun updateMuteStatus() {
- val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_TOP_VIDEO_VOICE, true)
- viewModel?.videoIsMuted = topVideoVoiceStatus
if (viewModel?.videoIsMuted == true) {
mute()
} else {
@@ -186,7 +184,6 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
viewModel?.videoIsMuted = true
volume.setImageResource(R.drawable.ic_game_detail_volume_off)
CustomManager.getCustomManager(getKey()).isNeedMute = true
- SPUtils.setBoolean(Constants.SP_TOP_VIDEO_VOICE, true)
if (isManual) {
Utils.toast(context, "当前处于静音状态")
uploadVideoStreamingPlaying("点击静音")
@@ -198,7 +195,6 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
viewModel?.videoIsMuted = false
volume.setImageResource(R.drawable.ic_game_detail_volume_on)
CustomManager.getCustomManager(getKey()).isNeedMute = false
- SPUtils.setBoolean(Constants.SP_TOP_VIDEO_VOICE, false)
if (isManual) {
uploadVideoStreamingPlaying("取消静音")
MtaHelper.onEvent("游戏详情_顶部视频", "${getMtaKeyPrefix()}-解除静音", combinedTitleAndId)
diff --git a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt
index 8d86398bdf..c1f7987273 100644
--- a/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/home/HomeFragment.kt
@@ -175,7 +175,7 @@ class HomeFragment : BaseFragment() {
if (position != 0L) {
mScrollCalculatorHelper.currentPlayer?.seekTo(position)
mScrollCalculatorHelper.currentPlayer?.onVideoResume(false)
- val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_TOP_VIDEO_VOICE, true)
+ val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
if (topVideoVoiceStatus) {
mScrollCalculatorHelper.currentPlayer?.mute()
} else {
diff --git a/app/src/main/java/com/gh/gamecenter/home/video/AutomaticVideoView.kt b/app/src/main/java/com/gh/gamecenter/home/video/AutomaticVideoView.kt
index 34d7ebc489..4f9e0e80e1 100644
--- a/app/src/main/java/com/gh/gamecenter/home/video/AutomaticVideoView.kt
+++ b/app/src/main/java/com/gh/gamecenter/home/video/AutomaticVideoView.kt
@@ -59,7 +59,7 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
override fun startPlayLogic() {
super.startPlayLogic()
- val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_TOP_VIDEO_VOICE, true)
+ val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
if (topVideoVoiceStatus) {
violenceUpdateMuteStatus()
}
diff --git a/app/src/main/java/com/gh/gamecenter/home/video/ScrollCalculatorHelper.kt b/app/src/main/java/com/gh/gamecenter/home/video/ScrollCalculatorHelper.kt
index faaa53f789..e383a00c28 100644
--- a/app/src/main/java/com/gh/gamecenter/home/video/ScrollCalculatorHelper.kt
+++ b/app/src/main/java/com/gh/gamecenter/home/video/ScrollCalculatorHelper.kt
@@ -1,6 +1,5 @@
package com.gh.gamecenter.home.video
-import android.content.Context
import android.graphics.Rect
import android.os.Handler
import android.os.Looper
@@ -13,9 +12,9 @@ import com.gh.common.util.SPUtils
import com.gh.common.util.safelyGetInRelease
import com.gh.gamecenter.entity.SimpleVideoEntity
import com.gh.gamecenter.home.HomeItemData
+import com.gh.gamecenter.setting.VideoSettingFragment
import com.gh.gamecenter.video.detail.CustomManager
import com.halo.assistant.HaloApp
-import com.halo.assistant.fragment.SettingsFragment
import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer
class ScrollCalculatorHelper(private val playId: Int, private val rangeTop: Int) {
@@ -115,15 +114,21 @@ class ScrollCalculatorHelper(private val playId: Int, private val rangeTop: Int)
override fun run() {
if (gsyBaseVideoPlayer != null && !gsyBaseVideoPlayer!!.isInPlayingState) {
- val sp = HaloApp.getInstance().application.getSharedPreferences("${HaloApp.getInstance().application.packageName}_preferences", Context.MODE_PRIVATE)
- val isNonWifiPlay = sp.getBoolean(SettingsFragment.TRAFFIC_HOME_VIDEO_SP_KEY, false)
- if (!isNonWifiPlay) {
- val isWifiConnected = NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
- if (isWifiConnected) {
+ val videoOption = SPUtils.getString(Constants.SP_HOME_OR_DETAIL_VIDEO_OPTION, VideoSettingFragment.VIDEO_OPTION_WIFI)
+ ?: VideoSettingFragment.VIDEO_OPTION_WIFI
+
+ when (videoOption) {
+ VideoSettingFragment.VIDEO_OPTION_ALL -> {
startPlayLogic(gsyBaseVideoPlayer, topVideo)
}
- } else {
- startPlayLogic(gsyBaseVideoPlayer, topVideo)
+
+ VideoSettingFragment.VIDEO_OPTION_WIFI -> {
+ if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
+ startPlayLogic(gsyBaseVideoPlayer, topVideo)
+ }
+ }
+
+ else -> {}
}
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java b/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java
index 5383f38001..449e796f1f 100644
--- a/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java
+++ b/app/src/main/java/com/gh/gamecenter/message/MessageItemViewHolder.java
@@ -34,6 +34,7 @@ import com.gh.gamecenter.qa.comment.CommentActivity;
import com.gh.gamecenter.qa.entity.Questions;
import com.gh.gamecenter.qa.follow.AskFollowMoreDialog;
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity;
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity;
import com.gh.gamecenter.retrofit.Response;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel;
@@ -527,7 +528,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder
case "invited":
if (view.getId() == R.id.message_original || view.getId() == R.id.message_item) {
MessageEntity.Question question = entity.getQuestion();
- context.startActivity(QuestionsDetailActivity.getIntent(context, question.getId(), entrance, path));
+ context.startActivity(NewQuestionDetailActivity.getIntent(context, question.getId(), entrance, path));
Questions questions = new Questions();
questions.setId(question.getId());
@@ -539,7 +540,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder
case "follow_question":
if (view.getId() == R.id.message_original) {
MessageEntity.Question question = entity.getQuestion();
- context.startActivity(QuestionsDetailActivity.getIntent(context, question.getId(), entrance, path));
+ context.startActivity(NewQuestionDetailActivity.getIntent(context, question.getId(), entrance, path));
Questions questions = new Questions();
questions.setId(question.getId());
@@ -579,13 +580,13 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder
case "community_article_comment_vote":
community = new CommunityEntity(entity.getArticle().getCommunityId(), "");
if (view.getId() == R.id.message_original || view.getId() == R.id.message_item) {
- context.startActivity(CommentActivity.getArticleDetailCommentIntent(context, entity.getComment().getId(), community.getId(), entity.getArticle().getId(), false, 1, entrance, path));
+ context.startActivity(CommentActivity.getCommentDetailIntent(context, entity.getComment().getId(), community.getId(), entity.getArticle().getId(), "", "",false, 1, entrance, path));
}
break;
case "community_article_comment_reply_vote":
community = new CommunityEntity(entity.getArticle().getCommunityId(), "");
if (view.getId() == R.id.message_original || view.getId() == R.id.message_item) {
- context.startActivity(CommentActivity.getArticleDetailCommentIntent(context, entity.getComment().getTopId(), community.getId(), entity.getArticle().getId(), false, 1, entrance, path));
+ context.startActivity(CommentActivity.getCommentDetailIntent(context, entity.getComment().getTopId(), community.getId(), entity.getArticle().getId(), "", "",false, 1, entrance, path));
}
break;
case "community_article_comment":
@@ -604,7 +605,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder
break;
case "reply_community_article_comment":
if (view.getId() == R.id.message_original || view.getId() == R.id.message_item) {
- context.startActivity(CommentActivity.getArticleDetailCommentIntent(context, entity.getDialogue().getTo().getTopId(), entity.getArticle().getCommunityId(), entity.getArticle().getId(), false, 1, entrance, path));
+ context.startActivity(CommentActivity.getCommentDetailIntent(context, entity.getDialogue().getTo().getTopId(), entity.getArticle().getCommunityId(), entity.getArticle().getId(), "", "",false, 1, entrance, path));
}
break;
case "game_comment_vote":
diff --git a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameFragment.kt b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameFragment.kt
index 96df1f5f60..7f4ae25c1d 100644
--- a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameFragment.kt
@@ -59,7 +59,7 @@ open class PlayedGameFragment : ListFragment()
override fun provideListViewModel(): PlayedGameViewModel {
val userId = arguments?.getString(EntranceUtils.KEY_USER_ID)
?: UserManager.getInstance().userId
- mViewModel = viewModelProvider(PlayedGameViewModel.Factory(HaloApp.getInstance().application, userId))
+ mViewModel = viewModelProvider(PlayedGameViewModel.Factory(userId))
return mViewModel
}
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 f01329c6a8..02bf110a82 100644
--- a/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/mygame/PlayedGameViewModel.kt
@@ -8,6 +8,7 @@ import com.gh.gamecenter.baselist.ListViewModel
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.Single
@@ -56,10 +57,9 @@ class PlayedGameViewModel(application: Application, var userId: String)
})
}
- class Factory(private val mApplication: Application,
- private val mUserId: String) : ViewModelProvider.NewInstanceFactory() {
+ class Factory(private val mUserId: String) : ViewModelProvider.NewInstanceFactory() {
override fun create(modelClass: Class): T {
- return PlayedGameViewModel(mApplication, mUserId) as T
+ return PlayedGameViewModel(HaloApp.getInstance().application, mUserId) as T
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt
index fd96233d32..9f61e07cd8 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/PersonalItemViewHolder.kt
@@ -2,31 +2,31 @@ package com.gh.gamecenter.personalhome
import android.view.View
import com.gh.common.util.MtaHelper
-import com.gh.gamecenter.databinding.PersonalHomeItemBinding
+import com.gh.gamecenter.databinding.UserHistoryItemBinding
import com.gh.gamecenter.entity.PersonalHistoryEntity
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.qa.answer.BaseAnswerOrArticleItemViewHolder
-import com.gh.gamecenter.qa.questions.CommunityQuestionViewHolder
-class PersonalItemViewHolder(val binding: PersonalHomeItemBinding) : BaseAnswerOrArticleItemViewHolder(binding.root) {
+class PersonalItemViewHolder(val binding: UserHistoryItemBinding) : BaseAnswerOrArticleItemViewHolder(binding.root) {
fun bindPersonalItem(entity: PersonalHistoryEntity, entrance: String) {
commentCountContainer.isClickable = true
- if (entity.type.contains("question")) {
- voteCountContainer.visibility = View.GONE
- CommunityQuestionViewHolder.bindAnswerCount(
- entity.transformQuestionEntity(),
- commentCountContainer,
- commentCount,
- entrance)
- } else {
+// if (entity.type.contains("question")) {
+// voteCountContainer.visibility = View.GONE
+// CommunityQuestionViewHolder.bindAnswerCount(
+// entity.transformQuestionEntity(),
+// commentCountContainer,
+// commentCount,
+// entrance)
+// } else {
voteCountContainer.visibility = View.VISIBLE
bindCommendAndVote(entity.transformAnswerEntity(), entrance)
- }
+// }
- forumNameTv.setOnClickListener {
- MtaHelper.onEvent(getEventId(entrance), getKey(entrance), entity.community.name)
- itemView.context.startActivity(ForumDetailActivity.getIntent(itemView.context, entity.community.id, entrance))
- }
+ forumNameLl?.visibility = View.GONE
+// forumNameContainer?.setOnClickListener {
+// MtaHelper.onEvent(getEventId(entrance), getKey(entrance), entity.community.name)
+// itemView.context.startActivity(ForumDetailActivity.getIntent(itemView.context, entity.community.id, entrance))
+// }
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt
index acd0c6b4ba..05ca0e8a3e 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt
@@ -15,19 +15,15 @@ import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
-import androidx.recyclerview.widget.LinearLayoutManager
import butterknife.OnClick
import com.gh.base.adapter.FragmentAdapter
import com.gh.base.fragment.BaseFragment_TabLayout
import com.gh.common.constant.Constants
import com.gh.common.util.*
import com.gh.common.util.DirectUtils.directToBadgeWall
-import com.gh.common.view.HorizontalItemDecoration
-import com.gh.download.DownloadManager
import com.gh.gamecenter.*
import com.gh.gamecenter.databinding.FragmentHomeBinding
import com.gh.gamecenter.entity.*
-import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.message.MessageUnreadViewModel
import com.gh.gamecenter.normal.NormalFragment
@@ -35,10 +31,8 @@ import com.gh.gamecenter.personalhome.background.PersonalityBackgroundActivity
import com.gh.gamecenter.personalhome.border.AvatarBorderActivity
import com.gh.gamecenter.personalhome.fans.FansActivity
import com.gh.gamecenter.personalhome.followers.FollowersActivity
-import com.gh.gamecenter.personalhome.home.UserCommentHistoryFragment
-import com.gh.gamecenter.personalhome.home.UserHistoryFragment
-import com.gh.gamecenter.personalhome.home.UserHistoryViewModel
-import com.gh.gamecenter.personalhome.home.UserVideoHistoryFragment
+import com.gh.gamecenter.personalhome.home.*
+import com.gh.gamecenter.personalhome.home.game.UserGameFragment
import com.gh.gamecenter.user.UserViewModel
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener
@@ -86,7 +80,6 @@ class UserHomeFragment : NormalFragment() {
mUserHomeViewModel.run {
getUserInfo()
getBadgeList()
- getUserPlayedGame()
getUserPlayedGameCount()
if (BuildConfig.DEBUG || BuildConfig.BUILD_TIME != 0L) {
getUserLevel()
@@ -189,40 +182,11 @@ class UserHomeFragment : NormalFragment() {
reuse_no_connection.visibility = View.VISIBLE
reuse_no_connection.setOnClickListener {
mUserHomeViewModel.getUserInfo()
- mUserHomeViewModel.getUserPlayedGame()
mUserHomeViewModel.getUserPlayedGameCount()
}
toast("网络异常")
}
- mUserHomeViewModel.playedGames.observe(this, Observer {
- if (!it.isNullOrEmpty()) {
- mPlayGameCount = it.size
- changeLayoutForPlayedGameVisible(true)
- showPlayedGames(it)
- } else {
- changeLayoutForPlayedGameVisible(false)
- }
- val installedList = PackagesManager.filterSameApk(PackagesManager.filterDownloadBlackPackage(PackagesManager.getInstalledList()))
- val simulatorDownloadEntityList = DownloadManager.getInstance(requireContext()).allSimulatorDownloadEntity
- simulatorDownloadEntityList.forEach { entity ->
- installedList.add(GameInstall(entity.gameId, packageName = entity.packageName, name = entity.name, icon = entity.icon))
- }
- //val count = SPUtils.getInt(Constants.SP_MARK_INSTALLED_GAME, 0)
- val isCancel = SPUtils.getBoolean(Constants.SP_MARK_INSTALLED_GAME_USER_HOME, false)
- if (mUserHomeViewModel.userId == UserManager.getInstance().userId
- && !isCancel
- && it.isNullOrEmpty()
- && installedList.isNotEmpty()) {
- mDialog = InstalledGameDialog(requireContext(), installedList, "个人主页详情", "标记玩过弹窗")
- mDialog.show()
- mDialog.onConfirmClickListener = {
- mUserHomeViewModel.getUserPlayedGame()
- mUserHomeViewModel.getUserPlayedGameCount()
- }
- }
- })
-
// 记录玩过的游戏总数
mUserHomeViewModel.playGamesCount.observe(this, Observer {
mPlayGameCount = it
@@ -266,60 +230,30 @@ class UserHomeFragment : NormalFragment() {
}
}
- private fun changeLayoutForPlayedGameVisible(isVisible: Boolean) {
+ private fun changeLayoutForContent() {
mHomeBinding?.run {
- if (isVisible) {
- playedGameEmptyVIew.visibility = View.GONE
+ val set = ConstraintSet()
+ set.run {
+ clone(contentContainer)
+ clear(R.id.user_icon, ConstraintSet.BOTTOM)
+ connect(R.id.user_icon, ConstraintSet.TOP, R.id.statusBarView, ConstraintSet.BOTTOM, 50F.dip2px())
+ applyTo(contentContainer)
+ }
- val set = ConstraintSet()
- set.run {
+ userCountContainer.post {
+ val newHeight = userCountContainer.bottom + (32F + 16F).dip2px()
+ userBackgroundContainer.layoutParams = userBackgroundContainer.layoutParams.apply {
+ height = newHeight
+ }
+
+ val newSet = ConstraintSet()
+ newSet.run {
clone(contentContainer)
- clear(R.id.user_icon, ConstraintSet.BOTTOM)
- connect(R.id.user_icon, ConstraintSet.TOP, R.id.statusBarView, ConstraintSet.BOTTOM, 50F.dip2px())
+ clear(R.id.user_icon, ConstraintSet.TOP)
+ val marginBottom = newHeight - DisplayUtils.getStatusBarHeight(resources) - 50F.dip2px() - 96F.dip2px()
+ connect(R.id.user_icon, ConstraintSet.BOTTOM, R.id.user_background_container, ConstraintSet.BOTTOM, marginBottom)
applyTo(contentContainer)
}
-
- playedGameContainer.post {
- val newHeight = playedGameContainer.bottom
- userBackgroundContainer.layoutParams = userBackgroundContainer.layoutParams.apply {
- height = newHeight
- }
-
- val newSet = ConstraintSet()
- newSet.run {
- clone(contentContainer)
- clear(R.id.user_icon, ConstraintSet.TOP)
- val marginBottom = newHeight - DisplayUtils.getStatusBarHeight(resources) - 50F.dip2px() - 96F.dip2px()
- connect(R.id.user_icon, ConstraintSet.BOTTOM, R.id.user_background_container, ConstraintSet.BOTTOM, marginBottom)
- applyTo(contentContainer)
- }
- }
- } else {
- playedGameEmptyVIew.visibility = View.VISIBLE
-
- val set = ConstraintSet()
- set.run {
- clone(contentContainer)
- clear(R.id.user_icon, ConstraintSet.BOTTOM)
- connect(R.id.user_icon, ConstraintSet.TOP, R.id.statusBarView, ConstraintSet.BOTTOM, 50F.dip2px())
- applyTo(contentContainer)
- }
-
- userCountContainer.post {
- val newHeight = userCountContainer.bottom + (32F + 16F).dip2px()
- userBackgroundContainer.layoutParams = userBackgroundContainer.layoutParams.apply {
- height = newHeight
- }
-
- val newSet = ConstraintSet()
- newSet.run {
- clone(contentContainer)
- clear(R.id.user_icon, ConstraintSet.TOP)
- val marginBottom = newHeight - DisplayUtils.getStatusBarHeight(resources) - 50F.dip2px() - 96F.dip2px()
- connect(R.id.user_icon, ConstraintSet.BOTTOM, R.id.user_background_container, ConstraintSet.BOTTOM, marginBottom)
- applyTo(contentContainer)
- }
- }
}
}
}
@@ -360,23 +294,22 @@ class UserHomeFragment : NormalFragment() {
// 根据是否有内容选择页面显示
when {
count.gameComment > 0 -> 0
- count.getQaCount() > 0 -> 1
- count.video > 0 -> 2
+ count.getTotalCount() > 0 -> 1
+// count.video > 0 -> 2
else -> 0
}
}
val tag = "android:switcher:${mHomeBinding?.viewpager?.id}:"
- val commentFragment = childFragmentManager.findFragmentByTag("${tag}0")
- ?: UserCommentHistoryFragment.getInstance(mUserHomeViewModel.userId)
+ val gameFragment = childFragmentManager.findFragmentByTag("${tag}0")
+ ?: UserGameFragment.getInstance(mUserHomeViewModel.userId, count.gameComment)
val qaFragment = childFragmentManager.findFragmentByTag("${tag}1")
?: UserHistoryFragment.getInstance(mUserHomeViewModel.userId, UserHistoryViewModel.SCENE.QUESTION_ANSWER, count)
- val videoFragment = childFragmentManager.findFragmentByTag("${tag}2")
- ?: UserVideoHistoryFragment.getInstance(mUserHomeViewModel.userId, count)
+// val videoFragment = childFragmentManager.findFragmentByTag("${tag}2")
+// ?: UserVideoHistoryFragment.getInstance(mUserHomeViewModel.userId, count)
- val fragmentList = listOf(commentFragment, qaFragment, videoFragment)
- val titleList = listOf("游戏评论", "论坛", "视频")
- val countList = listOf(count.gameComment, count.getQaCount(), count.video)
+ val fragmentList = listOf(gameFragment, qaFragment)
+ val titleList = listOf("游戏", "发布")
viewpager.offscreenPageLimit = fragmentList.size
viewpager.adapter = FragmentAdapter(childFragmentManager, fragmentList, titleList)
@@ -388,40 +321,21 @@ class UserHomeFragment : NormalFragment() {
for (i in 0 until tabLayout.tabCount) {
val tab = tabLayout.getTabAt(i) ?: continue
- val tabView = getTabView(titleList[i], countList[i])
+ val tabView = getTabView(titleList[i])
tab.customView = tabView
}
BaseFragment_TabLayout.initTabStyle(tabLayout, viewpager.currentItem)
}
- private fun getTabView(title: String, count: Int): View {
+ private fun getTabView(title: String): View {
val view = LayoutInflater.from(HaloApp.getInstance().application.baseContext).inflate(R.layout.tab_item_user_home, null)
val tabTitle = view.findViewById(R.id.tab_title)
- val tabCount = view.findViewById(R.id.tab_count)
if (tabTitle is CheckedTextView) {
tabTitle.text = title
}
- tabCount.text = if (count == 0) "" else count.toString()
return view
}
- private fun showPlayedGames(playedGames: List) {
- checkMoreTv.goneIf(playedGames.size <= 3)
- checkMoreTv.setOnClickListener {
- MtaHelper.onEvent("个人主页详情", "个人主页详情", "查看更多")
- DirectUtils.directToPlayedGame(checkMoreTv.context, mUserHomeViewModel.userId, mEntrance, mPath)
- }
-
- val adapter = UserHomePlayedGameAdapter(playedGames)
-
- playedGameContainer.visibility = View.VISIBLE
- playedGameRecyclerView.adapter = adapter
- playedGameRecyclerView.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
- playedGameRecyclerView.addItemDecoration(HorizontalItemDecoration(requireContext(), 16, playedGames.size, true))
-
- adapter.notifyDataSetChanged()
- }
-
private fun trackMtaEvent(name: String? = "") {
MtaHelper.onEvent("个人主页", mPath, StringUtils.combineTwoString(name, mUserHomeViewModel.userId))
MtaHelper.onEvent("个人主页", "不区分位置", StringUtils.combineTwoString(name, mUserHomeViewModel.userId))
@@ -440,7 +354,7 @@ class UserHomeFragment : NormalFragment() {
entity = personalData
executePendingBindings()
- changeLayoutForPlayedGameVisible(playedGameContainer.visibility == View.VISIBLE)
+ changeLayoutForContent()
// personalData.auth?.let {
// userAuthCommand.text = it.text
// userAuthCommand.setTextColor(Color.parseColor("#" + it.color))
@@ -479,6 +393,7 @@ class UserHomeFragment : NormalFragment() {
if (mUserHomeViewModel.userId != UserManager.getInstance().userId) {
ivMore.visibility = View.VISIBLE
ivShare.visibility = View.GONE
+ changeBgTips.visibility = View.GONE
userFansCountHint.visibility = View.GONE
if (personalData.me.isFollower) {
userConcernedBtn.visibility = View.VISIBLE
@@ -497,11 +412,27 @@ class UserHomeFragment : NormalFragment() {
DirectUtils.directToHomeActivity(requireContext(), personalData.lastVisitor?.id, "个人主页-最近来访")
}
+ // 默认显示悬浮窗,点击图标进入更换背景页,悬浮窗消失
+ // 若未点击图标,当天内不再显示,第2天后进入继续显示悬浮窗
+ changeBgTips.visibility = when {
+ SPUtils.getBoolean(Constants.SP_HAS_CLICK_CHANGE_BG) -> View.GONE
+
+ SPUtils.getBoolean(Constants.SP_SHOW_CHANGE_BG_TIPS, true) -> {
+ SPUtils.setBoolean(Constants.SP_SHOW_CHANGE_BG_TIPS, false)
+ View.VISIBLE
+ }
+
+ else -> View.GONE
+ }
+
// 跳转更换背景页
userChangeBgBtn.setOnClickListener {
IntegralLogHelper.log("click_change _background", LOCATION)
+ SPUtils.setBoolean(Constants.SP_HAS_CLICK_CHANGE_BG, false)
+ changeBgTips.visibility = View.GONE
startActivity(PersonalityBackgroundActivity.getIntent(requireContext()))
}
+ changeBgTips.setOnClickListener { userChangeBgBtn.performClick() }
// 个性签名
userIntroduce.setOnClickListener {
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt
index 84074bb0ef..1e070fa220 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeViewModel.kt
@@ -30,7 +30,6 @@ class UserHomeViewModel(application: Application, var userId: String) : AndroidV
var userInfo = MutableLiveData()
var networkError = MutableLiveData()
- var playedGames = MutableLiveData>()
var badges = MutableLiveData>()
var availableBadge = MutableLiveData()
var availableBadgeCount = MutableLiveData()
@@ -64,34 +63,6 @@ class UserHomeViewModel(application: Application, var userId: String) : AndroidV
followingCommand(false)
}
- @SuppressLint("CheckResult")
- fun getUserPlayedGame() {
- RetrofitManager.getInstance(getApplication())
- .api.getPlayedGames(userId, 1, Utils.getTime(getApplication()))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : BiResponse>() {
- override fun onSuccess(data: List) {
- for (game in data) {
- if (game.name!!.length > 6) {
- game.name = game.name!!.substring(0, 6) + "..."
- game.nameSuffix = ""
- }
- }
-
- if (data.isNotEmpty()) {
- playedGames.postValue(data.take(10))
- } else {
- playedGames.postValue(null)
- }
- }
-
- override fun onFailure(exception: Exception) {
- super.onFailure(exception)
- playedGames.postValue(null)
- }
- })
- }
@SuppressLint("CheckResult")
fun getUserPlayedGameCount() {
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/HorizontalExcellentCommentsAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/HorizontalExcellentCommentsAdapter.kt
deleted file mode 100644
index a6b08cb1f3..0000000000
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/HorizontalExcellentCommentsAdapter.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.gh.gamecenter.personalhome.home
-
-import android.content.Context
-import android.view.ViewGroup
-import com.gh.common.util.*
-import com.gh.gamecenter.R
-import com.gh.gamecenter.adapter.viewholder.UserHomeAmwayItemViewHolder
-import com.gh.gamecenter.databinding.UserHomeAmwayItemBinding
-import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
-import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
-import com.gh.gamecenter.personalhome.rating.MyRating
-import com.lightgame.adapter.BaseRecyclerAdapter
-import java.util.regex.Pattern
-
-class HorizontalExcellentCommentsAdapter(context: Context,
- var dataList: List) : BaseRecyclerAdapter(context) {
-
- var mMaxWidth = context.resources.displayMetrics.widthPixels
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserHomeAmwayItemViewHolder {
- val view = mLayoutInflater.inflate(R.layout.user_home_amway_item, parent, false)
- return UserHomeAmwayItemViewHolder(UserHomeAmwayItemBinding.bind(view))
- }
-
- override fun onBindViewHolder(holder: UserHomeAmwayItemViewHolder, position: Int) {
- holder.binding.run {
- data = dataList[position]
- var rating = dataList[position]
-
- root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
- leftMargin = if (position == 0) 16F.dip2px() else 12F.dip2px()
- rightMargin = if (position == itemCount - 1) 16F.dip2px() else 0
- }
-
- holder.itemView.layoutParams?.width = if (position == itemCount - 1) {
- if (itemCount == 1) mMaxWidth - 32F.dip2px() else mMaxWidth - 16F.dip2px()
- } else mMaxWidth - 60F.dip2px()
-
- gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript)
-
- val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content)
- if (m.find()) {
- val contents = TextHelper.getCommentLabelSpannableStringBuilder(rating.content, R.color.theme_font)
- content.text = contents
- } else {
- content.text = rating.content
- }
-
- commentBackground.setOnClickListener {
- DirectUtils.directToGameDetail(mContext, rating.game.id, "个人主页-优秀评论")
- }
-
- ratingBlock.setOnClickListener {
- val intent = RatingReplyActivity.getIntent(mContext, rating.game.id, rating.id, false, "个人主页-优秀评论", "")
-
- SyncDataBetweenPageHelper.startActivityForResult(mContext, intent, 100, position)
- }
- }
- }
-
- override fun getItemCount() = dataList.size
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryItemData.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryItemData.kt
deleted file mode 100644
index 298308a6d9..0000000000
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryItemData.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.gh.gamecenter.personalhome.home
-
-import com.gh.gamecenter.personalhome.rating.MyRating
-
-data class UserCommentHistoryItemData(var excellentComments: List? = null,
- var title: String? = null,
- var normalComment: MyRating? = null)
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryAdapter.kt
index 9eadff210e..08486ac404 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryAdapter.kt
@@ -1,5 +1,6 @@
package com.gh.gamecenter.personalhome.home
+import android.app.Activity
import android.content.Context
import android.text.SpannableStringBuilder
import android.util.SparseBooleanArray
@@ -13,18 +14,23 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.adapter.viewholder.PersonalHomeRatingViewHolder
import com.gh.gamecenter.baselist.ListAdapter
-import com.gh.gamecenter.databinding.PersonalHomeItemBinding
import com.gh.gamecenter.databinding.PersonalHomeRatingBinding
+import com.gh.gamecenter.databinding.UserHistoryItemBinding
+import com.gh.gamecenter.entity.ForumVideoEntity
import com.gh.gamecenter.entity.PersonalHistoryEntity
+import com.gh.gamecenter.forum.home.ArticleItemVideoView
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
import com.gh.gamecenter.personalhome.PersonalItemViewHolder
import com.gh.gamecenter.qa.entity.AnswerEntity
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import com.shuyu.gsyvideoplayer.utils.OrientationUtils
import java.util.regex.Pattern
class UserHistoryAdapter(context: Context,
private val mListViewModel: UserHistoryViewModel,
private val mEntrance: String,
- val itemClickCallback: (historyEntity: PersonalHistoryEntity, position: Int) -> Unit)
+ private val itemClickCallback: (historyEntity: PersonalHistoryEntity, position: Int) -> Unit)
: ListAdapter(context) {
private var mExpandSparseBooleanArray = SparseBooleanArray()
@@ -49,8 +55,8 @@ class UserHistoryAdapter(context: Context,
PersonalHomeRatingViewHolder(PersonalHomeRatingBinding.bind(view))
}
else -> {
- view = mLayoutInflater.inflate(R.layout.personal_home_item, parent, false)
- PersonalItemViewHolder(PersonalHomeItemBinding.bind(view))
+ view = mLayoutInflater.inflate(R.layout.user_history_item, parent, false)
+ PersonalItemViewHolder(UserHistoryItemBinding.bind(view))
}
}
}
@@ -80,11 +86,16 @@ class UserHistoryAdapter(context: Context,
answer.communityId = historyEntity.community.id
answer.communityName = historyEntity.community.name
holder.binding.imageContainer.bindData(answer, mEntrance)
+ if (historyEntity.type == "video") {
+ bindVideoData(holder.binding, historyEntity.transformForumVideoEntity())
+ } else {
+ bindArticleVideoData(holder.binding, historyEntity)
+ }
holder.binding.run {
entity = historyEntity
- userName.visibility = View.GONE
- forumNameTv.text = entity?.community?.name
+// userName.visibility = View.GONE
+ topLine.goneIf(position == 0)
userIcon.display(historyEntity.user?.border, historyEntity.user?.icon, historyEntity.user?.auth?.icon)
executePendingBindings()
@@ -96,13 +107,22 @@ class UserHistoryAdapter(context: Context,
.append(videoSpan)
}
- val command = getUserCommand(historyEntity.type, historyEntity.time, historyEntity.isEdit)
- userCommand.text = if (command.isNotEmpty()) command else historyEntity?.user?.name + ""
+ userCommand.text = getUserCommand(historyEntity.type, historyEntity.isEdit)
questionTitle.setOnClickListener {
holder.itemView.performClick()
}
+ historyEntity.user?.run {
+ userBadgeName.setOnClickListener { userBadgeIcon.performClick() }
+ userBadgeIcon.setOnClickListener {
+ DialogUtils.showViewBadgeDialog(mContext, badge) {
+ DirectUtils.directToBadgeWall(mContext, id, name, icon)
+ }
+ }
+ }
+
+
// 禁止click事件穿透
userIcon.setOnClickListener {}
userCommand.setOnClickListener {}
@@ -112,6 +132,131 @@ class UserHistoryAdapter(context: Context,
}
}
+ private fun bindVideoData(binding: UserHistoryItemBinding, entity: ForumVideoEntity) {
+ binding.run {
+ if (entity.url.isEmpty()) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.GONE
+ } else {
+ val videoInfo = entity.videoInfo
+ val visibleView = if (videoInfo.height > videoInfo.width) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.VISIBLE
+ verticalVideoView
+ } else {
+ horizontalVideoView.visibility = View.VISIBLE
+ verticalVideoView.visibility = View.GONE
+ horizontalVideoView
+ }
+
+ val orientationUtils = OrientationUtils(mContext as Activity, visibleView)
+ orientationUtils.isEnable = false
+ GSYVideoOptionBuilder()
+ .setIsTouchWiget(false)
+ .setUrl(entity.url)
+ .setRotateViewAuto(false)
+ .setCacheWithPlay(true)
+ .setRotateWithSystem(false)
+ .setReleaseWhenLossAudio(true)
+ .setLooping(false)
+ .setShowFullAnimation(false)
+ .setEnlargeImageRes(R.drawable.ic_game_detail_enter_full_screen)
+ .setShrinkImageRes(R.drawable.ic_game_detail_exit_full_screen)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onQuitFullscreen(url: String?, vararg objects: Any) {
+ orientationUtils.backToProtVideo()
+ visibleView.uploadVideoStreamingPlaying("退出全屏")
+ }
+ })
+ .build(visibleView)
+ visibleView.run {
+ updateVideoData(entity)
+ updateThumb(entity.poster)
+ updateDurationTv(TimeUtils.formatDuration(entity.length))
+
+ fullscreenButton.setOnClickListener {
+ val horizontalVideoView = startWindowFullscreen(mContext, true, true) as? ArticleItemVideoView
+ if (horizontalVideoView == null) {
+ toastInInternalRelease("全屏失败,请向技术人员提供具体的操作步骤")
+ return@setOnClickListener
+ }
+ orientationUtils.resolveByClick()
+ horizontalVideoView.uuid = uuid
+ horizontalVideoView.updateVideoData(entity)
+ horizontalVideoView.updateThumb(entity.poster)
+ horizontalVideoView.violenceUpdateMuteStatus()
+ horizontalVideoView.setFullViewStatus()
+ uploadVideoStreamingPlaying("开始播放")
+ uploadVideoStreamingPlaying("点击全屏")
+ }
+ }
+ }
+ }
+ }
+
+ private fun bindArticleVideoData(binding: UserHistoryItemBinding, entity: PersonalHistoryEntity) {
+ binding.run {
+ if (entity.getPassVideos().isNullOrEmpty()) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.GONE
+ } else {
+ val video = entity.getPassVideos()[0]
+ val visibleView = if (video.height > video.width) {
+ horizontalVideoView.visibility = View.GONE
+ verticalVideoView.visibility = View.VISIBLE
+ verticalVideoView
+ } else {
+ horizontalVideoView.visibility = View.VISIBLE
+ verticalVideoView.visibility = View.GONE
+ horizontalVideoView
+ }
+
+ val orientationUtils = OrientationUtils(mContext as Activity, visibleView)
+ orientationUtils.isEnable = false
+ GSYVideoOptionBuilder()
+ .setIsTouchWiget(false)
+ .setUrl(video.url)
+ .setRotateViewAuto(false)
+ .setCacheWithPlay(true)
+ .setRotateWithSystem(false)
+ .setReleaseWhenLossAudio(true)
+ .setLooping(false)
+ .setShowFullAnimation(false)
+ .setEnlargeImageRes(R.drawable.ic_game_detail_enter_full_screen)
+ .setShrinkImageRes(R.drawable.ic_game_detail_exit_full_screen)
+ .setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onQuitFullscreen(url: String?, vararg objects: Any) {
+ orientationUtils.backToProtVideo()
+ visibleView.uploadVideoStreamingPlaying("退出全屏")
+ }
+ })
+ .build(visibleView)
+ visibleView.run {
+ val forumVideoEntity = entity.transformForumVideoEntity()
+ updateVideoData(forumVideoEntity)
+ updateThumb(video.poster)
+ updateDurationTv(video.duration)
+
+ fullscreenButton.setOnClickListener {
+ val horizontalVideoView = startWindowFullscreen(mContext, true, true) as? ArticleItemVideoView
+ if (horizontalVideoView == null) {
+ toastInInternalRelease("全屏失败,请向技术人员提供具体的操作步骤")
+ return@setOnClickListener
+ }
+ orientationUtils.resolveByClick()
+ horizontalVideoView.uuid = uuid
+ horizontalVideoView.updateVideoData(forumVideoEntity)
+ horizontalVideoView.updateThumb(video.poster)
+ horizontalVideoView.violenceUpdateMuteStatus()
+ horizontalVideoView.setFullViewStatus()
+ uploadVideoStreamingPlaying("开始播放")
+ uploadVideoStreamingPlaying("点击全屏")
+ }
+ }
+ }
+ }
+ }
+
private fun bindRatingItem(holder: PersonalHomeRatingViewHolder, position: Int) {
val historyEntity = mEntityList[holder.adapterPosition]
holder.binding.entity = historyEntity
@@ -170,15 +315,15 @@ class UserHistoryAdapter(context: Context,
}
companion object {
- fun getUserCommand(type: String, time: Long, isEdit: Boolean = false): String {
+ fun getUserCommand(type: String, isEdit: Boolean = false): String {
return when (type) {
- "answer" -> NewsUtils.getFormattedTime(time) + if (isEdit) " 修改了回答" else " 发布了回答"
- "question" -> NewsUtils.getFormattedTime(time) + if (isEdit) " 修改了问题" else " 提交了问题"
- "answer_vote" -> NewsUtils.getFormattedTime(time) + " 赞同了回答"
- "follow_question" -> NewsUtils.getFormattedTime(time) + " 关注了问题"
- "community_article_vote" -> NewsUtils.getFormattedTime(time) + " 赞同了帖子"
- "community_article" -> NewsUtils.getFormattedTime(time) + if (isEdit) " 修改了帖子" else " 发布了帖子"
- "update-answer" -> NewsUtils.getFormattedTime(time) + " 更新了回答"
+ "answer" -> if (isEdit) "修改了回答" else "发布了回答"
+ "question" -> if (isEdit) "修改了问题" else "提交了问题"
+ "answer_vote" -> "赞同了回答"
+ "follow_question" -> "关注了问题"
+ "community_article_vote" -> "赞同了帖子"
+ "community_article" -> if (isEdit) "修改了帖子" else "发布了帖子"
+ "update-answer" -> "更新了回答"
else -> ""
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryFragment.kt
index 98967e7822..6ad503ba5a 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryFragment.kt
@@ -2,21 +2,16 @@ package com.gh.gamecenter.personalhome.home
import android.app.Activity
import android.content.Intent
-import android.graphics.Color
import android.os.Bundle
-import android.view.LayoutInflater
import android.view.View
-import android.widget.LinearLayout
import android.widget.TextView
-import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
-import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.*
-import com.gh.common.view.BugFixedPopupWindow
-import com.gh.common.view.VerticalItemDecoration
import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.databinding.FragmentUserPublishBinding
+import com.gh.gamecenter.entity.ForumVideoEntity
import com.gh.gamecenter.entity.PersonalEntity
import com.gh.gamecenter.entity.PersonalHistoryEntity
import com.gh.gamecenter.entity.RatingComment
@@ -26,9 +21,9 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
-import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
+import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
import com.halo.assistant.HaloApp
-import kotlinx.android.synthetic.main.fragment_user_history.*
class UserHistoryFragment : ListFragment() {
@@ -38,10 +33,12 @@ class UserHistoryFragment : ListFragment= childCount) return
+
+ for (i in 0 until childCount) {
+ val typeTv = getChildAt(i) as TextView
+ typeTv.run {
+ if (i == index) {
+ setBackgroundResource(R.drawable.button_round_f0f8ff)
+ setTextColor(R.color.theme_font.toColor())
+ } else {
+ setBackgroundResource(R.drawable.button_round_fafafa)
+ setTextColor(R.color.text_333333.toColor())
+ }
+ }
+ }
- updateFilterHintText()
- filter.background = ContextCompat.getDrawable(requireContext(), R.color.white)
- filterContainer.visibleIf(mScene == UserHistoryViewModel.SCENE.QUESTION_ANSWER)
- filterContainer.setOnClickListener {
- showFilterWindow()
- MtaHelper.onEvent("个人主页详情", "个人主页详情", "问答筛选")
}
}
@@ -80,11 +135,14 @@ class UserHistoryFragment : ListFragment "全部内容(${mCount.getQaCount()})"
- UserHistoryViewModel.TYPE.QUESTION -> "提问(${mCount.question})"
- UserHistoryViewModel.TYPE.ANSWER -> "回答(${mCount.answer})"
- UserHistoryViewModel.TYPE.COMMUNITY_ARTICLE -> "帖子(${mCount.communityArticle})"
- }
- }
- }
-
- private fun showFilterWindow() {
- val contentList = UserHistoryViewModel.TYPE.TYPE_LIST
-
- val inflater = LayoutInflater.from(requireContext())
- val layout = inflater.inflate(R.layout.layout_popup_container, null)
- val popupWindow = BugFixedPopupWindow(
- layout,
- LinearLayout.LayoutParams.WRAP_CONTENT,
- LinearLayout.LayoutParams.WRAP_CONTENT
- )
-
- val container = layout.findViewById(R.id.container)
- for (text in contentList) {
- val item = inflater.inflate(R.layout.layout_popup_option_item, container, false)
-
- container.addView(item)
-
- val hintTv = item.findViewById(R.id.hint_text)
- hintTv.text = text
-
- if (mViewModel.type.getDisplayText() == text) {
- hintTv.setTextColor(Color.parseColor("#1383EB"))
- }
-
- item.setOnClickListener {
- MtaHelper.onEvent("个人主页详情", "个人主页详情", "问答-${text}")
- forumFilter.text = text
- mViewModel.changeType(UserHistoryViewModel.TYPE.typeFromDisplayText(text))
- popupWindow.dismiss()
- }
- }
-
- popupWindow.setOnDismissListener {
- filterArrow.rotation = 0f
- }
-
- popupWindow.isTouchable = true
- popupWindow.isFocusable = true
-
- filterArrow.rotation = 180f
- popupWindow.showAutoOrientation(filterContainer, DisplayUtils.dip2px(16f))
- }
-
- override fun onLoadDone() {
- super.onLoadDone()
-
- updateFilterHintText()
- filter.visibility = View.VISIBLE
- }
+ override fun getItemDecoration() = null
override fun onLoadEmpty() {
super.onLoadEmpty()
@@ -168,10 +161,9 @@ class UserHistoryFragment : ListFragment filter.visibility = View.GONE
+ UserHistoryViewModel.TYPE.ALL -> mBinding?.typeScrollView?.visibility = View.GONE
else -> {
- filter.visibility = View.VISIBLE
- updateFilterHintText()
+ mBinding?.typeScrollView?.visibility = View.VISIBLE
}
}
}
@@ -203,35 +195,37 @@ class UserHistoryFragment : ListFragment {
val resultData = data.getParcelableExtra(ArticleDetailEntity::class.java.simpleName)
historyEntity?.apply {
- if (title != resultData?.title || brief != HtmlUtils.stripHtmlCode(resultData.content)) {
- onLoadRefresh()
- return
- }
- count.vote = resultData.count.vote
- count.comment = resultData.count.comment
- me.isCommunityArticleVote = resultData.me.isCommunityArticleVote
+ count.vote = resultData?.count?.vote ?: 0
+ count.comment = resultData?.count?.comment ?: 0
+ title = resultData?.title ?: ""
+ brief = HtmlUtils.stripHtmlCode(resultData?.content ?: "")
+ me.isCommunityArticleVote = resultData?.me?.isCommunityArticleVote ?: false
}
}
102 -> {
val resultData = data.getParcelableExtra(AnswerDetailEntity::class.java.simpleName)
historyEntity?.apply {
- if (brief != HtmlUtils.stripHtmlCode(resultData?.content ?: "")) {
- onLoadRefresh()
- return
- }
count.vote = resultData?.vote ?: 0
count.comment = resultData?.commentCount ?: 0
+ brief = HtmlUtils.stripHtmlCode(resultData?.content ?: "")
question.title = resultData?.question?.title ?: ""
}
}
103 -> {
val resultData = data.getParcelableExtra(QuestionsDetailEntity::class.java.simpleName)
historyEntity?.apply {
- if (title != resultData?.title ?: "" || description != resultData?.description ?: "") {
- onLoadRefresh()
- return
- }
- count.answer = resultData?.answersCount ?: 0
+ title = resultData?.title ?: ""
+ count.answer = resultData?.count?.answer ?: count.answer
+ }
+ }
+ 104 -> {
+ val resultData = data.getParcelableExtra(ForumVideoEntity::class.java.simpleName)
+ historyEntity?.apply {
+ count.vote = resultData?.count?.vote ?: 0
+ count.comment = resultData?.count?.comment ?: 0
+ des = HtmlUtils.stripHtmlCode(resultData?.des ?: "")
+ title = resultData?.title ?: ""
+ me.isVoted = resultData?.me?.isVoted ?: false
}
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryViewModel.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryViewModel.kt
index 243d951da1..2e2096c239 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/UserHistoryViewModel.kt
@@ -23,13 +23,8 @@ class UserHistoryViewModel(application: Application, var userId: String, private
private val mApi = RetrofitManager.getInstance(getApplication()).api
-
var type: TYPE = TYPE.ALL
- init {
- setOverLimitSize(1)
- }
-
override fun provideDataObservable(page: Int): Observable> {
return mApi.getPersonalHistory(userId, page,
HaloApp.getInstance().channel, getFilter())
@@ -112,13 +107,15 @@ class UserHistoryViewModel(application: Application, var userId: String, private
ALL("all"),
COMMUNITY_ARTICLE("community_article"),
QUESTION("question"),
- ANSWER("answer");
+ ANSWER("answer"),
+ VIDEO("video");
fun getDisplayText() = when (this) {
ALL -> "全部"
QUESTION -> "提问"
ANSWER -> "回答"
COMMUNITY_ARTICLE -> "帖子"
+ VIDEO -> "视频"
}
companion object {
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryAdapter.kt
similarity index 92%
rename from app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryAdapter.kt
rename to app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryAdapter.kt
index 45d48f518f..4fb0aa94a0 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryAdapter.kt
@@ -1,4 +1,4 @@
-package com.gh.gamecenter.personalhome.home
+package com.gh.gamecenter.personalhome.home.game
import android.content.Context
import android.util.SparseBooleanArray
@@ -51,8 +51,10 @@ class UserCommentHistoryAdapter(context: Context,
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is UserCommentHistoryItemViewHolder -> {
- var padTop = if (position == 0) 0F.dip2px() else 16F.dip2px()
- holder.binding.gameInfo.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 0)
+ val marginTop = if (position == 0) 8F.dip2px() else 16F.dip2px()
+ holder.binding.gameInfo.layoutParams = (holder.binding.gameInfo.layoutParams as ViewGroup.MarginLayoutParams).apply {
+ setMargins(0, marginTop, 0, 0)
+ }
var isChildLongClick = false
val rating = mEntityList[position]
@@ -60,6 +62,9 @@ class UserCommentHistoryAdapter(context: Context,
holder.binding.divider.visibility = if (position == 0) View.GONE else View.VISIBLE
+ holder.binding.runTimeTv.text = NumberUtils.transSimpleUsageTime(rating.game.playedTime)
+ holder.binding.date.text = TimeUtils.getFormatTime(rating.time, "")
+
val maxDesLines = if (mExpandSparseBooleanArray.get(holder.adapterPosition)) Int.MAX_VALUE else 3
holder.binding.tvComment.setExpandMaxLines(maxDesLines)
holder.binding.tvComment.setIsExpanded(Int.MAX_VALUE == maxDesLines)
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryFragment.kt
similarity index 55%
rename from app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryFragment.kt
rename to app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryFragment.kt
index a2f1d6ddc6..1dabf37cfb 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryFragment.kt
@@ -1,36 +1,30 @@
-package com.gh.gamecenter.personalhome.home
+package com.gh.gamecenter.personalhome.home.game
import android.os.Bundle
import android.view.View
-import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
-import butterknife.OnClick
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.baselist.ListFragment
-import com.gh.gamecenter.databinding.FragmentUserCommentHistoryBinding
+import com.gh.gamecenter.personalhome.home.UserHistoryFragment
+import com.gh.gamecenter.personalhome.rating.MyRating
import com.halo.assistant.HaloApp
-class UserCommentHistoryFragment : ListFragment() {
+class UserCommentHistoryFragment : ListFragment() {
private var mUserId: String = ""
private var mAdapter: UserCommentHistoryAdapter? = null
- private var mBinding: FragmentUserCommentHistoryBinding? = null
private lateinit var mViewModel: UserCommentHistoryViewModel
- override fun getLayoutId() = 0
-
- override fun getInflatedLayout() = FragmentUserCommentHistoryBinding.inflate(layoutInflater).apply { mBinding = this }.root
-
override fun onCreate(savedInstanceState: Bundle?) {
arguments?.apply {
mUserId = getString(USER_ID, "")
}
super.onCreate(savedInstanceState)
-
+ mListRv.overScrollMode = View.OVER_SCROLL_NEVER
}
override fun getItemDecoration() = null
@@ -54,10 +48,6 @@ class UserCommentHistoryFragment : ListFragment {
- mViewModel.changeType(UserCommentHistoryViewModel.TYPE.ALL)
- updateTypeBg(0)
- }
-
- R.id.excellentType -> {
- mViewModel.changeType(UserCommentHistoryViewModel.TYPE.JINGXUAN)
- updateTypeBg(1)
- }
-
- R.id.anliType -> {
- mViewModel.changeType(UserCommentHistoryViewModel.TYPE.ANLIWALL)
- updateTypeBg(2)
- }
- }
- }
-
- private fun updateTypeBg(index: Int) {
- mBinding?.run {
- for (i in 0 until typeContainer.childCount) {
- val sizeTv = typeContainer.getChildAt(i) as TextView
- if (i == index) {
- sizeTv.setTextColor(R.color.theme_font.toColor())
- sizeTv.setBackgroundResource(R.drawable.button_round_ebf5ff)
- } else {
- sizeTv.setTextColor(R.color.text_333333.toColor())
- sizeTv.setBackgroundResource(R.drawable.button_round_f5f5f5)
- }
- }
+ fun changeType(text: String) {
+ when (text) {
+ "全部" -> mViewModel.changeType(UserCommentHistoryViewModel.TYPE.ALL)
+ "精华" -> mViewModel.changeType(UserCommentHistoryViewModel.TYPE.JINGXUAN)
+ "安利墙" -> mViewModel.changeType(UserCommentHistoryViewModel.TYPE.ANLIWALL)
}
}
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryViewModel.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryViewModel.kt
similarity index 98%
rename from app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryViewModel.kt
rename to app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryViewModel.kt
index c28e3a3c21..e41de14e90 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/home/UserCommentHistoryViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserCommentHistoryViewModel.kt
@@ -1,4 +1,4 @@
-package com.gh.gamecenter.personalhome.home
+package com.gh.gamecenter.personalhome.home.game
import android.app.Application
import androidx.lifecycle.ViewModel
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserGameFragment.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserGameFragment.kt
new file mode 100644
index 0000000000..2d12705a54
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserGameFragment.kt
@@ -0,0 +1,169 @@
+package com.gh.gamecenter.personalhome.home.game
+
+import android.graphics.drawable.ColorDrawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.LinearLayout
+import android.widget.PopupWindow
+import android.widget.TextView
+import androidx.core.content.ContextCompat
+import androidx.core.os.bundleOf
+import com.gh.common.util.*
+import com.gh.common.util.EntranceUtils.KEY_COMMENT_COUNT
+import com.gh.common.util.EntranceUtils.KEY_USER_ID
+import com.gh.gamecenter.R
+import com.gh.gamecenter.databinding.FragmentUserGameBinding
+import com.gh.gamecenter.normal.NormalFragment
+
+class UserGameFragment: NormalFragment() {
+
+ private var mBinding: FragmentUserGameBinding? = null
+ private var mViewModel: UserGameViewModel? = null
+ private var mPlayedGameFragment: UserPlayedGameFragment? = null
+ private var mCommentFragment: UserCommentHistoryFragment? = null
+ private var mUserId: String = ""
+ private var mFilter: String = "全部"
+ private var mCommentCount = 0
+ private var mCurrentType = TYPE_PLAYED_GAME
+
+ override fun getLayoutId() = 0
+
+ override fun getInflatedLayout() = FragmentUserGameBinding.inflate(layoutInflater).apply { mBinding = this }.root
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mUserId = arguments?.getString(KEY_USER_ID, "") ?: ""
+ mCommentCount = arguments?.getInt(KEY_COMMENT_COUNT, 0) ?: 0
+ mViewModel = viewModelProvider(UserGameViewModel.Factory(mUserId))
+ changeType(TYPE_PLAYED_GAME)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ mViewModel?.playedGameCount?.observeNonNull(viewLifecycleOwner) {
+ mBinding?.gameType?.text = "玩过 $it"
+ }
+
+ mBinding?.run {
+ commentType.text = "评论 $mCommentCount"
+
+ gameType.setOnClickListener {
+ if (mCurrentType == TYPE_PLAYED_GAME) return@setOnClickListener
+ mCurrentType = TYPE_PLAYED_GAME
+ updateTypeView(TYPE_PLAYED_GAME)
+ changeType(TYPE_PLAYED_GAME)
+ }
+
+ commentType.setOnClickListener {
+ if (mCurrentType == TYPE_COMMENT) return@setOnClickListener
+ mCurrentType = TYPE_COMMENT
+ updateTypeView(TYPE_COMMENT)
+ changeType(TYPE_COMMENT)
+ }
+
+ commentSubType.setOnClickListener {
+ showCommentTypePopupWindow()
+ }
+ }
+ }
+
+ private fun updateTypeView(type: Int) {
+ mBinding?.run {
+ if (type == TYPE_PLAYED_GAME) {
+ commentSubType.visibility = View.GONE
+ arrowIv.visibility = View.GONE
+ gameType.setBackgroundResource(R.drawable.button_round_f0f8ff)
+ gameType.setTextColor(R.color.theme_font.toColor())
+ commentType.setBackgroundResource(R.drawable.button_round_fafafa)
+ commentType.setTextColor(R.color.text_333333.toColor())
+ } else {
+ commentSubType.visibility = View.VISIBLE
+ arrowIv.visibility = View.VISIBLE
+ gameType.setBackgroundResource(R.drawable.button_round_fafafa)
+ gameType.setTextColor(R.color.text_333333.toColor())
+ commentType.setBackgroundResource(R.drawable.button_round_f0f8ff)
+ commentType.setTextColor(R.color.theme_font.toColor())
+ }
+ }
+ }
+
+ private fun changeType(type: Int) {
+ if (type == TYPE_PLAYED_GAME) {
+ mPlayedGameFragment = childFragmentManager.findFragmentByTag(UserPlayedGameFragment::class.java.simpleName) as? UserPlayedGameFragment
+ ?: UserPlayedGameFragment()
+ mPlayedGameFragment?.arguments = bundleOf(KEY_USER_ID to mUserId)
+ childFragmentManager.beginTransaction().replace(R.id.contentContainer, mPlayedGameFragment!!, UserPlayedGameFragment::class.java.simpleName).commitAllowingStateLoss()
+ } else {
+ mCommentFragment = childFragmentManager.findFragmentByTag(UserCommentHistoryFragment::class.java.simpleName) as? UserCommentHistoryFragment
+ ?: UserCommentHistoryFragment()
+ mCommentFragment?.arguments = bundleOf(KEY_USER_ID to mUserId)
+ childFragmentManager.beginTransaction().replace(R.id.contentContainer, mCommentFragment!!, UserCommentHistoryFragment::class.java.simpleName).commitAllowingStateLoss()
+ }
+ }
+
+ private fun showCommentTypePopupWindow() {
+ mBinding?.run {
+ val contentList = arrayListOf("全部", "精华", "安利墙")
+
+ val inflater = LayoutInflater.from(requireContext())
+ val layout = inflater.inflate(R.layout.layout_popup_container, null)
+ val popupWindow = PopupWindow(
+ layout,
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+ popupWindow.apply {
+ setBackgroundDrawable(ColorDrawable(0))
+ isTouchable = true
+ isFocusable = true
+ isOutsideTouchable = true
+ }
+
+ val container = layout.findViewById(R.id.container)
+ for (text in contentList) {
+ val item = inflater.inflate(R.layout.layout_popup_option_item, container, false)
+ if (mFilter == text) {
+ (item as TextView).setTextColor(ContextCompat.getColor(requireContext(), R.color.theme_font))
+ } else {
+ (item as TextView).setTextColor(ContextCompat.getColor(requireContext(), R.color.text_666666))
+ }
+ container.addView(item)
+
+ val hitText = item.findViewById(R.id.hint_text)
+ hitText.text = text
+
+ item.setOnClickListener {
+ mFilter = text
+ commentSubType.text = text
+ changeCommentType(text)
+ popupWindow.dismiss()
+ }
+ }
+ popupWindow.setOnDismissListener {
+ arrowIv.rotation = 0f
+ }
+ arrowIv.rotation = 180f
+ popupWindow.showAutoOrientation(commentSubType)
+ }
+ }
+
+ private fun changeCommentType(text: String) {
+ mCommentFragment?.changeType(text)
+ }
+
+ companion object {
+ private const val TYPE_PLAYED_GAME = 100
+ private const val TYPE_COMMENT = 101
+
+ fun getInstance(userId: String, commentCount: Int): UserGameFragment {
+ return UserGameFragment().apply {
+ with(bundleOf(
+ KEY_USER_ID to userId,
+ KEY_COMMENT_COUNT to commentCount
+ ))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserGameViewModel.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserGameViewModel.kt
new file mode 100644
index 0000000000..d587b49d51
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserGameViewModel.kt
@@ -0,0 +1,47 @@
+package com.gh.gamecenter.personalhome.home.game
+
+import android.annotation.SuppressLint
+import android.app.Application
+import android.text.TextUtils
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.gh.gamecenter.retrofit.BiResponse
+import com.gh.gamecenter.retrofit.RetrofitManager
+import com.halo.assistant.HaloApp
+import com.lightgame.utils.Utils
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.schedulers.Schedulers
+import okhttp3.ResponseBody
+
+class UserGameViewModel(application: Application, private val mUserId: String)
+ : AndroidViewModel(application) {
+
+ var playedGameCount = MutableLiveData()
+
+ init {
+ getUserPlayedGameCount()
+ }
+
+ @SuppressLint("CheckResult")
+ fun getUserPlayedGameCount() {
+ RetrofitManager.getInstance(getApplication())
+ .api.getPlayedGamesCount(mUserId, Utils.getTime(getApplication()))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : BiResponse>() {
+ override fun onSuccess(data: retrofit2.Response) {
+ val countContent = data.headers().get("Total")
+ playedGameCount.postValue(if (TextUtils.isEmpty(countContent)) 0 else countContent?.toInt() ?: 0)
+ }
+ })
+ }
+
+
+ class Factory(private val userId: String) : ViewModelProvider.NewInstanceFactory() {
+ override fun create(modelClass: Class): T {
+ return UserGameViewModel(HaloApp.getInstance().application, userId) as T
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameAdapter.kt b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameAdapter.kt
new file mode 100644
index 0000000000..66bdcf91de
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameAdapter.kt
@@ -0,0 +1,137 @@
+package com.gh.gamecenter.personalhome.home.game
+
+import android.content.Context
+import android.util.TypedValue
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.databinding.DataBindingUtil
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.constant.ItemViewType
+import com.gh.common.util.*
+import com.gh.gamecenter.GameDetailActivity
+import com.gh.gamecenter.R
+import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
+import com.gh.gamecenter.adapter.viewholder.GameViewHolder
+import com.gh.gamecenter.baselist.ListAdapter
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.eventbus.EBDownloadStatus
+import com.gh.gamecenter.game.GameItemViewHolder
+import com.gh.gamecenter.mygame.PlayedGameViewModel
+import com.lightgame.download.DownloadEntity
+import java.util.HashMap
+
+class UserPlayedGameAdapter(context: Context,
+ private val mViewModel: PlayedGameViewModel): ListAdapter(context) {
+
+ private val mEntrance = "个人主页-游戏-玩过"
+
+ val positionAndPackageMap = HashMap()
+
+ override fun setListData(updateData: MutableList?) {
+ // 记录游戏位置
+ if (updateData != null) {
+ for (i in 0 until updateData.size) {
+ val gameEntity = updateData[i]
+ var packages = gameEntity.id
+ for (apkEntity in gameEntity.getApk()) {
+ packages += apkEntity.packageName
+ }
+ positionAndPackageMap[packages + i] = i
+ }
+ }
+ super.setListData(updateData)
+ }
+
+ override fun getItemCount(): Int {
+ return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return if (position == itemCount - 1) {
+ ItemViewType.ITEM_FOOTER
+ } else {
+ ItemViewType.GAME_NORMAL
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ ItemViewType.GAME_NORMAL -> GameItemViewHolder(DataBindingUtil.inflate(mLayoutInflater, R.layout.game_item, parent, false))
+
+ else -> FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is GameItemViewHolder -> {
+ holder.binding.run {
+ root.setPadding(16F.dip2px(), 8F.dip2px(), 16F.dip2px(), 8F.dip2px())
+
+ val gameEntity = mEntityList[position]
+ game = gameEntity
+ executePendingBindings()
+
+ val platform = PlatformUtils.getInstance(mContext).getPlatformName(gameEntity.platform)
+ gameDes.run {
+ setTextSize(TypedValue.COMPLEX_UNIT_SP, 11F)
+ setTextColor(R.color.text_666666.toColor())
+ text = platform
+ }
+
+ labelList.removeAllViews()
+ val runTimeView = TextView(mContext).apply {
+ isSingleLine = true
+ setTextSize(TypedValue.COMPLEX_UNIT_SP, 11F)
+ setTextColor(R.color.text_999999.toColor())
+ text = ("游戏时长: " + NumberUtils.transSimpleUsageTime(gameEntity.playedTime))
+ }
+ labelList.addView(runTimeView)
+
+ DownloadItemUtils.setOnClickListener(mContext,
+ downloadBtn,
+ gameEntity,
+ position,
+ this@UserPlayedGameAdapter,
+ "(${mEntrance})",
+ StringUtils.buildString(mEntrance, ":", gameEntity.name))
+ DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(holder.binding), true, true)
+
+ holder.itemView.setOnClickListener {
+ GameDetailActivity.startGameDetailActivity(mContext, gameEntity.id, "(${mEntrance})")
+ }
+ }
+ }
+
+ is FooterViewHolder -> holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
+ }
+ }
+ fun notifyItemByDownload(download: DownloadEntity) {
+ for (key in positionAndPackageMap.keys) {
+ // sentry上报download.packageName可能为空
+ if (download.packageName != null
+ && download.gameId != null
+ && key.contains(download.packageName)
+ && key.contains(download.gameId)) {
+ val position = positionAndPackageMap[key]
+ if (position != null && mEntityList != null && position < mEntityList.size) {
+ mEntityList[position].getEntryMap()[download.platform] = download
+ notifyItemChanged(position)
+ }
+ }
+ }
+ }
+
+ fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
+ for (key in positionAndPackageMap.keys) {
+ if (key.contains(status.packageName) && key.contains(status.gameId)) {
+ val position = positionAndPackageMap[key]
+ if (position != null && mEntityList != null && position < mEntityList.size) {
+ mEntityList[position].getEntryMap().remove(status.platform)
+ notifyItemChanged(position)
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
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
new file mode 100644
index 0000000000..70d8602043
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/home/game/UserPlayedGameFragment.kt
@@ -0,0 +1,117 @@
+package com.gh.gamecenter.personalhome.home.game
+
+import android.os.Bundle
+import android.view.View
+import androidx.recyclerview.widget.RecyclerView
+import com.gh.common.constant.Constants
+import com.gh.common.util.DialogUtils
+import com.gh.common.util.EntranceUtils.KEY_USER_ID
+import com.gh.common.util.SPUtils
+import com.gh.common.util.viewModelProvider
+import com.gh.common.xapk.XapkInstaller
+import com.gh.common.xapk.XapkUnzipStatus
+import com.gh.download.DownloadManager
+import com.gh.gamecenter.baselist.ListFragment
+import com.gh.gamecenter.entity.GameEntity
+import com.gh.gamecenter.entity.GameInstall
+import com.gh.gamecenter.eventbus.EBDownloadStatus
+import com.gh.gamecenter.eventbus.EBPackage
+import com.gh.gamecenter.manager.PackagesManager
+import com.gh.gamecenter.manager.UserManager
+import com.gh.gamecenter.mygame.PlayedGameViewModel
+import com.gh.gamecenter.personalhome.InstalledGameDialog
+import com.lightgame.download.DataWatcher
+import com.lightgame.download.DownloadEntity
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class UserPlayedGameFragment: ListFragment() {
+
+ private var mUserId = ""
+ private var mAdapter: UserPlayedGameAdapter? = null
+ private var mDialog: InstalledGameDialog? = null
+ private val mDataWatcher = object : DataWatcher() {
+ override fun onDataChanged(downloadEntity: DownloadEntity) {
+ mAdapter?.notifyItemByDownload(downloadEntity)
+
+ if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
+ showUnzipFailureDialog(downloadEntity)
+ }
+ }
+ }
+
+ override fun provideListViewModel() = viewModelProvider(PlayedGameViewModel.Factory(mUserId))
+
+ override fun provideListAdapter() = mAdapter ?: UserPlayedGameAdapter(requireContext(), mListViewModel).apply { mAdapter = this }
+
+ override fun getItemDecoration() = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ mUserId = arguments?.getString(KEY_USER_ID, "") ?: ""
+ super.onCreate(savedInstanceState)
+ mListRv.overScrollMode = View.OVER_SCROLL_NEVER
+ }
+
+ override fun onResume() {
+ if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
+ super.onResume()
+ DownloadManager.getInstance(context).addObserver(mDataWatcher)
+ }
+
+
+ override fun onLoadEmpty() {
+ super.onLoadEmpty()
+
+ val installedList = PackagesManager.filterSameApk(PackagesManager.filterDownloadBlackPackage(PackagesManager.getInstalledList()))
+ val simulatorDownloadEntityList = DownloadManager.getInstance(requireContext()).allSimulatorDownloadEntity
+ simulatorDownloadEntityList.forEach { entity ->
+ installedList.add(GameInstall(entity.gameId, packageName = entity.packageName, name = entity.name, icon = entity.icon))
+ }
+ //val count = SPUtils.getInt(Constants.SP_MARK_INSTALLED_GAME, 0)
+ val isCancel = SPUtils.getBoolean(Constants.SP_MARK_INSTALLED_GAME_USER_HOME, false)
+ if (mUserId == UserManager.getInstance().userId
+ && !isCancel
+// && it.isNullOrEmpty()
+ && installedList.isNotEmpty()) {
+ mDialog = InstalledGameDialog(requireContext(), installedList, "个人主页详情", "标记玩过弹窗")
+ mDialog?.show()
+ mDialog?.onConfirmClickListener = {
+ onLoadRefresh()
+ }
+ }
+ }
+
+ override fun onPause() {
+ super.onPause()
+ DownloadManager.getInstance(context).removeObserver(mDataWatcher)
+ }
+
+ // 下载被删除事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(status: EBDownloadStatus) {
+ if ("delete" == status.status) {
+ mAdapter?.notifyItemAndRemoveDownload(status)
+ }
+ }
+
+ // 安装/卸载 事件
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun onEventMainThread(busFour: EBPackage) {
+ if ("安装" == busFour.type || "卸载" == busFour.type) {
+ mAdapter?.notifyDataSetChanged()
+ }
+ }
+
+ fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
+ val data = mAdapter?.positionAndPackageMap ?: return
+ for (gameAndPosition in data) {
+ if (gameAndPosition.key.contains(downloadEntity.packageName)) {
+ val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
+ if (targetView != null) {
+ DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
+ return
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt b/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt
index ce2e182be6..e6a44dff00 100644
--- a/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt
+++ b/app/src/main/java/com/gh/gamecenter/personalhome/rating/MyRating.kt
@@ -3,6 +3,8 @@ package com.gh.gamecenter.personalhome.rating
import androidx.annotation.Keep
import com.gh.gamecenter.entity.*
import com.google.gson.annotations.SerializedName
+import java.text.SimpleDateFormat
+import java.util.*
/**
* 该实体与View同级,因为其他页面也用不着
@@ -38,6 +40,12 @@ data class MyRating(@SerializedName("_id")
user = user)
}
+ fun getFormatTime(pattern: String): String? {
+ if (time == 0L) return null
+ val formatTime = SimpleDateFormat(pattern, Locale.CHINA)
+ return formatTime.format(time * 1000)
+ }
+
fun transformGameEntity(): GameEntity {
return GameEntity(id = game.id, mName = game.name, nameSuffix = game.nameSuffix, mIcon = game.icon, mTagStyle = game.tag, star = game.star)
}
diff --git a/app/src/main/java/com/gh/gamecenter/qa/BbsType.kt b/app/src/main/java/com/gh/gamecenter/qa/BbsType.kt
new file mode 100644
index 0000000000..82c46b65c4
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/BbsType.kt
@@ -0,0 +1,11 @@
+package com.gh.gamecenter.qa
+
+enum class BbsType(val value: String) {
+ GAME_BBS("game_bbs"),//游戏论坛
+ OFFICIAL_BBS("official_bbs"),//官方论坛
+
+ GAME_BBS_QUESTION_INSERT("game_bbs_question_insert"),//游戏论坛提问视频插入
+ GAME_BBS_ARTICLE_INSERT("game_bbs_article_insert"),//游戏论坛帖子视频插入
+ OFFICIAL_BBS_QUESTION_INSERT("official_bbs_question_insert"),//官方论坛提问视频插入
+ OFFICIAL_BBS_ARTICLE_INSERT("official_bbs_article_insert")//官方论坛帖子视频插入
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/CommunityFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/CommunityFragment.kt
index c337e74242..c85a6f0137 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/CommunityFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/CommunityFragment.kt
@@ -390,7 +390,7 @@ class CommunityFragment : BaseLazyTabFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busNine: EBUISwitch) {
if (MainWrapperFragment.EB_MAIN_SCROLL_TOP == busNine.from
- && MainWrapperFragment.INDEX_ASK == busNine.position) {
+ && MainWrapperFragment.INDEX_BBS == busNine.position) {
when (mTabLayout.getTabAt(mViewPager.currentItem)?.text) {
TAB_TITLE_FOLLOW -> mAskFollowFragment?.scrollToTop(false)
TAB_TITLE_RECOMMEND -> mRecommendsFragment?.scrollToTop(false)
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt
index 5018ba0bac..1927e89809 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/BaseAnswerOrArticleItemViewHolder.kt
@@ -1,25 +1,32 @@
package com.gh.gamecenter.qa.answer
+import android.annotation.SuppressLint
import android.view.View
import android.widget.TextView
import com.airbnb.lottie.LottieAnimationView
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.util.*
+import com.gh.common.view.GameIconView
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.CommunityEntity
import com.gh.gamecenter.entity.VoteEntity
import com.gh.gamecenter.forum.detail.ForumDetailActivity
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
-import com.gh.gamecenter.qa.comment.CommentActivity
import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
+import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
+import com.gh.gamecenter.qa.questions.invite.QuestionsInviteActivity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
+import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
+import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import com.lightgame.view.CheckableImageView
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
+import okhttp3.ResponseBody
import retrofit2.HttpException
/**
@@ -34,6 +41,9 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
val commentCountContainer: View = itemView.findViewById(R.id.comment_count_container)
val voteCountContainer: View = itemView.findViewById(R.id.vote_count_container)
val forumNameTv: View = itemView.findViewById(R.id.forumNameTv)
+ val forumNameLl: View? = itemView.findViewById(R.id.forumNameLl)
+ val forumNameContainer: View? = itemView.findViewById(R.id.forumNameContainer)
+ val forumIcon: GameIconView? = itemView.findViewById(R.id.forumIcon)
open fun bindCommendAndVote(entity: AnswerEntity, entrance: String) {
@@ -41,20 +51,24 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
commentCountContainer.setOnClickListener {
if (filterIllegalCommentStatus(entity.commentable, entity.active)) return@setOnClickListener
- if (entity.type == "community_article") {
- val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
- else UserManager.getInstance().community.id
- val intent = ArticleDetailActivity.getCommentIntent(itemView.context,
- CommunityEntity(communityId, entity.communityName ?: ""),
- entity.id ?: "",
- entrance, "")
- itemView.context.startActivity(intent)
- } else {
- val intent = CommentActivity.getAnswerCommentIntent(itemView.context,
- entity.id!!,
- entity.commentCount,
- false)
- itemView.context.startActivity(intent)
+ when (entity.type) {
+ "community_article" -> {
+ val communityId = if (!entity.communityId.isNullOrEmpty()) entity.communityId
+ ?: "" else entity.bbs.id
+ val intent = ArticleDetailActivity.getCommentIntent(itemView.context,
+ CommunityEntity(communityId, entity.communityName ?: ""),
+ entity.id ?: "", entrance, "")
+ itemView.context.startActivity(intent)
+ }
+ "video" -> {
+ itemView.context.startActivity(ForumVideoDetailActivity.getIntent(itemView.context, entity.id
+ ?: ""))
+ }
+ else -> {
+ val intent = NewQuestionDetailActivity.getCommentIntent(itemView.context, entity.id
+ ?: "", entrance, "")
+ itemView.context.startActivity(intent)
+ }
}
}
@@ -93,23 +107,38 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
open fun bindCommendAndVote(entity: ArticleEntity, entrance: String) {
binNormalView(entity.transformAnswerEntity())
+ if (entity.bbs.type == "official_bbs") {
+ forumIcon?.displayGameIcon(entity.bbs.icon, null)
+ } else {
+ forumIcon?.displayGameIcon(entity.bbs.game?.getIcon(), entity.bbs.game?.iconSubscript)
+ }
+
forumNameTv.setOnClickListener {
MtaHelper.onEvent(getEventId(entrance), getKey(entrance), if (entity.bbs.name.isEmpty()) entity.community.name else entity.bbs.name)
itemView.context.startActivity(ForumDetailActivity.getIntent(itemView.context, entity.community.id, entrance))
LogUtils.uploadAccessToBbs(entity.community.id, "文章外所属论坛")
}
+ forumNameContainer?.setOnClickListener {
+ forumNameTv.performClick()
+ }
+
commentCountContainer.setOnClickListener {
if (filterIllegalCommentStatus(entity.commentable, entity.active)) return@setOnClickListener
- val communityId = if (entity.community.id.isNotEmpty()) entity.community.id
- else UserManager.getInstance().community.id
- val intent = ArticleDetailActivity.getCommentIntent(itemView.context,
- CommunityEntity(communityId, entity.community.name),
- entity.id,
- entrance, "")
- itemView.context.startActivity(intent)
- MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "评论图标")
+ if (entity.type == "question") {
+ val intent = NewQuestionDetailActivity.getCommentIntent(it.context, entity.id, entrance, "")
+ itemView.context.startActivity(intent)
+ } else {
+ val communityId = if (entity.community.id.isNotEmpty()) entity.community.id
+ else UserManager.getInstance().community.id
+ val intent = ArticleDetailActivity.getCommentIntent(itemView.context,
+ CommunityEntity(communityId, entity.community.name),
+ entity.id,
+ entrance, "")
+ itemView.context.startActivity(intent)
+ MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "评论图标")
+ }
}
voteCountContainer.setOnClickListener {
@@ -117,9 +146,20 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
debounceActionWithInterval(R.id.container_like, 1000) {
CheckLoginUtils.checkLogin(itemView.context, entrance) {
- if (!voteIcon.isChecked) voteArticle(entity)
- else cancelArticleVote(entity)
- MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "点赞图标")
+ if (entity.type == "question") {
+ val questionsDetailEntity = QuestionsDetailEntity(
+ id = entity.id,
+ title = entity.title,
+ images = entity.images,
+ description = entity.brief)
+ it.context.startActivity(QuestionsInviteActivity.getIntent(it.context,
+ questionsDetailEntity,
+ entrance))
+ } else {
+ if (!voteIcon.isChecked) voteArticle(entity)
+ else cancelArticleVote(entity)
+ MtaHelper.onEvent(getEventId(entrance), getKey(entrance), "点赞图标")
+ }
}
}
}
@@ -127,23 +167,31 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
fun binNormalView(entity: AnswerEntity) {
setVoteAndCommentStyle(entity)
- commentCount.text = if (entity.commentCount > 0) entity.commentCount.toString() else "评论"
- voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
+ if (entity.type == "question") {
+ commentCount.text = if (entity.count.answer > 0) entity.count.answer.toString() else "回答"
+ voteCount.text = "邀请回答"
+ } else {
+ commentCount.text = if (entity.count.comment > 0) entity.count.comment.toString() else "评论"
+ voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同"
+ }
}
private fun setVoteAndCommentStyle(entity: AnswerEntity) {
-
- if (!entity.active) {
- voteIcon.setImageResource(R.drawable.community_vote_unavailable)
- voteCount.setTextColor(R.color.text_cccccc.toColor())
- } else if (entity.me.isCommunityArticleVote || entity.me.isAnswerVoted) {
- voteIcon.setImageResource(R.drawable.community_vote_selector)
- voteIcon.isChecked = true
- voteCount.setTextColor(R.color.theme_font.toColor())
+ if (entity.type == "question") {
+ voteIcon.setImageDrawable(R.drawable.community_invite_follow.toDrawable())
} else {
- voteIcon.setImageResource(R.drawable.community_vote_selector)
- voteIcon.isChecked = false
- voteCount.setTextColor(R.color.text_999999.toColor())
+ if (!entity.active) {
+ voteIcon.setImageResource(R.drawable.community_vote_unavailable)
+ voteCount.setTextColor(R.color.text_cccccc.toColor())
+ } else if (entity.me.isCommunityArticleVote || entity.me.isAnswerVoted || entity.me.isVoted) {
+ voteIcon.setImageResource(R.drawable.community_vote_selector)
+ voteIcon.isChecked = true
+ voteCount.setTextColor(R.color.theme_font.toColor())
+ } else {
+ voteIcon.setImageResource(R.drawable.community_vote_selector)
+ voteIcon.isChecked = false
+ voteCount.setTextColor(R.color.text_999999.toColor())
+ }
}
if (entity.commentable && entity.active) {
@@ -159,119 +207,160 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
}
}
+ @SuppressLint("CheckResult")
fun voteAnswer(entity: AnswerEntity) {
- entity.vote = entity.vote + 1
- voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
+ entity.count.vote = entity.count.vote + 1
+ voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同"
playVoteAnimation()
- val voteObservable = if (entity.type == "community_article") {
- val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
- else entity.bbs.id
- RetrofitManager.getInstance(itemView.context).api
- .postCommunityArticleVote(communityId, entity.id)
- } else {
- RetrofitManager.getInstance(itemView.context).api
- .postAnswerVote(entity.id)
- }
- voteObservable
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : Response() {
- override fun onResponse(response: VoteEntity?) {
- if (entity.type == "community_article") {
- entity.me.isCommunityArticleVote = true
- EnergyTaskHelper.postEnergyTask("vote_community_article", entity.id)
- } else {
- entity.me.isAnswerVoted = true
- EnergyTaskHelper.postEnergyTask("vote_answer", entity.id)
+ if (entity.type == "video") {
+ RetrofitManager.getInstance(itemView.context)
+ .api.voteVideo(entity.id)
+ .subscribeOn(Schedulers.io())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ //Utils.toast(getApplication(), "已点赞")
+ EnergyTaskHelper.postEnergyTask("vote_video", entity.id)
}
- ToastUtils.showToast("已赞同")
- }
- override fun onFailure(e: HttpException?) {
- ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) {
- if (403008 == it) {
- Utils.toast(itemView.context, R.string.ask_vote_hint)
- true
- } else if (403036 == it) {
- Utils.toast(itemView.context, R.string.ask_vote_limit_hint)
- true
- } else if (404001 == it) {
- Utils.toast(itemView.context, "内容可能已被删除")
- entity.active = false
- setVoteAndCommentStyle(entity)
- true
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ entity.count.vote = entity.count.vote - 1
+ entity.me.isVoted = false
+ voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同"
+ setVoteAndCommentStyle(entity)
+ }
+ })
+ } else {
+ val voteObservable = if (entity.type == "community_article") {
+ val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
+ else entity.bbs.id
+ RetrofitManager.getInstance(itemView.context).api
+ .postCommunityArticleVote(communityId, entity.id)
+ } else {
+ RetrofitManager.getInstance(itemView.context).api
+ .postAnswerVote(entity.id)
+ }
+ voteObservable
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Response() {
+ override fun onResponse(response: VoteEntity?) {
+ if (entity.type == "community_article") {
+ entity.me.isCommunityArticleVote = true
+ EnergyTaskHelper.postEnergyTask("vote_community_article", entity.id)
} else {
- entity.vote = entity.vote - 1
- if (entity.type == "community_article") {
- entity.me.isCommunityArticleVote = true
+ entity.me.isAnswerVoted = true
+ EnergyTaskHelper.postEnergyTask("vote_answer", entity.id)
+ }
+ ToastUtils.showToast("已赞同")
+ }
+
+ override fun onFailure(e: HttpException?) {
+ ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) {
+ if (403008 == it) {
+ Utils.toast(itemView.context, R.string.ask_vote_hint)
+ true
+ } else if (403036 == it) {
+ Utils.toast(itemView.context, R.string.ask_vote_limit_hint)
+ true
+ } else if (404001 == it) {
+ Utils.toast(itemView.context, "内容可能已被删除")
+ entity.active = false
+ setVoteAndCommentStyle(entity)
+ true
} else {
- entity.me.isAnswerVoted = true
+ entity.count.vote = entity.count.vote - 1
+ if (entity.type == "community_article") {
+ entity.me.isCommunityArticleVote = true
+ } else {
+ entity.me.isAnswerVoted = true
+ }
+ voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同"
+ setVoteAndCommentStyle(entity)
+ false
}
- voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
- setVoteAndCommentStyle(entity)
- false
}
}
- }
- })
+ })
+ }
}
+ @SuppressLint("CheckResult")
fun cancelAnswerVote(entity: AnswerEntity) {
- entity.vote = entity.vote - 1
+ entity.count.vote = entity.count.vote - 1
voteIcon.isChecked = false
voteCount.setTextColor(R.color.text_999999.toColor())
- voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
+ voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同"
- val unVoteObservable = if (entity.type == "community_article") {
- entity.me.isCommunityArticleVote = false
+ if (entity.type == "video") {
+ RetrofitManager.getInstance(itemView.context)
+ .api.undoVoteVideo(entity.id)
+ .subscribeOn(Schedulers.io())
+ .subscribe(object : BiResponse() {
+ override fun onSuccess(data: ResponseBody) {
+ Utils.toast(itemView.context, "取消点赞")
+ }
- val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
- else entity.bbs.id
- RetrofitManager.getInstance(itemView.context).api
- .postCommunityArticleUnVote(communityId, entity.id)
+ override fun onFailure(exception: Exception) {
+ super.onFailure(exception)
+ entity.count.vote = entity.count.vote + 1
+ entity.me.isVoted = true
+ voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同"
+ setVoteAndCommentStyle(entity)
+ }
+ })
} else {
- entity.me.isAnswerVoted = false
+ val unVoteObservable = if (entity.type == "community_article") {
+ entity.me.isCommunityArticleVote = false
- RetrofitManager.getInstance(itemView.context).api
- .postAnswerUnvote(entity.id)
- }
- unVoteObservable
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(object : Response() {
- override fun onResponse(response: VoteEntity?) {
- Utils.toast(itemView.context, "取消赞同")
- }
+ val communityId = if (entity.articleCommunityId.isNotEmpty()) entity.articleCommunityId
+ else entity.bbs.id
+ RetrofitManager.getInstance(itemView.context).api
+ .postCommunityArticleUnVote(communityId, entity.id)
+ } else {
+ entity.me.isAnswerVoted = false
- override fun onFailure(e: HttpException?) {
- ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) {
- if (403008 == it) {
- Utils.toast(itemView.context, R.string.ask_vote_hint)
- true
- } else if (403036 == it) {
- Utils.toast(itemView.context, R.string.ask_vote_limit_hint)
- true
- } else if (404001 == it) {
- Utils.toast(itemView.context, "内容可能已被删除")
- entity.active = false
- setVoteAndCommentStyle(entity)
- true
- } else {
- entity.vote = entity.vote + 1
- if (entity.type == "community_article") {
- entity.me.isCommunityArticleVote = true
+ RetrofitManager.getInstance(itemView.context).api
+ .postAnswerUnvote(entity.id)
+ }
+ unVoteObservable
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Response() {
+ override fun onResponse(response: VoteEntity?) {
+ Utils.toast(itemView.context, "取消赞同")
+ }
+
+ override fun onFailure(e: HttpException?) {
+ ErrorHelper.handleErrorWithCustomizedHandler(itemView.context, e?.response()?.errorBody()?.string(), false) {
+ if (403008 == it) {
+ Utils.toast(itemView.context, R.string.ask_vote_hint)
+ true
+ } else if (403036 == it) {
+ Utils.toast(itemView.context, R.string.ask_vote_limit_hint)
+ true
+ } else if (404001 == it) {
+ Utils.toast(itemView.context, "内容可能已被删除")
+ entity.active = false
+ setVoteAndCommentStyle(entity)
+ true
} else {
- entity.me.isAnswerVoted = true
+ entity.count.vote = entity.count.vote + 1
+ if (entity.type == "community_article") {
+ entity.me.isCommunityArticleVote = true
+ } else {
+ entity.me.isAnswerVoted = true
+ }
+ voteCount.text = if (entity.count.vote > 0) entity.count.vote.toString() else "赞同"
+ setVoteAndCommentStyle(entity)
+ false
}
- voteCount.text = if (entity.vote > 0) entity.vote.toString() else "赞同"
- setVoteAndCommentStyle(entity)
- false
}
}
- }
- })
+ })
+ }
}
fun voteArticle(entity: ArticleEntity) {
@@ -360,6 +449,24 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
})
}
+ fun followUser(entity: AnswerEntity, callback: EmptyCallback?) {
+ RetrofitManager.getInstance(itemView.context).api
+ .postFollowing(entity.user.id)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(object : Response() {
+ override fun onResponse(response: ResponseBody?) {
+ super.onResponse(response)
+ callback?.onCallback()
+ }
+
+ override fun onFailure(e: HttpException?) {
+ super.onFailure(e)
+ Utils.toast(itemView.context, R.string.loading_failed_hint)
+ }
+ })
+ }
+
private fun playVoteAnimation() {
voteCount.setTextColor(R.color.theme_font.toColor())
voteIcon.isChecked = true
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/CommunityAnswerItemViewHolder.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/CommunityAnswerItemViewHolder.kt
index 22e78b26fe..20b9b4c7a2 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/answer/CommunityAnswerItemViewHolder.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/CommunityAnswerItemViewHolder.kt
@@ -68,13 +68,19 @@ class CommunityAnswerItemViewHolder(val binding: CommunityAnswerItemBinding) : B
binding.userIcon.display(entity.user.border, entity.user.icon, entity.user.auth?.icon)
binding.imageContainer.bindData(entity, entrance, path)
- if (entity.getPassVideos().isNotEmpty() && entity.images.isNotEmpty()) {
- val title = binding.title.text
- val videoSpan = SpanBuilder(" ").image(1, " ".length, R.drawable.ic_article_video_label).build()
- binding.title.text = SpannableStringBuilder()
- .append(title)
- .append(videoSpan)
+ val spanBuilder = SpannableStringBuilder()
+ if (entity.type == "question") {
+ val title = " ${binding.title.text}"
+ val askLabelSpan = SpanBuilder(title).image(0, 1, R.drawable.ic_ask_label).build()
+ spanBuilder.append(askLabelSpan)
+ } else {
+ spanBuilder.append(binding.title.text)
}
+ if (entity.getPassVideos().isNotEmpty() && entity.images.isNotEmpty()) {
+ val videoSpan = SpanBuilder(" ").image(1, " ".length, R.drawable.ic_article_video_label).build()
+ spanBuilder.append(videoSpan)
+ }
+ binding.title.text = spanBuilder
val user = entity.user
binding.userBadgeName.setOnClickListener { binding.userBadgeIcon.performClick() }
binding.userBadgeIcon.setOnClickListener {
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt
index c206e5ea71..bc7d9f012b 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/AnswerDetailFragment.kt
@@ -63,7 +63,7 @@ import java.io.IOException
import java.util.*
import kotlin.collections.ArrayList
-class AnswerDetailFragment : NormalFragment() {
+open class AnswerDetailFragment : NormalFragment() {
@BindView(R.id.reuse_no_connection)
lateinit var mNoConn: View
@@ -126,7 +126,7 @@ class AnswerDetailFragment : NormalFragment() {
private var mRefreshFooter: AnswerDetailRefreshFooter? = null
private var mSkeletonScreen: SkeletonScreen? = null
- private lateinit var mBinding: FragmentAnswerDetailBinding
+ lateinit var mBinding: FragmentAnswerDetailBinding
lateinit var mViewModel: AnswerDetailViewModel
private lateinit var mContainerViewModel: AnswerDetailContainerViewModel
@@ -994,10 +994,14 @@ class AnswerDetailFragment : NormalFragment() {
private fun hideLoadingViewAndShowContent() {
mNoConn.visibility = View.GONE
- mBinding.bottomController.root.visibility = View.VISIBLE
+ mBinding.bottomController.root.visibility = if (shouldShowBottomController()) View.VISIBLE else View.GONE
mBinding.scrollView.visibility = View.VISIBLE
}
+ open fun shouldShowBottomController(): Boolean {
+ return true
+ }
+
@SuppressLint("SetTextI18n")
private fun updateQuestionView(question: Questions) {
val video = if (!question.videos.isNullOrEmpty()) question.videos[0] else null
@@ -1062,7 +1066,7 @@ class AnswerDetailFragment : NormalFragment() {
mBinding.answerCountTv.text = String.format("查看全部%d个回答", question.answerCount)
// 作为 viewpager 里的第一个回答时隐藏问题内容
- if (mAnswerId == mContainerViewModel.answerIdList.first()) {
+ if (mContainerViewModel.answerIdList.isNotEmpty() && mAnswerId == mContainerViewModel.answerIdList.first()) {
mQuestionContent.visibility = View.VISIBLE
} else {
mQuestionContent.visibility = View.GONE
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailActivity.kt
new file mode 100644
index 0000000000..71a9234155
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailActivity.kt
@@ -0,0 +1,21 @@
+package com.gh.gamecenter.qa.answer.detail
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.gh.base.BaseActivity
+import com.gh.common.util.EntranceUtils
+import com.gh.gamecenter.NormalActivity
+
+class SimpleAnswerDetailActivity : NormalActivity() {
+
+ companion object {
+ fun getIntent(context: Context, answerId: String, entrance: String, path: String): Intent {
+ val bundle = Bundle()
+ bundle.putString(EntranceUtils.KEY_ANSWER_ID, answerId)
+ bundle.putString(EntranceUtils.KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
+ bundle.putString(EntranceUtils.KEY_PATH, path)
+ return getTargetIntent(context, SimpleAnswerDetailActivity::class.java, SimpleAnswerDetailFragment::class.java, bundle)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailFragment.kt
new file mode 100644
index 0000000000..aad62b30cb
--- /dev/null
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/detail/SimpleAnswerDetailFragment.kt
@@ -0,0 +1,19 @@
+package com.gh.gamecenter.qa.answer.detail
+
+import android.os.Bundle
+import android.view.View
+
+class SimpleAnswerDetailFragment : AnswerDetailFragment() {
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mBinding.refreshLayout.isEnabled = false
+ mBinding.answerDetailTitleRl.visibility = View.GONE
+ mBinding.bottomController.root.visibility = View.GONE
+ mBinding.topPaddingView.visibility = View.GONE
+ mBinding.bottomShadowView.visibility = View.GONE
+ mBinding.bottomDividerView.visibility = View.GONE
+ }
+
+ override fun shouldShowBottomController(): Boolean = false
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt
index 1a7c83e9bb..21c21357ab 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditActivity.kt
@@ -31,32 +31,20 @@ import com.gh.gamecenter.qa.entity.Questions
import com.gh.gamecenter.video.VideoVerifyItemViewHolder
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.halo.assistant.HaloApp
-import com.zhihu.matisse.Matisse
-import com.zhihu.matisse.MimeType
-import org.json.JSONArray
import org.json.JSONObject
/**
* Created by khy on 10/04/18.
*/
-class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
+class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
private lateinit var mMenuDraft: MenuItem
private lateinit var mMenuPost: MenuItem
private lateinit var mBinding: FragmentAnswerEditBinding
- private lateinit var mViewModel: AnswerEditViewModel
-
private var mProcessingDialog: WaitingDialogFragment? = null
private var mUploadImageCancelDialog: Dialog? = null
-
private var mCommunityName: String? = null
-
private var mOpenAnswerInNewPage: Boolean = false
- private var mAgreePostPic: Boolean = false
-
- private var mKeyboardHeightProvider: KeyboardHeightProvider? = null
-
- private var mIsKeyBoardShow = false
override fun mtaEventName(): String {
return "回答详情" // issues 定的就是回答详情
@@ -72,9 +60,7 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
- if (requestCode == REQUEST_CODE_IMAGE && resultCode == Activity.RESULT_OK) {
- if (data != null) mViewModel.postImg(data)
- } else if (requestCode == ANSWER_DRAFT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
+ if (requestCode == ANSWER_DRAFT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
mViewModel.getUserAnswerDrafts()
}
}
@@ -87,15 +73,6 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
mCommunityName = intent?.getStringExtra(EntranceUtils.KEY_COMMUNITY_NAME)
mOpenAnswerInNewPage = intent?.getBooleanExtra(EntranceUtils.KEY_ANSWER_OPEN_IN_NEW_PAGE, false)!!
mBinding = FragmentAnswerEditBinding.bind(mContentView)
-
- val factory = AnswerEditViewModel.Factory(
- HaloApp.getInstance().application,
- intent?.getStringExtra(EntranceUtils.KEY_ANSWER_ID),
- intent?.getStringExtra(EntranceUtils.KEY_ANSWER_CONTENT),
- intent?.getStringExtra(EntranceUtils.KEY_DRAFT_ID),
- intent?.getParcelableExtra(Questions::class.java.simpleName) ?: Questions())
- mViewModel = ViewModelProviders.of(this, factory).get(AnswerEditViewModel::class.java)
-
addObserver()
initQuestionContent()
@@ -133,28 +110,27 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
mMenuDraft.isVisible = false
}
- mKeyboardHeightProvider = KeyboardHeightProvider(this)
- mBinding.root.post { mKeyboardHeightProvider?.start() }
checkPostButtonEnable()
}
+ override fun provideViewModel(): AnswerEditViewModel {
+ val factory = AnswerEditViewModel.Factory(
+ HaloApp.getInstance().application,
+ intent?.getStringExtra(EntranceUtils.KEY_ANSWER_ID),
+ intent?.getStringExtra(EntranceUtils.KEY_ANSWER_CONTENT),
+ intent?.getStringExtra(EntranceUtils.KEY_DRAFT_ID),
+ intent?.getParcelableExtra(Questions::class.java.simpleName) ?: Questions())
+ mViewModel = ViewModelProviders.of(this, factory).get(AnswerEditViewModel::class.java)
+ return mViewModel
+ }
+
override fun getLayoutId(): Int {
return R.layout.fragment_answer_edit
}
override fun onKeyboardHeightChanged(height: Int, orientation: Int) {
+ super.onKeyboardHeightChanged(height, orientation)
if (height > 0) mBinding.appBar.setExpanded(false, true)
- mIsKeyBoardShow = height > 0
- }
-
- override fun onResume() {
- super.onResume()
- mKeyboardHeightProvider?.setKeyboardHeightObserver(this)
- }
-
- override fun onPause() {
- super.onPause()
- mKeyboardHeightProvider?.setKeyboardHeightObserver(null)
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
@@ -170,7 +146,9 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
mViewModel.postLiveData.observeNonNull(this) {
if (it.status == Status.SUCCESS) {
MtaHelper.onEvent("发表答案", "提交成功", mCommunityName)
- toast("发布成功")
+ if (mViewModel.checkIsAllUploadedAndToast()) {
+ toast("发布成功")
+ }
var answerId: String? = null
tryWithDefaultCatch {
answerId = JSONObject(it.data).getString("_id")
@@ -200,19 +178,9 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
when (code) {
403037 -> consume {
if (TextUtils.isEmpty(mViewModel.draftId)) {
- DialogUtils.showAlertDialog(this,
- "发布失败",
- "问题已被删除,无法发布回答",
- "好吧",
- "",
- { finish() },
- null)
+ DialogUtils.showAlertDialog(this, "发布失败", "问题已被删除,无法发布回答", "好吧", "", { finish() }, null)
} else {
- DialogUtils.showAlertDialog(this,
- "发布失败",
- "问题已被删除,需要删除草稿吗?",
- "删除草稿",
- "暂不",
+ DialogUtils.showAlertDialog(this, "发布失败", "问题已被删除,需要删除草稿吗?", "删除草稿", "暂不",
{
mViewModel.deleteAnswerDraft()
finish()
@@ -250,23 +218,6 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
}
}
- mViewModel.chooseImagesUpload.observe(this, Observer {
- for (key in it.keys) {
- mRichEditor.insertPlaceholderImage(key)
- }
- })
-
- mViewModel.chooseImagesUploadSuccess.observe(this, Observer {
- val jsonArray = JSONArray()
- for (key in it.keys) {
- val jsonObject = JSONObject()
- jsonObject.put("id", key)
- jsonObject.put("url", it[key])
- jsonArray.put(jsonObject)
- }
- mRichEditor.replacePlaceholderImage(jsonArray.toString())
- })
-
mViewModel.deleteDraftLiveDate.observe(this, Observer {
if (it == true) {
setResult(Activity.RESULT_OK)
@@ -445,8 +396,6 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
mProcessingDialog?.dismissAllowingStateLoss()
mProcessingDialog = null
super.onDestroy()
-
- mKeyboardHeightProvider?.close()
}
private fun showDraftFailureDialog() {
@@ -481,28 +430,11 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
mViewModel.saveAnswerDrafts(editContent, forcedExit)
}
- @OnClick(
- R.id.editor_image,
- R.id.question_images_1,
- R.id.question_images_2,
- R.id.question_images_3)
+ @OnClick(R.id.question_images_1, R.id.question_images_2, R.id.question_images_3)
fun onClick(view: View) {
val videoSize = if (!mViewModel.question.videos.isNullOrEmpty()) 1 else 0
when (view.id) {
- R.id.editor_image -> {
- MtaHelper.onEvent("发表答案", "上传图片", mCommunityName)
- if (!mAgreePostPic && !NetworkUtils.isWifiOr4GOr3GConnected(this)) {
- mAgreePostPic = true
- DialogUtils.showAlertDialog(this,
- "警告",
- "当前使用移动网络,上传图片会消耗手机流量",
- "我知道了", "", { startMediaStore() }, null)
- MtaHelper.onEvent("发表答案", "上传图片-移动网络提示", mCommunityName)
- return
- }
- startMediaStore()
- }
R.id.question_images_1 -> {
val question = mViewModel.question
if (!question.videos.isNullOrEmpty()) {
@@ -538,46 +470,17 @@ class AnswerEditActivity : BaseRichEditorActivity(), KeyboardHeightObserver {
}
}
-
- private fun startMediaStore() {
- MtaHelper.onEvent(mtaEventName(), "插入图片", "插入图片")
- if (mViewModel.mapImages.size >= 50) {
- toast(R.string.answer_edit_max_img_hint)
- return
- }
- try {
- PermissionHelper.checkStoragePermissionBeforeAction(this, object : EmptyCallback {
- override fun onCallback() {
- Matisse.from(this@AnswerEditActivity)
- .choose(MimeType.ofImage())
- .showSingleMediaType(true)
- .countable(true)
- .addFilter(GhMatisseFilter())
- .maxSelectable(10)
- .forResult(REQUEST_CODE_IMAGE)
- }
- })
- } catch (e: Exception) {
- toast(R.string.media_image_hint)
- e.printStackTrace()
- }
- }
-
companion object {
-
const val SAVE_DRAFTS = 110
const val AUTO_SAVE_DRAFT = 1
- const val REQUEST_CODE_IMAGE = 111
const val SAVE_DRAFTS_INTERVAL_TIME = 15000
const val SAVE_DRAFTS_TOAST_COUNT = 3
const val MIN_ANSWER_TEXT_LENGTH = 6
const val MAX_ANSWER_TEXT_LENGTH = 10000
const val ANSWER_DRAFT_REQUEST_CODE = 112
- const val FILE_HOST = "file:///"
const val ANSWER_DRAFT_CHANGE_TAG = "ANSWER_DRAFT_CHANGE_TAG"
-
/**
* 撰写回答
*/
diff --git a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditViewModel.kt
index 04c358c816..0f43a17765 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditViewModel.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/answer/edit/AnswerEditViewModel.kt
@@ -1,7 +1,6 @@
package com.gh.gamecenter.qa.answer.edit
import android.app.Application
-import android.content.Intent
import android.text.TextUtils
import androidx.lifecycle.*
import com.gh.base.fragment.WaitingDialogFragment
@@ -13,16 +12,14 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.eventbus.EBReuse
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.mvvm.Resource
+import com.gh.base.BaseRichEditorViewModel
+import com.gh.base.RichType
import com.gh.gamecenter.qa.entity.AnswerDraftEntity
import com.gh.gamecenter.qa.entity.Questions
import com.gh.gamecenter.retrofit.Response
-import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
-import com.zhihu.matisse.Matisse
-import com.zhihu.matisse.internal.utils.PathUtils
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
@@ -32,34 +29,19 @@ import org.greenrobot.eventbus.EventBus
import org.json.JSONException
import org.json.JSONObject
import retrofit2.HttpException
-import java.io.File
-import java.util.*
class AnswerEditViewModel(application: Application,
var answerId: String?, // 以mAnswerId为标识,如果mAnswerId不为空则是-修改答案(不需要保存草稿) 为空则是-编写答案
var answerContent: String?,
var draftId: String?,
- var question: Questions) : AndroidViewModel(application) {
-
+ var question: Questions) : BaseRichEditorViewModel(application) {
private var mPostDraftsCount: Int = 0
- private val mApi = RetrofitManager.getInstance(getApplication()).api
-
var cacheAnswerContent: String? = null
-
- val processDialog = MediatorLiveData()
val postLiveData = MediatorLiveData>()
- val postImageLiveData = MediatorLiveData>>()
val deleteDraftLiveDate = MediatorLiveData()
val draftsLiveData = MediatorLiveData()
val saveDraftsLiveData = MediatorLiveData() // 自动保存不会回调
- val uploadingImage = ArrayList>()
- val chooseImagesUpload = MutableLiveData>()
- val chooseImagesUploadSuccess = MutableLiveData>()
-
- var uploadImageSubscription: Disposable? = null
- val mapImages = HashMap()
-
fun postAnswer(editContent: String) {
processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
@@ -141,80 +123,6 @@ class AnswerEditViewModel(application: Application,
})
}
- fun postImg(data: Intent) {
- val uris = Matisse.obtainResult(data)
- val pictureList = ArrayList()
- for (uri in uris) {
- val picturePath = PathUtils.getPath(getApplication(), uri)
- if (picturePath != null) {
- if (File(picturePath).length() > ImageUtils.getUploadFileMaxSize()) {
- val count = ImageUtils.getUploadFileMaxSize() / 1024 / 1024
- val application: Application = getApplication()
- Utils.toast(getApplication(), application.getString(R.string.pic_max_hint, count))
- continue
- }
- Utils.log("picturePath = $picturePath")
- pictureList.add(picturePath)
- } else {
- Utils.log("picturePath is null")
- }
- }
-
- if (pictureList.size == 0) return
- uploadImageSubscription = UploadImageUtils.compressAndUploadImageList(UploadImageUtils.UploadType.answer, pictureList
- , false, object : UploadImageUtils.OnUploadImageListListener {
- override fun onProgress(total: Long, progress: Long) {
- }
-
- override fun onCompressSuccess(imageUrls: List) {
- val chooseImageMd5Map = LinkedHashMap()
- imageUrls.forEach {
- chooseImageMd5Map[MD5Utils.getUrlMD5(it)] = ""
- }
- uploadingImage.add(chooseImageMd5Map)
- chooseImagesUpload.postValue(chooseImageMd5Map)
-
- }
- override fun onSuccess(imageUrl: LinkedHashMap, errorMap: Map) {
- val uploadMap = uploadingImage.find { it.containsKey(MD5Utils.getUrlMD5(imageUrl.entries.iterator().next().key)) }
- uploadMap?.let {
- for (key in imageUrl.keys) {
- uploadMap[MD5Utils.getUrlMD5(key)] = AnswerEditActivity.FILE_HOST + key.decodeURI()
- mapImages[TextUtils.htmlEncode(key).decodeURI()] = imageUrl[key] ?: ""
- }
- chooseImagesUploadSuccess.postValue(uploadMap)
- uploadingImage.remove(uploadMap)
- }
- val errorSize = pictureList.size - imageUrl.size
- if (errorSize > 0) {
- for (error in errorMap.values) {
- if (error is HttpException && error.code() == 403) {
- Utils.toast(getApplication(), errorSize.toString() + "张违规图片上传失败")
- return
- }
- }
- Utils.toast(getApplication(), errorSize.toString() + "张图片上传失败")
- }
- }
-
- override fun onError(errorMap: Map) {
- val errorSize = pictureList.size
-
- for (error in errorMap.values) {
- if (error is HttpException && error.code() == 403) {
- Utils.toast(getApplication(), errorSize.toString() + "张违规图片上传失败")
- return
- }
- }
- if (errorSize == 1) {
- Utils.toast(getApplication(), "图片上传失败")
- } else {
- Utils.toast(getApplication(), errorSize.toString() + "张图片上传失败")
- }
- }
- })
- }
-
fun getUserAnswerDrafts() {
mApi
.getUserAnswerDrafts(question.id,
@@ -260,7 +168,9 @@ class AnswerEditViewModel(application: Application,
super.onResponse(response)
if (forcedExit) {
saveDraftsLiveData.postValue(true)
- Utils.toast(getApplication(), "回答已保存到草稿箱")
+ if (checkIsAllUploadedAndToast()) {
+ Utils.toast(getApplication(), "回答已保存到草稿箱")
+ }
EventBus.getDefault().post(EBReuse(AnswerEditActivity.ANSWER_DRAFT_CHANGE_TAG))
} else {
if (mPostDraftsCount >= AnswerEditActivity.SAVE_DRAFTS_TOAST_COUNT) {
@@ -280,6 +190,8 @@ class AnswerEditViewModel(application: Application,
})
}
+ override fun getRichType(): RichType = RichType.ANSWER
+
class Factory(private val mApplication: Application,
private val answerId: String?,
private val answerContent: String?,
diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleAdapter.kt b/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleAdapter.kt
index 424dcb01ab..bbdb554cb2 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleAdapter.kt
@@ -4,17 +4,24 @@ import android.content.Context
import android.text.SpannableStringBuilder
import android.view.View
import android.view.ViewGroup
+import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.ItemViewType
import com.gh.common.syncpage.ISyncAdapterHandler
import com.gh.common.util.SpanBuilder
+import com.gh.common.util.toDrawable
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder
import com.gh.gamecenter.baselist.ListAdapter
import com.gh.gamecenter.databinding.CommunityMyAnswerItemBinding
import com.gh.gamecenter.qa.answer.MyAnswerViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
+import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
+import com.gh.gamecenter.qa.entity.Questions
+import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
+import com.gh.gamecenter.qa.questions.invite.QuestionsInviteActivity
+import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
class MyArticleAdapter(context: Context,
private val mEntrance: String,
@@ -51,15 +58,26 @@ class MyArticleAdapter(context: Context,
holder.bindItem(entity, mEntrance)
holder.binding.executePendingBindings()
holder.binding.imageContainer.bindData(entity.transformAnswerEntity(), mEntrance, mPath)
- if (entity.getPassVideos().isNotEmpty() && entity.images.isNotEmpty()) {
- val title = holder.binding.title.text
- val videoSpan = SpanBuilder(" ").image(1, " ".length, R.drawable.ic_article_video_label).build()
- holder.binding.title.text = SpannableStringBuilder()
- .append(title)
- .append(videoSpan)
+ val spanBuilder = SpannableStringBuilder()
+ if (entity.type == "question") {
+ val title = " ${holder.binding.title.text}"
+ val askLabelSpan = SpanBuilder(title).image(0, 1, R.drawable.ic_ask_label).build()
+ spanBuilder.append(askLabelSpan)
+ } else {
+ spanBuilder.append(holder.binding.title.text)
}
+ holder.binding.title.text = spanBuilder
+ if (entity.getPassVideos().isNotEmpty() && entity.images.isNotEmpty()) {
+ val videoSpan = SpanBuilder(" ").image(1, " ".length, R.drawable.ic_article_video_label).build()
+ spanBuilder.append(videoSpan)
+ }
+
holder.itemView.setOnClickListener {
- mContext.startActivity(ArticleDetailActivity.getIntent(mContext, entity.community, entity.id, mEntrance, mPath))
+ if (entity.type == "question") {
+ mContext.startActivity(NewQuestionDetailActivity.getIntent(mContext, entity.id, mEntrance, mPath))
+ } else {
+ mContext.startActivity(ArticleDetailActivity.getIntent(mContext, entity.bbs, entity.id, mEntrance, mPath))
+ }
}
} else if (holder is FooterViewHolder) {
holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver)
diff --git a/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleFragment.kt b/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleFragment.kt
index 9605139395..4612a528e2 100644
--- a/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleFragment.kt
+++ b/app/src/main/java/com/gh/gamecenter/qa/article/MyArticleFragment.kt
@@ -14,10 +14,12 @@ import com.gh.gamecenter.baselist.LoadType
import com.gh.gamecenter.baselist.NormalListViewModel
import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
+import com.gh.gamecenter.qa.entity.AnswerEntity
import com.gh.gamecenter.qa.entity.ArticleEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Observable
+import io.reactivex.functions.Function
class MyArticleFragment : ListFragment>() {
@@ -37,7 +39,16 @@ class MyArticleFragment : ListFragment>? {
- return RetrofitManager.getInstance(HaloApp.getInstance().application).api.getMyArticle(mTargetUserId, page)
+ return RetrofitManager.getInstance(HaloApp.getInstance().application).api.getMyArticleAndQuestion(mTargetUserId, page)
+ .flatMap(object :Function, Observable>>{
+ override fun apply(list: List): Observable