Newer
Older
CasicSmartTube / app / src / main / java / com / casic / smarttube / fragment / MinePageFragment.kt
package com.casic.smarttube.fragment

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.CountDownTimer
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.FileProvider
import androidx.lifecycle.ViewModelProvider
import com.casic.smarttube.databinding.FragmentMineBinding
import com.casic.smarttube.extensions.compareVersion
import com.casic.smarttube.model.UserDetailModel
import com.casic.smarttube.utils.AuthenticationHelper
import com.casic.smarttube.utils.FileDownloadManager
import com.casic.smarttube.utils.LocaleConstant
import com.casic.smarttube.utils.RSAUtils
import com.casic.smarttube.view.AboutUsActivity
import com.casic.smarttube.view.LoginActivity
import com.casic.smarttube.vm.LoginViewModel
import com.casic.smarttube.vm.UserViewModel
import com.casic.smarttube.vm.VersionViewModel
import com.casic.smarttube.widgets.ProgressDialog
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.pengxh.kt.lite.base.KotlinBaseFragment
import com.pengxh.kt.lite.extensions.calculateSize
import com.pengxh.kt.lite.extensions.createDownloadFileDir
import com.pengxh.kt.lite.extensions.deleteFile
import com.pengxh.kt.lite.extensions.formatFileSize
import com.pengxh.kt.lite.extensions.isNetworkConnected
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
import com.pengxh.kt.lite.utils.ActivityStackManager
import com.pengxh.kt.lite.utils.LoadState
import com.pengxh.kt.lite.utils.LoadingDialog
import com.pengxh.kt.lite.utils.SaveKeyValues
import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog
import java.io.File
import java.nio.charset.StandardCharsets

class MinePageFragment : KotlinBaseFragment<FragmentMineBinding>() {

    private val kTag = "MinePageFragment"
    private val gson = Gson()
    private lateinit var userViewModel: UserViewModel
    private lateinit var loginViewModel: LoginViewModel
    private lateinit var versionViewModel: VersionViewModel

    override fun initViewBinding(
        inflater: LayoutInflater, container: ViewGroup?
    ): FragmentMineBinding {
        return FragmentMineBinding.inflate(inflater, container, false)
    }

    override fun setupTopBarLayout() {

    }

    override fun initOnCreate(savedInstanceState: Bundle?) {
        loginViewModel = ViewModelProvider(this)[LoginViewModel::class.java]
        userViewModel = ViewModelProvider(this)[UserViewModel::class.java]
        versionViewModel = ViewModelProvider(this)[VersionViewModel::class.java]
    }

    override fun observeRequestState() {
        userViewModel.loadState.observe(this) {
            when (it) {
                is LoadState.Loading -> LoadingDialog.show(requireActivity(), "修改中,请稍后")
                is LoadState.Success -> {
                    "修改成功,请重新登录".show(requireContext())
                    LoadingDialog.dismiss()
                    AuthenticationHelper.removeToken()
                    requireContext().navigatePageTo<LoginActivity>()
                    ActivityStackManager.finishAllActivity()
                }

                else -> LoadingDialog.dismiss()
            }
        }

        versionViewModel.loadState.observe(this) {
            when (it) {
                is LoadState.Loading -> LoadingDialog.show(
                    requireActivity(), "检查版本中,请稍后"
                )

                else -> LoadingDialog.dismiss()
            }
        }
    }

