功能:作品编辑和删除
This commit is contained in:
parent
c8e22d497e
commit
cc667a7643
|
|
@ -148,6 +148,21 @@ public class WorksServiceImpl extends ServiceImpl<WorksDao, Works> implements Wo
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean updateWorks(WorksRequest request, Integer userId) {
|
public Boolean updateWorks(WorksRequest request, Integer userId) {
|
||||||
|
log.info("=== 开始更新作品 ===");
|
||||||
|
log.info("作品ID: {}", request.getId());
|
||||||
|
log.info("用户ID: {}", userId);
|
||||||
|
log.info("标题: {}", request.getTitle());
|
||||||
|
log.info("描述: {}", request.getDescription());
|
||||||
|
log.info("类型: {}", request.getType());
|
||||||
|
log.info("封面URL: {}", request.getCoverUrl());
|
||||||
|
log.info("视频URL: {}", request.getVideoUrl());
|
||||||
|
log.info("图片URLs: {}", request.getImageUrls() != null ? request.getImageUrls().size() + " 张图片" : "无图片");
|
||||||
|
if (request.getImageUrls() != null) {
|
||||||
|
for (int i = 0; i < request.getImageUrls().size(); i++) {
|
||||||
|
log.info(" 图片 {}: {}", i+1, request.getImageUrls().get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (request.getId() == null) {
|
if (request.getId() == null) {
|
||||||
throw new CrmebException("作品ID不能为空");
|
throw new CrmebException("作品ID不能为空");
|
||||||
}
|
}
|
||||||
|
|
@ -157,6 +172,13 @@ public class WorksServiceImpl extends ServiceImpl<WorksDao, Works> implements Wo
|
||||||
if (works == null || works.getIsDeleted() == 1) {
|
if (works == null || works.getIsDeleted() == 1) {
|
||||||
throw new CrmebException("作品不存在");
|
throw new CrmebException("作品不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("原作品信息:");
|
||||||
|
log.info(" 原标题: {}", works.getTitle());
|
||||||
|
log.info(" 原描述: {}", works.getDescription());
|
||||||
|
log.info(" 原封面: {}", works.getCoverImage());
|
||||||
|
log.info(" 原图片: {}", works.getImages());
|
||||||
|
log.info(" 原视频: {}", works.getVideoUrl());
|
||||||
|
|
||||||
// 验证是否是作品作者
|
// 验证是否是作品作者
|
||||||
if (!works.getUid().equals(userId)) {
|
if (!works.getUid().equals(userId)) {
|
||||||
|
|
@ -187,12 +209,64 @@ public class WorksServiceImpl extends ServiceImpl<WorksDao, Works> implements Wo
|
||||||
if (request.getStatus() != null) {
|
if (request.getStatus() != null) {
|
||||||
works.setStatus(request.getStatus());
|
works.setStatus(request.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新媒体资源
|
||||||
|
if (request.getCoverUrl() != null) {
|
||||||
|
works.setCoverImage(request.getCoverUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理图片列表
|
||||||
|
if (request.getImageUrls() != null) {
|
||||||
|
if (request.getImageUrls().isEmpty()) {
|
||||||
|
works.setImages(null);
|
||||||
|
} else {
|
||||||
|
works.setImages(String.join(",", request.getImageUrls()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理视频URL
|
||||||
|
if (request.getVideoUrl() != null) {
|
||||||
|
works.setVideoUrl(request.getVideoUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新作品类型(如果提供)
|
||||||
|
if (request.getType() != null) {
|
||||||
|
works.setType(request.getType().toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新位置信息
|
||||||
|
if (request.getLocation() != null) {
|
||||||
|
works.setLocation(request.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新可见范围
|
||||||
|
if (request.getVisibility() != null) {
|
||||||
|
String visibility = request.getVisibility().toUpperCase();
|
||||||
|
if (visibility.equals("PUBLIC") || visibility.equals("FRIENDS") || visibility.equals("PRIVATE")) {
|
||||||
|
works.setVisibility(visibility);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新评论设置
|
||||||
|
if (request.getCommentSetting() != null) {
|
||||||
|
String commentSetting = request.getCommentSetting().toUpperCase();
|
||||||
|
if (commentSetting.equals("ALL") || commentSetting.equals("FRIENDS") || commentSetting.equals("DISABLED")) {
|
||||||
|
works.setCommentSetting(commentSetting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean updated = updateById(works);
|
boolean updated = updateById(works);
|
||||||
if (!updated) {
|
if (!updated) {
|
||||||
throw new CrmebException("更新作品失败");
|
throw new CrmebException("更新作品失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("=== 作品更新完成 ===");
|
||||||
|
log.info("更新后作品信息:");
|
||||||
|
log.info(" 新标题: {}", works.getTitle());
|
||||||
|
log.info(" 新描述: {}", works.getDescription());
|
||||||
|
log.info(" 新封面: {}", works.getCoverImage());
|
||||||
|
log.info(" 新图片: {}", works.getImages());
|
||||||
|
log.info(" 新视频: {}", works.getVideoUrl());
|
||||||
log.info("用户{}更新作品成功,作品ID:{}", userId, works.getId());
|
log.info("用户{}更新作品成功,作品ID:{}", userId, works.getId());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,8 @@ public class MyCollectionsActivity extends AppCompatActivity {
|
||||||
private void setupRecyclerView() {
|
private void setupRecyclerView() {
|
||||||
adapter = new WorksAdapter(work -> {
|
adapter = new WorksAdapter(work -> {
|
||||||
if (work != null && getActivity() != null) {
|
if (work != null && getActivity() != null) {
|
||||||
WorkDetailActivity.start(getActivity(), String.valueOf(work.getId()));
|
// 从我的收藏进入,显示编辑删除菜单(如果是自己的作品)
|
||||||
|
WorkDetailActivity.start(getActivity(), String.valueOf(work.getId()), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,8 @@ public class MyLikesActivity extends AppCompatActivity {
|
||||||
private void setupRecyclerView() {
|
private void setupRecyclerView() {
|
||||||
adapter = new WorksAdapter(work -> {
|
adapter = new WorksAdapter(work -> {
|
||||||
if (work != null && getActivity() != null) {
|
if (work != null && getActivity() != null) {
|
||||||
WorkDetailActivity.start(getActivity(), String.valueOf(work.getId()));
|
// 从我的点赞进入,显示编辑删除菜单(如果是自己的作品)
|
||||||
|
WorkDetailActivity.start(getActivity(), String.valueOf(work.getId()), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||||
|
|
|
||||||
|
|
@ -566,7 +566,8 @@ public class ProfileActivity extends AppCompatActivity {
|
||||||
// 设置我的作品区域
|
// 设置我的作品区域
|
||||||
myWorksAdapter = new WorksAdapter(work -> {
|
myWorksAdapter = new WorksAdapter(work -> {
|
||||||
if (work != null && work.getId() != null) {
|
if (work != null && work.getId() != null) {
|
||||||
WorkDetailActivity.start(this, String.valueOf(work.getId()));
|
// 从"我"页面进入,显示编辑删除菜单
|
||||||
|
WorkDetailActivity.start(this, String.valueOf(work.getId()), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
binding.myWorksRecycler.setLayoutManager(new GridLayoutManager(this, 2));
|
binding.myWorksRecycler.setLayoutManager(new GridLayoutManager(this, 2));
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,10 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
// 天地图定位服务继续
|
// 天地图定位服务继续
|
||||||
private TianDiTuLocationService locationService;
|
private TianDiTuLocationService locationService;
|
||||||
private ActivityResultLauncher<String[]> requestLocationPermissionLauncher;
|
private ActivityResultLauncher<String[]> requestLocationPermissionLauncher;
|
||||||
|
|
||||||
|
// 编辑模式相关
|
||||||
|
private boolean isEditMode = false;
|
||||||
|
private String editWorkId = null;
|
||||||
|
|
||||||
public static void start(Context context) {
|
public static void start(Context context) {
|
||||||
Intent intent = new Intent(context, PublishWorkActivity.class);
|
Intent intent = new Intent(context, PublishWorkActivity.class);
|
||||||
|
|
@ -106,6 +110,17 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否是编辑模式
|
||||||
|
isEditMode = getIntent().getBooleanExtra("edit_mode", false);
|
||||||
|
if (isEditMode) {
|
||||||
|
editWorkId = getIntent().getStringExtra("work_id");
|
||||||
|
if (TextUtils.isEmpty(editWorkId)) {
|
||||||
|
Toast.makeText(this, "作品ID不能为空", Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding = ActivityPublishWorkBinding.inflate(getLayoutInflater());
|
binding = ActivityPublishWorkBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
|
@ -117,6 +132,65 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
setupLaunchers();
|
setupLaunchers();
|
||||||
setupClickListeners();
|
setupClickListeners();
|
||||||
loadCategories(); // 加载分类数据
|
loadCategories(); // 加载分类数据
|
||||||
|
|
||||||
|
// 如果是编辑模式,预填充数据
|
||||||
|
if (isEditMode) {
|
||||||
|
loadEditData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载编辑数据
|
||||||
|
*/
|
||||||
|
private void loadEditData() {
|
||||||
|
if (TextUtils.isEmpty(editWorkId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从Intent中获取作品数据
|
||||||
|
String workTitle = getIntent().getStringExtra("work_title");
|
||||||
|
String workDescription = getIntent().getStringExtra("work_description");
|
||||||
|
String workType = getIntent().getStringExtra("work_type");
|
||||||
|
String workCoverUrl = getIntent().getStringExtra("work_cover_url");
|
||||||
|
String workVideoUrl = getIntent().getStringExtra("work_video_url");
|
||||||
|
ArrayList<String> workImageUrls = getIntent().getStringArrayListExtra("work_image_urls");
|
||||||
|
|
||||||
|
// 填充标题和描述
|
||||||
|
if (!TextUtils.isEmpty(workTitle)) {
|
||||||
|
binding.titleEditText.setText(workTitle);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(workDescription)) {
|
||||||
|
binding.descriptionEditText.setText(workDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置作品类型和媒体
|
||||||
|
if ("VIDEO".equals(workType)) {
|
||||||
|
currentWorkType = WorkItem.WorkType.VIDEO;
|
||||||
|
if (!TextUtils.isEmpty(workVideoUrl)) {
|
||||||
|
selectedVideoUri = Uri.parse(workVideoUrl);
|
||||||
|
selectedMediaUris.clear();
|
||||||
|
selectedMediaUris.add(selectedVideoUri);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentWorkType = WorkItem.WorkType.IMAGE;
|
||||||
|
if (workImageUrls != null && !workImageUrls.isEmpty()) {
|
||||||
|
selectedMediaUris.clear();
|
||||||
|
for (String url : workImageUrls) {
|
||||||
|
if (!TextUtils.isEmpty(url)) {
|
||||||
|
selectedMediaUris.add(Uri.parse(url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置封面
|
||||||
|
if (!TextUtils.isEmpty(workCoverUrl)) {
|
||||||
|
selectedCoverUri = Uri.parse(workCoverUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新UI显示
|
||||||
|
updateMediaDisplay();
|
||||||
|
updateCoverPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupToolbar() {
|
private void setupToolbar() {
|
||||||
|
|
@ -124,6 +198,14 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
if (getSupportActionBar() != null) {
|
if (getSupportActionBar() != null) {
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||||
|
// 根据模式设置标题
|
||||||
|
if (isEditMode) {
|
||||||
|
getSupportActionBar().setTitle("编辑作品");
|
||||||
|
binding.publishButton.setText("保存");
|
||||||
|
} else {
|
||||||
|
getSupportActionBar().setTitle("发布作品");
|
||||||
|
binding.publishButton.setText("发布");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binding.toolbar.setNavigationOnClickListener(v -> finish());
|
binding.toolbar.setNavigationOnClickListener(v -> finish());
|
||||||
}
|
}
|
||||||
|
|
@ -636,11 +718,29 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publishWork() {
|
private void publishWork() {
|
||||||
|
android.util.Log.d("PublishWork", "=== 开始发布/更新作品 ===");
|
||||||
|
android.util.Log.d("PublishWork", "编辑模式: " + isEditMode);
|
||||||
|
android.util.Log.d("PublishWork", "作品ID: " + editWorkId);
|
||||||
|
|
||||||
String title = binding.titleEditText.getText() != null
|
String title = binding.titleEditText.getText() != null
|
||||||
? binding.titleEditText.getText().toString().trim() : "";
|
? binding.titleEditText.getText().toString().trim() : "";
|
||||||
String description = binding.descriptionEditText.getText() != null
|
String description = binding.descriptionEditText.getText() != null
|
||||||
? binding.descriptionEditText.getText().toString().trim() : "";
|
? binding.descriptionEditText.getText().toString().trim() : "";
|
||||||
|
|
||||||
|
android.util.Log.d("PublishWork", "标题: " + title);
|
||||||
|
android.util.Log.d("PublishWork", "描述: " + description);
|
||||||
|
android.util.Log.d("PublishWork", "作品类型: " + currentWorkType);
|
||||||
|
android.util.Log.d("PublishWork", "媒体文件数量: " + selectedMediaUris.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < selectedMediaUris.size(); i++) {
|
||||||
|
Uri uri = selectedMediaUris.get(i);
|
||||||
|
android.util.Log.d("PublishWork", "媒体文件 " + (i+1) + ": " + uri.toString());
|
||||||
|
android.util.Log.d("PublishWork", " -> 是否本地文件: " + isLocalUri(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
android.util.Log.d("PublishWork", "封面URI: " + (selectedCoverUri != null ? selectedCoverUri.toString() : "null"));
|
||||||
|
android.util.Log.d("PublishWork", "封面是否本地文件: " + (selectedCoverUri != null ? isLocalUri(selectedCoverUri) : "N/A"));
|
||||||
|
|
||||||
// 验证标题
|
// 验证标题
|
||||||
if (TextUtils.isEmpty(title)) {
|
if (TextUtils.isEmpty(title)) {
|
||||||
Toast.makeText(this, "请输入作品标题", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "请输入作品标题", Toast.LENGTH_SHORT).show();
|
||||||
|
|
@ -675,23 +775,38 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
|
|
||||||
// 显示加载对话框
|
// 显示加载对话框
|
||||||
android.app.ProgressDialog progressDialog = new android.app.ProgressDialog(this);
|
android.app.ProgressDialog progressDialog = new android.app.ProgressDialog(this);
|
||||||
progressDialog.setMessage("正在发布作品...");
|
progressDialog.setMessage(isEditMode ? "正在更新作品..." : "正在发布作品...");
|
||||||
progressDialog.setCancelable(false);
|
progressDialog.setCancelable(false);
|
||||||
progressDialog.show();
|
progressDialog.show();
|
||||||
|
|
||||||
// 开始上传流程
|
// 开始上传流程
|
||||||
if (currentWorkType == WorkItem.WorkType.VIDEO && selectedVideoUri != null) {
|
if (currentWorkType == WorkItem.WorkType.VIDEO && selectedVideoUri != null) {
|
||||||
// 视频作品:先上传封面,再上传视频,最后发布
|
// 视频作品处理
|
||||||
uploadCoverImage(selectedCoverUri != null ? selectedCoverUri : selectedVideoUri,
|
handleVideoWorkUpload(title, description, progressDialog);
|
||||||
new UploadCallback() {
|
} else {
|
||||||
@Override
|
// 图片作品处理
|
||||||
public void onSuccess(String url) {
|
handleImageWorkUpload(title, description, progressDialog);
|
||||||
String coverUrl = url;
|
}
|
||||||
// 上传视频
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理视频作品上传
|
||||||
|
*/
|
||||||
|
private void handleVideoWorkUpload(String title, String description, android.app.ProgressDialog progressDialog) {
|
||||||
|
// 检查视频是否是本地文件(需要上传)还是网络URL(编辑模式,无需上传)
|
||||||
|
boolean needUploadVideo = isLocalUri(selectedVideoUri);
|
||||||
|
boolean needUploadCover = selectedCoverUri != null && isLocalUri(selectedCoverUri);
|
||||||
|
|
||||||
|
if (needUploadCover) {
|
||||||
|
// 需要上传新封面
|
||||||
|
uploadCoverImage(selectedCoverUri, new UploadCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(String coverUrl) {
|
||||||
|
if (needUploadVideo) {
|
||||||
|
// 需要上传新视频
|
||||||
uploadVideo(selectedVideoUri, new UploadCallback() {
|
uploadVideo(selectedVideoUri, new UploadCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(String videoUrl) {
|
public void onSuccess(String videoUrl) {
|
||||||
// 发布作品
|
|
||||||
publishWorkToServer(title, description, "VIDEO", coverUrl, videoUrl, null, progressDialog);
|
publishWorkToServer(title, description, "VIDEO", coverUrl, videoUrl, null, progressDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -701,36 +816,11 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
Toast.makeText(PublishWorkActivity.this, "视频上传失败: " + error, Toast.LENGTH_SHORT).show();
|
Toast.makeText(PublishWorkActivity.this, "视频上传失败: " + error, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// 使用原有视频URL
|
||||||
|
String videoUrl = selectedVideoUri.toString();
|
||||||
|
publishWorkToServer(title, description, "VIDEO", coverUrl, videoUrl, null, progressDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(String error) {
|
|
||||||
progressDialog.dismiss();
|
|
||||||
Toast.makeText(PublishWorkActivity.this, "封面上传失败: " + error, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// 图片作品:先上传封面,再上传所有图片,最后发布
|
|
||||||
Uri coverUri = selectedCoverUri != null ? selectedCoverUri :
|
|
||||||
(!selectedMediaUris.isEmpty() ? selectedMediaUris.get(0) : null);
|
|
||||||
|
|
||||||
uploadCoverImage(coverUri, new UploadCallback() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(String coverUrl) {
|
|
||||||
// 上传所有图片
|
|
||||||
uploadImages(selectedMediaUris, new UploadImagesCallback() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(List<String> imageUrls) {
|
|
||||||
// 发布作品
|
|
||||||
publishWorkToServer(title, description, "IMAGE", coverUrl, null, imageUrls, progressDialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(String error) {
|
|
||||||
progressDialog.dismiss();
|
|
||||||
Toast.makeText(PublishWorkActivity.this, "图片上传失败: " + error, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -739,8 +829,140 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
Toast.makeText(PublishWorkActivity.this, "封面上传失败: " + error, Toast.LENGTH_SHORT).show();
|
Toast.makeText(PublishWorkActivity.this, "封面上传失败: " + error, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (needUploadVideo) {
|
||||||
|
// 只需要上传视频,使用原有封面
|
||||||
|
String coverUrl = selectedCoverUri != null ? selectedCoverUri.toString() : selectedVideoUri.toString();
|
||||||
|
uploadVideo(selectedVideoUri, new UploadCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(String videoUrl) {
|
||||||
|
publishWorkToServer(title, description, "VIDEO", coverUrl, videoUrl, null, progressDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(String error) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "视频上传失败: " + error, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 都不需要上传,直接使用原有URL
|
||||||
|
String coverUrl = selectedCoverUri != null ? selectedCoverUri.toString() : selectedVideoUri.toString();
|
||||||
|
String videoUrl = selectedVideoUri.toString();
|
||||||
|
publishWorkToServer(title, description, "VIDEO", coverUrl, videoUrl, null, progressDialog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理图片作品上传
|
||||||
|
*/
|
||||||
|
private void handleImageWorkUpload(String title, String description, android.app.ProgressDialog progressDialog) {
|
||||||
|
android.util.Log.d("PublishWork", "=== 处理图片作品上传 ===");
|
||||||
|
android.util.Log.d("PublishWork", "selectedMediaUris数量: " + selectedMediaUris.size());
|
||||||
|
|
||||||
|
// 分离本地文件和网络URL
|
||||||
|
List<Uri> localImageUris = new ArrayList<>();
|
||||||
|
List<String> existingImageUrls = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < selectedMediaUris.size(); i++) {
|
||||||
|
Uri uri = selectedMediaUris.get(i);
|
||||||
|
android.util.Log.d("PublishWork", "图片" + i + ": " + uri.toString());
|
||||||
|
if (isLocalUri(uri)) {
|
||||||
|
localImageUris.add(uri);
|
||||||
|
android.util.Log.d("PublishWork", " -> 本地文件,需要上传");
|
||||||
|
} else {
|
||||||
|
existingImageUrls.add(uri.toString());
|
||||||
|
android.util.Log.d("PublishWork", " -> 网络URL,保留原有");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android.util.Log.d("PublishWork", "本地图片数量: " + localImageUris.size());
|
||||||
|
android.util.Log.d("PublishWork", "原有图片数量: " + existingImageUrls.size());
|
||||||
|
|
||||||
|
boolean needUploadCover = selectedCoverUri != null && isLocalUri(selectedCoverUri);
|
||||||
|
android.util.Log.d("PublishWork", "需要上传封面: " + needUploadCover);
|
||||||
|
|
||||||
|
Uri coverUri = selectedCoverUri != null ? selectedCoverUri :
|
||||||
|
(!selectedMediaUris.isEmpty() ? selectedMediaUris.get(0) : null);
|
||||||
|
|
||||||
|
if (needUploadCover) {
|
||||||
|
android.util.Log.d("PublishWork", "开始上传新封面...");
|
||||||
|
// 需要上传新封面
|
||||||
|
uploadCoverImage(selectedCoverUri, new UploadCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(String coverUrl) {
|
||||||
|
android.util.Log.d("PublishWork", "封面上传成功: " + coverUrl);
|
||||||
|
if (!localImageUris.isEmpty()) {
|
||||||
|
android.util.Log.d("PublishWork", "开始上传新图片...");
|
||||||
|
// 需要上传新图片
|
||||||
|
uploadImages(localImageUris, new UploadImagesCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<String> newImageUrls) {
|
||||||
|
android.util.Log.d("PublishWork", "新图片上传成功,数量: " + newImageUrls.size());
|
||||||
|
// 合并新上传的图片URL和原有的图片URL
|
||||||
|
List<String> allImageUrls = new ArrayList<>(existingImageUrls);
|
||||||
|
allImageUrls.addAll(newImageUrls);
|
||||||
|
android.util.Log.d("PublishWork", "合并后图片总数: " + allImageUrls.size());
|
||||||
|
publishWorkToServer(title, description, "IMAGE", coverUrl, null, allImageUrls, progressDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(String error) {
|
||||||
|
android.util.Log.e("PublishWork", "图片上传失败: " + error);
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "图片上传失败: " + error, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
android.util.Log.d("PublishWork", "无新图片需要上传,使用原有图片");
|
||||||
|
// 只使用原有图片
|
||||||
|
publishWorkToServer(title, description, "IMAGE", coverUrl, null, existingImageUrls, progressDialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(String error) {
|
||||||
|
android.util.Log.e("PublishWork", "封面上传失败: " + error);
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "封面上传失败: " + error, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (!localImageUris.isEmpty()) {
|
||||||
|
android.util.Log.d("PublishWork", "无需上传封面,开始上传新图片...");
|
||||||
|
// 只需要上传新图片,使用原有封面
|
||||||
|
String coverUrl = coverUri != null ? coverUri.toString() : "";
|
||||||
|
uploadImages(localImageUris, new UploadImagesCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<String> newImageUrls) {
|
||||||
|
android.util.Log.d("PublishWork", "新图片上传成功,数量: " + newImageUrls.size());
|
||||||
|
List<String> allImageUrls = new ArrayList<>(existingImageUrls);
|
||||||
|
allImageUrls.addAll(newImageUrls);
|
||||||
|
android.util.Log.d("PublishWork", "合并后图片总数: " + allImageUrls.size());
|
||||||
|
publishWorkToServer(title, description, "IMAGE", coverUrl, null, allImageUrls, progressDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(String error) {
|
||||||
|
android.util.Log.e("PublishWork", "图片上传失败: " + error);
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "图片上传失败: " + error, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
android.util.Log.d("PublishWork", "无新文件需要上传,直接使用原有URL");
|
||||||
|
// 都不需要上传,直接使用原有URL
|
||||||
|
String coverUrl = coverUri != null ? coverUri.toString() : "";
|
||||||
|
publishWorkToServer(title, description, "IMAGE", coverUrl, null, existingImageUrls, progressDialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断URI是否是本地文件
|
||||||
|
*/
|
||||||
|
private boolean isLocalUri(Uri uri) {
|
||||||
|
if (uri == null) return false;
|
||||||
|
String scheme = uri.getScheme();
|
||||||
|
return "file".equals(scheme) || "content".equals(scheme);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传封面图片
|
* 上传封面图片
|
||||||
|
|
@ -936,12 +1158,24 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发布作品到服务器
|
* 发布或更新作品到服务器
|
||||||
*/
|
*/
|
||||||
private void publishWorkToServer(String title, String description, String type,
|
private void publishWorkToServer(String title, String description, String type,
|
||||||
String coverUrl, String videoUrl, List<String> imageUrls,
|
String coverUrl, String videoUrl, List<String> imageUrls,
|
||||||
android.app.ProgressDialog progressDialog) {
|
android.app.ProgressDialog progressDialog) {
|
||||||
WorksRequest request = new WorksRequest();
|
WorksRequest request = new WorksRequest();
|
||||||
|
|
||||||
|
// 如果是编辑模式,设置作品ID
|
||||||
|
if (isEditMode && !TextUtils.isEmpty(editWorkId)) {
|
||||||
|
try {
|
||||||
|
request.setId(Long.parseLong(editWorkId));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(this, "作品ID格式错误", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
request.setTitle(title);
|
request.setTitle(title);
|
||||||
request.setDescription(description);
|
request.setDescription(description);
|
||||||
request.setType(type);
|
request.setType(type);
|
||||||
|
|
@ -979,34 +1213,70 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiService apiService = ApiClient.getService(this);
|
ApiService apiService = ApiClient.getService(this);
|
||||||
Call<ApiResponse<Long>> call = apiService.publishWork(request);
|
|
||||||
|
if (isEditMode) {
|
||||||
call.enqueue(new retrofit2.Callback<ApiResponse<Long>>() {
|
// 编辑模式:调用更新API
|
||||||
@Override
|
Call<ApiResponse<Boolean>> updateCall = apiService.updateWork(request);
|
||||||
public void onResponse(Call<ApiResponse<Long>> call, retrofit2.Response<ApiResponse<Long>> response) {
|
updateCall.enqueue(new retrofit2.Callback<ApiResponse<Boolean>>() {
|
||||||
progressDialog.dismiss();
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<Boolean>> call, retrofit2.Response<ApiResponse<Boolean>> response) {
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
progressDialog.dismiss();
|
||||||
ApiResponse<Long> apiResponse = response.body();
|
|
||||||
if (apiResponse.getCode() == 200) {
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
Toast.makeText(PublishWorkActivity.this, "发布成功", Toast.LENGTH_SHORT).show();
|
ApiResponse<Boolean> apiResponse = response.body();
|
||||||
finish();
|
if (apiResponse.getCode() == 200) {
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "更新成功", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
// 设置结果并返回
|
||||||
|
setResult(RESULT_OK);
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
String errorMessage = apiResponse.getMessage() != null ? apiResponse.getMessage() : "更新失败";
|
||||||
|
Toast.makeText(PublishWorkActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(PublishWorkActivity.this,
|
Toast.makeText(PublishWorkActivity.this, "更新失败", Toast.LENGTH_SHORT).show();
|
||||||
apiResponse.getMessage() != null ? apiResponse.getMessage() : "发布失败",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Toast.makeText(PublishWorkActivity.this, "发布失败", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<ApiResponse<Long>> call, Throwable t) {
|
public void onFailure(Call<ApiResponse<Boolean>> call, Throwable t) {
|
||||||
progressDialog.dismiss();
|
progressDialog.dismiss();
|
||||||
Toast.makeText(PublishWorkActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
Toast.makeText(PublishWorkActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// 发布模式:调用发布API
|
||||||
|
Call<ApiResponse<Long>> publishCall = apiService.publishWork(request);
|
||||||
|
publishCall.enqueue(new retrofit2.Callback<ApiResponse<Long>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<Long>> call, retrofit2.Response<ApiResponse<Long>> response) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
ApiResponse<Long> apiResponse = response.body();
|
||||||
|
if (apiResponse.getCode() == 200) {
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "发布成功", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
// 设置结果并返回
|
||||||
|
setResult(RESULT_OK);
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
String errorMessage = apiResponse.getMessage() != null ? apiResponse.getMessage() : "发布失败";
|
||||||
|
Toast.makeText(PublishWorkActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "发布失败", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ApiResponse<Long>> call, Throwable t) {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
Toast.makeText(PublishWorkActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1598,4 +1868,5 @@ public class PublishWorkActivity extends AppCompatActivity {
|
||||||
} else {
|
} else {
|
||||||
binding.categorySpinner.setText(selectedCategory.getName());
|
binding.categorySpinner.setText(selectedCategory.getName());
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -440,26 +440,16 @@ public class RoomDetailActivity extends AppCompatActivity implements SurfaceHold
|
||||||
// 加载点赞数
|
// 加载点赞数
|
||||||
loadLikeCount();
|
loadLikeCount();
|
||||||
|
|
||||||
// 点赞按钮点击事件
|
// 点赞按钮点击事件 - TRTC风格动画
|
||||||
likeButton.setOnClickListener(v -> {
|
likeButton.setOnClickListener(v -> {
|
||||||
if (!AuthHelper.isLoggedIn(this)) {
|
if (!AuthHelper.isLoggedIn(this)) {
|
||||||
Toast.makeText(this, "请先登录", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "请先登录", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 点赞动画
|
// TRTC风格点赞动画
|
||||||
likeButton.animate()
|
android.view.animation.Animation likeAnim = android.view.animation.AnimationUtils.loadAnimation(this, R.anim.trtc_like_animation);
|
||||||
.scaleX(1.3f)
|
likeButton.startAnimation(likeAnim);
|
||||||
.scaleY(1.3f)
|
|
||||||
.setDuration(100)
|
|
||||||
.withEndAction(() -> {
|
|
||||||
likeButton.animate()
|
|
||||||
.scaleX(1.0f)
|
|
||||||
.scaleY(1.0f)
|
|
||||||
.setDuration(100)
|
|
||||||
.start();
|
|
||||||
})
|
|
||||||
.start();
|
|
||||||
|
|
||||||
// 调用点赞API
|
// 调用点赞API
|
||||||
likeRoom();
|
likeRoom();
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,16 @@ public class WorkDetailActivity extends AppCompatActivity {
|
||||||
private int commentCount = 0;
|
private int commentCount = 0;
|
||||||
|
|
||||||
private static final String EXTRA_WORK_ID = "work_id";
|
private static final String EXTRA_WORK_ID = "work_id";
|
||||||
|
private static final String EXTRA_SHOW_MENU = "show_menu";
|
||||||
|
|
||||||
public static void start(Context context, String workId) {
|
public static void start(Context context, String workId) {
|
||||||
|
start(context, workId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void start(Context context, String workId, boolean showMenu) {
|
||||||
Intent intent = new Intent(context, WorkDetailActivity.class);
|
Intent intent = new Intent(context, WorkDetailActivity.class);
|
||||||
intent.putExtra(EXTRA_WORK_ID, workId);
|
intent.putExtra(EXTRA_WORK_ID, workId);
|
||||||
|
intent.putExtra(EXTRA_SHOW_MENU, showMenu);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,12 +69,21 @@ public class WorkDetailActivity extends AppCompatActivity {
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
String workId = getIntent().getStringExtra(EXTRA_WORK_ID);
|
String workId = getIntent().getStringExtra(EXTRA_WORK_ID);
|
||||||
|
boolean showMenu = getIntent().getBooleanExtra(EXTRA_SHOW_MENU, false);
|
||||||
|
|
||||||
if (TextUtils.isEmpty(workId)) {
|
if (TextUtils.isEmpty(workId)) {
|
||||||
Toast.makeText(this, "作品ID不能为空", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "作品ID不能为空", Toast.LENGTH_SHORT).show();
|
||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据showMenu参数控制菜单显示
|
||||||
|
if (showMenu) {
|
||||||
|
binding.actionButton.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
binding.actionButton.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
// 加载作品详情
|
// 加载作品详情
|
||||||
loadWorkDetail(workId);
|
loadWorkDetail(workId);
|
||||||
}
|
}
|
||||||
|
|
@ -968,39 +983,36 @@ public class WorkDetailActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupActionButton() {
|
private void setupActionButton() {
|
||||||
// ============================================
|
// 检查是否应该显示菜单
|
||||||
// TODO: 判断是否是当前用户的作品
|
boolean showMenu = getIntent().getBooleanExtra(EXTRA_SHOW_MENU, false);
|
||||||
// ============================================
|
if (!showMenu) {
|
||||||
// 判断方式(推荐方式3):
|
binding.actionButton.setVisibility(View.GONE);
|
||||||
// 1. 从WorkItem中获取userId字段,与当前登录用户ID比较(需要从AuthStore获取当前用户ID)
|
return;
|
||||||
// 2. 或调用接口: GET /api/works/{workId}/isOwner
|
}
|
||||||
// 3. 或从作品详情接口返回的WorkItem中包含isOwner字段(推荐,已在获取详情时返回)
|
|
||||||
//
|
// 检查是否是当前用户的作品
|
||||||
// 如果使用方式3(推荐):
|
String currentUserIdStr = AuthStore.getUserId(this);
|
||||||
// - 在获取作品详情时,后端已经返回isOwner字段
|
if (currentUserIdStr == null || workItem == null) {
|
||||||
// - 直接使用 workItem.getIsOwner() 或从详情接口返回的isOwner字段
|
binding.actionButton.setVisibility(View.GONE);
|
||||||
// - 如果isOwner为true,显示编辑/删除按钮
|
return;
|
||||||
// - 如果isOwner为false或用户未登录,隐藏编辑/删除按钮
|
}
|
||||||
//
|
|
||||||
// 如果使用方式1:
|
try {
|
||||||
// - 需要从AuthStore获取当前登录用户的userId
|
int currentUserId = Integer.parseInt(currentUserIdStr);
|
||||||
// - 比较 workItem.getUserId() 与当前用户ID
|
int authorId = workItem.getAuthorId();
|
||||||
// - 如果相同,显示编辑/删除按钮;否则隐藏
|
|
||||||
//
|
if (currentUserId != authorId) {
|
||||||
// 如果使用方式2:
|
// 不是自己的作品,隐藏菜单
|
||||||
// 接口路径: GET /api/works/{workId}/isOwner
|
binding.actionButton.setVisibility(View.GONE);
|
||||||
// 请求方法: GET
|
return;
|
||||||
// 请求头:
|
}
|
||||||
// - Authorization: Bearer {token} (必填,需要登录)
|
} catch (NumberFormatException e) {
|
||||||
// 路径参数:
|
binding.actionButton.setVisibility(View.GONE);
|
||||||
// - workId: String (必填) - 作品ID
|
return;
|
||||||
// 返回数据格式: ApiResponse<IsOwnerResponse>
|
}
|
||||||
// 后端返回: { "code": 200, "data": { "isOwner": true/false } }
|
|
||||||
//
|
// 是自己的作品且需要显示菜单,设置点击事件
|
||||||
// 目前简化处理,所有作品都显示操作按钮
|
binding.actionButton.setVisibility(View.VISIBLE);
|
||||||
// TODO: 根据isOwner字段控制按钮显示/隐藏
|
|
||||||
|
|
||||||
// 新布局中actionButton是ImageView,不是FloatingActionButton(添加防抖)
|
|
||||||
binding.actionButton.setOnClickListener(new DebounceClickListener() {
|
binding.actionButton.setOnClickListener(new DebounceClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDebouncedClick(View v) {
|
public void onDebouncedClick(View v) {
|
||||||
|
|
@ -1010,10 +1022,21 @@ public class WorkDetailActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showActionMenu() {
|
private void showActionMenu() {
|
||||||
// TODO: 判断是否是当前用户的作品
|
// 检查是否是当前用户的作品
|
||||||
boolean isOwner = true; // 简化处理
|
String currentUserIdStr = AuthStore.getUserId(this);
|
||||||
|
if (currentUserIdStr == null || workItem == null) {
|
||||||
if (!isOwner) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int currentUserId = Integer.parseInt(currentUserIdStr);
|
||||||
|
int authorId = workItem.getAuthorId();
|
||||||
|
|
||||||
|
if (currentUserId != authorId) {
|
||||||
|
Toast.makeText(this, "只能编辑自己的作品", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1032,58 +1055,32 @@ public class WorkDetailActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void editWork() {
|
private void editWork() {
|
||||||
// ============================================
|
// 检查登录状态
|
||||||
// TODO: 实现编辑作品功能
|
if (!AuthHelper.requireLogin(this, "编辑作品需要登录")) {
|
||||||
// ============================================
|
return;
|
||||||
// 方案1: 跳转到编辑页面(PublishWorkActivity,传入workItem数据)
|
}
|
||||||
// 方案2: 在当前页面弹出编辑对话框
|
|
||||||
//
|
if (workItem == null) {
|
||||||
// 如果使用方案1(推荐):
|
Toast.makeText(this, "作品信息不完整", Toast.LENGTH_SHORT).show();
|
||||||
// 1. 创建EditWorkActivity或复用PublishWorkActivity
|
return;
|
||||||
// 2. 传入workItem数据(通过Intent传递)
|
}
|
||||||
// 3. 在编辑页面预填充作品信息(标题、描述、图片/视频)
|
|
||||||
// 4. 用户修改后,调用更新接口保存
|
// 跳转到编辑页面(复用PublishWorkActivity)
|
||||||
//
|
Intent intent = new Intent(this, PublishWorkActivity.class);
|
||||||
// 更新作品接口:
|
intent.putExtra("edit_mode", true);
|
||||||
// 接口路径: PUT /api/works/{workId}
|
intent.putExtra("work_id", workItem.getId());
|
||||||
// 请求方法: PUT
|
intent.putExtra("work_title", workItem.getTitle());
|
||||||
// 请求头:
|
intent.putExtra("work_description", workItem.getDescription());
|
||||||
// - Authorization: Bearer {token} (必填,需要登录)
|
intent.putExtra("work_type", workItem.getType().name());
|
||||||
// 路径参数:
|
intent.putExtra("work_cover_url", workItem.getCoverUrl());
|
||||||
// - workId: String (必填) - 作品ID
|
|
||||||
// 请求体 (multipart/form-data 或 JSON):
|
|
||||||
// - title: String (可选) - 作品标题
|
|
||||||
// - description: String (可选) - 作品描述
|
|
||||||
// - cover: File (可选) - 新的封面图片(如果要更换封面)
|
|
||||||
// - video: File (可选) - 新的视频文件(如果要更换视频,仅视频作品)
|
|
||||||
// - images: File[] (可选) - 新的图片文件数组(如果要更换图片,仅图片作品)
|
|
||||||
// - deletedImageIds: String[] (可选) - 要删除的图片ID列表(图片作品)
|
|
||||||
// 返回数据格式: ApiResponse<WorkItem>
|
|
||||||
//
|
|
||||||
// 前端需要传入的参数:
|
|
||||||
// - workId: String (从workItem.getId()获取)
|
|
||||||
// - title: String (用户修改后的标题)
|
|
||||||
// - description: String (用户修改后的描述,可选)
|
|
||||||
// - cover: File (如果要更换封面)
|
|
||||||
// - video/images: File/File[] (如果要更换媒体文件)
|
|
||||||
// - token: String (必填,从AuthStore获取)
|
|
||||||
//
|
|
||||||
// 实现步骤:
|
|
||||||
// 1. 跳转到编辑页面,传入workItem
|
|
||||||
// 2. 在编辑页面加载作品数据并预填充表单
|
|
||||||
// 3. 用户修改内容后点击保存
|
|
||||||
// 4. 验证输入(标题不能为空等)
|
|
||||||
// 5. 如果有新上传的文件,先上传文件获取URL
|
|
||||||
// 6. 调用 PUT /api/works/{workId} 更新作品信息
|
|
||||||
// 7. 更新成功后,刷新当前页面或返回并刷新列表
|
|
||||||
// 8. 处理错误情况(未登录、无权限、文件上传失败等)
|
|
||||||
//
|
|
||||||
// 注意:
|
|
||||||
// - 只有作品作者才能编辑
|
|
||||||
// - 如果更换媒体文件,需要先上传新文件
|
|
||||||
// - 图片作品可以删除部分图片,需要传递deletedImageIds
|
|
||||||
|
|
||||||
Toast.makeText(this, "编辑功能待实现", Toast.LENGTH_SHORT).show();
|
if (workItem.getType() == WorkItem.WorkType.VIDEO) {
|
||||||
|
intent.putExtra("work_video_url", workItem.getVideoUrl());
|
||||||
|
} else if (workItem.getImageUrls() != null) {
|
||||||
|
intent.putStringArrayListExtra("work_image_urls", new ArrayList<>(workItem.getImageUrls()));
|
||||||
|
}
|
||||||
|
|
||||||
|
startActivityForResult(intent, 1001);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteWork() {
|
private void deleteWork() {
|
||||||
|
|
@ -1312,5 +1309,18 @@ public class WorkDetailActivity extends AppCompatActivity {
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
if (requestCode == 1001 && resultCode == RESULT_OK) {
|
||||||
|
// 编辑成功,重新加载作品详情
|
||||||
|
String workId = getIntent().getStringExtra(EXTRA_WORK_ID);
|
||||||
|
if (!TextUtils.isEmpty(workId)) {
|
||||||
|
loadWorkDetail(workId);
|
||||||
|
Toast.makeText(this, "作品更新成功", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,9 @@ public interface ApiService {
|
||||||
@POST("api/front/works/publish")
|
@POST("api/front/works/publish")
|
||||||
Call<ApiResponse<Long>> publishWork(@Body WorksRequest body);
|
Call<ApiResponse<Long>> publishWork(@Body WorksRequest body);
|
||||||
|
|
||||||
|
@POST("api/front/works/update")
|
||||||
|
Call<ApiResponse<Boolean>> updateWork(@Body WorksRequest body);
|
||||||
|
|
||||||
@GET("api/front/works/detail/{id}")
|
@GET("api/front/works/detail/{id}")
|
||||||
Call<ApiResponse<WorksResponse>> getWorkDetail(@Path("id") long id);
|
Call<ApiResponse<WorksResponse>> getWorkDetail(@Path("id") long id);
|
||||||
|
|
||||||
|
|
@ -394,7 +397,7 @@ public interface ApiService {
|
||||||
@Query("page") int page,
|
@Query("page") int page,
|
||||||
@Query("pageSize") int pageSize);
|
@Query("pageSize") int pageSize);
|
||||||
|
|
||||||
@DELETE("api/front/works/delete/{id}")
|
@POST("api/front/works/delete/{id}")
|
||||||
Call<ApiResponse<Boolean>> deleteWork(@Path("id") long id);
|
Call<ApiResponse<Boolean>> deleteWork(@Path("id") long id);
|
||||||
|
|
||||||
@POST("api/front/works/like/{id}")
|
@POST("api/front/works/like/{id}")
|
||||||
|
|
|
||||||
20
android-app/app/src/main/res/anim/trtc_button_click.xml
Normal file
20
android-app/app/src/main/res/anim/trtc_button_click.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<scale
|
||||||
|
android:duration="100"
|
||||||
|
android:fromXScale="1.0"
|
||||||
|
android:fromYScale="1.0"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
android:toXScale="0.95"
|
||||||
|
android:toYScale="0.95" />
|
||||||
|
<scale
|
||||||
|
android:duration="100"
|
||||||
|
android:fromXScale="0.95"
|
||||||
|
android:fromYScale="0.95"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
android:startOffset="100"
|
||||||
|
android:toXScale="1.0"
|
||||||
|
android:toYScale="1.0" />
|
||||||
|
</set>
|
||||||
29
android-app/app/src/main/res/anim/trtc_like_animation.xml
Normal file
29
android-app/app/src/main/res/anim/trtc_like_animation.xml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<scale
|
||||||
|
android:duration="150"
|
||||||
|
android:fromXScale="1.0"
|
||||||
|
android:fromYScale="1.0"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
android:toXScale="1.3"
|
||||||
|
android:toYScale="1.3" />
|
||||||
|
<scale
|
||||||
|
android:duration="150"
|
||||||
|
android:fromXScale="1.3"
|
||||||
|
android:fromYScale="1.3"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%"
|
||||||
|
android:startOffset="150"
|
||||||
|
android:toXScale="1.0"
|
||||||
|
android:toYScale="1.0" />
|
||||||
|
<alpha
|
||||||
|
android:duration="300"
|
||||||
|
android:fromAlpha="1.0"
|
||||||
|
android:toAlpha="0.8" />
|
||||||
|
<alpha
|
||||||
|
android:duration="200"
|
||||||
|
android:fromAlpha="0.8"
|
||||||
|
android:startOffset="300"
|
||||||
|
android:toAlpha="1.0" />
|
||||||
|
</set>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/trtc_accent"/>
|
||||||
|
<corners android:radius="22dp"/>
|
||||||
|
<stroke android:width="1dp" android:color="@color/trtc_accent_light"/>
|
||||||
|
</shape>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/trtc_overlay_dark"/>
|
||||||
|
<corners android:radius="22dp"/>
|
||||||
|
<stroke android:width="1dp" android:color="@color/trtc_overlay_light"/>
|
||||||
|
</shape>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/trtc_overlay_dark"/>
|
||||||
|
<corners android:radius="16dp"/>
|
||||||
|
<stroke android:width="1dp" android:color="@color/trtc_overlay_light"/>
|
||||||
|
</shape>
|
||||||
6
android-app/app/src/main/res/drawable/bg_trtc_input.xml
Normal file
6
android-app/app/src/main/res/drawable/bg_trtc_input.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/trtc_overlay_light"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
<stroke android:width="1dp" android:color="@color/trtc_overlay_light"/>
|
||||||
|
</shape>
|
||||||
|
|
@ -150,32 +150,32 @@
|
||||||
android:src="@drawable/ic_arrow_back_24"
|
android:src="@drawable/ic_arrow_back_24"
|
||||||
app:tint="@android:color/white" />
|
app:tint="@android:color/white" />
|
||||||
|
|
||||||
<!-- 主播信息卡片 - 放在顶部栏内 -->
|
<!-- 主播信息卡片 - TRTC风格 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/roomInfoLayout"
|
android:id="@+id/roomInfoLayout"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:background="@drawable/bg_rounded_semi_transparent"
|
android:background="@drawable/bg_trtc_info_card"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingHorizontal="8dp"
|
android:paddingHorizontal="10dp"
|
||||||
android:paddingVertical="6dp">
|
android:paddingVertical="8dp">
|
||||||
|
|
||||||
<de.hdodenhof.circleimageview.CircleImageView
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
android:id="@+id/streamerAvatar"
|
android:id="@+id/streamerAvatar"
|
||||||
android:layout_width="32dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="36dp"
|
||||||
android:src="@drawable/ic_person_24"
|
android:src="@drawable/ic_person_24"
|
||||||
app:civ_border_color="#FFFFFF"
|
app:civ_border_color="@color/trtc_accent"
|
||||||
app:civ_border_width="1dp" />
|
app:civ_border_width="2dp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="10dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
@ -183,8 +183,8 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="主播"
|
android:text="主播"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@color/trtc_text_primary"
|
||||||
android:textSize="13sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
@ -195,68 +195,70 @@
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="直播间"
|
android:text="直播间"
|
||||||
android:textColor="#CCFFFFFF"
|
android:textColor="@color/trtc_text_secondary"
|
||||||
android:textSize="11sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/followButton"
|
android:id="@+id/followButton"
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
style="@style/Widget.Material3.Button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="26dp"
|
android:layout_height="32dp"
|
||||||
android:layout_marginStart="4dp"
|
android:layout_marginStart="6dp"
|
||||||
android:minWidth="48dp"
|
android:minWidth="56dp"
|
||||||
android:paddingHorizontal="10dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:text="关注"
|
android:text="关注"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@color/trtc_text_primary"
|
||||||
android:textSize="11sp"
|
android:textSize="12sp"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
app:backgroundTint="#FF4081"
|
app:backgroundTint="@color/trtc_accent"
|
||||||
app:cornerRadius="13dp" />
|
app:cornerRadius="16dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 直播状态标签 -->
|
<!-- 直播状态标签 - TRTC风格 -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/liveTag"
|
android:id="@+id/liveTag"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:background="@drawable/live_badge_background"
|
android:background="@drawable/bg_trtc_button_primary"
|
||||||
android:paddingHorizontal="8dp"
|
android:paddingHorizontal="10dp"
|
||||||
android:paddingVertical="3dp"
|
android:paddingVertical="4dp"
|
||||||
android:text="● 直播中"
|
android:text="● LIVE"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@color/trtc_text_primary"
|
||||||
android:textSize="11sp"
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"
|
||||||
android:visibility="visible" />
|
android:visibility="visible" />
|
||||||
|
|
||||||
<!-- 观看人数 -->
|
<!-- 观看人数 - TRTC风格 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/topViewerLayout"
|
android:id="@+id/topViewerLayout"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:background="@drawable/bg_rounded_semi_transparent"
|
android:background="@drawable/bg_trtc_button_secondary"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingHorizontal="8dp"
|
android:paddingHorizontal="10dp"
|
||||||
android:paddingVertical="4dp">
|
android:paddingVertical="6dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="14dp"
|
android:layout_width="16dp"
|
||||||
android:layout_height="14dp"
|
android:layout_height="16dp"
|
||||||
android:layout_marginEnd="4dp"
|
android:layout_marginEnd="4dp"
|
||||||
android:src="@drawable/ic_people_24"
|
android:src="@drawable/ic_people_24"
|
||||||
app:tint="@android:color/white" />
|
app:tint="@color/trtc_text_primary" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/topViewerCount"
|
android:id="@+id/topViewerCount"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="0"
|
android:text="0"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@color/trtc_text_primary"
|
||||||
android:textSize="12sp" />
|
android:textSize="13sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
@ -296,7 +298,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<!-- 右侧悬浮功能按钮 -->
|
<!-- 右侧悬浮功能按钮 - TRTC风格 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/rightButtons"
|
android:id="@+id/rightButtons"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
@ -308,60 +310,61 @@
|
||||||
app:layout_constraintBottom_toTopOf="@id/chatInputLayout"
|
app:layout_constraintBottom_toTopOf="@id/chatInputLayout"
|
||||||
app:layout_constraintEnd_toEndOf="parent">
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
<!-- 点赞按钮 -->
|
<!-- 点赞按钮 - TRTC风格 -->
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="12dp">
|
android:layout_marginBottom="16dp">
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/likeButton"
|
android:id="@+id/likeButton"
|
||||||
android:layout_width="44dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="44dp"
|
android:layout_height="48dp"
|
||||||
android:background="@drawable/bg_circle_semi_transparent"
|
android:background="@drawable/bg_trtc_button_secondary"
|
||||||
android:contentDescription="点赞"
|
android:contentDescription="点赞"
|
||||||
android:src="@drawable/ic_like_24"
|
android:src="@drawable/ic_like_24"
|
||||||
android:tint="#FF4081" />
|
android:tint="@color/trtc_accent" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/likeCountText"
|
android:id="@+id/likeCountText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|center_horizontal"
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
android:layout_marginBottom="-2dp"
|
android:layout_marginBottom="-4dp"
|
||||||
android:background="@drawable/bg_purple_20"
|
android:background="@drawable/bg_trtc_button_primary"
|
||||||
android:paddingHorizontal="5dp"
|
android:paddingHorizontal="6dp"
|
||||||
android:paddingVertical="1dp"
|
android:paddingVertical="2dp"
|
||||||
android:text="0"
|
android:text="0"
|
||||||
android:textColor="#FFFFFF"
|
android:textColor="@color/trtc_text_primary"
|
||||||
android:textSize="9sp" />
|
android:textSize="10sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<!-- 礼物按钮 -->
|
<!-- 礼物按钮 - TRTC风格 -->
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/giftButton"
|
android:id="@+id/giftButton"
|
||||||
android:layout_width="44dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="44dp"
|
android:layout_height="48dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:background="@drawable/bg_circle_semi_transparent"
|
android:background="@drawable/bg_trtc_button_secondary"
|
||||||
android:contentDescription="送礼物"
|
android:contentDescription="送礼物"
|
||||||
android:src="@drawable/ic_gift_24"
|
android:src="@drawable/ic_gift_24"
|
||||||
android:tint="#FF9800" />
|
android:tint="@color/trtc_secondary" />
|
||||||
|
|
||||||
<!-- 分享按钮 -->
|
<!-- 分享按钮 - TRTC风格 -->
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/shareButton"
|
android:id="@+id/shareButton"
|
||||||
android:layout_width="44dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="44dp"
|
android:layout_height="48dp"
|
||||||
android:background="@drawable/bg_circle_semi_transparent"
|
android:background="@drawable/bg_trtc_button_secondary"
|
||||||
android:contentDescription="分享"
|
android:contentDescription="分享"
|
||||||
android:src="@drawable/ic_share_24"
|
android:src="@drawable/ic_share_24"
|
||||||
android:tint="@android:color/white" />
|
android:tint="@color/trtc_text_primary" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 底部输入栏 - 悬浮 -->
|
<!-- 底部输入栏 - TRTC风格 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/chatInputLayout"
|
android:id="@+id/chatInputLayout"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
@ -369,7 +372,7 @@
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:paddingVertical="10dp"
|
android:paddingVertical="12dp"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|
@ -378,27 +381,29 @@
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/chatInput"
|
android:id="@+id/chatInput"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="38dp"
|
android:layout_height="42dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@drawable/bg_chat_input_dark"
|
android:background="@drawable/bg_trtc_input"
|
||||||
android:hint="说点什么..."
|
android:hint="说点什么..."
|
||||||
android:textColorHint="#80FFFFFF"
|
android:textColorHint="@color/trtc_text_hint"
|
||||||
android:imeOptions="actionSend"
|
android:imeOptions="actionSend"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:paddingHorizontal="14dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@color/trtc_text_primary"
|
||||||
android:textSize="13sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/sendButton"
|
android:id="@+id/sendButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="38dp"
|
android:layout_height="42dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="10dp"
|
||||||
|
android:minWidth="64dp"
|
||||||
android:text="发送"
|
android:text="发送"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
app:backgroundTint="#FF4081"
|
android:textStyle="bold"
|
||||||
app:cornerRadius="19dp" />
|
app:backgroundTint="@color/trtc_accent"
|
||||||
|
app:cornerRadius="21dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
||||||
29
android-app/app/src/main/res/values/colors_trtc.xml
Normal file
29
android-app/app/src/main/res/values/colors_trtc.xml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- TRTC风格颜色主题 -->
|
||||||
|
<color name="trtc_primary">#FF6B35</color>
|
||||||
|
<color name="trtc_primary_dark">#E55A2B</color>
|
||||||
|
<color name="trtc_secondary">#4ECDC4</color>
|
||||||
|
<color name="trtc_accent">#FF4081</color>
|
||||||
|
<color name="trtc_accent_light">#FF6FA3</color>
|
||||||
|
|
||||||
|
<!-- 背景色 -->
|
||||||
|
<color name="trtc_background">#1A1A1A</color>
|
||||||
|
<color name="trtc_surface">#2D2D2D</color>
|
||||||
|
<color name="trtc_surface_light">#3D3D3D</color>
|
||||||
|
|
||||||
|
<!-- 文字颜色 -->
|
||||||
|
<color name="trtc_text_primary">#FFFFFF</color>
|
||||||
|
<color name="trtc_text_secondary">#CCFFFFFF</color>
|
||||||
|
<color name="trtc_text_hint">#80FFFFFF</color>
|
||||||
|
|
||||||
|
<!-- 半透明背景 -->
|
||||||
|
<color name="trtc_overlay_dark">#80000000</color>
|
||||||
|
<color name="trtc_overlay_light">#40FFFFFF</color>
|
||||||
|
<color name="trtc_overlay_accent">#40FF4081</color>
|
||||||
|
|
||||||
|
<!-- 状态颜色 -->
|
||||||
|
<color name="trtc_live_indicator">#FF4444</color>
|
||||||
|
<color name="trtc_online_indicator">#4CAF50</color>
|
||||||
|
<color name="trtc_offline_indicator">#999999</color>
|
||||||
|
</resources>
|
||||||
Loading…
Reference in New Issue
Block a user