diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7946048092..049c58de7d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -674,6 +674,10 @@ android:screenOrientation="landscape" android:theme="@style/AppFullScreenTheme"/> + + () { 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/ForumDetailEntity.kt b/app/src/main/java/com/gh/gamecenter/entity/ForumDetailEntity.kt index 6e8e72c3be..e9f1eec5ab 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/ForumDetailEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/ForumDetailEntity.kt @@ -15,4 +15,13 @@ data class ForumDetailEntity( @SerializedName("zone_tab") var zone: ZoneEntity? = null, var me: MeEntity = MeEntity() -) \ No newline at end of file +) { + fun convertForumDetailEntityToForumEntity(): ForumEntity { + val forumEntity = ForumEntity() + forumEntity.id = id + forumEntity.name = name + forumEntity.game = game + forumEntity.orderTag = System.currentTimeMillis() + 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..4cc98bed5f 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/ForumEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/ForumEntity.kt @@ -1,8 +1,12 @@ 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(), @@ -10,7 +14,8 @@ data class ForumEntity( @SerializedName("is_follow") var isFollow: Boolean = false, //本地字段,判断是否是推荐论坛 - var isRecommend: Boolean = false + var isRecommend: Boolean = false, + var orderTag: Long = 0 ) data class ForumCategoryEntity( 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..f8718ab257 100644 --- a/app/src/main/java/com/gh/gamecenter/entity/MeEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/entity/MeEntity.kt @@ -65,6 +65,7 @@ class MeEntity(@SerializedName("is_community_voted") @SerializedName("is_version_requested") var isVersionRequested: Boolean = false, + @SyncPage(syncNames = [SyncFieldConstants.IS_FOLLOWER]) @SerializedName("is_follower", alternate = ["is_follow"]) var isFollower: Boolean = false, // 是否已经关注该用户 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/ForumDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/detail/ForumDetailViewModel.kt index 1de25fe3ff..d4b071a4de 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 @@ -7,19 +7,23 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider 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.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 { @@ -34,6 +38,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/ForumMyFollowActivity.kt b/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowActivity.kt deleted file mode 100644 index 76765bc2e9..0000000000 --- a/app/src/main/java/com/gh/gamecenter/forum/follow/ForumMyFollowActivity.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.gh.gamecenter.forum.follow - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import com.gh.gamecenter.NormalActivity - -class ForumMyFollowActivity : NormalActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setNavigationTitle("我的关注") - } - - companion object { - fun getIntent(context: Context): Intent { - return getTargetIntent(context, ForumMyFollowActivity::class.java, ForumMyFollowFragment::class.java) - } - } -} \ No newline at end of file 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..3c71bf2313 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ArticleItemVideoView.kt @@ -0,0 +1,229 @@ +package com.gh.gamecenter.forum.home + +import android.app.Activity +import android.app.Application +import android.content.Context +import android.os.Bundle +import android.os.Handler +import android.util.AttributeSet +import android.util.Log +import android.view.Surface +import android.view.View +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import com.facebook.drawee.view.SimpleDraweeView +import com.gh.common.observer.MuteCallback +import com.gh.common.observer.VolumeObserver +import com.gh.common.util.ImageUtils +import com.gh.gamecenter.R +import com.gh.gamecenter.qa.entity.CommunityVideoEntity +import com.gh.gamecenter.video.detail.CustomManager +import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer +import com.shuyu.gsyvideoplayer.video.base.GSYVideoView +import kotlinx.android.synthetic.main.piece_video_control.view.* +import java.util.* + +class ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : StandardGSYVideoPlayer(context, attrs) { + + private var mMuteCallback: MuteCallback + private var mVolumeObserver: VolumeObserver + private var mVideoEntity: CommunityVideoEntity? = null + var uuid = UUID.randomUUID().toString() + + var thumbImage: SimpleDraweeView = findViewById(R.id.thumbImage) + var durationTv: TextView = findViewById(R.id.durationTv) + var completeContainer: LinearLayout = findViewById(R.id.completeContainer) + var replayIv: ImageView = findViewById(R.id.replayIv) + var replayTv: TextView = findViewById(R.id.replayTv) + var volume: ImageView = findViewById(R.id.volume) + + override fun getLayoutId(): Int { + return R.layout.layout_article_item_video + } + + init { + post { + volume.setOnClickListener { toggleMute() } + } + + mMuteCallback = object : MuteCallback { + override fun onMute(isMute: Boolean) { + if (isMute) { + mute() + } else { + unMute() + } + } + } + + mVolumeObserver = VolumeObserver(context, Handler(), mMuteCallback) + } + + 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 + } + } + + fun updateThumb(url: String) { + ImageUtils.display(thumbImage, url) + } + + fun updateDurationTv(duration: String) { + durationTv.text = duration + } + + fun updateVideoData(video: CommunityVideoEntity) { + 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) + replayIv.setOnClickListener { + startButton.performClick() +// violenceUpdateMuteStatus() +// uploadVideoStreamingPlaying("重新播放") + } + replayTv.setOnClickListener { replayIv.performClick() } + } + +// if (currentState == GSYVideoView.CURRENT_STATE_PLAYING) { +// setViewShowState(mBottomProgressBar, View.VISIBLE) +// } + + if (currentState == GSYVideoView.CURRENT_STATE_AUTO_COMPLETE) { + hideAllWidget() + setViewShowState(completeContainer, View.VISIBLE) + } else { + setViewShowState(completeContainer, View.GONE) + } + } + + override fun changeUiToPlayingClear() { + super.changeUiToPlayingClear() +// setViewShowState(mBottomProgressBar, View.GONE) + } + + override fun changeUiToPlayingShow() { + super.changeUiToPlayingShow() + setViewShowState(mBottomProgressBar, View.VISIBLE) + } + + private fun toggleMute() { + if (mVideoEntity?.videoIsMuted == true) { + unMute() + } else { + mute() + } + } + + fun updateMuteStatus() { + if (mVideoEntity?.videoIsMuted == true) { + mute() + } else { + unMute() + } + } + + private fun mute() { + mVideoEntity?.videoIsMuted = true + volume.setImageResource(R.drawable.ic_article_video_volume_off) + CustomManager.getCustomManager(getKey()).isNeedMute = true + } + + private fun unMute() { + mVideoEntity?.videoIsMuted = false + volume.setImageResource(R.drawable.ic_article_video_volume_on) + CustomManager.getCustomManager(getKey()).isNeedMute = false + } + + fun observeVolume(activity: AppCompatActivity) { + activity.contentResolver?.registerContentObserver( + android.provider.Settings.System.CONTENT_URI, true, mVolumeObserver) + + activity.application?.registerActivityLifecycleCallbacks( + object : Application.ActivityLifecycleCallbacks { + override fun onActivityPaused(a: Activity) { + if (activity == a) { + activity.contentResolver?.unregisterContentObserver(mVolumeObserver) + activity.application?.unregisterActivityLifecycleCallbacks(this) + } + } + + override fun onActivityStarted(activity: Activity) { + } + + override fun onActivityDestroyed(activity: Activity) { + } + + override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) { + } + + override fun onActivityStopped(activity: Activity) { + } + + override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { + } + + override fun onActivityResumed(activity: Activity) { + } + }) + } + + fun getKey(): String { + return uuid + } +} \ 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..911134b7d3 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 @@ -2,13 +2,11 @@ package com.gh.gamecenter.forum.home import android.text.SpannableStringBuilder -import android.text.Spanned import android.view.View +import androidx.appcompat.app.AppCompatActivity 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 @@ -22,6 +20,7 @@ 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.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : BaseAnswerOrArticleItemViewHolder(binding.root) { @@ -60,6 +59,8 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) : B } binding.imageContainer.bindData(entity, entrance, path) + bindVideoData(entity) + val user = entity.user binding.userBadgeName.setOnClickListener { binding.userBadgeIcon.performClick() } binding.userBadgeIcon.setOnClickListener { @@ -78,16 +79,68 @@ 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() } + fun bindVideoData(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 + } + + GSYVideoOptionBuilder() + .setIsTouchWiget(false) + .setUrl(video.url) + .setRotateViewAuto(false) + .setCacheWithPlay(true) + .setRotateWithSystem(false) + .setReleaseWhenLossAudio(true) + .setLooping(false) + .setShowFullAnimation(false) + .setEnlargeImageRes(R.drawable.ic_article_video_full_screen) + .build(visibleView) + visibleView.run { + updateVideoData(video) + updateThumb(video.poster) + updateDurationTv(video.duration) + updateMuteStatus() + observeVolume(itemView.context as AppCompatActivity) + } + } + } + } + override fun bindCommendAndVote(entity: AnswerEntity, entrance: String) { if (entity.type == "community_article") { binNormalView(entity) } else { if (entity.questions.answerCount > 0) { commentCount.text = entity.questions.answerCount.toString() - commentCount.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(itemView.context, R.drawable.community_question_answer_count), null, null, null) + commentCount.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(itemView.context, R.drawable.community_comment_count), null, null, null) } else { commentCount.text = "我来回答" commentCount.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(itemView.context, R.drawable.community_question_answer_edit), null, null, null) 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..0e37b68251 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,6 +1,7 @@ package com.gh.gamecenter.forum.home import android.content.Context +import android.graphics.Color import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat @@ -9,19 +10,17 @@ 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.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 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 +37,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 +55,20 @@ 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) + 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) 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)) } } + 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..9b3903904e 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,97 +1,87 @@ 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.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.LazyListFragment import com.gh.gamecenter.baselist.ListAdapter -import com.gh.gamecenter.baselist.ListFragment +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.qa.CommunityFragment import com.gh.gamecenter.qa.entity.ArticleEntity import com.gh.gamecenter.user.UserViewModel -import kotterknife.bindView import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode -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 var mBinding: FragmentForumListBinding? = null private lateinit var mAdapter: ForumArticleListAdapter private var mPath = "" - 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 } }) + + super.onFragmentFirstVisible() + + mViewModel?.getRecordForums() } - 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 - } else { - mNoLoginView.visibility = View.GONE - onLoadRefresh() + override fun initRealView() { + super.initRealView() + + mViewModel?.recordForumsLiveData?.observeNonNull(viewLifecycleOwner) { + mBaseHandler.postDelayed({ + initRecordForums(it) + }, 500) } - mLoginTv.setOnClickListener { - CheckLoginUtils.checkLogin(requireContext(), mEntrance, null) + + mBinding?.run { + nestedScrollRoot.setOnScrollChangeListener( + NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY -> + val dy = scrollY - oldScrollY + 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 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 onRealLayoutInflated(inflatedView: View) { + super.onRealLayoutInflated(inflatedView) + mBinding = FragmentForumListBinding.bind(inflatedView) } 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(): RecyclerView.ItemDecoration { - return HorizontalDividerItemDecoration.Builder(requireContext()) - .size(0.5f.dip2px()) - .margin(20f.dip2px()) - .color(ContextCompat.getColor(requireContext(), R.color.text_eeeeee)).build() - } + override fun getItemDecoration() = null override fun provideListAdapter(): ListAdapter<*> { if (!::mAdapter.isInitialized) { @@ -100,45 +90,30 @@ class ForumArticleListFragment : ListFragment) { + mBinding?.run { + recordForumsContainer.visibility = View.VISIBLE + recordForumsMore.setOnClickListener { + (parentFragment as? NewForumHomeFragment)?.run { + setCurrentItem(NewForumHomeFragment.TAB_FORUM_INDEX) + } + } + recordForumsRv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false) + recordForumsRv.adapter = ForumRecordsAdapter(requireContext(), "社区-论坛-关注论坛", ArrayList(list)) + } + } + fun onRefresh(filter: String) { mViewModel?.sort = if (filter == "最新发布") "time.edit" else "time.comment" onRefresh() } - override fun onLoadEmpty() { - super.onLoadEmpty() - if (mPath == "关注") { - mReuseNoData?.visibility = View.GONE - mNoFollowView.visibility = View.VISIBLE - } - getDumbRefreshLayout()?.finishRefresh() - } - - override fun onLoadDone() { - super.onLoadDone() - mNoFollowView.visibility = View.GONE - getDumbRefreshLayout()?.finishRefresh() - } - - override fun onLoadError() { - super.onLoadError() - getDumbRefreshLayout()?.finishRefresh() - } - - private fun getDumbRefreshLayout(): DumbRefreshLayout? { - val parentFragment = parentFragment - if (parentFragment is ForumHomeFragment) { - parentFragment.refreshHeader.setFinishText("刷新完成") - if (parentFragment.refreshLayout.isRefreshing) { - ToastUtils.showToast("内容已刷新") - } - return parentFragment.refreshLayout - } - return null - } - - override fun isAutomaticLoad(): Boolean = false - override fun scrollToTop() { mListRv.scrollToPosition(0) } @@ -154,4 +129,25 @@ class ForumArticleListFragment : ListFragment(application) { +class ForumArticleListViewModel(application: Application) : ListViewModel(application) { + + private val mForumDao = AppDatabase.getInstance(HaloApp.getInstance()).forumDao() + val recordForumsLiveData = MutableLiveData>() var sort: String = "time.comment"//排序 time.edit 最新发布 time.comment 最新回复 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()) + return RetrofitManager.getInstance(getApplication()) .api.getForumRecommendsArticle(UrlFilterUtils.getFilterQuery(sort, "-1"), page) - } - } - - override fun load(loadType: LoadType?) { - if (path == "关注" && !UserManager.getInstance().isLoggedIn) return - super.load(loadType) } override fun mergeResultLiveData() { mResultLiveData.addSource(mListLiveData) { mResultLiveData.postValue(it) } } - class Factory(val path: String) : ViewModelProvider.NewInstanceFactory() { - override fun create(modelClass: Class): T { - return ForumArticleListViewModel(HaloApp.getInstance().application, path) as T - } + @SuppressLint("CheckResult") + fun getRecordForums() { + mForumDao.getForum() + .subscribe({ + it?.run { + if (it.isNotEmpty()) recordForumsLiveData.postValue(this) + } + }, { }) } } \ 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..16ca7706bd --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumFragment.kt @@ -0,0 +1,167 @@ +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.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.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 + + 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?.followForums?.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) + } + mViewModel?.getHotForum() + } else { + reuseNoneData.root.visibility = View.GONE + reuseNoConnection.root.visibility = View.VISIBLE + reuseNoConnection.root.setOnClickListener { + reuseLoading.root.visibility = View.VISIBLE + mViewModel?.getFollowForum() + } + } + } + }) + + mViewModel?.hotForums?.observe(viewLifecycleOwner, Observer { + mBinding?.run { + if (mHaveFollowForum) { + if (it != null && it.isNotEmpty()) { + 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?.getHotForum() + } + } + } + } + }) + + initWelfare() + } + + private fun initFollowForums(list: List) { + mBinding?.run { + followForumContainer.visibility = View.VISIBLE + followMore.setOnClickListener { startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_FOLLOW)) } + 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 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) { + val adapter = followForumRv.adapter as? ForumRecordsAdapter + adapter?.run { + list.add(forumFollowChange.forumEntity) + notifyDataSetChanged() + } + } else { + initFollowForums(listOf(forumFollowChange.forumEntity)) + } + } else { + val adapter = followForumRv.adapter as? ForumRecordsAdapter + adapter?.run { + val findEntity = list.find { it.id == forumFollowChange.forumEntity.id } + list.remove(findEntity) + if (list.isEmpty()) { + followForumContainer.visibility = View.GONE + } else { + notifyDataSetChanged() + } + } + } + + } + } +} \ 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 2ac021888f..641c3594fc 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,7 +30,7 @@ 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 @@ -249,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)) } } } 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..e14941b20c --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumRecordsAdapter.kt @@ -0,0 +1,45 @@ +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, + var list: ArrayList) + : BaseRecyclerAdapter(context) { + + + override fun getItemCount() = list.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 = list[position] + entity = forumEntity + executePendingBindings() + + 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/ForumViewModel.kt b/app/src/main/java/com/gh/gamecenter/forum/home/ForumViewModel.kt new file mode 100644 index 0000000000..7ce321d7cb --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/forum/home/ForumViewModel.kt @@ -0,0 +1,95 @@ +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.LogUtils +import com.gh.gamecenter.entity.CatalogEntity +import com.gh.gamecenter.entity.ForumEntity +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 com.halo.assistant.HaloApp +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 followForums = MediatorLiveData>() + val hotForums = MediatorLiveData>() + + init { + if (CheckLoginUtils.isLogin()) { + getFollowForum() + } else { + getHotForum() + } + } + + @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) + followForums.postValue(response) + } + + override fun onFailure(e: HttpException?) { + super.onFailure(e) + followForums.postValue(null) + } + }) + } + + @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 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/NewForumHomeFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/home/NewForumHomeFragment.kt new file mode 100644 index 0000000000..d578419790 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/forum/home/NewForumHomeFragment.kt @@ -0,0 +1,257 @@ +package com.gh.gamecenter.forum.home + +import android.graphics.Typeface +import android.util.Log +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 butterknife.OnClick +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.FragmentNewForumHomeBinding +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.VideoInsertType +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 kotlinx.android.synthetic.main.fragment_new_forum_home.* +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode +import kotlin.math.abs + +class NewForumHomeFragment : LazyFragment() { + + private var mBinding: FragmentNewForumHomeBinding? = null + private var mFragmentList = arrayListOf() + private var mTitleList = arrayListOf("推荐", "论坛") + private var mTabList = arrayListOf() + + override fun getRealLayoutId(): Int { + return R.layout.fragment_new_forum_home + } + + override fun onRealLayoutInflated(inflatedView: View) { + mBinding = FragmentNewForumHomeBinding.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) + + 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, VideoInsertType.GAME_BBS, 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/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..51cff29fcf --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListAdapter.kt @@ -0,0 +1,113 @@ +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() + + 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..fd223c036e --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/forum/list/ForumListVIewModel.kt @@ -0,0 +1,56 @@ +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) + 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/ForumOrUserSearchFragment.kt b/app/src/main/java/com/gh/gamecenter/forum/search/ForumOrUserSearchFragment.kt index 5fbdfd8520..01522eb819 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 @@ -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 2a754435d0..7e6e6cbb30 100644 --- a/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java +++ b/app/src/main/java/com/gh/gamecenter/fragment/MainWrapperFragment.java @@ -50,6 +50,7 @@ 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.NewForumHomeFragment; import com.gh.gamecenter.game.GameFragment; import com.gh.gamecenter.message.MessageUnreadRepository; import com.gh.gamecenter.message.MessageUnreadViewModel; @@ -147,7 +148,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem videoArgs.putBoolean(EntranceUtils.KEY_IS_HOME_VIDEO, true); homeVideoFragment.setArguments(videoArgs); - fragments.add(new ForumHomeFragment()); + fragments.add(new NewForumHomeFragment()); fragments.add(homeVideoFragment); if (mViewModel.shouldHideVideoTab()) { 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 a0c740afc6..764bb7e331 100644 --- a/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt +++ b/app/src/main/java/com/gh/gamecenter/personalhome/UserHomeFragment.kt @@ -308,7 +308,7 @@ class UserHomeFragment : NormalFragment() { ?: UserVideoHistoryFragment.getInstance(mUserHomeViewModel.userId, count) val fragmentList = listOf(gameFragment, qaFragment, videoFragment) - val titleList = listOf("游戏评论", "论坛", "视频") + val titleList = listOf("游戏", "论坛", "视频") val countList = listOf(count.gameComment, count.getQaCount(), count.video) viewpager.offscreenPageLimit = fragmentList.size @@ -330,11 +330,9 @@ class UserHomeFragment : NormalFragment() { private fun getTabView(title: String, count: Int): 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 } 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..d884906f80 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 @@ -20,6 +20,7 @@ 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 +35,8 @@ 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 forumNameContainer: View? = itemView.findViewById(R.id.forumNameContainer) + val concernBtn: View? = itemView.findViewById(R.id.concernBtn) open fun bindCommendAndVote(entity: AnswerEntity, entrance: String) { @@ -99,6 +102,10 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH LogUtils.uploadAccessToBbs(entity.community.id, "文章外所属论坛") } + forumNameContainer?.setOnClickListener { + forumNameTv.performClick() + } + commentCountContainer.setOnClickListener { if (filterIllegalCommentStatus(entity.commentable, entity.active)) return@setOnClickListener @@ -360,6 +367,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/article/detail/ArticleDetailViewModel.kt b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt index 562cf67d46..181987f385 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/article/detail/ArticleDetailViewModel.kt @@ -177,6 +177,15 @@ class ArticleDetailViewModel(application: Application, } } + private fun syncFollowData(isFollow: Boolean) { + articleId.apply { + SyncPageRepository.postSyncData(SyncDataEntity(this, + SyncFieldConstants.IS_FOLLOWER, + isFollow, + checkFieldEntity = true)) + } + } + fun collectionCommand(isCollection: Boolean, callback: (isFollow: Boolean) -> Unit) { val observable = if (isCollection) { mApi.postCommunityArticleFavorites(UserManager.getInstance().userId, communityId, articleId) @@ -233,9 +242,11 @@ class ArticleDetailViewModel(application: Application, if (isFollow) { // 关注成功 mFollowLiveData.postValue(true) + syncFollowData(true) } else { // 取消关注成功 mFollowLiveData.postValue(false) + syncFollowData(false) } } diff --git a/app/src/main/java/com/gh/gamecenter/qa/entity/AnswerEntity.kt b/app/src/main/java/com/gh/gamecenter/qa/entity/AnswerEntity.kt index 09361c5e1a..f313a4f0a0 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/entity/AnswerEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/entity/AnswerEntity.kt @@ -70,6 +70,9 @@ class AnswerEntity() : Parcelable { @SerializedName("community_name") var communityName: String? = null + @SerializedName("community_icon") + var communityIcon: String = "" + @SyncPage(syncNames = [SyncFieldConstants.ANSWER_COMMENT_COUNT, SyncFieldConstants.ARTICLE_COMMENT_COUNT]) @SerializedName("comment_count") var commentCount: Int = 0 diff --git a/app/src/main/java/com/gh/gamecenter/qa/entity/CommunityVideoEntity.kt b/app/src/main/java/com/gh/gamecenter/qa/entity/CommunityVideoEntity.kt index 0f07eceb69..d8e1e40c23 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/entity/CommunityVideoEntity.kt +++ b/app/src/main/java/com/gh/gamecenter/qa/entity/CommunityVideoEntity.kt @@ -1,6 +1,7 @@ package com.gh.gamecenter.qa.entity import android.os.Parcelable +import kotlinx.android.parcel.IgnoredOnParcel import kotlinx.android.parcel.Parcelize @Parcelize @@ -10,4 +11,8 @@ data class CommunityVideoEntity(val id: String = "", var status: String = "", // 有三种状态 pass通过,fail未通过,pending审核中 val poster: String = "", var width: Int = 0, - var height: Int = 0) : Parcelable \ No newline at end of file + var height: Int = 0, + //本地数据 + @IgnoredOnParcel + var videoIsMuted: Boolean = false //是否静音标记 +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index 58f0f2087a..1bb3a24de1 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -2627,6 +2627,12 @@ public interface ApiService { @GET("./bbses:hot") Observable> getHotForum(); + /** + * 热门论坛列表 + */ + @GET("./bbses:hot") + Observable> getHotForumWithPage(@Query("page") int page); + /** * 获取论坛分类 */ diff --git a/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java b/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java index 12b9b51c84..859d96c1ef 100644 --- a/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java +++ b/app/src/main/java/com/gh/gamecenter/room/AppDatabase.java @@ -13,16 +13,19 @@ import androidx.sqlite.db.SupportSQLiteDatabase; import com.gh.common.videolog.VideoRecordDao; import com.gh.common.videolog.VideoRecordEntity; import com.gh.gamecenter.entity.CommentDraft; +import com.gh.gamecenter.entity.ForumEntity; import com.gh.gamecenter.entity.HomePluggableFilterEntity; import com.gh.gamecenter.entity.SignEntity; import com.gh.gamecenter.entity.SimulatorGameRecordEntity; import com.gh.gamecenter.qa.entity.AnswerEntity; import com.gh.gamecenter.room.converter.ApkArrayListConverter; +import com.gh.gamecenter.room.converter.SimpleGameConverter; import com.gh.gamecenter.room.converter.SimulatorConverter; import com.gh.gamecenter.room.converter.StringArrayListConverter; import com.gh.gamecenter.room.converter.TagStyleListConverter; import com.gh.gamecenter.room.dao.AnswerDao; import com.gh.gamecenter.room.dao.CommentDraftDao; +import com.gh.gamecenter.room.dao.ForumDao; import com.gh.gamecenter.room.dao.HomePluggableFilterDao; import com.gh.gamecenter.room.dao.SignDao; import com.gh.gamecenter.room.dao.SimulatorGameDao; @@ -39,12 +42,14 @@ import com.gh.gamecenter.video.upload.UploadEntity; CommentDraft.class, HomePluggableFilterEntity.class, VideoRecordEntity.class, - SimulatorGameRecordEntity.class}, version = 18, exportSchema = false) + SimulatorGameRecordEntity.class, + ForumEntity.class}, version = 19, exportSchema = false) @TypeConverters({ StringArrayListConverter.class, TagStyleListConverter.class, SimulatorConverter.class, - ApkArrayListConverter.class + ApkArrayListConverter.class, + SimpleGameConverter.class }) public abstract class AppDatabase extends RoomDatabase { @@ -62,6 +67,8 @@ public abstract class AppDatabase extends RoomDatabase { public abstract SimulatorGameDao simulatorGameDao(); + public abstract ForumDao forumDao(); + private static AppDatabase sInstance; private static final String DATABASE_NAME = "gh-db"; @@ -187,6 +194,13 @@ public abstract class AppDatabase extends RoomDatabase { } }; + static final Migration MIGRATION_18_19 = new Migration(18, 19) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("CREATE TABLE ForumEntity (id TEXT NOT NULL PRIMARY KEY, game TEXT NOT NULL, name TEXT NOT NULL, isFollow INTEGER NOT NULL DEFAULT 0, isRecommend INTEGER NOT NULL DEFAULT 0, orderTag INTEGER NOT NULL DEFAULT 0)"); + } + }; + private static AppDatabase buildDatabase(Context context) { return Room.databaseBuilder(context, AppDatabase.class, DATABASE_NAME) .addMigrations( @@ -204,7 +218,8 @@ public abstract class AppDatabase extends RoomDatabase { MIGRATION_14_15, MIGRATION_15_16, MIGRATION_16_17, - MIGRATION_17_18 + MIGRATION_17_18, + MIGRATION_18_19 ) // 不允许主线程查询 .allowMainThreadQueries() diff --git a/app/src/main/java/com/gh/gamecenter/room/converter/SimpleGameConverter.kt b/app/src/main/java/com/gh/gamecenter/room/converter/SimpleGameConverter.kt new file mode 100644 index 0000000000..2ae56bf945 --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/room/converter/SimpleGameConverter.kt @@ -0,0 +1,18 @@ +package com.gh.gamecenter.room.converter + +import androidx.room.TypeConverter +import com.gh.common.util.toJson +import com.gh.common.util.toObject +import com.gh.gamecenter.entity.SimpleGame + +class SimpleGameConverter { + @TypeConverter + fun toSimpleGameString(data: SimpleGame?): String { + return data?.toJson() ?: "" + } + + @TypeConverter + fun toSimpleGameEntity(token: String?): SimpleGame { + return token?.toObject() ?: SimpleGame() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/gh/gamecenter/room/dao/ForumDao.kt b/app/src/main/java/com/gh/gamecenter/room/dao/ForumDao.kt new file mode 100644 index 0000000000..92be2d4d8a --- /dev/null +++ b/app/src/main/java/com/gh/gamecenter/room/dao/ForumDao.kt @@ -0,0 +1,19 @@ +package com.gh.gamecenter.room.dao + +import androidx.room.* +import com.gh.gamecenter.entity.ForumEntity +import io.reactivex.Single + +@Dao +interface ForumDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun addForum(forum: ForumEntity) + + @Query("select * from ForumEntity order by orderTag desc") + fun getForum(): Single> + + @Delete + fun deleteForum(answer: ForumEntity) + +} diff --git a/app/src/main/java/com/gh/gamecenter/video/label/VideoLabelActivity.kt b/app/src/main/java/com/gh/gamecenter/video/label/VideoLabelActivity.kt index 3b6e647f50..c2f1c2bde5 100644 --- a/app/src/main/java/com/gh/gamecenter/video/label/VideoLabelActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/video/label/VideoLabelActivity.kt @@ -3,25 +3,7 @@ package com.gh.gamecenter.video.label import android.content.Context import android.content.Intent import android.os.Bundle -import android.view.View -import android.widget.LinearLayout -import androidx.core.content.ContextCompat -import androidx.lifecycle.Observer -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import com.gh.common.util.dip2px -import com.gh.common.util.viewModelProvider -import com.gh.common.view.divider.HorizontalDividerItemDecoration import com.gh.gamecenter.NormalActivity -import com.gh.gamecenter.R -import com.gh.gamecenter.baselist.ListActivity -import com.gh.gamecenter.baselist.ListAdapter -import com.gh.gamecenter.forum.follow.ForumMyFollowActivity -import com.gh.gamecenter.forum.follow.ForumMyFollowAdapter -import com.gh.gamecenter.forum.follow.ForumMyFollowFragment -import com.gh.gamecenter.normal.NormalFragment -import kotterknife.bindView @Deprecated("v5.0.0废弃") class VideoLabelActivity : NormalActivity() { diff --git a/app/src/main/res/drawable-xxhdpi/community_edit_icon.webp b/app/src/main/res/drawable-xxhdpi/community_edit_icon.webp deleted file mode 100644 index 55f98b4ffb..0000000000 Binary files a/app/src/main/res/drawable-xxhdpi/community_edit_icon.webp and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/community_edit_icon.webp b/app/src/main/res/drawable-xxxhdpi/community_edit_icon.webp new file mode 100644 index 0000000000..58ae8dd724 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/community_edit_icon.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_article_video_full_screen.webp b/app/src/main/res/drawable-xxxhdpi/ic_article_video_full_screen.webp new file mode 100644 index 0000000000..5dbb2888ad Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_article_video_full_screen.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_article_video_replay.png b/app/src/main/res/drawable-xxxhdpi/ic_article_video_replay.png new file mode 100644 index 0000000000..7500720b48 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_article_video_replay.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_article_video_share.png b/app/src/main/res/drawable-xxxhdpi/ic_article_video_share.png new file mode 100644 index 0000000000..926ebd464a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_article_video_share.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_article_video_volume_off.webp b/app/src/main/res/drawable-xxxhdpi/ic_article_video_volume_off.webp new file mode 100644 index 0000000000..136ceebc09 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_article_video_volume_off.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_article_video_volume_on.webp b/app/src/main/res/drawable-xxxhdpi/ic_article_video_volume_on.webp new file mode 100644 index 0000000000..7250221800 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_article_video_volume_on.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_forum_accelerator.webp b/app/src/main/res/drawable-xxxhdpi/ic_forum_accelerator.webp new file mode 100644 index 0000000000..aadb563093 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_forum_accelerator.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_forum_detail_game_zone_left.webp b/app/src/main/res/drawable-xxxhdpi/ic_forum_detail_game_zone_left.webp index 169b4b849a..b1472c908f 100644 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_forum_detail_game_zone_left.webp and b/app/src/main/res/drawable-xxxhdpi/ic_forum_detail_game_zone_left.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_forum_game_moment.webp b/app/src/main/res/drawable-xxxhdpi/ic_forum_game_moment.webp new file mode 100644 index 0000000000..992d3d0d12 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_forum_game_moment.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_forum_libao_center.webp b/app/src/main/res/drawable-xxxhdpi/ic_forum_libao_center.webp new file mode 100644 index 0000000000..0a63fec4ed Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_forum_libao_center.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_forum_news.webp b/app/src/main/res/drawable-xxxhdpi/ic_forum_news.webp new file mode 100644 index 0000000000..44ff7586fc Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_forum_news.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_forum_tool_box.webp b/app/src/main/res/drawable-xxxhdpi/ic_forum_tool_box.webp new file mode 100644 index 0000000000..8d345a994c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_forum_tool_box.webp differ diff --git a/app/src/main/res/drawable/button_round_f0f8fa.xml b/app/src/main/res/drawable/button_round_f0f8fa.xml new file mode 100644 index 0000000000..92752d1151 --- /dev/null +++ b/app/src/main/res/drawable/button_round_f0f8fa.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/community_answer_item.xml b/app/src/main/res/layout/community_answer_item.xml index 7456986130..f75193cd88 100644 --- a/app/src/main/res/layout/community_answer_item.xml +++ b/app/src/main/res/layout/community_answer_item.xml @@ -21,7 +21,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" - android:paddingLeft="12dp" + android:paddingLeft="11dp" android:paddingRight="20dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" @@ -31,6 +31,7 @@ android:id="@+id/top_line" android:layout_width="match_parent" android:layout_height="@dimen/cutting_line" + android:layout_marginLeft="9dp" android:background="@color/cutting_line" android:visibility="gone" app:layout_constraintTop_toTopOf="parent" @@ -50,26 +51,27 @@ android:id="@+id/user_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="12dp" - app:avatar_width="32dp" + android:layout_marginTop="11dp" + app:avatar_width="36dp" app:badge_width="12dp" app:border_color="@color/black_alpha_10" app:border_width="1px" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@+id/top_line" - tools:layout_height="48dp" - tools:layout_width="48dp" /> + tools:layout_height="54dp" + tools:layout_width="54dp" /> + + + + + + - + android:gravity="center_vertical" + android:orientation="horizontal" + android:background="@drawable/bg_shape_f5_radius_999"> + + + + + + + + android:orientation="vertical"> - + - + - + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/forum_record_item.xml b/app/src/main/res/layout/forum_record_item.xml new file mode 100644 index 0000000000..a7a9253ce2 --- /dev/null +++ b/app/src/main/res/layout/forum_record_item.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/forum_welfare_item.xml b/app/src/main/res/layout/forum_welfare_item.xml new file mode 100644 index 0000000000..f27e95ecc9 --- /dev/null +++ b/app/src/main/res/layout/forum_welfare_item.xml @@ -0,0 +1,36 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_forum.xml b/app/src/main/res/layout/fragment_forum.xml new file mode 100644 index 0000000000..56308c37a8 --- /dev/null +++ b/app/src/main/res/layout/fragment_forum.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_forum_list.xml b/app/src/main/res/layout/fragment_forum_list.xml index f6014ea42c..a91edd33d8 100644 --- a/app/src/main/res/layout/fragment_forum_list.xml +++ b/app/src/main/res/layout/fragment_forum_list.xml @@ -1,5 +1,6 @@ @@ -9,12 +10,68 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:overScrollMode="never" + android:scrollbars="none"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/hot_forum_item.xml b/app/src/main/res/layout/hot_forum_item.xml new file mode 100644 index 0000000000..b351baaeb9 --- /dev/null +++ b/app/src/main/res/layout/hot_forum_item.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_article_item_video.xml b/app/src/main/res/layout/layout_article_item_video.xml new file mode 100644 index 0000000000..4432b9ef34 --- /dev/null +++ b/app/src/main/res/layout/layout_article_item_video.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/piece_article_video_control.xml b/app/src/main/res/layout/piece_article_video_control.xml new file mode 100644 index 0000000000..a608e268a1 --- /dev/null +++ b/app/src/main/res/layout/piece_article_video_control.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/piece_community_vote_and_comment.xml b/app/src/main/res/layout/piece_community_vote_and_comment.xml index 40367d5bc8..98357099ae 100644 --- a/app/src/main/res/layout/piece_community_vote_and_comment.xml +++ b/app/src/main/res/layout/piece_community_vote_and_comment.xml @@ -22,7 +22,7 @@ android:layout_height="match_parent" android:layout_gravity="center" android:drawableLeft="@drawable/community_comment_count" - android:drawablePadding="8dp" + android:drawablePadding="4dp" android:gravity="center" android:paddingTop="20dp" android:paddingBottom="20dp" diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 566005e321..97251e4145 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -260,6 +260,8 @@ #F67722 #4B4B4B #FF925C + #3087D9 + #C0C6CC #99666666 #6621282E