    override fun initEvent() {
        binding.userImageView.setOnClickListener {
            "尽情期待~".show(requireContext())
        }

        binding.loginOutButton.setOnClickListener {
            AlertControlDialog.Builder().setContext(requireContext()).setTitle("退出登录")
                .setMessage("确定要退出吗?").setNegativeButton("取消").setPositiveButton("确定")
                .setOnDialogButtonClickListener(object :
                    AlertControlDialog.OnDialogButtonClickListener {
                    override fun onConfirmClick() {
                        if (!requireActivity().isNetworkConnected()) {
                            "网络异常,退出失败".show(requireContext())
                            return
                        }
                        loginViewModel.out(requireContext())
                    }

                    override fun onCancelClick() {}
                }).build().show()
        }

        binding.changePwdLayout.setOnClickListener {
            ChangePasswordDialog.Builder().setContext(requireContext())
                .setOnDialogButtonClickListener(object :
                    ChangePasswordDialog.OnDialogButtonClickListener {
                    override fun onConfirmClick(oldPwd: String, newPwd: String) {
                        val publicKey = RSAUtils.keyStrToPublicKey(AuthenticationHelper.publicKey)!!
                        val oldPassKey = RSAUtils.encryptDataByPublicKey(
                            oldPwd.toByteArray(StandardCharsets.UTF_8), publicKey
                        )
                        val newPassKey = RSAUtils.encryptDataByPublicKey(
                            newPwd.toByteArray(StandardCharsets.UTF_8), publicKey
                        )
                        userViewModel.changePassword(requireContext(), oldPassKey, newPassKey)
                    }
                }).build().show()
        }

        binding.aboutUsLayout.setOnClickListener {
            requireContext().navigatePageTo<AboutUsActivity>()
        }

        binding.updateVersionLayout.setOnClickListener {
            versionViewModel.updateVersion(requireContext())
        }

        binding.updateLogLayout.setOnClickListener {
            "尽情期待~".show(requireContext())
        }

        binding.clearCacheLayout.setOnClickListener {
            //删除缓存之后在设置缓存大小
            LoadingDialog.show(requireActivity(), "清理中,请稍后")
            File(requireContext().cacheDir.path).deleteFile()
            object : CountDownTimer(1500, 500) {
                override fun onTick(millisUntilFinished: Long) {

                }

                override fun onFinish() {
                    LoadingDialog.dismiss()
                    binding.cacheSizeView.text = collectApplicationCache().formatFileSize()
                }
            }.start()
        }

        binding.phoneNumberView.setOnClickListener {
            val intent = Intent()
            intent.action = Intent.ACTION_CALL
            intent.data = Uri.parse("tel:${binding.phoneNumberView.text}")
            startActivity(intent)
        }

        /**
         * 数据监听
         * */
        dataObserve()
    }

    private fun dataObserve() {
        versionViewModel.versionResultData.observe(this) {
            if (it.version.compareVersion()) {
                "已是最新版本,无需更新".show(requireContext())
            } else {
                AlertControlDialog.Builder().setContext(requireContext()).setTitle("提示")
                    .setMessage("有新版本,是否更新?").setNegativeButton("稍后再说")
                    .setPositiveButton("立即下载").setOnDialogButtonClickListener(object :
                        AlertControlDialog.OnDialogButtonClickListener {
                        override fun onConfirmClick() {
                            downloadApk(it.downloadUrl)
                        }

                        override fun onCancelClick() {

                        }
                    }).build().show()
            }
        }

        loginViewModel.outResultData.observe(this) {
            if (it.code == 200) {
                AuthenticationHelper.removeToken()
                ActivityStackManager.finishAllActivity()
            }
        }
    }

    private fun collectApplicationCache(): Long {
        return File(requireContext().cacheDir.path).calculateSize()
    }

    override fun onResume() {
        super.onResume()
        val userDetailJson = SaveKeyValues.getValue(LocaleConstant.USER_DETAIL_KEY, "") as String
        if (userDetailJson.isNotBlank()) {
            val userData = gson.fromJson<UserDetailModel.Data>(
                userDetailJson, object : TypeToken<UserDetailModel.Data>() {}.type
            )
            binding.userNameView.text = userData.name
            binding.userPhoneView.text = String.format("电话:${userData.phone}")
            binding.userDeptView.text = String.format("部门:${userData.deptName}")
        }
        //缓存
        binding.cacheSizeView.text = collectApplicationCache().formatFileSize()
    }

    private fun downloadApk(url: String) {
        val progressDialog = ProgressDialog(requireContext())
        progressDialog.show()
        FileDownloadManager.Builder()
            .setDownloadFileSource(url)
            .setFileSuffix("apk")
            .setFileSaveDirectory(requireContext().createDownloadFileDir())
            .setOnFileDownloadListener(object : FileDownloadManager.OnFileDownloadListener {
                override fun onDownloadStart(total: Long) {
                    progressDialog.setMaxProgress(total)
                }

                override fun onDownloadEnd(file: File) {
                    progressDialog.dismiss()
                    //安装APK文件
                    installApk(file)
                }

                override fun onFailed(t: Throwable) {
                    t.printStackTrace()
                    progressDialog.dismiss()
                }

                override fun onProgressChanged(progress: Long) {
                    progressDialog.updateProgress(progress)
                }
            }).build().start()
    }

    private fun installApk(file: File) {
        val apkUri = FileProvider.getUriForFile(
            requireContext(), "${requireContext().packageName}.provider", file
        )
        val intent = Intent(Intent.ACTION_VIEW).apply {
            setDataAndType(apkUri, "application/vnd.android.package-archive")
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK)
        }
        requireContext().startActivity(intent)
    }
}