pikapika/lib/screens/components/UserProfileCard.dart

211 lines
6.3 KiB
Dart
Raw Normal View History

2022-02-25 05:50:43 +00:00
import 'dart:convert';
import 'dart:io';
2021-09-29 23:57:09 +00:00
import 'dart:ui';
import 'package:flutter/material.dart';
2022-02-25 05:50:43 +00:00
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
2021-11-11 03:00:38 +00:00
import 'package:pikapika/basic/Common.dart';
import 'package:pikapika/basic/Entities.dart';
2022-02-24 16:08:18 +00:00
import 'package:pikapika/basic/Method.dart';
2021-11-11 03:00:38 +00:00
import 'package:pikapika/screens/components/Avatar.dart';
import 'package:pikapika/screens/components/Images.dart';
2022-02-24 16:08:18 +00:00
import 'package:pikapika/screens/components/ItemBuilder.dart';
const double _cardHeight = 180;
2021-09-29 23:57:09 +00:00
// 用户信息卡
class UserProfileCard extends StatefulWidget {
2022-03-17 03:31:25 +00:00
const UserProfileCard({Key? key}) : super(key: key);
2021-09-29 23:57:09 +00:00
@override
State<StatefulWidget> createState() => _UserProfileCardState();
}
class _UserProfileCardState extends State<UserProfileCard> {
late Future<UserProfile> _future = _load();
Future<UserProfile> _load() async {
var profile = await method.userProfile();
if (!profile.isPunched) {
await method.punchIn();
profile.isPunched = true;
defaultToast(context, "自动打卡");
}
return profile;
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
2022-03-17 03:31:25 +00:00
var nameStyle = const TextStyle(
2022-02-24 16:08:18 +00:00
fontSize: 14,
fontWeight: FontWeight.bold,
);
2022-03-17 03:31:25 +00:00
var nameStrutStyle = const StrutStyle(
2022-02-24 16:08:18 +00:00
fontSize: 14,
forceStrutHeight: true,
fontWeight: FontWeight.bold,
);
2021-09-29 23:57:09 +00:00
var levelStyle = TextStyle(
2022-02-24 16:08:18 +00:00
fontSize: 12,
color: theme.colorScheme.secondary.withOpacity(.9),
fontWeight: FontWeight.bold,
);
2022-03-17 03:31:25 +00:00
var levelStrutStyle = const StrutStyle(
2022-02-24 16:08:18 +00:00
fontSize: 12,
forceStrutHeight: true,
fontWeight: FontWeight.bold,
);
var sloganStyle = TextStyle(
fontSize: 10,
color: theme.textTheme.bodyText1?.color?.withOpacity(.5),
);
2022-03-17 03:31:25 +00:00
var sloganStrutStyle = const StrutStyle(
2022-02-24 16:08:18 +00:00
fontSize: 10,
forceStrutHeight: true,
);
2021-09-29 23:57:09 +00:00
return ItemBuilder(
future: _future,
onRefresh: () async {
setState(() => _future = method.userProfile());
},
2022-02-24 16:08:18 +00:00
height: _cardHeight,
2021-09-29 23:57:09 +00:00
successBuilder:
(BuildContext context, AsyncSnapshot<UserProfile> snapshot) {
UserProfile profile = snapshot.data!;
return Stack(
children: [
2022-03-17 03:31:25 +00:00
Stack(
children: [
Opacity(
opacity: .25, //
child: LayoutBuilder(
builder:
(BuildContext context, BoxConstraints constraints) {
return RemoteImage(
path: profile.avatar.path,
fileServer: profile.avatar.fileServer,
width: constraints.maxWidth,
height: _cardHeight,
);
},
2021-09-29 23:57:09 +00:00
),
2022-03-17 03:31:25 +00:00
),
Positioned.fromRect(
rect: Rect.largest,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 30, sigmaY: 30),
child: Container(),
2021-09-29 23:57:09 +00:00
),
2022-03-17 03:31:25 +00:00
),
],
2021-09-29 23:57:09 +00:00
),
2022-03-17 03:31:25 +00:00
SizedBox(
2022-02-24 16:08:18 +00:00
height: _cardHeight,
2021-09-29 23:57:09 +00:00
child: Column(
children: [
Expanded(child: Container()),
2022-02-25 05:50:43 +00:00
GestureDetector(
onTap: () async {
if (Platform.isAndroid || Platform.isIOS) {
await _updateAvatarPhone();
}
},
child: Avatar(profile.avatar, size: 65),
),
2022-02-24 16:08:18 +00:00
Container(height: 5),
2021-09-29 23:57:09 +00:00
Text(
profile.name,
style: nameStyle,
2022-02-24 16:08:18 +00:00
strutStyle: nameStrutStyle,
2021-09-29 23:57:09 +00:00
),
Text(
2022-02-27 23:20:58 +00:00
"(Lv. ${profile.level}) (${profile.title})",
2021-09-29 23:57:09 +00:00
style: levelStyle,
2022-02-24 16:08:18 +00:00
strutStyle: levelStrutStyle,
),
Container(height: 8),
GestureDetector(
onTap: () async {
var input = await inputString(
context,
"更新签名",
defaultValue: profile.slogan ?? "",
);
if (input != null) {
await method.updateSlogan(input);
2022-02-25 05:50:43 +00:00
_reload();
2022-02-24 16:08:18 +00:00
}
},
child: Text(
profile.slogan == null || profile.slogan!.isEmpty
? "这个人很懒, 什么也没留下"
: profile.slogan!,
style: sloganStyle,
strutStyle: sloganStrutStyle,
),
2021-09-29 23:57:09 +00:00
),
Expanded(child: Container()),
],
),
)
],
);
},
);
}
2022-02-25 05:50:43 +00:00
Future _updateAvatarPhone() async {
final ImagePicker _picker = ImagePicker();
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
if (image != null) {
final theme = Theme.of(context);
final cropper = ImageCropper();
File? croppedFile = await cropper.cropImage(
sourcePath: image.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
],
2022-03-17 03:31:25 +00:00
aspectRatio: const CropAspectRatio(ratioX: 200, ratioY: 200),
2022-02-25 05:50:43 +00:00
maxWidth: 200,
maxHeight: 200,
androidUiSettings: AndroidUiSettings(
toolbarTitle: "修改头像",
toolbarColor: theme.appBarTheme.backgroundColor,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: true,
),
2022-03-17 03:31:25 +00:00
iosUiSettings: const IOSUiSettings(
2022-02-25 05:50:43 +00:00
resetAspectRatioEnabled: true,
aspectRatioLockEnabled: true,
title: "修改头像",
),
);
if (croppedFile != null) {
var buff = await croppedFile.readAsBytes();
var data = base64Encode(buff);
await method.updateAvatar(data);
_reload();
}
}
}
void _reload() {
setState(() {
_future = _load();
});
}
2021-09-29 23:57:09 +00:00
}