feat:媒体文件上传控件优化 (二、三)—客户端 https://jira.shanqu.cc/browse/GHZSCY-6645
This commit is contained in:
@ -21,26 +21,31 @@ import com.gh.common.view.RichEditor
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.qa.editor.*
|
||||
import com.gh.gamecenter.entity.GamesCollectionEntity
|
||||
import com.gh.gamecenter.entity.MyVideoEntity
|
||||
import com.gh.gamecenter.entity.VideoEntity
|
||||
import com.gh.gamecenter.feature.entity.AnswerEntity
|
||||
import com.gh.gamecenter.feature.entity.ArticleEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.qa.editor.*
|
||||
import com.gh.gamecenter.qa.entity.EditorInsertEntity
|
||||
import com.gh.gamecenter.video.poster.PosterEditActivity
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
|
||||
import com.gh.gamecenter.video.upload.UploadManager
|
||||
import com.google.gson.JsonObject
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import com.lightgame.view.CheckableImageView
|
||||
import com.therouter.TheRouter
|
||||
import io.reactivex.disposables.Disposable
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
@ -229,6 +234,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
|
||||
@SuppressLint("AddJavascriptInterface", "ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
VideoPosterFragment.createVideoCoverFile(this)
|
||||
findView()
|
||||
onRichClick()
|
||||
mViewModel = provideViewModel()
|
||||
@ -739,9 +745,9 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
|
||||
mViewModel.id = id
|
||||
mViewModel.videoId = videoId
|
||||
val videoEntity = VideoEntity(url = url)
|
||||
val intent =
|
||||
PosterEditActivity.getIntentByVideo(this@BaseRichEditorActivity, videoEntity)
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
TheRouter.build(RouteConsts.activity.videoCoverEditActivity)
|
||||
.withParcelable(EntranceConsts.KEY_VIDEO_ENTITY, videoEntity)
|
||||
.navigation(this@BaseRichEditorActivity, REQUEST_CODE_IMAGE_CROP)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.core.provider.ICropImageProvider
|
||||
import com.gh.gamecenter.personalhome.background.BackgroundClipActivity
|
||||
import com.halo.assistant.fragment.user.UserPortraitCropImageActivity
|
||||
import com.lightgame.utils.Utils
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
|
||||
@com.therouter.inject.ServiceProvider
|
||||
class CropImageProviderImpl : ICropImageProvider {
|
||||
override fun getCropImageIntent(data: List<Uri>, imageType: Int, entrance: String, context: Context): Intent? {
|
||||
if (data.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
val picturePath = PathUtils.getPath(context, data[0])
|
||||
Utils.log("picturePath = $picturePath")
|
||||
return when (imageType) {
|
||||
|
||||
IMAGE_TYPE_AVATAR -> {// 上传头像
|
||||
UserPortraitCropImageActivity.getIntent(
|
||||
context,
|
||||
picturePath,
|
||||
"我的光环(选择头像)"
|
||||
)
|
||||
}
|
||||
|
||||
IMAGE_TYPE_GAME_COLLECTION_COVER -> {// 游戏单封面
|
||||
CropImageActivity.getIntent(
|
||||
context,
|
||||
picturePath,
|
||||
142 / 328F,
|
||||
false,
|
||||
R.layout.layout_game_collection_crop_image_assist,
|
||||
entrance
|
||||
)
|
||||
}
|
||||
|
||||
IMAGE_TYPE_PERSONAL_BACKGROUND -> { // 用户主页背景
|
||||
BackgroundClipActivity.getIntent(context, picturePath, entrance)
|
||||
}
|
||||
|
||||
else ->
|
||||
null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val IMAGE_TYPE_AVATAR = 1
|
||||
const val IMAGE_TYPE_GAME_COLLECTION_COVER = 2
|
||||
const val IMAGE_TYPE_PERSONAL_BACKGROUND = 3
|
||||
}
|
||||
}
|
||||
@ -3,26 +3,25 @@ package com.gh.gamecenter;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils;
|
||||
import com.gh.gamecenter.common.view.CropImageCustom;
|
||||
import com.gh.gamecenter.common.view.cropbox.CropBoxStyle;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* 裁剪图片
|
||||
*/
|
||||
@ -32,6 +31,8 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
|
||||
public static final String RESULT_CLIP_PATH = "result_clip_path";
|
||||
|
||||
public static final String RESULT_ORIGINAL_PATH = "result_original_path";
|
||||
|
||||
private SoftReference<Bitmap> reference;
|
||||
|
||||
protected boolean mBlackTheme = false;
|
||||
@ -51,7 +52,7 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
Intent intent = new Intent(context, CropImageActivity.class);
|
||||
intent.putExtra(EntranceConsts.KEY_PATH, picturePath);
|
||||
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance);
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_CROP_RATIO, cropRatio);
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_CROP_STYLE, new CropBoxStyle.Rectangle(cropRatio));
|
||||
intent.putExtra(EntranceConsts.KEY_BLACK_THEME, isBlackTheme);
|
||||
intent.putExtra(EntranceConsts.KEY_ASSIST_RES, assistRes);
|
||||
return intent;
|
||||
@ -68,20 +69,14 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mCropImageCustom = findViewById(R.id.cropimage_custom);
|
||||
View statusBarView = findViewById(R.id.status_bar);
|
||||
TextView tvCancel = findViewById(R.id.tv_cancel);
|
||||
TextView tvSubmit = findViewById(R.id.tv_submit);
|
||||
|
||||
mTitleTv.setTextColor(mBlackTheme ? Color.WHITE : Color.BLACK);
|
||||
mToolbar.setBackgroundColor(getResources().getColor(mBlackTheme ? com.gh.gamecenter.common.R.color.text_28282E : com.gh.gamecenter.common.R.color.white));
|
||||
statusBarView.setBackgroundColor(getResources().getColor(mBlackTheme ? com.gh.gamecenter.common.R.color.text_28282E : com.gh.gamecenter.common.R.color.white));
|
||||
|
||||
setNavigationTitle(getString(R.string.title_crop_image));
|
||||
setToolbarMenu(R.menu.menu_positive);
|
||||
MenuItem menuItem = getMenuItem(R.id.layout_menu_positive);
|
||||
TextView menuButton = menuItem.getActionView().findViewById(R.id.menu_answer_post);
|
||||
menuButton.setTextColor(getResources().getColor(com.gh.gamecenter.common.R.color.text_theme));
|
||||
|
||||
float ratio = getIntent().getFloatExtra(EntranceConsts.KEY_IMAGE_CROP_RATIO, 1F);
|
||||
mCropImageCustom.setCropRatio(ratio);
|
||||
CropBoxStyle boxStyle = getIntent().getParcelableExtra(EntranceConsts.KEY_IMAGE_CROP_STYLE);
|
||||
if (boxStyle == null) {
|
||||
boxStyle = new CropBoxStyle.Rectangle(1F);
|
||||
}
|
||||
mCropImageCustom.setCropBoxStyle(boxStyle);
|
||||
|
||||
int assistRes = getIntent().getIntExtra(EntranceConsts.KEY_ASSIST_RES, -1);
|
||||
if (assistRes > 0) {
|
||||
@ -89,8 +84,21 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
addAssistView(view);
|
||||
}
|
||||
|
||||
DisplayUtils.setLightStatusBar(this, !mBlackTheme);
|
||||
DisplayUtils.setStatusBarColor(this, com.gh.gamecenter.common.R.color.transparent, !mBlackTheme);
|
||||
DisplayUtils.setLightStatusBar(this, false);
|
||||
DisplayUtils.setStatusBarColor(this, com.gh.gamecenter.common.R.color.transparent, false);
|
||||
|
||||
tvCancel.setOnClickListener(v -> finish());
|
||||
|
||||
tvSubmit.setOnClickListener(v -> saveImage());
|
||||
}
|
||||
|
||||
protected void saveImage() {
|
||||
Intent data = new Intent();
|
||||
String clipPath = getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg";
|
||||
mCropImageCustom.savePicture(clipPath);
|
||||
data.putExtra(RESULT_CLIP_PATH, clipPath);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -98,20 +106,6 @@ public class CropImageActivity extends ToolBarActivity {
|
||||
return mBlackTheme ? com.gh.gamecenter.common.R.drawable.ic_toolbar_back_white : com.gh.gamecenter.common.R.drawable.ic_bar_back;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.layout_menu_positive) {
|
||||
Intent data = new Intent();
|
||||
String clipPath = getCacheDir().getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg";
|
||||
mCropImageCustom.savePicture(clipPath);
|
||||
|
||||
data.putExtra(RESULT_CLIP_PATH, clipPath);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
return super.onMenuItemClick(item);
|
||||
}
|
||||
|
||||
public void addAssistView(View view) {
|
||||
mCropImageCustom.addAssistView(view);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import com.gh.common.provider.CropImageProviderImpl.Companion.IMAGE_TYPE_GAME_COLLECTION_COVER
|
||||
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.common.util.NewLogUtils
|
||||
@ -45,7 +46,8 @@ class ChooseGameCollectionCoverTypeDialog : BaseDialogFragment() {
|
||||
requireContext(),
|
||||
ChooseType.IMAGE,
|
||||
1,
|
||||
"创建游戏单"
|
||||
"创建游戏单",
|
||||
IMAGE_TYPE_GAME_COLLECTION_COVER
|
||||
), REQUEST_CODE_IMAGE
|
||||
)
|
||||
}
|
||||
@ -101,7 +103,8 @@ class ChooseGameCollectionCoverTypeDialog : BaseDialogFragment() {
|
||||
com.gh.gamecenter.common.R.drawable.bg_choose_option_selector.toDrawable(requireContext())
|
||||
defaultUploadContainer.background =
|
||||
com.gh.gamecenter.common.R.drawable.bg_choose_option_selector.toDrawable(requireContext())
|
||||
cancelBtn.background = com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(requireContext())
|
||||
cancelBtn.background =
|
||||
com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(requireContext())
|
||||
recommentTv.background = R.drawable.bg_game_collection_cover_tag.toDrawable(requireContext())
|
||||
titleTv.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
|
||||
localUploadTitleTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
|
||||
|
||||
@ -313,14 +313,14 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
|
||||
if (mIsCreateGameCollection) {
|
||||
SensorsBridge.trackEvent("GameCollectCreateSuccess", json {
|
||||
"game_collect_status" to if(mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_collect_status" to if (mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_num" to games.size
|
||||
"game_collect_title" to mBinding.gameCollectionTitleEt.text.toString().trim()
|
||||
"game_collect_id" to it.data as String
|
||||
})
|
||||
} else if (mViewModel.gameCollectionPatch != null) {
|
||||
SensorsBridge.trackEvent("GameCollectEditSuccess", json {
|
||||
"game_collect_status" to if(mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_collect_status" to if (mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
|
||||
"game_num" to games.size
|
||||
"game_collect_title" to mBinding.gameCollectionTitleEt.text.toString().trim()
|
||||
"game_collect_id" to mViewModel.gameCollectionPatch?.id
|
||||
@ -355,7 +355,7 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
CheckLoginUtils.checkLogin(this, mEntrance) {}
|
||||
return@observe
|
||||
}
|
||||
ErrorHelper.handleError(this, errorMsg, false, "发布游戏单", "社区实名") {
|
||||
ErrorHelper.handleError(this, errorMsg, false, "发布游戏单", "社区实名") {
|
||||
if (::mMenuPost.isInitialized) {
|
||||
onMenuItemClick(mMenuPost)
|
||||
}
|
||||
@ -433,18 +433,6 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (data == null || resultCode != Activity.RESULT_OK) return
|
||||
when (requestCode) {
|
||||
REQUEST_CODE_IMAGE_CROP -> {
|
||||
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
|
||||
mViewModel.imageUrl = ""
|
||||
mViewModel.imagePath = imagePath
|
||||
if (imagePath.isEmpty()) {
|
||||
mBinding.uploadPictureTv.text = "点击上传图片"
|
||||
} else {
|
||||
mBinding.uploadPictureTv.text = "图片上传中..."
|
||||
mViewModel.uploadPoster()
|
||||
}
|
||||
initPosterUI()
|
||||
}
|
||||
REQUEST_CHOOSE_TAG -> {
|
||||
val tags = data.getParcelableArrayListExtra<TagInfoEntity>(GameCollectionTagSelectFragment.SELECTED_TAG)
|
||||
?: arrayListOf()
|
||||
@ -457,20 +445,16 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
fun onActivityDialogResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
if (requestCode == REQUEST_CODE_IMAGE) {
|
||||
val selectedPaths = Matisse.obtainResult(data)
|
||||
if (!selectedPaths.isNullOrEmpty()) {
|
||||
val path = PathUtils.getPath(this, selectedPaths[0])
|
||||
val intent =
|
||||
CropImageActivity.getIntent(
|
||||
this,
|
||||
path,
|
||||
142 / 328F,
|
||||
false,
|
||||
R.layout.layout_game_collection_crop_image_assist,
|
||||
mEntrance
|
||||
)
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
|
||||
mViewModel.imageUrl = ""
|
||||
mViewModel.imagePath = imagePath
|
||||
if (imagePath.isEmpty()) {
|
||||
mBinding.uploadPictureTv.text = "点击上传图片"
|
||||
} else {
|
||||
mBinding.uploadPictureTv.text = "图片上传中..."
|
||||
mViewModel.uploadPoster()
|
||||
}
|
||||
initPosterUI()
|
||||
} else if (requestCode == ChooseGameCollectionDefaultCoverDialog.REQUEST_CODE_DEFAULT_IMAGE) {
|
||||
val entity = data.getParcelableExtra<GameCollectionCoverEntity>(EntranceConsts.KEY_DATA)
|
||||
if (entity != null) {
|
||||
@ -731,9 +715,17 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
} else {
|
||||
DialogHelper.showDialog(this, "温馨提示", "游戏单会在1-2个工作日内审核完成,您可以在“我的光环-我的游戏单”查看进度", "继续提交", "取消", {
|
||||
mViewModel.uploadContent(this, requestMap)
|
||||
}, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
|
||||
DialogHelper.showDialog(
|
||||
this,
|
||||
"温馨提示",
|
||||
"游戏单会在1-2个工作日内审核完成,您可以在“我的光环-我的游戏单”查看进度",
|
||||
"继续提交",
|
||||
"取消",
|
||||
{
|
||||
mViewModel.uploadContent(this, requestMap)
|
||||
},
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -804,7 +796,8 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
activityDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
|
||||
titleDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
|
||||
introduceDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
|
||||
placeholderView.background = com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_8.toDrawable(this@GameCollectionEditActivity)
|
||||
placeholderView.background =
|
||||
com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_8.toDrawable(this@GameCollectionEditActivity)
|
||||
selfOnlyCb.background =
|
||||
R.drawable.border_round_stroke_0dot5_eee_999.toDrawable(this@GameCollectionEditActivity)
|
||||
uploadPictureTv.setTextColor(com.gh.gamecenter.common.R.color.text_instance.toColor(this@GameCollectionEditActivity))
|
||||
@ -912,7 +905,6 @@ class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDra
|
||||
companion object {
|
||||
|
||||
const val REQUEST_CODE_IMAGE = 100
|
||||
const val REQUEST_CODE_IMAGE_CROP = 101
|
||||
const val REQUEST_CHOOSE_GAMES = 102
|
||||
const val REQUEST_CHOOSE_TAG = 103
|
||||
const val REQUEST_CHOOSE_ACTIVITY = 105
|
||||
|
||||
@ -6,14 +6,16 @@ import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Bundle
|
||||
import android.widget.ImageView
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.common.provider.CropImageProviderImpl.Companion.IMAGE_TYPE_PERSONAL_BACKGROUND
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils
|
||||
import com.gh.gamecenter.common.view.cropbox.CropBoxStyle
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.ActivityBackgroundClipBinding
|
||||
import java.io.File
|
||||
import java.lang.ref.SoftReference
|
||||
@ -33,7 +35,6 @@ class BackgroundClipActivity : BaseActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
DisplayUtils.transparentStatusBar(this)
|
||||
mBinding = ActivityBackgroundClipBinding.bind(mContentView)
|
||||
mBinding.cropImageIv.setCropRatio(392 / 360F)
|
||||
|
||||
mBinding.cancelTv.setOnClickListener {
|
||||
finish()
|
||||
@ -84,6 +85,8 @@ class BackgroundClipActivity : BaseActivity() {
|
||||
val intent = Intent(context, BackgroundClipActivity::class.java)
|
||||
intent.putExtra(EntranceConsts.KEY_PATH, picturePath)
|
||||
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_CROP_STYLE, CropBoxStyle.Rectangle(356F / 328))
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_TYPE, IMAGE_TYPE_PERSONAL_BACKGROUND)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import android.view.View
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.provider.CropImageProviderImpl.Companion.IMAGE_TYPE_PERSONAL_BACKGROUND
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
|
||||
@ -78,7 +79,8 @@ class PersonalityBackgroundFragment : ToolbarFragment() {
|
||||
requireContext(),
|
||||
ChooseType.IMAGE,
|
||||
1,
|
||||
"个性背景"
|
||||
"个性背景",
|
||||
IMAGE_TYPE_PERSONAL_BACKGROUND
|
||||
), MEDIA_STORE_REQUEST
|
||||
)
|
||||
}
|
||||
@ -89,19 +91,15 @@ class PersonalityBackgroundFragment : ToolbarFragment() {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
if (requestCode == MEDIA_STORE_REQUEST && resultCode == Activity.RESULT_OK) {
|
||||
val selectedPaths = Matisse.obtainPathResult(data)
|
||||
if (!selectedPaths.isNullOrEmpty()) {
|
||||
val intent = BackgroundClipActivity.getIntent(requireContext(), selectedPaths[0], mEntrance)
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
}
|
||||
} else if (requestCode == REQUEST_CODE_IMAGE_CROP && resultCode == Activity.RESULT_OK) {
|
||||
if (data != null) {
|
||||
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
|
||||
val intent = BackgroundPreviewActivity.getIntent(
|
||||
requireContext(), imagePath
|
||||
?: "", null
|
||||
)
|
||||
requireActivity().startActivityForResult(intent, CHANGE_BACKGROUND_SUCCESS)
|
||||
if (imagePath != null) {
|
||||
val intent = BackgroundPreviewActivity.getIntent(
|
||||
requireContext(), imagePath
|
||||
?: "", null
|
||||
)
|
||||
requireActivity().startActivityForResult(intent, CHANGE_BACKGROUND_SUCCESS)
|
||||
}
|
||||
}
|
||||
} else if (requestCode == CHANGE_BACKGROUND_SUCCESS && resultCode == Activity.RESULT_OK) {
|
||||
requireActivity().finish()
|
||||
@ -119,7 +117,6 @@ class PersonalityBackgroundFragment : ToolbarFragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REQUEST_CODE_IMAGE_CROP = 100
|
||||
const val MEDIA_STORE_REQUEST = 101
|
||||
const val CHANGE_BACKGROUND_SUCCESS = 102
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ import com.gh.gamecenter.qa.editor.GameActivity
|
||||
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
|
||||
import com.gh.gamecenter.qa.questions.edit.TagsSelectFragment
|
||||
import com.gh.gamecenter.qa.video.publish.VideoPublishFragment
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
@ -123,6 +124,7 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
VideoPosterFragment.clearVideoCoverCache(this)
|
||||
updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
|
||||
mBinding = ActivityCommunityArticleEditBinding.bind(mContentView)
|
||||
setToolbarMenu(R.menu.menu_answer_post)
|
||||
@ -651,8 +653,14 @@ class ArticleEditActivity : BaseRichEditorActivity<ArticleEditViewModel>(), Keyb
|
||||
|
||||
private fun setForumUI() {
|
||||
mBinding.forumIconView.visibility = View.VISIBLE
|
||||
mBinding.forumContainer.background = ContextCompat.getDrawable(this, com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999)
|
||||
mBinding.articleGameName.setTextColor(ContextCompat.getColor(this, com.gh.gamecenter.common.R.color.text_secondary))
|
||||
mBinding.forumContainer.background =
|
||||
ContextCompat.getDrawable(this, com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999)
|
||||
mBinding.articleGameName.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
this,
|
||||
com.gh.gamecenter.common.R.color.text_secondary
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun setSectionUI(isEmpty: Boolean) {
|
||||
|
||||
@ -50,6 +50,7 @@ import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
|
||||
import com.gh.gamecenter.qa.questions.draft.QuestionDraftActivity
|
||||
import com.gh.gamecenter.qa.questions.edit.tip.QuestionTitleTipAdapter
|
||||
import com.gh.gamecenter.qa.video.publish.VideoPublishFragment
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
@ -147,6 +148,7 @@ class QuestionEditActivity : BaseRichEditorActivity<QuestionEditViewModel>(),
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
VideoPosterFragment.clearVideoCoverCache(this)
|
||||
updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
|
||||
setToolbarMenu(R.menu.menu_question_post)
|
||||
mToolbar.navigationIcon = null
|
||||
@ -280,12 +282,14 @@ class QuestionEditActivity : BaseRichEditorActivity<QuestionEditViewModel>(),
|
||||
detailEntity != null -> { // 问题编辑
|
||||
setPatchContent(detailEntity)
|
||||
}
|
||||
|
||||
draftEntity != null -> { //草稿编辑
|
||||
mViewModel.questionDraftEntity = draftEntity
|
||||
setQuestionDraft(draftEntity)
|
||||
mViewModel.getQuestionDraftContent(draftEntity.id)
|
||||
mBaseHandler.sendEmptyMessageDelayed(1, SAVE_DRAFTS_INTERVAL_TIME.toLong())
|
||||
}
|
||||
|
||||
else -> { // 新增问题
|
||||
var searchKey = intent.getStringExtra(EntranceConsts.KEY_QUESTIONS_SEARCH_KEY)
|
||||
if (!searchKey.isNullOrEmpty() && searchKey.length > QuestionEditViewModel.QUESTION_TITLE_MAX_LENGTH)
|
||||
@ -468,6 +472,7 @@ class QuestionEditActivity : BaseRichEditorActivity<QuestionEditViewModel>(),
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
SaveDraftType.AUTO -> {
|
||||
if (pair.second) {
|
||||
if (mPostDraftsCount >= SAVE_DRAFTS_TOAST_COUNT) {
|
||||
@ -478,6 +483,7 @@ class QuestionEditActivity : BaseRichEditorActivity<QuestionEditViewModel>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SaveDraftType.SKIP -> {
|
||||
if (pair.second) {
|
||||
Utils.toast(this, "问题已保存到草稿箱")
|
||||
@ -690,7 +696,12 @@ class QuestionEditActivity : BaseRichEditorActivity<QuestionEditViewModel>(),
|
||||
return false
|
||||
}
|
||||
DialogHelper.showDialog(
|
||||
this, "提示", "确定退出修改?已编辑的内容将丢失", "继续编辑", " 退出", cancelClickCallback = { finish() },
|
||||
this,
|
||||
"提示",
|
||||
"确定退出修改?已编辑的内容将丢失",
|
||||
"继续编辑",
|
||||
" 退出",
|
||||
cancelClickCallback = { finish() },
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
return true
|
||||
@ -847,7 +858,12 @@ class QuestionEditActivity : BaseRichEditorActivity<QuestionEditViewModel>(),
|
||||
mBinding.forumIconView.visibility = View.VISIBLE
|
||||
mBinding.forumContainer.background =
|
||||
ContextCompat.getDrawable(this, com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999)
|
||||
mBinding.chooseForumTv.setTextColor(ContextCompat.getColor(this, com.gh.gamecenter.common.R.color.text_secondary))
|
||||
mBinding.chooseForumTv.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
this,
|
||||
com.gh.gamecenter.common.R.color.text_secondary
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun setSectionUI(isEmpty: Boolean) {
|
||||
|
||||
@ -13,6 +13,7 @@ import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.feature.entity.ForumVideoEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.qa.BbsType
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
|
||||
|
||||
/**
|
||||
* 发视频
|
||||
@ -22,6 +23,7 @@ class VideoPublishActivity : ToolBarActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
VideoPosterFragment.clearVideoCoverCache(this)
|
||||
updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
|
||||
mToolbar.navigationIcon = null
|
||||
findViewById<View>(R.id.backBtn).setOnClickListener { onBackPressed() }
|
||||
|
||||
@ -23,20 +23,24 @@ import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
|
||||
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc
|
||||
import com.gh.gamecenter.common.mvvm.Status
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.databinding.FragmentVideoPublishBinding
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.entity.ActivityLabelEntity
|
||||
import com.gh.gamecenter.entity.ForumDetailEntity
|
||||
import com.gh.gamecenter.entity.VideoDraftEntity
|
||||
import com.gh.gamecenter.entity.VideoEntity
|
||||
import com.gh.gamecenter.feature.entity.ForumVideoEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.qa.BbsType
|
||||
import com.gh.gamecenter.qa.dialog.ChooseActivityDialogFragment
|
||||
@ -44,12 +48,12 @@ import com.gh.gamecenter.qa.dialog.ChooseForumActivity
|
||||
import com.gh.gamecenter.qa.dialog.ChooseSectionDialogFragment
|
||||
import com.gh.gamecenter.qa.dialog.InputUrlDialogFragment
|
||||
import com.gh.gamecenter.qa.editor.GameActivity
|
||||
import com.gh.gamecenter.video.poster.PosterEditActivity
|
||||
import com.gh.gamecenter.video.upload.OnUploadListener
|
||||
import com.gh.gamecenter.video.upload.UploadManager
|
||||
import com.gh.gamecenter.video.upload.view.VideoFileEntity
|
||||
import com.gh.gamecenter.video.videomanager.VideoDraftActivity
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.therouter.TheRouter
|
||||
import java.io.File
|
||||
|
||||
class VideoPublishFragment : ToolbarFragment(), KeyboardHeightObserver {
|
||||
@ -661,7 +665,8 @@ class VideoPublishFragment : ToolbarFragment(), KeyboardHeightObserver {
|
||||
|
||||
private fun setForumUI() {
|
||||
mBinding.forumIconView.visibility = View.VISIBLE
|
||||
mBinding.forumContainer.background = com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(requireContext())
|
||||
mBinding.forumContainer.background =
|
||||
com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(requireContext())
|
||||
mBinding.chooseForumTv.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
|
||||
}
|
||||
|
||||
@ -757,29 +762,24 @@ class VideoPublishFragment : ToolbarFragment(), KeyboardHeightObserver {
|
||||
private fun startMediaStore() {
|
||||
try {
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(requireContext()) {
|
||||
var intent: Intent? = null
|
||||
val postcard = TheRouter.build(RouteConsts.activity.videoCoverEditActivity)
|
||||
when {
|
||||
mVideoFileEntity?.url?.isNotEmpty() == true -> {
|
||||
val videoEntity = VideoEntity(
|
||||
length = mVideoFileEntity?.length ?: 0, url = mVideoFileEntity?.url ?: ""
|
||||
)
|
||||
intent = PosterEditActivity.getIntentByVideo(
|
||||
requireContext(),
|
||||
videoEntity
|
||||
)
|
||||
postcard.withParcelable(EntranceConsts.KEY_VIDEO_ENTITY, videoEntity)
|
||||
}
|
||||
|
||||
mVideoFileEntity?.path?.isNotEmpty() == true -> {
|
||||
intent = PosterEditActivity.getIntentByPath(
|
||||
requireContext(), mVideoFileEntity?.url ?: ""
|
||||
)
|
||||
postcard.withString(EntranceConsts.KEY_PATH_VIDEO, mVideoFileEntity?.url ?: "")
|
||||
}
|
||||
|
||||
else -> {
|
||||
throwExceptionInDebug("video not found")
|
||||
}
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
postcard.navigation(requireActivity(), REQUEST_CODE_IMAGE_CROP)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
toast(R.string.media_image_hint)
|
||||
@ -966,9 +966,11 @@ class VideoPublishFragment : ToolbarFragment(), KeyboardHeightObserver {
|
||||
super.onDarkModeChanged()
|
||||
setSectionUI(mViewModel.selectSection == null)
|
||||
mBinding.activityTv.setTextColor(
|
||||
if (mViewModel.selectActivityLabelEntity != null) com.gh.gamecenter.common.R.color.text_FA8500.toColor(requireContext()) else com.gh.gamecenter.common.R.color.text_primary.toColor(
|
||||
requireContext()
|
||||
)
|
||||
if (mViewModel.selectActivityLabelEntity != null) {
|
||||
com.gh.gamecenter.common.R.color.text_FA8500.toColor(requireContext())
|
||||
} else {
|
||||
com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext())
|
||||
}
|
||||
)
|
||||
mBinding.forumContainer.background =
|
||||
if (mViewModel.communityEntity == null) R.drawable.button_round_primary_light.toDrawable(requireContext()) else com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(
|
||||
|
||||
@ -1,231 +1,34 @@
|
||||
package com.gh.gamecenter.video.poster
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.database.Cursor
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity_TabLayout
|
||||
import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.databinding.ActivityPosterEditBinding
|
||||
import com.gh.gamecenter.entity.VideoEntity
|
||||
import com.gh.gamecenter.video.poster.photo.PhotoAlbumsAdapter
|
||||
import com.gh.gamecenter.video.poster.photo.PhotoAlbumsSpanner
|
||||
import com.gh.gamecenter.video.poster.photo.PhotoPosterFragment
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
|
||||
import com.gh.gamecenter.video.upload.view.UploadVideoActivity
|
||||
import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.MimeType
|
||||
import com.zhihu.matisse.internal.entity.Album
|
||||
import com.zhihu.matisse.internal.entity.SelectionSpec
|
||||
import com.zhihu.matisse.internal.model.AlbumCollection
|
||||
import java.io.File
|
||||
import com.therouter.TheRouter
|
||||
import com.therouter.router.Route
|
||||
|
||||
class PosterEditActivity : BaseActivity_TabLayout(), AdapterView.OnItemSelectedListener,
|
||||
AlbumCollection.AlbumCallbacks {
|
||||
|
||||
private lateinit var mBinding: ActivityPosterEditBinding
|
||||
|
||||
private val mAlbumCollection = AlbumCollection()
|
||||
|
||||
private lateinit var mAlbumsSpinner: PhotoAlbumsSpanner
|
||||
private lateinit var mAlbumsAdapter: PhotoAlbumsAdapter
|
||||
|
||||
private lateinit var mPhotoPosterFragment: PhotoPosterFragment
|
||||
private lateinit var mVideoPosterFragment: VideoPosterFragment
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (UploadVideoActivity.REQUEST_CODE_IMAGE_CROP == requestCode && resultCode == Activity.RESULT_OK) {
|
||||
setResult(Activity.RESULT_OK, data)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideTabView(position: Int, tabTitle: String?): View {
|
||||
val tabCustomView = BaseFragment_TabLayout.createDefaultTabCustomView(this, tabTitle)
|
||||
tabCustomView.findViewById<TextView>(R.id.tab_title)
|
||||
.setTextColor(resources.getColorStateList(R.color.poster_text_tabbar_style))
|
||||
return tabCustomView
|
||||
}
|
||||
|
||||
override fun initFragmentList(fragments: MutableList<Fragment>) {
|
||||
val videoPath = intent.getStringExtra(EntranceConsts.KEY_PATH_VIDEO)
|
||||
val videoEntity = intent.getParcelableExtra<VideoEntity>(VideoEntity::class.java.simpleName)
|
||||
mPhotoPosterFragment = PhotoPosterFragment()
|
||||
mVideoPosterFragment = VideoPosterFragment.newInstance(videoPath, videoEntity)
|
||||
fragments.add(mVideoPosterFragment)
|
||||
fragments.add(mPhotoPosterFragment)
|
||||
}
|
||||
|
||||
override fun initTabTitleList(tabTitleList: MutableList<String>) {
|
||||
tabTitleList.add("视频截图")
|
||||
tabTitleList.add("相册选择")
|
||||
}
|
||||
@Route(path = RouteConsts.activity.videoCoverEditActivity)
|
||||
class PosterEditActivity : BaseActivity() {
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.activity_poster_edit
|
||||
return R.layout.actvitity_video_cover_edit
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
TheRouter.inject(this)
|
||||
super.onCreate(savedInstanceState)
|
||||
Matisse.from(this).choose(MimeType.ofImage()).showSingleMediaType(true)
|
||||
DisplayUtils.setLightStatusBar(this, false)
|
||||
setStatusBarColor(Color.TRANSPARENT)
|
||||
|
||||
setNavigationTitle("编辑封面")
|
||||
|
||||
initView()
|
||||
initAlbumsSpinner()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
mBinding = ActivityPosterEditBinding.bind(mContentView)
|
||||
|
||||
mBinding.activityViewPager.setScrollable(false)
|
||||
mBinding.activityViewPager.addOnPageChangeListener {
|
||||
if (VIDEO_POSTER_INDEX == it) {
|
||||
setNavigationTitle("编辑封面")
|
||||
mTitleTv.removeDrawable()
|
||||
} else {
|
||||
setPhotoNavigationTitle(false)
|
||||
}
|
||||
}
|
||||
mBinding.confirm.setOnClickListener {
|
||||
val selectImagePath = getSelectImagePath()
|
||||
if (selectImagePath != null) {
|
||||
if (mBinding.activityViewPager.currentItem == 0) {
|
||||
val data = Intent()
|
||||
data.putExtra(CropImageActivity.RESULT_CLIP_PATH, selectImagePath)
|
||||
setResult(Activity.RESULT_OK, data)
|
||||
finish()
|
||||
} else {
|
||||
val intent = CropImageActivity.getIntent(this, selectImagePath, 9 / 16F, mEntrance)
|
||||
startActivityForResult(intent, UploadVideoActivity.REQUEST_CODE_IMAGE_CROP)
|
||||
}
|
||||
} else {
|
||||
toast("请选择图片")
|
||||
}
|
||||
}
|
||||
mTitleTv.setOnClickListener {
|
||||
setPhotoNavigationTitle(true)
|
||||
mAlbumsSpinner.show(mBinding.activityViewPager.height)
|
||||
}
|
||||
|
||||
DisplayUtils.transparentStatusBar(this)
|
||||
mBaseHandler.postDelayed({
|
||||
mBinding.activityTabIndicator.generatePath(
|
||||
mBinding.activityViewPager.currentItem,
|
||||
0F
|
||||
)
|
||||
}, 10)
|
||||
}
|
||||
|
||||
private fun initAlbumsSpinner() {
|
||||
mAlbumsAdapter = PhotoAlbumsAdapter(this)
|
||||
mAlbumsSpinner = PhotoAlbumsSpanner(this)
|
||||
|
||||
mAlbumsSpinner.setPopupAnchorView(findViewById(R.id.normal_toolbar))
|
||||
mAlbumsSpinner.setAdapter(mAlbumsAdapter)
|
||||
mAlbumsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
mAlbumCollection.setStateCurrentSelection(position)
|
||||
mAlbumsAdapter.cursor.moveToPosition(position)
|
||||
val album = Album.valueOf(mAlbumsAdapter.cursor)
|
||||
if (album.isAll && SelectionSpec.getInstance().capture) {
|
||||
album.addCaptureCount()
|
||||
}
|
||||
if (mPhotoPosterFragment.isAdded) {
|
||||
mPhotoPosterFragment.loadPhotos(album)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mAlbumsSpinner.setDismissListener(PopupWindow.OnDismissListener {
|
||||
setPhotoNavigationTitle(false)
|
||||
})
|
||||
|
||||
mAlbumCollection.onCreate(this, this)
|
||||
mAlbumCollection.loadAlbums()
|
||||
}
|
||||
|
||||
|
||||
private fun setPhotoNavigationTitle(up: Boolean) {
|
||||
if (mBinding.activityViewPager.currentItem == VIDEO_POSTER_INDEX) return
|
||||
mTitleTv.setDrawableEnd(if (up) R.drawable.poster_select_up else R.drawable.poster_select_down)
|
||||
mTitleTv.compoundDrawablePadding = 2F.dip2px()
|
||||
mTitleTv.text = "全部图片"
|
||||
}
|
||||
|
||||
private fun getSelectImagePath(): String? {
|
||||
if (mBinding.activityViewPager.currentItem == VIDEO_POSTER_INDEX) {
|
||||
val clipPath = cacheDir.absolutePath + File.separator + System.currentTimeMillis() + ".jpg"
|
||||
mVideoPosterFragment.savePicture(clipPath)
|
||||
return clipPath
|
||||
} else {
|
||||
return mPhotoPosterFragment.getSelectImagePath()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
}
|
||||
|
||||
override fun onAlbumLoad(cursor: Cursor?) {
|
||||
mAlbumsAdapter.swapCursor(cursor)
|
||||
mBaseHandler.post {
|
||||
cursor?.moveToPosition(mAlbumCollection.currentSelection)
|
||||
val album = Album.valueOf(cursor)
|
||||
if (album.isAll && SelectionSpec.getInstance().capture) {
|
||||
album.addCaptureCount()
|
||||
}
|
||||
if (::mPhotoPosterFragment.isInitialized && mPhotoPosterFragment.isAdded) {
|
||||
mPhotoPosterFragment.loadPhotos(album)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAlbumReset() {
|
||||
}
|
||||
|
||||
override fun provideNavigationIcon(): Int {
|
||||
return com.gh.gamecenter.common.R.drawable.ic_toolbar_back_white
|
||||
}
|
||||
|
||||
override fun handleBackPressed(): Boolean {
|
||||
DialogHelper.showDialog(this, "提示", "确定放弃编辑封面吗?", "确定", "暂不", { finish() })
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val VIDEO_POSTER_INDEX = 0
|
||||
private const val PHOTO_POSTER_INDEX = 1
|
||||
|
||||
fun getIntentByPath(context: Context, videoPath: String): Intent {
|
||||
val intent = Intent(context, PosterEditActivity::class.java)
|
||||
intent.putExtra(EntranceConsts.KEY_PATH_VIDEO, videoPath)
|
||||
return intent
|
||||
}
|
||||
|
||||
fun getIntentByVideo(context: Context, videoEntity: VideoEntity): Intent {
|
||||
val intent = Intent(context, PosterEditActivity::class.java)
|
||||
intent.putExtra(VideoEntity::class.java.simpleName, videoEntity)
|
||||
return intent
|
||||
}
|
||||
val tag = VideoPosterFragment::class.java.name
|
||||
val fragment = supportFragmentManager.findFragmentByTag(tag) ?: VideoPosterFragment.newInstance()
|
||||
fragment.arguments = intent.extras
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.fcv_container, fragment, tag)
|
||||
.commitNowAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package com.gh.gamecenter.video.poster
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
|
||||
class PreviewMaskView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0,
|
||||
defStyleRes: Int = 0
|
||||
) :
|
||||
View(context, attrs, defStyleAttr, defStyleRes) {
|
||||
|
||||
private var isLight = false
|
||||
|
||||
private var leftTopCorner = 0F
|
||||
private var rightTopCorner = 0F
|
||||
private var leftBottomCorner = 0F
|
||||
private var rightBottomCorner = 0F
|
||||
|
||||
private val paint by lazy {
|
||||
Paint().apply {
|
||||
isAntiAlias = true
|
||||
isDither = true
|
||||
}
|
||||
}
|
||||
|
||||
val defaultColor = Color.parseColor("#40000000")
|
||||
val lightColor = Color.parseColor("#000000")
|
||||
|
||||
private val xFermode by lazy {
|
||||
PorterDuffXfermode(PorterDuff.Mode.CLEAR)
|
||||
}
|
||||
|
||||
private val rectF = RectF()
|
||||
private var path = Path()
|
||||
|
||||
fun setCorners(leftTop: Float, rightTop: Float, rightBottom: Float, leftBottom: Float) {
|
||||
leftTopCorner = leftTop
|
||||
rightTopCorner = rightTop
|
||||
rightBottomCorner = rightBottom
|
||||
leftBottomCorner = leftBottom
|
||||
postInvalidateOnAnimation()
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
rectF.set(0F, 0F, w.toFloat(), h.toFloat())
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
if (isLight) {
|
||||
paint.color = lightColor
|
||||
val layerId = canvas.saveLayerAlpha(rectF, 64)
|
||||
|
||||
drawBackground(canvas)
|
||||
paint.xfermode = xFermode
|
||||
canvas.drawRoundRect(rectF, 4F.dip2px().toFloat(), 4F.dip2px().toFloat(), paint)
|
||||
paint.xfermode = null
|
||||
canvas.restoreToCount(layerId)
|
||||
} else {
|
||||
paint.color = defaultColor
|
||||
drawBackground(canvas)
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawBackground(canvas: Canvas) {
|
||||
path.reset()
|
||||
val radii = floatArrayOf(
|
||||
leftTopCorner,
|
||||
leftTopCorner,
|
||||
rightTopCorner,
|
||||
rightTopCorner,
|
||||
rightBottomCorner,
|
||||
rightBottomCorner,
|
||||
leftBottomCorner,
|
||||
leftBottomCorner,
|
||||
)
|
||||
path.addRoundRect(rectF, radii, Path.Direction.CW)
|
||||
canvas.drawPath(path, paint)
|
||||
}
|
||||
|
||||
fun setLight(isLight: Boolean) {
|
||||
this.isLight = isLight
|
||||
postInvalidateOnAnimation()
|
||||
}
|
||||
}
|
||||
@ -1,75 +1,282 @@
|
||||
package com.gh.gamecenter.video.poster.video
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.gh.gamecenter.common.base.fragment.BaseFragment
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.observeNonNull
|
||||
import com.gh.gamecenter.common.utils.throwExceptionInDebug
|
||||
import com.gh.gamecenter.CropImageActivity
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.databinding.FragmentVideoPosterBinding
|
||||
import com.gh.gamecenter.common.base.fragment.BaseFragment
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper.checkStoragePermissionBeforeAction
|
||||
import com.gh.gamecenter.common.view.cropbox.CropBoxStyle
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.databinding.FragmentVideoCoverEditBinding
|
||||
import com.gh.gamecenter.entity.VideoEntity
|
||||
import com.gh.gamecenter.feature.selector.ChooseType
|
||||
import com.gh.gamecenter.feature.selector.LocalMediaActivity
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterViewModel.Companion.SELECTED_IMAGE_POSITION
|
||||
import com.google.android.material.shape.CornerFamily
|
||||
import com.google.android.material.shape.ShapeAppearanceModel
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class VideoPosterFragment : BaseFragment<Any>() {
|
||||
|
||||
private lateinit var mBinding: FragmentVideoPosterBinding
|
||||
private lateinit var mAdapter: VideoPosterReviewAdapter
|
||||
private lateinit var binding: FragmentVideoCoverEditBinding
|
||||
private lateinit var viewModel: VideoPosterViewModel
|
||||
|
||||
private lateinit var mViewModel: VideoPosterViewModel
|
||||
var videoPath: String? = null
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.fragment_video_poster
|
||||
var videoEntity: VideoEntity? = null
|
||||
|
||||
private lateinit var adapter: VideoPosterReviewAdapter
|
||||
|
||||
private lateinit var takePhotoLauncher: ActivityResultLauncher<Unit>
|
||||
|
||||
override fun getInflatedLayout(): View {
|
||||
return View(requireContext())
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
videoPath = arguments?.getString(EntranceConsts.KEY_PATH_VIDEO)
|
||||
videoEntity = arguments?.getParcelable<VideoEntity>(EntranceConsts.KEY_VIDEO_ENTITY)
|
||||
super.onCreate(savedInstanceState)
|
||||
mBinding = FragmentVideoPosterBinding.bind(mCachedView)
|
||||
|
||||
val videoPath = arguments?.getString(EntranceConsts.KEY_PATH_VIDEO)
|
||||
val videoEntity = arguments?.getParcelable<VideoEntity>(VideoEntity::class.java.simpleName)
|
||||
val videoCoverCache =
|
||||
SPUtils.getString(Constants.SP_VIDEO_COVER_CACHE).toObject<VideoPosterViewModel.VideoCoverCache>()
|
||||
val factory =
|
||||
VideoPosterViewModel.Factory(HaloApp.getInstance().application, videoPath, videoEntity, videoCoverCache)
|
||||
viewModel = ViewModelProviders.of(this, factory).get(VideoPosterViewModel::class.java)
|
||||
|
||||
val factory = VideoPosterViewModel.Factory(HaloApp.getInstance().application, videoPath, videoEntity)
|
||||
mViewModel = ViewModelProviders.of(this, factory).get(VideoPosterViewModel::class.java)
|
||||
mViewModel.videoPreviewsLiveData.observeNonNull(this, callback = {
|
||||
mAdapter.submitList(it)
|
||||
})
|
||||
mViewModel.previewLiveData.observeNonNull(this, callback = {
|
||||
if (it.thumbs != null) {
|
||||
mBinding.receiveIv.setBitmap(it.thumbs)
|
||||
} else if (it.thumbsUrl != null) {
|
||||
ImageUtils.picasso
|
||||
.load(Uri.parse(it.thumbsUrl))
|
||||
.into(mBinding.receiveIv.cropImageZoomView)
|
||||
takePhotoLauncher = registerForActivityResult(object : ActivityResultContract<Unit, Intent?>() {
|
||||
override fun createIntent(context: Context, input: Unit): Intent {
|
||||
return LocalMediaActivity.getIntent(
|
||||
context,
|
||||
ChooseType.IMAGE,
|
||||
1,
|
||||
"视频封面编辑"
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): Intent? {
|
||||
return intent
|
||||
}
|
||||
}) {
|
||||
if (it != null) {
|
||||
val uris = Matisse.obtainResult(it)
|
||||
if (uris.isNotEmpty()) {
|
||||
val path = PathUtils.getPath(requireContext(), uris.first())
|
||||
if (path != null) {
|
||||
val ivZoom = binding.cropImageCustom.cropImageZoomView
|
||||
val bitmap = BitmapUtils.getBitmapByFile(path, ivZoom.width, ivZoom.height)
|
||||
if (bitmap != null) {
|
||||
val videoPreview = VideoPosterViewModel.VideoPreview(0, bitmap, null)
|
||||
viewModel.setSelectedImage(videoPreview)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView(view: View?) = Unit
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return FragmentVideoCoverEditBinding.inflate(inflater, container, false)
|
||||
.also {
|
||||
binding = it
|
||||
}.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mBinding.receiveIv.setCropRatio(9 / 16F)
|
||||
mBinding.reviewList.layoutManager = GridLayoutManager(requireContext(), 10)
|
||||
mAdapter = VideoPosterReviewAdapter(requireContext(), mViewModel)
|
||||
mBinding.reviewList.adapter = mAdapter
|
||||
|
||||
adapter = VideoPosterReviewAdapter(requireContext(), viewModel)
|
||||
binding.rvImages.layoutManager = GridLayoutManager(requireContext(), 10)
|
||||
binding.rvImages.adapter = adapter
|
||||
|
||||
binding.ivTakePhoto.shapeAppearanceModel = ShapeAppearanceModel()
|
||||
.toBuilder()
|
||||
.setAllCorners(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
.build()
|
||||
binding.ivTakePhoto.clipToOutline = true
|
||||
|
||||
binding.ivPreviewBorder.shapeAppearanceModel = ShapeAppearanceModel()
|
||||
.toBuilder()
|
||||
.setAllCorners(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
.build()
|
||||
binding.ivPreviewBorder.strokeWidth = 4F.dip2px().toFloat()
|
||||
binding.ivPreviewBorder.strokeColor = ColorStateList.valueOf(Color.parseColor("#2496FF"))
|
||||
binding.ivPreviewBorder.clipToOutline = true
|
||||
|
||||
binding.cropImageCustom.setCropBoxStyle(CropBoxStyle.Rectangle(23F / 41))
|
||||
|
||||
binding.ivTakePhoto.setOnClickListener {
|
||||
val videoPreview = viewModel.selectedImage.value
|
||||
if (videoPreview == null) {
|
||||
checkStoragePermissionBeforeAction(requireContext()) { takePhotoLauncher.launch(Unit) }
|
||||
} else {
|
||||
viewModel.setPreviewImage(SELECTED_IMAGE_POSITION, videoPreview)
|
||||
}
|
||||
}
|
||||
|
||||
binding.ivRemove.setOnClickListener {
|
||||
viewModel.setSelectedImage(null)
|
||||
if (viewModel.previewPosition.value == SELECTED_IMAGE_POSITION) {
|
||||
adapter.getItem(0)?.let {
|
||||
viewModel.setPreviewImage(0, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding.tvCancel.setOnClickListener {
|
||||
activity?.finish()
|
||||
}
|
||||
|
||||
binding.tvSubmit.setOnClickListener {
|
||||
activity?.let {
|
||||
val clipPath = it.cacheDir.absolutePath + File.separator + System.currentTimeMillis() + ".jpg"
|
||||
binding.cropImageCustom.savePicture(clipPath)
|
||||
|
||||
saveVideoOriginalCoverToLocal(it)
|
||||
|
||||
val data = Intent()
|
||||
data.putExtra(CropImageActivity.RESULT_CLIP_PATH, clipPath)
|
||||
it.setResult(Activity.RESULT_OK, data)
|
||||
it.finish()
|
||||
}
|
||||
}
|
||||
|
||||
with(viewModel) {
|
||||
videoPreviewsLiveData.observeNonNull(viewLifecycleOwner, callback = {
|
||||
adapter.submitList(it)
|
||||
})
|
||||
|
||||
previewLiveData.observeNonNull(viewLifecycleOwner, callback = {
|
||||
binding.cropImageCustom.reset()
|
||||
it.values?.let(binding.cropImageCustom::setTransformationValues)
|
||||
if (it.thumbs != null) {
|
||||
binding.cropImageCustom.setBitmap(it.thumbs)
|
||||
} else if (it.thumbsUrl != null) {
|
||||
ImageUtils.picasso
|
||||
.load(Uri.parse(it.thumbsUrl))
|
||||
.into(binding.cropImageCustom.cropImageZoomView)
|
||||
}
|
||||
})
|
||||
|
||||
selectedImage.observe(viewLifecycleOwner) {
|
||||
if (it == null) {
|
||||
binding.ivTakePhoto.setImageResource(R.drawable.ic_video_cover_edit_take_photo)
|
||||
} else {
|
||||
binding.ivTakePhoto.setImageBitmap(it.thumbs)
|
||||
}
|
||||
binding.ivRemove.goneIf(it == null)
|
||||
}
|
||||
|
||||
previewPosition.observe(viewLifecycleOwner) {
|
||||
setSelectedImageSelected(it == SELECTED_IMAGE_POSITION)
|
||||
adapter.setPreviewPosition(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun savePicture(path: String) {
|
||||
if (isAdded) throwExceptionInDebug("save clip picture failure", !mBinding.receiveIv.savePicture(path))
|
||||
/**
|
||||
* 将封面原图保存在本地,以便下次编辑时显示
|
||||
*/
|
||||
private fun saveVideoOriginalCoverToLocal(context: Context) {
|
||||
val preview = viewModel.previewLiveData.value
|
||||
if (preview != null) {
|
||||
val position = viewModel.previewPosition.value ?: -2
|
||||
var cache: VideoPosterViewModel.VideoCoverCache? = null
|
||||
val values = binding.cropImageCustom.transformationValues
|
||||
if (preview.thumbs != null) {
|
||||
val path = saveToInternalStorage(context, preview.thumbs)
|
||||
if (path != null) {
|
||||
cache = VideoPosterViewModel.VideoCoverCache(position, localPath = path, values = values)
|
||||
}
|
||||
} else if (preview.thumbsUrl != null) {
|
||||
cache = VideoPosterViewModel.VideoCoverCache(position, url = preview.thumbsUrl, values = values)
|
||||
}
|
||||
val json = cache?.toJson()
|
||||
if (json != null) {
|
||||
SPUtils.setString(Constants.SP_VIDEO_COVER_CACHE, json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setSelectedImageSelected(isSelected: Boolean) {
|
||||
if (isSelected) {
|
||||
binding.ivTakePhoto.strokeWidth = 6F.dip2px().toFloat()
|
||||
binding.ivTakePhoto.strokeColor = ColorStateList.valueOf(Color.parseColor("#232323"))
|
||||
} else {
|
||||
binding.ivTakePhoto.strokeWidth = 0F
|
||||
}
|
||||
binding.ivPreviewBorder.goneIf(!isSelected)
|
||||
}
|
||||
|
||||
// 保存到内部存储
|
||||
private fun saveToInternalStorage(
|
||||
context: Context,
|
||||
bitmap: Bitmap
|
||||
): String? {
|
||||
try {
|
||||
val file = createVideoCoverFile(context)
|
||||
// 将图片保存到文件
|
||||
FileOutputStream(file).use { fos ->
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos)
|
||||
fos.flush()
|
||||
}
|
||||
|
||||
return file.absolutePath
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(videoPath: String?, videoEntity: VideoEntity?): VideoPosterFragment {
|
||||
val fragment = VideoPosterFragment()
|
||||
val bundle = Bundle()
|
||||
bundle.putString(EntranceConsts.KEY_PATH_VIDEO, videoPath)
|
||||
bundle.putParcelable(VideoEntity::class.java.simpleName, videoEntity)
|
||||
fragment.arguments = bundle
|
||||
return fragment
|
||||
private const val VIDEO_COVER_DIRECTORY_NAME = "videoCover"
|
||||
|
||||
fun createVideoCoverFile(context: Context): File {
|
||||
// 获取应用私有目录
|
||||
val directory = context.getDir(VIDEO_COVER_DIRECTORY_NAME, Context.MODE_PRIVATE)
|
||||
|
||||
// 创建文件
|
||||
return File(directory, "cover_image.jpg")
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理上次裁剪图片留下的缓存文件
|
||||
*/
|
||||
fun clearVideoCoverCache(context: Context) {
|
||||
SPUtils.setString(Constants.SP_VIDEO_COVER_CACHE, "")
|
||||
context.getDir(VIDEO_COVER_DIRECTORY_NAME, Context.MODE_PRIVATE).let { directory ->
|
||||
directory.listFiles()?.forEach { it.delete() }
|
||||
}
|
||||
}
|
||||
|
||||
fun newInstance() = VideoPosterFragment()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,15 +1,19 @@
|
||||
package com.gh.gamecenter.video.poster.video
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.goneIf
|
||||
import com.gh.gamecenter.databinding.VideoPosterPreviewItemBinding
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterViewModel.Companion.SELECTED_IMAGE_POSITION
|
||||
import com.google.android.material.shape.CornerFamily
|
||||
import com.google.android.material.shape.ShapeAppearanceModel
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter
|
||||
|
||||
class VideoPosterReviewAdapter(
|
||||
@ -19,11 +23,7 @@ class VideoPosterReviewAdapter(
|
||||
|
||||
private var mListData: MutableList<VideoPosterViewModel.VideoPreview> = ArrayList()
|
||||
|
||||
private val mSelectMap = HashMap<Int, Boolean>()
|
||||
|
||||
init {
|
||||
mSelectMap[0] = true // default select
|
||||
}
|
||||
private var selectedPosition = 0
|
||||
|
||||
fun submitList(listData: List<VideoPosterViewModel.VideoPreview>) {
|
||||
mListData = listData.toMutableList()
|
||||
@ -41,6 +41,22 @@ class VideoPosterReviewAdapter(
|
||||
|
||||
override fun onBindViewHolder(holder: VideoPosterReviewItemViewHolder, position: Int) {
|
||||
|
||||
val builder = ShapeAppearanceModel().toBuilder()
|
||||
when (position) {
|
||||
0 -> builder.setTopLeftCorner(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
.setTopRightCorner(CornerFamily.ROUNDED, 0F)
|
||||
.setBottomRightCorner(CornerFamily.ROUNDED, 0F)
|
||||
.setBottomLeftCorner(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
|
||||
itemCount - 1 -> builder.setTopLeftCorner(CornerFamily.ROUNDED, 0F)
|
||||
.setTopRightCorner(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
.setBottomRightCorner(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
.setBottomLeftCorner(CornerFamily.ROUNDED, 0F)
|
||||
|
||||
else -> builder.setAllCorners(CornerFamily.ROUNDED, 0F)
|
||||
}
|
||||
holder.binding.preview.shapeAppearanceModel = builder.build()
|
||||
|
||||
val videoPreview = mListData[position]
|
||||
val thumbs = videoPreview.thumbs
|
||||
if (thumbs != null) {
|
||||
@ -51,41 +67,67 @@ class VideoPosterReviewAdapter(
|
||||
.into(holder.binding.preview)
|
||||
}
|
||||
holder.binding.preview.setOnClickListener {
|
||||
viewModel.previewLiveData.postValue(videoPreview)
|
||||
viewModel.setPreviewImage(position, mListData[position])
|
||||
}
|
||||
setSelected(holder, position)
|
||||
|
||||
mSelectMap[position] = true
|
||||
for (entry in mSelectMap) {
|
||||
if (entry.value && entry.key != position) {
|
||||
mSelectMap[entry.key] = false
|
||||
notifyItemChanged(entry.key)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VideoPosterReviewItemViewHolder, position: Int, payloads: MutableList<Any>) {
|
||||
if (payloads.contains(PAYLOADS_IS_SELECTED)) {
|
||||
setSelected(holder, position)
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position, payloads)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun setSelected(holder: VideoPosterReviewItemViewHolder, position: Int) {
|
||||
holder.binding.preview.clipToOutline = true
|
||||
holder.binding.previewBorderInner.clipToOutline = true
|
||||
holder.binding.previewBorderOut.shapeAppearanceModel = ShapeAppearanceModel().toBuilder()
|
||||
.setAllCorners(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
.build()
|
||||
holder.binding.previewBorderOut.strokeColor = ColorStateList.valueOf(Color.parseColor("#232323"))
|
||||
holder.binding.previewBorderOut.strokeWidth = 6F.dip2px().toFloat()
|
||||
|
||||
holder.binding.previewBorderOut.clipToOutline = true
|
||||
holder.binding.previewBorderInner.shapeAppearanceModel = ShapeAppearanceModel().toBuilder()
|
||||
.setAllCorners(CornerFamily.ROUNDED, 4F.dip2px().toFloat())
|
||||
.build()
|
||||
holder.binding.previewBorderInner.strokeColor = ColorStateList.valueOf(Color.parseColor("#2496FF"))
|
||||
holder.binding.previewBorderInner.strokeWidth = 4F.dip2px().toFloat()
|
||||
|
||||
holder.binding.gPreviewBorder.goneIf(selectedPosition != position)
|
||||
fun getCorner(hasCorner: Boolean) = if (hasCorner) 4F.dip2px().toFloat() else 0F
|
||||
val leftCorner = getCorner(position == 0)
|
||||
val rightCorner = getCorner(position == itemCount - 1)
|
||||
holder.binding.vCover.setCorners(
|
||||
leftCorner,
|
||||
rightCorner,
|
||||
rightCorner,
|
||||
leftCorner,
|
||||
)
|
||||
holder.binding.vCover.setLight(selectedPosition == position)
|
||||
}
|
||||
|
||||
fun setPreviewPosition(position: Int) {
|
||||
if (selectedPosition != position) {
|
||||
val lastPosition = selectedPosition
|
||||
selectedPosition = position
|
||||
if (lastPosition != SELECTED_IMAGE_POSITION) {
|
||||
notifyItemChanged(lastPosition, PAYLOADS_IS_SELECTED)
|
||||
}
|
||||
if (selectedPosition != SELECTED_IMAGE_POSITION) {
|
||||
notifyItemChanged(position, PAYLOADS_IS_SELECTED)
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
holder.binding.previewContainer.radius = if (mSelectMap[position] == true) {
|
||||
3F.dip2px().toFloat()
|
||||
} else if (position == 0 || position == itemCount - 1) {
|
||||
4F.dip2px().toFloat()
|
||||
} else {
|
||||
0F
|
||||
}
|
||||
holder.binding.previewBorder.visibility = if (mSelectMap[position] == true) {
|
||||
View.VISIBLE
|
||||
} else View.GONE
|
||||
fun getItem(position: Int) = mListData.getOrNull(position)
|
||||
|
||||
val previewContainerLp = holder.binding.previewContainer.layoutParams as ConstraintLayout.LayoutParams
|
||||
if (position == 0) {
|
||||
previewContainerLp.rightMargin = (-4F).dip2px()
|
||||
previewContainerLp.leftMargin = 0
|
||||
} else if (position == itemCount - 1) {
|
||||
previewContainerLp.leftMargin = (-4F).dip2px()
|
||||
previewContainerLp.rightMargin = 0
|
||||
} else {
|
||||
previewContainerLp.rightMargin = 0
|
||||
previewContainerLp.leftMargin = 0
|
||||
}
|
||||
holder.binding.previewContainer.layoutParams = previewContainerLp
|
||||
companion object {
|
||||
private const val PAYLOADS_IS_SELECTED = "payloads_is_selected"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,9 +4,11 @@ import android.app.Application
|
||||
import android.graphics.Bitmap
|
||||
import android.media.MediaMetadataRetriever
|
||||
import androidx.lifecycle.*
|
||||
import com.gh.gamecenter.common.utils.BitmapUtils
|
||||
import com.gh.gamecenter.common.utils.ImageUtils
|
||||
import com.gh.gamecenter.common.utils.throwExceptionInDebug
|
||||
import com.gh.gamecenter.common.utils.tryCatchInRelease
|
||||
import com.gh.gamecenter.common.view.CropImageZoomView.TransformationValues
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.entity.VideoEntity
|
||||
import java.io.File
|
||||
@ -15,13 +17,33 @@ import kotlin.math.roundToLong
|
||||
class VideoPosterViewModel(
|
||||
application: Application,
|
||||
val videoPath: String?,
|
||||
val videoEntity: VideoEntity?
|
||||
val videoEntity: VideoEntity?,
|
||||
val cache: VideoCoverCache?
|
||||
) : AndroidViewModel(application) {
|
||||
|
||||
val videoPreviewsLiveData = MutableLiveData<List<VideoPreview>>()
|
||||
|
||||
val previewLiveData = MutableLiveData<VideoPreview>()
|
||||
|
||||
private val _selectedImage = MutableLiveData<VideoPreview?>()
|
||||
val selectedImage: LiveData<VideoPreview?> = _selectedImage
|
||||
fun setSelectedImage(videoPreview: VideoPreview?) {
|
||||
_selectedImage.value = videoPreview
|
||||
if (videoPreview != null) {
|
||||
setPreviewImage(SELECTED_IMAGE_POSITION, videoPreview)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val _previewPosition = MutableLiveData<Int>()
|
||||
val previewPosition: LiveData<Int> = _previewPosition
|
||||
fun setPreviewImage(position: Int, videoPreview: VideoPreview) {
|
||||
val oldPosition = _previewPosition.value
|
||||
if (oldPosition != position) {
|
||||
_previewPosition.value = position
|
||||
previewLiveData.value = videoPreview
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
if (videoPath != null) {
|
||||
@ -36,22 +58,35 @@ class VideoPosterViewModel(
|
||||
}
|
||||
val videoReviews = ArrayList<VideoPreview>()
|
||||
|
||||
val cachePreview = cache?.toVideoPreview()
|
||||
for (i in 0 until totalThumbsCount) {
|
||||
val frameTime: Long = (startPosition + interval * i).roundToLong()
|
||||
val thumbsUrl = ImageUtils.getVideoSnapshot(videoEntity.url, frameTime * 1000)
|
||||
val element = VideoPreview(frameTime, null, thumbsUrl)
|
||||
videoReviews.add(element)
|
||||
|
||||
if (videoReviews.size == 1) {
|
||||
if (cachePreview == null && videoReviews.size == 1) {
|
||||
previewLiveData.postValue(element)
|
||||
}
|
||||
}
|
||||
|
||||
videoPreviewsLiveData.postValue(videoReviews)
|
||||
|
||||
cachePreview?.let(::initFromCache)
|
||||
|
||||
} else {
|
||||
throwExceptionInDebug("video not found")
|
||||
}
|
||||
}
|
||||
|
||||
private fun initFromCache(cachePreview: VideoPreview) {
|
||||
cache ?: return
|
||||
previewLiveData.postValue(cachePreview)
|
||||
_previewPosition.postValue(cache.position)
|
||||
if (cache.position == SELECTED_IMAGE_POSITION) {
|
||||
_selectedImage.value = cachePreview
|
||||
}
|
||||
}
|
||||
|
||||
private fun getImagesByVideo() {
|
||||
throwExceptionInDebug("video file not found", !File(videoPath).exists())
|
||||
|
||||
@ -68,6 +103,7 @@ class VideoPosterViewModel(
|
||||
return
|
||||
}
|
||||
|
||||
val cachePreview = cache?.toVideoPreview()
|
||||
val duration = durationString.toLong()
|
||||
val interval = (duration / totalThumbsCount)
|
||||
val videoReviews = ArrayList<VideoPreview>()
|
||||
@ -88,23 +124,64 @@ class VideoPosterViewModel(
|
||||
val element = VideoPreview(frameTime * 1000, bitmap)
|
||||
videoReviews.add(element)
|
||||
videoPreviewsLiveData.postValue(videoReviews)
|
||||
if (videoReviews.size == 1) {
|
||||
if (cachePreview == null && videoReviews.size == 1) {
|
||||
previewLiveData.postValue(element)
|
||||
}
|
||||
}
|
||||
|
||||
cachePreview?.let(::initFromCache)
|
||||
mediaMetadataRetriever.release()
|
||||
}
|
||||
|
||||
class VideoPreview(val time: Long, val thumbs: Bitmap? = null, val thumbsUrl: String? = null)
|
||||
companion object {
|
||||
|
||||
const val SELECTED_IMAGE_POSITION = -1
|
||||
}
|
||||
|
||||
class VideoPreview(
|
||||
val time: Long,
|
||||
val thumbs: Bitmap? = null,
|
||||
val thumbsUrl: String? = null,
|
||||
val values: TransformationValues? = null
|
||||
)
|
||||
|
||||
class VideoCoverCache(
|
||||
val position: Int,
|
||||
val localPath: String? = null,
|
||||
val url: String? = null,
|
||||
val values: TransformationValues
|
||||
) {
|
||||
|
||||
fun toVideoPreview(): VideoPreview? =
|
||||
when {
|
||||
localPath != null -> {
|
||||
if (File(localPath).exists()) {
|
||||
val bitmap = BitmapUtils.getBitmapByFile(localPath, Bitmap.Config.RGB_565)
|
||||
if (bitmap != null) {
|
||||
VideoPreview(0, bitmap, null, values)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
url != null -> VideoPreview(0, null, url, values)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val mApplication: Application,
|
||||
private val mVideoPath: String?,
|
||||
private val mVideoEntity: VideoEntity?
|
||||
private val mVideoEntity: VideoEntity?,
|
||||
private val cache: VideoCoverCache?
|
||||
) : ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return VideoPosterViewModel(mApplication, mVideoPath, mVideoEntity) as T
|
||||
return VideoPosterViewModel(mApplication, mVideoPath, mVideoEntity, cache) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,7 @@ import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
|
||||
import com.gh.gamecenter.common.callback.CancelListener
|
||||
import com.gh.gamecenter.common.callback.ConfirmListener
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.common.mvvm.Status
|
||||
@ -49,12 +50,13 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.newsdetail.NewsDetailActivity
|
||||
import com.gh.gamecenter.qa.editor.GameActivity
|
||||
import com.gh.gamecenter.video.label.VideoLabelActivity
|
||||
import com.gh.gamecenter.video.poster.PosterEditActivity
|
||||
import com.gh.gamecenter.video.poster.video.VideoPosterFragment
|
||||
import com.gh.gamecenter.video.upload.OnUploadListener
|
||||
import com.gh.gamecenter.video.upload.UploadManager
|
||||
import com.google.android.flexbox.FlexboxLayout
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lightgame.utils.Utils
|
||||
import com.therouter.TheRouter
|
||||
import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
import org.json.JSONArray
|
||||
@ -96,25 +98,6 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
mBinding.gameName.text = game.name
|
||||
mBinding.gameName.setTextColor(resources.getColor(com.gh.gamecenter.common.R.color.text_primary))
|
||||
}
|
||||
} else if (requestCode == REQUEST_CODE_IMAGE_STORE && resultCode == Activity.RESULT_OK) {
|
||||
if (data != null) {
|
||||
val uris = Matisse.obtainResult(data)
|
||||
for (uri in uris) {
|
||||
val picturePath = PathUtils.getPath(application, uri)
|
||||
if (File(picturePath).length() > ImageUtils.getUploadFileMaxSize()) {
|
||||
val count = ImageUtils.getUploadFileMaxSize() / 1024 / 1024
|
||||
val application: Application = application
|
||||
Utils.toast(getApplication(), application.getString(com.gh.gamecenter.common.R.string.pic_max_hint, count))
|
||||
continue
|
||||
}
|
||||
Utils.log("picturePath = $picturePath")
|
||||
|
||||
// skip image crop
|
||||
val intent = CropImageActivity.getIntent(this@UploadVideoActivity, picturePath, 9 / 16F, mEntrance)
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (requestCode == REQUEST_CODE_IMAGE_CROP && resultCode == Activity.RESULT_OK) {
|
||||
if (data != null) {
|
||||
val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH)
|
||||
@ -136,6 +119,7 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
VideoPosterFragment.clearVideoCoverCache(this)
|
||||
mVideoLink = intent.getParcelableExtra(VideoLinkEntity::class.java.simpleName)
|
||||
mEntranceLink = intent.getStringExtra(EntranceConsts.KEY_ENTRANCE_LINK) ?: ""
|
||||
mPath = intent.getStringExtra(EntranceConsts.KEY_PATH) ?: "其他"
|
||||
@ -259,7 +243,8 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
R.drawable.ic_upload_video_activity_unenable
|
||||
)
|
||||
)
|
||||
mBinding.chooseActivityIv.background = ContextCompat.getDrawable(this, com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999)
|
||||
mBinding.chooseActivityIv.background =
|
||||
ContextCompat.getDrawable(this, com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999)
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,14 +414,7 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
private fun startMediaStore() {
|
||||
try {
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(this) {
|
||||
// Matisse.from(this@UploadVideoActivity)
|
||||
// .choose(MimeType.ofImage())
|
||||
// .showSingleMediaType(true)
|
||||
// .countable(true)
|
||||
// .addFilter(GhMatisseFilter())
|
||||
// .maxSelectable(1)
|
||||
// .forResult(REQUEST_CODE_IMAGE_STORE)
|
||||
|
||||
val postcard = TheRouter.build(RouteConsts.activity.videoCoverEditActivity)
|
||||
|
||||
val videoPath = if (mViewModel.videoDraft != null) {
|
||||
mViewModel.videoDraft?.localPath
|
||||
@ -444,22 +422,17 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
intent.getStringExtra(EntranceConsts.KEY_PATH_VIDEO)
|
||||
}
|
||||
|
||||
var intent: Intent? = null
|
||||
if (!videoPath.isNullOrEmpty()) {
|
||||
intent = PosterEditActivity.getIntentByPath(this@UploadVideoActivity, videoPath)
|
||||
postcard.withString(EntranceConsts.KEY_PATH_VIDEO, videoPath)
|
||||
} else {
|
||||
val videoPatch = mViewModel.videoPatch
|
||||
if (videoPatch != null) {
|
||||
intent = PosterEditActivity.getIntentByVideo(this@UploadVideoActivity, videoPatch)
|
||||
postcard.withParcelable(EntranceConsts.KEY_VIDEO_ENTITY, videoPatch)
|
||||
} else {
|
||||
throwExceptionInDebug("video not found")
|
||||
}
|
||||
}
|
||||
if (intent != null) {
|
||||
startActivityForResult(intent, REQUEST_CODE_IMAGE_CROP)
|
||||
} else {
|
||||
toast("找不到相关视频")
|
||||
}
|
||||
postcard.navigation(this, REQUEST_CODE_IMAGE_CROP)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
toast(R.string.media_image_hint)
|
||||
@ -672,8 +645,16 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
flexCell.gravity = Gravity.CENTER
|
||||
flexCell.text = videoTagEntity.name
|
||||
flexCell.tag = videoTagEntity.id
|
||||
flexCell.setTextColor(DrawableView.getSelectorColorStyle(com.gh.gamecenter.common.R.color.text_secondary, com.gh.gamecenter.common.R.color.white))
|
||||
flexCell.background = DrawableView.getOvalSelectorStyle(com.gh.gamecenter.common.R.color.text_f2f2f2, com.gh.gamecenter.common.R.color.primary_theme)
|
||||
flexCell.setTextColor(
|
||||
DrawableView.getSelectorColorStyle(
|
||||
com.gh.gamecenter.common.R.color.text_secondary,
|
||||
com.gh.gamecenter.common.R.color.white
|
||||
)
|
||||
)
|
||||
flexCell.background = DrawableView.getOvalSelectorStyle(
|
||||
com.gh.gamecenter.common.R.color.text_f2f2f2,
|
||||
com.gh.gamecenter.common.R.color.primary_theme
|
||||
)
|
||||
flexCell.setPadding(12F.dip2px(), 0, 12F.dip2px(), 0)
|
||||
flexCell.setOnClickListener {
|
||||
Util_System_Keyboard.hideSoftKeyboard(this, mBinding.gameTitle)
|
||||
@ -789,7 +770,11 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
mBinding.uploadSpeed.visibility = View.VISIBLE
|
||||
mBinding.uploadButton.visibility = View.VISIBLE
|
||||
mBinding.uploadSpeed.text =
|
||||
(SpeedUtils.getSpeed(speed) + "预计还需" + SpeedUtils.getRemainTime(totalSize, currentSize, speed))
|
||||
(SpeedUtils.getSpeed(speed) + "预计还需" + SpeedUtils.getRemainTime(
|
||||
totalSize,
|
||||
currentSize,
|
||||
speed
|
||||
))
|
||||
mBinding.uploadProgress.update(((360 * currentSize) / totalSize).toInt(), "")
|
||||
}
|
||||
}
|
||||
@ -941,7 +926,6 @@ class UploadVideoActivity : ToolBarActivity() {
|
||||
private const val REQUEST_GAME_CODE = 116
|
||||
const val RESULT_CODE_VIDEO = 117
|
||||
const val RESULT_CODE_DRAFT = 118
|
||||
const val REQUEST_CODE_IMAGE_STORE = 119
|
||||
const val REQUEST_CODE_IMAGE_CROP = 120
|
||||
const val REQUEST_CODE_CHOOSE_LABEL = 121
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ import com.gh.gamecenter.common.utils.UploadImageUtils;
|
||||
import com.gh.gamecenter.CropImageActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
import com.gh.gamecenter.common.view.cropbox.CropBoxStyle;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -68,108 +69,104 @@ public class UserPortraitCropImageActivity extends CropImageActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.layout_menu_positive) {
|
||||
final WaitingDialogFragment postDialog = WaitingDialogFragment.newInstance(getString(R.string.post_img));
|
||||
postDialog.show(getSupportFragmentManager(), null);
|
||||
final String path = getCacheDir() + File.separator + System.currentTimeMillis() + ".jpg";
|
||||
Observable.create((ObservableOnSubscribe<String>) emitter -> {
|
||||
boolean isSuccess = savePicture(path);
|
||||
if (isSuccess) {
|
||||
UploadImageUtils.INSTANCE.uploadImage(UploadImageUtils.UploadType.icon, path, new UploadImageUtils.OnUploadImageListener() {
|
||||
@Override
|
||||
public void onSuccess(@NotNull String imageUrl) {
|
||||
emitter.onNext(imageUrl);
|
||||
emitter.onComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@Nullable Throwable e) {
|
||||
if (e != null) {
|
||||
emitter.onError(e);
|
||||
} else {
|
||||
emitter.onError(new IllegalStateException("upload image error"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(long total, long progress) {
|
||||
int percent = (int) (100 * (progress / (float) total));
|
||||
if (percent >= 100) percent = 99;
|
||||
if (postDialog != null) {
|
||||
postDialog.uploadWaitingHint("图片上传中 " + percent + "%");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(new Response<String>() {
|
||||
@Override
|
||||
public void onResponse(String url) {
|
||||
try {
|
||||
if (postDialog != null) postDialog.dismissAllowingStateLoss();
|
||||
mBaseHandler.sendEmptyMessage(0);
|
||||
|
||||
String iconCount = sp.getString("updateIconCount", null);
|
||||
|
||||
long l = System.currentTimeMillis();
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
|
||||
String time = format.format(new Date(l));
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("time", time);
|
||||
|
||||
if (TextUtils.isEmpty(iconCount)) {
|
||||
jsonObject.put("count", 1);
|
||||
} else {
|
||||
JSONObject json = new JSONObject(iconCount);
|
||||
String lastTime = json.getString("time");
|
||||
if (lastTime.equals(time)) {
|
||||
jsonObject.put("count", json.getInt("count") + 1);
|
||||
} else {
|
||||
jsonObject.put("count", 1);
|
||||
}
|
||||
}
|
||||
|
||||
sp.edit().putString("updateIconCount", jsonObject.toString()).apply();
|
||||
|
||||
Intent data = new Intent();
|
||||
data.putExtra(EntranceConsts.KEY_URL, url);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
protected void saveImage() {
|
||||
final WaitingDialogFragment postDialog = WaitingDialogFragment.newInstance(getString(R.string.post_img));
|
||||
postDialog.show(getSupportFragmentManager(), null);
|
||||
final String path = getCacheDir() + File.separator + System.currentTimeMillis() + ".jpg";
|
||||
Observable.create((ObservableOnSubscribe<String>) emitter -> {
|
||||
boolean isSuccess = savePicture(path);
|
||||
if (isSuccess) {
|
||||
UploadImageUtils.INSTANCE.uploadImage(UploadImageUtils.UploadType.icon, path, new UploadImageUtils.OnUploadImageListener() {
|
||||
@Override
|
||||
public void onSuccess(@NotNull String imageUrl) {
|
||||
emitter.onNext(imageUrl);
|
||||
emitter.onComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
@Override
|
||||
public void onError(@Nullable Throwable e) {
|
||||
if (e != null) {
|
||||
emitter.onError(e);
|
||||
} else {
|
||||
emitter.onError(new IllegalStateException("upload image error"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(long total, long progress) {
|
||||
int percent = (int) (100 * (progress / (float) total));
|
||||
if (percent >= 100) percent = 99;
|
||||
if (postDialog != null) {
|
||||
postDialog.uploadWaitingHint("图片上传中 " + percent + "%");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(new Response<String>() {
|
||||
@Override
|
||||
public void onResponse(String url) {
|
||||
try {
|
||||
if (postDialog != null) postDialog.dismissAllowingStateLoss();
|
||||
try {
|
||||
if (e != null && e.code() == HttpURLConnection.HTTP_FORBIDDEN && e.response().errorBody() != null) {
|
||||
JSONObject object = new JSONObject(e.response().errorBody().string());
|
||||
String detail = object.getString("detail");
|
||||
if ("too frequent".equals(detail)) {
|
||||
mBaseHandler.sendEmptyMessage(2);
|
||||
} else if ("INVALID PICTURE".equals(detail)) {
|
||||
mBaseHandler.sendEmptyMessage(3);
|
||||
} else {
|
||||
mBaseHandler.sendEmptyMessage(1);
|
||||
}
|
||||
mBaseHandler.sendEmptyMessage(0);
|
||||
|
||||
String iconCount = sp.getString("updateIconCount", null);
|
||||
|
||||
long l = System.currentTimeMillis();
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
|
||||
String time = format.format(new Date(l));
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("time", time);
|
||||
|
||||
if (TextUtils.isEmpty(iconCount)) {
|
||||
jsonObject.put("count", 1);
|
||||
} else {
|
||||
JSONObject json = new JSONObject(iconCount);
|
||||
String lastTime = json.getString("time");
|
||||
if (lastTime.equals(time)) {
|
||||
jsonObject.put("count", json.getInt("count") + 1);
|
||||
} else {
|
||||
jsonObject.put("count", 1);
|
||||
}
|
||||
}
|
||||
|
||||
sp.edit().putString("updateIconCount", jsonObject.toString()).apply();
|
||||
|
||||
Intent data = new Intent();
|
||||
data.putExtra(EntranceConsts.KEY_URL, url);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
if (postDialog != null) postDialog.dismissAllowingStateLoss();
|
||||
try {
|
||||
if (e != null && e.code() == HttpURLConnection.HTTP_FORBIDDEN && e.response().errorBody() != null) {
|
||||
JSONObject object = new JSONObject(e.response().errorBody().string());
|
||||
String detail = object.getString("detail");
|
||||
if ("too frequent".equals(detail)) {
|
||||
mBaseHandler.sendEmptyMessage(2);
|
||||
} else if ("INVALID PICTURE".equals(detail)) {
|
||||
mBaseHandler.sendEmptyMessage(3);
|
||||
} else {
|
||||
mBaseHandler.sendEmptyMessage(1);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
} else {
|
||||
mBaseHandler.sendEmptyMessage(1);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
mBaseHandler.sendEmptyMessage(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
return super.onMenuItemClick(item);
|
||||
}
|
||||
|
||||
// 用户头像压缩规则
|
||||
@ -188,11 +185,11 @@ public class UserPortraitCropImageActivity extends CropImageActivity {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Intent getIntent(Context context, String picturePath, float cropRatio, String entrance) {
|
||||
public static Intent getIntent(Context context, String picturePath, String entrance) {
|
||||
Intent intent = new Intent(context, UserPortraitCropImageActivity.class);
|
||||
intent.putExtra(EntranceConsts.KEY_PATH, picturePath);
|
||||
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance);
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_CROP_RATIO, cropRatio);
|
||||
intent.putExtra(EntranceConsts.KEY_IMAGE_CROP_STYLE, CropBoxStyle.Circle.INSTANCE);
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.os.bundleOf
|
||||
import com.gh.common.provider.CropImageProviderImpl.Companion.IMAGE_TYPE_AVATAR
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
|
||||
@ -93,23 +94,13 @@ class ChangeAvatarDialog : BaseDialogFragment() {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
when (requestCode) {
|
||||
REQUEST_MEDIA_ICON -> {
|
||||
val selectedPaths = Matisse.obtainResult(data) ?: return
|
||||
val picturePath = PathUtils.getPath(requireContext(), selectedPaths[0])
|
||||
Utils.log("picturePath = $picturePath")
|
||||
// 上传头像
|
||||
val intent = UserPortraitCropImageActivity.getIntent(
|
||||
context,
|
||||
picturePath, 1F, "我的光环(选择头像)"
|
||||
)
|
||||
startActivityForResult(intent, REQUEST_CROP_ICON)
|
||||
}
|
||||
REQUEST_CROP_ICON -> {
|
||||
if (data.extras != null) {
|
||||
val url = data.extras!!.getString(EntranceConsts.KEY_URL)
|
||||
mUserViewModel?.changeUserInfo(url, UserViewModel.TYPE_PORTRAIT)
|
||||
mUploadAvatar = true
|
||||
}
|
||||
}
|
||||
|
||||
ChooseDefaultAvatarDialog.REQUEST_CODE_DEFAULT_AVATAR -> {
|
||||
val tag = requireArguments().getString(EntranceConsts.KEY_PARENT_TAG)
|
||||
requireActivity().supportFragmentManager.findFragmentByTag(tag)
|
||||
@ -145,7 +136,7 @@ class ChangeAvatarDialog : BaseDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
val intent = LocalMediaActivity.getIntent(requireContext(), ChooseType.IMAGE, 1, "头像选择")
|
||||
val intent = LocalMediaActivity.getIntent(requireContext(), ChooseType.IMAGE, 1, "头像选择", IMAGE_TYPE_AVATAR)
|
||||
startActivityForResult(intent, REQUEST_MEDIA_ICON)
|
||||
}
|
||||
|
||||
@ -154,7 +145,6 @@ class ChangeAvatarDialog : BaseDialogFragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REQUEST_CROP_ICON = 12
|
||||
const val REQUEST_MEDIA_ICON = 13
|
||||
const val REQUEST_CODE_UPLOAD_AVATAR = 100
|
||||
|
||||
|
||||
Reference in New Issue
Block a user