Files
plan_flutter/lib/page/my/widget/avatar_name.dart
2025-09-09 14:07:38 +08:00

179 lines
5.9 KiB
Dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:plan/api/dto/login_dto.dart';
import 'package:plan/api/endpoints/user_api.dart';
import 'package:plan/providers/app_store.dart';
import 'package:plan/utils/common.dart';
import 'package:provider/provider.dart';
import 'package:remixicon/remixicon.dart';
import 'package:file_picker/file_picker.dart';
class AvatarName extends StatefulWidget {
final Function(UserInfo) onUpdate;
const AvatarName({super.key, required this.onUpdate});
@override
State<AvatarName> createState() => _AvatarNameState();
}
class _AvatarNameState extends State<AvatarName> {
//输入口
final TextEditingController _inputController = TextEditingController();
final FocusNode _focusNode = FocusNode();
bool _isEdit = false;
///开始编辑
void _handleEdit() {
setState(() {
_isEdit = true;
});
AppStore appStore = context.read<AppStore>();
WidgetsBinding.instance.addPostFrameCallback((_) {
_inputController.text = appStore.userInfo?.name ?? "";
_focusNode.requestFocus();
});
}
///确定编辑名字
void _confirmEdit(String value) async {
setState(() {
_isEdit = false;
});
widget.onUpdate(UserInfo(name: value));
await updateUserInfoApi(name: value);
}
///选择图片
void _handPickImage() async {
var result = await FilePicker.platform.pickFiles(
type: FileType.image,
allowMultiple: false,
);
if (result != null) {
//压缩文件
final compress = await FlutterImageCompress.compressWithFile(
result.files[0].path!,
minWidth: 500,
minHeight: 500,
quality: 85,
rotate: 0,
);
var res = await updateUserInfoApi(avatar: compress);
widget.onUpdate(res);
}
}
@override
Widget build(BuildContext context) {
return Consumer<AppStore>(
builder: (context, store, __) {
return Row(
spacing: 15,
children: [
InkWell(
onTap: _handPickImage,
child: Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: Color(0xffcae2fd),
border: Border.all(
color: Color(0xff797e80),
width: 2,
),
borderRadius: BorderRadius.circular(5),
),
alignment: Alignment.center,
child: Visibility(
visible: getNotEmpty(store.userInfo?.avatar) == null,
replacement: CachedNetworkImage(
width: double.infinity,
height: double.infinity,
fit: BoxFit.cover,
imageUrl: store.userInfo?.avatar ?? "",
errorWidget: (context, url, error) => Icon(Icons.error),
placeholder: (context, url) => Container(
width: 30,
height: 30,
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
),
child: Container(
width: 50,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color(0xff8e8d93),
borderRadius: BorderRadius.circular(5),
),
child: Icon(
RemixIcons.user_fill,
color: Color(0xffcae2fd),
),
),
),
),
),
Expanded(
child: Visibility(
visible: _isEdit,
replacement: InkWell(
onTap: _handleEdit,
child: Row(
spacing: 10,
children: [
Visibility(
visible: getNotEmpty(store.userInfo?.name) == null,
replacement: Text(
store.userInfo?.name ?? "",
style: Theme.of(context).textTheme.titleSmall,
),
child: Text(
"What should we call you?",
style: Theme.of(context).textTheme.labelMedium,
),
),
Icon(
RemixIcons.pencil_fill,
size: 18,
color: Theme.of(context).textTheme.labelMedium?.color,
),
],
),
),
child: TextField(
focusNode: _focusNode,
controller: _inputController,
style: TextStyle(fontSize: 14),
maxLength: 20,
decoration: InputDecoration(
hintText: "Enter your name",
isCollapsed: true,
contentPadding: EdgeInsets.symmetric(vertical: 8, horizontal: 10),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color: Theme.of(context).colorScheme.surfaceContainerHigh,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color: Theme.of(context).colorScheme.surfaceContainerHigh,
),
),
),
onSubmitted: _confirmEdit,
),
),
),
],
);
},
);
}
}