diff --git a/LOCAL_CHANGES.md b/LOCAL_CHANGES.md
index 8ddc20f..b5b75b8 100644
--- a/LOCAL_CHANGES.md
+++ b/LOCAL_CHANGES.md
@@ -26,13 +26,13 @@
* `Positioned` 底部距离从 `20` 调整为 `50`。
* `Positioned` 左右距离从 `20` 调整为 `10`。
-### `lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart`
-* **修改日期**: 2026-01-05
-* **修改目的**: 修复底部"照片"、"文件"图标显示为纯黑色的问题。
+### `lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart` 及相关 SVG
+* **修改日期**: 2026-01-05
+* **修改目的**: 完全使用官方 upstream 版本,避免本地定制导致的兼容性问题。
* **详细改动**:
- * 将本地 `images/photo.svg` 替换为官方 SDK 的 `images/svg/send_image.svg`。
- * 将本地 `images/file.svg` 替换为官方 SDK 的 `images/svg/send_file.svg`。
- * **原因**: 在上游同步时,本地 SVG 文件被覆盖为缺少 `fill` 属性的版本,导致渲染为黑色。
+ * 从 upstream/main 同步了 `tim_uikit_more_panel.dart` 的完整官方代码。
+ * 从 upstream/main 同步了 `images/photo.svg`、`images/screen.svg`、`images/file.svg` 官方资源。
+ * 移除了之前的所有本地修改(包括使用 `images/svg/send_image.svg` 等的尝试)。
### `scripts/sync_from_upstream.sh`
* **修改日期**: 2026-01-05
diff --git a/images/file.svg b/images/file.svg
index ba5f2d1..cc0fb6d 100644
--- a/images/file.svg
+++ b/images/file.svg
@@ -1 +1,14 @@
-
\ No newline at end of file
+
+
diff --git a/images/photo.svg b/images/photo.svg
index 838ca8b..2e8b1b2 100644
--- a/images/photo.svg
+++ b/images/photo.svg
@@ -1 +1,16 @@
-
\ No newline at end of file
+
+
diff --git a/images/screen.svg b/images/screen.svg
index d58b683..60c1170 100644
--- a/images/screen.svg
+++ b/images/screen.svg
@@ -1 +1,12 @@
-
\ No newline at end of file
+
+
diff --git a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart
index 1f00c06..229e35b 100644
--- a/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart
+++ b/lib/ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel.dart
@@ -72,8 +72,7 @@ class MorePanelItem {
final Widget icon;
final Function(BuildContext context)? onTap;
- MorePanelItem(
- {this.onTap, required this.icon, required this.id, required this.title});
+ MorePanelItem({this.onTap, required this.icon, required this.id, required this.title});
}
class MorePanel extends StatefulWidget {
@@ -85,11 +84,7 @@ class MorePanel extends StatefulWidget {
final MorePanelConfig? morePanelConfig;
- const MorePanel(
- {required this.conversationID,
- required this.conversationType,
- Key? key,
- this.morePanelConfig})
+ const MorePanel({required this.conversationID, required this.conversationType, Key? key, this.morePanelConfig})
: super(key: key);
@override
@@ -98,8 +93,7 @@ class MorePanel extends StatefulWidget {
class _MorePanelState extends TIMUIKitState {
final ImagePicker _picker = ImagePicker();
- final TUISelfInfoViewModel _selfInfoViewModel =
- serviceLocator();
+ final TUISelfInfoViewModel _selfInfoViewModel = serviceLocator();
Uint8List? fileContent;
String? fileName;
File? tempFile;
@@ -120,8 +114,7 @@ class _MorePanelState extends TIMUIKitState {
isInstallCallkit = value;
});
});
- _betterPlayerController =
- BetterPlayerController(const BetterPlayerConfiguration());
+ _betterPlayerController = BetterPlayerController(const BetterPlayerConfiguration());
}
}
@@ -144,11 +137,9 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
- "images/svg/send_image.svg",
+ "images/photo.svg",
package: 'tencent_cloud_chat_uikit',
height: 64,
width: 64,
@@ -165,9 +156,7 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
"images/screen.svg",
package: 'tencent_cloud_chat_uikit',
@@ -186,9 +175,7 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: Image.asset(
"images/take_video.png",
package: 'tencent_cloud_chat_uikit',
@@ -212,11 +199,9 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
- "images/svg/send_image.svg",
+ "images/photo.svg",
package: 'tencent_cloud_chat_uikit',
height: 64,
width: 64,
@@ -238,11 +223,8 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
- child:
- Icon(Icons.video_file, color: hexToColor("5c6168"), size: 26),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
+ child: Icon(Icons.video_file, color: hexToColor("5c6168"), size: 26),
)),
MorePanelItem(
id: "file",
@@ -259,11 +241,9 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
- "images/svg/send_file.svg",
+ "images/file.svg",
package: 'tencent_cloud_chat_uikit',
height: 64,
width: 64,
@@ -285,9 +265,7 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
"images/video-call.svg",
package: 'tencent_cloud_chat_uikit',
@@ -311,9 +289,7 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- color: Colors.white,
- borderRadius: BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5))),
child: SvgPicture.asset(
"images/voice-call.svg",
package: 'tencent_cloud_chat_uikit',
@@ -352,11 +328,9 @@ class _MorePanelState extends TIMUIKitState {
}).toList();
}
- _sendVideoMessage(String originFilePath, int duration, int size,
- TUIChatSeparateViewModel model) async {
+ _sendVideoMessage(String originFilePath, int duration, int size, TUIChatSeparateViewModel model) async {
if (size >= MorePanelConfig.VIDEO_MAX_SIZE) {
- onTIMCallback(TIMCallback(
- type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
+ onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
return;
}
@@ -365,9 +339,7 @@ class _MorePanelState extends TIMUIKitState {
final convID = widget.conversationID;
final convType = widget.conversationType;
- String tempPath = (await getTemporaryDirectory()).path +
- p.basename(originFilePath) +
- ".jpeg";
+ String tempPath = (await getTemporaryDirectory()).path + p.basename(originFilePath) + ".jpeg";
await plugin.getVideoThumbnail(
srcFile: originFilePath,
@@ -379,11 +351,7 @@ class _MorePanelState extends TIMUIKitState {
);
MessageUtils.handleMessageError(
model.sendVideoMessage(
- videoPath: originFilePath,
- duration: duration,
- snapshotPath: tempPath,
- convID: convID,
- convType: convType),
+ videoPath: originFilePath, duration: duration, snapshotPath: tempPath, convID: convID, convType: convType),
context);
}
@@ -443,47 +411,34 @@ class _MorePanelState extends TIMUIKitState {
if (filePath != null) {
if (type == AssetType.image) {
if (size >= MorePanelConfig.IMAGE_MAX_SIZE) {
- onTIMCallback(TIMCallback(
- type: TIMCallbackType.INFO,
- infoRecommendText: TIM_t("文件大小超出了限制")));
+ onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
return;
}
MessageUtils.handleMessageError(
- model.sendImageMessage(
- imagePath: filePath,
- convID: convID,
- convType: convType),
- context);
+ model.sendImageMessage(imagePath: filePath, convID: convID, convType: convType), context);
}
if (type == AssetType.video) {
- _sendVideoMessage(originFile!.path,
- asset.videoDuration.inSeconds, size, model);
+ _sendVideoMessage(originFile!.path, asset.videoDuration.inSeconds, size, model);
}
}
}
}
} else {
- FilePickerResult? result =
- await FilePicker.platform.pickFiles(type: FileType.media);
+ FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.media);
if (result != null && result.files.isNotEmpty) {
File file = File(result.files.single.path!);
final String savePath = file.path;
- final String type = TencentUtils.getFileType(
- savePath.split(".")[savePath.split(".").length - 1])
- .split("/")[0];
+ final String type =
+ TencentUtils.getFileType(savePath.split(".")[savePath.split(".").length - 1]).split("/")[0];
if (type == "image") {
MessageUtils.handleMessageError(
- model.sendImageMessage(
- imagePath: savePath, convID: convID, convType: convType),
- context);
+ model.sendImageMessage(imagePath: savePath, convID: convID, convType: convType), context);
} else if (type == "video") {
MessageUtils.handleMessageError(
- model.sendVideoMessage(
- videoPath: savePath, convID: convID, convType: convType),
- context);
+ model.sendVideoMessage(videoPath: savePath, convID: convID, convType: convType), context);
}
} else {
throw TypeError();
@@ -494,8 +449,7 @@ class _MorePanelState extends TIMUIKitState {
}
}
- _sendImageFromCamera(TUIChatSeparateViewModel model, TUITheme theme,
- {required isVideo}) async {
+ _sendImageFromCamera(TUIChatSeparateViewModel model, TUITheme theme, {required isVideo}) async {
try {
if (!await Permissions.checkPermission(
context,
@@ -522,25 +476,18 @@ class _MorePanelState extends TIMUIKitState {
final size = await originFile!.length();
if (!isVideo) {
if (size >= MorePanelConfig.IMAGE_MAX_SIZE) {
- onTIMCallback(TIMCallback(
- type: TIMCallbackType.INFO,
- infoRecommendText: TIM_t("文件大小超出了限制")));
+ onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
return;
}
MessageUtils.handleMessageError(
- model.sendImageMessage(
- imagePath: originFile.path, convID: convID, convType: convType),
- context);
+ model.sendImageMessage(imagePath: originFile.path, convID: convID, convType: convType), context);
} else {
// 监听视频准备完成事件
_betterPlayerController.addEventsListener((event) {
- if (event.betterPlayerEventType ==
- BetterPlayerEventType.initialized) {
+ if (event.betterPlayerEventType == BetterPlayerEventType.initialized) {
// 获取视频时长(单位:秒)
- int durationInSeconds = _betterPlayerController
- .videoPlayerController?.value.duration?.inSeconds ??
- 0;
+ int durationInSeconds = _betterPlayerController.videoPlayerController?.value.duration?.inSeconds ?? 0;
_sendVideoMessage(originFile!.path, durationInSeconds, size, model);
}
});
@@ -567,17 +514,12 @@ class _MorePanelState extends TIMUIKitState {
fileContent = imageContent;
html.Node? inputElem;
- inputElem = html.document
- .getElementById("__image_picker_web-file-input")
- ?.querySelector("input");
+ inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input");
final convID = widget.conversationID;
final convType = widget.conversationType;
MessageUtils.handleMessageError(
model.sendImageMessage(
- inputElement: inputElem,
- imagePath: tempFile?.path,
- convID: convID,
- convType: convType),
+ inputElement: inputElem, imagePath: tempFile?.path, convID: convID, convType: convType),
context);
} catch (e) {
outputLogger.i("_sendFileErr: ${e.toString()}");
@@ -593,25 +535,18 @@ class _MorePanelState extends TIMUIKitState {
fileContent = videoContent;
if (fileName!.split(".")[fileName!.split(".").length - 1] != "mp4") {
- onTIMCallback(TIMCallback(
- type: TIMCallbackType.INFO,
- infoRecommendText: TIM_t("视频消息仅限 mp4 格式"),
- infoCode: 6660412));
+ onTIMCallback(
+ TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("视频消息仅限 mp4 格式"), infoCode: 6660412));
return;
}
html.Node? inputElem;
- inputElem = html.document
- .getElementById("__image_picker_web-file-input")
- ?.querySelector("input");
+ inputElem = html.document.getElementById("__image_picker_web-file-input")?.querySelector("input");
final convID = widget.conversationID;
final convType = widget.conversationType;
MessageUtils.handleMessageError(
model.sendVideoMessage(
- inputElement: inputElem,
- videoPath: tempFile?.path,
- convID: convID,
- convType: convType),
+ inputElement: inputElem, videoPath: tempFile?.path, convID: convID, convType: convType),
context);
} catch (e) {
outputLogger.i("_sendFileErr: ${e.toString()}");
@@ -629,43 +564,29 @@ class _MorePanelState extends TIMUIKitState {
if (result != null && result.files.isNotEmpty) {
if (PlatformUtils().isWeb) {
html.Node? inputElem;
- inputElem = html.document
- .getElementById("__file_picker_web-file-input")
- ?.querySelector("input");
+ inputElem = html.document.getElementById("__file_picker_web-file-input")?.querySelector("input");
fileName = result.files.single.name;
MessageUtils.handleMessageError(
- model.sendFileMessage(
- inputElement: inputElem,
- fileName: fileName,
- convID: convID,
- convType: convType),
+ model.sendFileMessage(inputElement: inputElem, fileName: fileName, convID: convID, convType: convType),
context);
return;
}
String? option2 = result.files.single.path ?? "";
- outputLogger
- .i(TIM_t_para("选择成功{{option2}}", "选择成功$option2")(option2: option2));
+ outputLogger.i(TIM_t_para("选择成功{{option2}}", "选择成功$option2")(option2: option2));
File file = File(result.files.single.path!);
final int size = file.lengthSync();
if (size >= MorePanelConfig.FILE_MAX_SIZE) {
- onTIMCallback(TIMCallback(
- type: TIMCallbackType.INFO,
- infoRecommendText: TIM_t("文件大小超出了限制")));
+ onTIMCallback(TIMCallback(type: TIMCallbackType.INFO, infoRecommendText: TIM_t("文件大小超出了限制")));
return;
}
final String savePath = file.path;
MessageUtils.handleMessageError(
- model.sendFileMessage(
- filePath: savePath,
- size: size,
- convID: convID,
- convType: convType),
- context);
+ model.sendFileMessage(filePath: savePath, size: size, convID: convID, convType: convType), context);
} else {
throw TypeError();
}
@@ -715,16 +636,13 @@ class _MorePanelState extends TIMUIKitState {
bool hasCameraPermission = false;
bool hasMicrophonePermission = false;
if (type == TYPE_VIDEO) {
- hasCameraPermission =
- await Permissions.checkPermission(context, Permission.camera.value);
- hasMicrophonePermission = await Permissions.checkPermission(
- context, Permission.microphone.value);
+ hasCameraPermission = await Permissions.checkPermission(context, Permission.camera.value);
+ hasMicrophonePermission = await Permissions.checkPermission(context, Permission.microphone.value);
if (!hasCameraPermission || !hasMicrophonePermission) {
return;
}
} else {
- hasMicrophonePermission = await Permissions.checkPermission(
- context, Permission.microphone.value);
+ hasMicrophonePermission = await Permissions.checkPermission(context, Permission.microphone.value);
if (!hasMicrophonePermission) {
return;
}
@@ -746,9 +664,7 @@ class _MorePanelState extends TIMUIKitState {
_tUICore.callService(TUICALLKIT_SERVICE_NAME, METHOD_NAME_CALL, {
PARAM_NAME_TYPE: type,
PARAM_NAME_USERIDS: inviteMember,
- PARAM_NAME_GROUPID: widget.conversationType == ConvType.group
- ? widget.conversationID
- : ""
+ PARAM_NAME_GROUPID: widget.conversationType == ConvType.group ? widget.conversationID : ""
});
}
} else {
@@ -769,8 +685,7 @@ class _MorePanelState extends TIMUIKitState {
@override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUITheme theme = value.theme;
- final TUIChatSeparateViewModel model =
- Provider.of(context);
+ final TUIChatSeparateViewModel model = Provider.of(context);
final screenWidth = MediaQuery.of(context).size.width;
return Container(
height: 248,
@@ -807,15 +722,12 @@ class _MorePanelState extends TIMUIKitState {
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
- decoration: const BoxDecoration(
- borderRadius:
- BorderRadius.all(Radius.circular(5))),
+ decoration: const BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5))),
child: item.icon,
),
Text(
item.title,
- style: TextStyle(
- fontSize: 12, color: theme.darkTextColor),
+ style: TextStyle(fontSize: 12, color: theme.darkTextColor),
)
],
),