This commit is contained in:
2025-06-30 16:24:20 +08:00
commit 68de5eb048
454 changed files with 56921 additions and 0 deletions
@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
class TIMUIKitSearchFolder extends TIMUIKitStatelessWidget {
final String folderName;
final List<Widget> children;
TIMUIKitSearchFolder(
{Key? key, required this.folderName, required this.children})
: super(key: key);
@override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUITheme theme = value.theme;
return Container(
margin: const EdgeInsets.only(bottom: 16),
padding: const EdgeInsets.fromLTRB(16, 0, 16, 0),
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
color: Colors.white,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: hexToColor("DBDBDB"), width: 0.5))),
padding: const EdgeInsets.fromLTRB(0, 6, 0, 6),
child: Text(
folderName,
style: TextStyle(
color: theme.weakTextColor, height: 1.5, fontSize: 14),
),
),
...children
],
),
);
}
}
@@ -0,0 +1,112 @@
import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
enum SearchType { contact, group, history }
class TIMUIKitSearchIndicator extends TIMUIKitStatelessWidget {
final List<SearchType> typeList;
final ValueChanged<List<SearchType>> onChange;
TIMUIKitSearchIndicator(
{required this.typeList, required this.onChange, Key? key})
: super(key: key);
final titleMap = {
SearchType.contact: "联系人",
SearchType.group: "群聊",
SearchType.history: "聊天记录"
};
Widget renderItemBox(
IconData icon, SearchType item, bool isSelect, TUITheme theme) {
return InkWell(
onTap: () {
if (isSelect) {
typeList.remove(item);
} else {
typeList.add(item);
}
onChange(typeList);
},
child: Container(
padding: const EdgeInsets.all(6),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
children: [
Padding(
padding: const EdgeInsets.all(6),
child: Icon(
icon,
color: theme.weakTextColor,
size: 30,
),
),
if (isSelect)
Positioned(
right: 0,
bottom: 0,
child: Container(
height: 16,
width: 16,
decoration: BoxDecoration(shape: BoxShape.circle, color: theme.primaryColor),
child: const Icon(
Icons.check,
size: 8,
color: Colors.white,
),
))
],
),
const SizedBox(height: 4),
Text(
TIM_t(titleMap[item]!),
style: TextStyle(color: theme.textColor, fontSize: 13),
)
],
),
),
);
}
@override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final theme = value.theme;
return Container(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Text(TIM_t("搜索指定内容"),
style: TextStyle(color: theme.weakTextColor, fontSize: 12)),
)
],
),
const SizedBox(height: 1),
Divider(thickness: 0.8, color: theme.weakDividerColor),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
renderItemBox(Icons.person, SearchType.contact,
typeList.contains(SearchType.contact), theme),
renderItemBox(Icons.people, SearchType.group,
typeList.contains(SearchType.group), theme),
renderItemBox(Icons.message, SearchType.history,
typeList.contains(SearchType.history), theme),
],
)
],
),
);
}
}
@@ -0,0 +1,150 @@
import 'package:flutter/material.dart';
import 'package:tencent_chat_i18n_tool/tencent_chat_i18n_tool.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_state.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitSearchInput extends StatefulWidget {
final ValueChanged<String> onChange;
final String? initValue;
final TextEditingController? controller;
final Widget? prefixIcon;
final Widget? prefixText;
final bool? isAutoFocus;
final FocusNode focusNode;
const TIMUIKitSearchInput({
required this.onChange,
this.initValue,
this.controller,
Key? key,
this.prefixIcon,
this.isAutoFocus = true,
this.prefixText,
required this.focusNode,
}) : super(key: key);
@override
State<StatefulWidget> createState() => TIMUIKitSearchInputState();
}
class TIMUIKitSearchInputState extends TIMUIKitState<TIMUIKitSearchInput> {
late TextEditingController textEditingController =
widget.controller ?? TextEditingController();
bool isEmptyInput = true;
@override
void initState() {
super.initState();
textEditingController.text = widget.initValue ?? "";
isEmptyInput = textEditingController.text.isEmpty;
}
hideAllPanel() {
widget.focusNode.unfocus();
}
@override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUITheme theme = value.theme;
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
return Container(
// height: 64,
padding: EdgeInsets.fromLTRB(16, isDesktopScreen ? 16 : 8, 16, 16),
margin: isDesktopScreen ? const EdgeInsets.only(bottom: 2) : null,
decoration: BoxDecoration(
color: isDesktopScreen
? theme.wideBackgroundColor
: theme.primaryColor,
boxShadow: [
BoxShadow(
color: theme.weakBackgroundColor ?? hexToColor("E6E9EB"),
offset: const Offset(0.0, 2.0),
)
]
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: ConstrainedBox(
constraints: BoxConstraints(maxHeight: isDesktopScreen ? 30 : 36),
child: TextField(
autofocus: widget.isAutoFocus ?? true,
onChanged: (value) async {
final trimValue = value.trim();
final isEmpty = trimValue.isEmpty;
if(isEmpty != isEmptyInput){
setState(() {
isEmptyInput = isEmpty ? true : false;
});
}
widget.onChange(trimValue);
},
keyboardType: TextInputType.text,
textInputAction: TextInputAction.search,
maxLines: 4,
minLines: 1,
focusNode: widget.focusNode,
controller: textEditingController,
textAlignVertical: TextAlignVertical.center,
textAlign: TextAlign.start,
style: isDesktopScreen ? const TextStyle(
fontSize: 12
) : null,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(0),
border: const OutlineInputBorder(borderSide: BorderSide.none),
hintStyle: TextStyle(
fontSize: isDesktopScreen ? 12 : 14,
color: hexToColor("CCCCCC"),
),
fillColor: isDesktopScreen ? hexToColor("f3f3f4") : Colors.white,
filled: true,
isDense: true,
hintText: TIM_t("搜索"),
prefix: widget.prefixText != null
? Container(
margin: const EdgeInsets.only(right: 8),
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth:
MediaQuery.of(context).size.width * 0.2),
child: widget.prefixText,
),
)
: null,
prefixIcon: widget.prefixIcon,
suffixIcon: isEmptyInput
? null
: IconButton(
onPressed: () {
textEditingController.clear();
setState(() {
isEmptyInput = true;
});
widget.onChange("");
},
icon: Icon(Icons.cancel, color: hexToColor("979797")),
),
),
),
)),
if(!isDesktopScreen) Container(
margin: const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Text(TIM_t("取消"),
style: const TextStyle(
color: Colors.white,
)),
))
],
),
);
}
}
@@ -0,0 +1,120 @@
import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/ui/views/TIMUIKitSearch/tim_uikit_search_item_wide.dart';
import 'package:tencent_cloud_chat_uikit/ui/widgets/avatar.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
import 'package:tencent_cloud_chat_uikit/theme/tui_theme.dart';
class TIMUIKitSearchItem extends TIMUIKitStatelessWidget {
final String faceUrl;
final String showName;
final String lineOne;
final String? lineOneRight;
final String? lineTwo;
final VoidCallback? onClick;
TIMUIKitSearchItem(
{Key? key,
required this.faceUrl,
required this.showName,
required this.lineOne,
this.lineTwo,
this.lineOneRight,
this.onClick})
: super(key: key);
_renderLineOneRight(String? text, TUITheme theme) {
if (text != null) {
return Text(text,
style: TextStyle(
fontSize: 12,
color: theme.weakTextColor,
));
} else {
return Container();
}
}
_renderLineTwo(String? text, TUITheme theme) {
return (text != null)
? Text(
text,
style: TextStyle(
color: theme.weakTextColor, height: 1.5, fontSize: 14),
)
: Container(
height: 0,
);
}
@override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final TUITheme theme = value.theme;
return TUIKitScreenUtils.getDeviceWidget(
context: context,
defaultWidget: GestureDetector(
onTap: onClick,
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: hexToColor("DBDBDB"), width: 0.5))),
padding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 40,
height: 40,
child: Stack(
fit: StackFit.expand,
clipBehavior: Clip.none,
children: [Avatar(faceUrl: faceUrl, showName: showName)],
),
),
Expanded(
child: Container(
margin: const EdgeInsets.only(left: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
// height: 24,
padding: const EdgeInsets.symmetric(vertical: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
lineOne,
style: TextStyle(
color: theme.darkTextColor,
fontSize: 18.0,
fontWeight: FontWeight.w400),
),
_renderLineOneRight(lineOneRight, theme),
],
),
),
_renderLineTwo(lineTwo, theme),
],
),
))
],
),
),
),
desktopWidget: TIMUIKitSearchWideItem(
lineOneRight: lineOneRight,
key: key,
lineTwo: lineTwo,
onClick: onClick,
faceUrl: faceUrl,
showName: showName,
lineOne: lineOne),
);
}
}
@@ -0,0 +1,69 @@
// ignore_for_file: file_names
import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_statelesswidget.dart';
import 'package:tencent_cloud_chat_uikit/base_widgets/tim_ui_kit_base.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';
import 'package:tencent_cloud_chat_uikit/theme/color.dart';
class TIMUIKitSearchShowALl extends TIMUIKitStatelessWidget {
final String textShow;
final VoidCallback? onClick;
final bool isNeedMoreBottom;
TIMUIKitSearchShowALl(
{Key? key,
this.onClick,
required this.textShow,
this.isNeedMoreBottom = false})
: super(key: key);
@override
Widget tuiBuild(BuildContext context, TUIKitBuildValue value) {
final isDesktopScreen = TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
return InkWell(
onTap: onClick,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(color: hexToColor("DBDBDB"), width: 0.5))),
padding: EdgeInsets.fromLTRB(0, 8, 0, (isNeedMoreBottom ? 24 : 8)),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.search,
color: hexToColor("979797"),
),
Expanded(
child: Container(
margin: const EdgeInsets.only(left: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
// height: 24,
padding: const EdgeInsets.symmetric(vertical: 2),
child: Text(
textShow,
style: TextStyle(
color: Colors.black,
fontSize: isDesktopScreen ? 14 : 16.0,
fontWeight: FontWeight.w400),
),
),
],
),
)),
Icon(
Icons.expand_more,
color: hexToColor("979797"),
),
],
),
),
);
}
}