feat: v1.1.1 batch2 - profile page, messages, friends screen
This commit is contained in:
parent
c20335bd7b
commit
6ff5757110
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||||
import 'publish_screen.dart';
|
import 'publish_screen.dart';
|
||||||
import 'activity_detail_screen.dart';
|
import 'activity_detail_screen.dart';
|
||||||
|
import 'friends_screen.dart';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
class ActivityListScreen extends StatefulWidget {
|
class ActivityListScreen extends StatefulWidget {
|
||||||
@ -73,6 +74,13 @@ class _ActivityListScreenState extends State<ActivityListScreen> {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (index == 1) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => const FriendsScreen()),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_selectedIndex = index;
|
_selectedIndex = index;
|
||||||
});
|
});
|
||||||
|
|||||||
118
lib/screens/friends_screen.dart
Normal file
118
lib/screens/friends_screen.dart
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FriendsScreen extends StatefulWidget {
|
||||||
|
const FriendsScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FriendsScreen> createState() => _FriendsScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FriendsScreenState extends State<FriendsScreen> {
|
||||||
|
final List<Map<String, dynamic>> _followingUsers = [
|
||||||
|
{'name': '林阿姨', 'avatar': 3, 'isFollowing': true},
|
||||||
|
{'name': '黄叔叔', 'avatar': 7, 'isFollowing': true},
|
||||||
|
{'name': '周老师', 'avatar': 12, 'isFollowing': true},
|
||||||
|
{'name': '何姐', 'avatar': 18, 'isFollowing': true},
|
||||||
|
{'name': '苏大哥', 'avatar': 24, 'isFollowing': false},
|
||||||
|
{'name': '陶阿姨', 'avatar': 31, 'isFollowing': true},
|
||||||
|
];
|
||||||
|
|
||||||
|
final List<Map<String, dynamic>> _fansUsers = [
|
||||||
|
{'name': '白阿姨', 'avatar': 5, 'isFollowing': false},
|
||||||
|
{'name': '邓叔', 'avatar': 14, 'isFollowing': true},
|
||||||
|
{'name': '贺老师', 'avatar': 19, 'isFollowing': false},
|
||||||
|
{'name': '任姐', 'avatar': 26, 'isFollowing': true},
|
||||||
|
{'name': '罗阿姨', 'avatar': 38, 'isFollowing': false},
|
||||||
|
{'name': '章叔叔', 'avatar': 46, 'isFollowing': true},
|
||||||
|
];
|
||||||
|
|
||||||
|
void _toggleFollow(List<Map<String, dynamic>> users, int index) {
|
||||||
|
setState(() {
|
||||||
|
users[index]['isFollowing'] = !(users[index]['isFollowing'] as bool);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DefaultTabController(
|
||||||
|
length: 2,
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFFFF8F0),
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('好友'),
|
||||||
|
bottom: const TabBar(
|
||||||
|
labelColor: Color(0xFFFF8A3D),
|
||||||
|
unselectedLabelColor: Color(0xFF999999),
|
||||||
|
indicatorColor: Color(0xFFFF8A3D),
|
||||||
|
tabs: [
|
||||||
|
Tab(text: '关注'),
|
||||||
|
Tab(text: '粉丝'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: TabBarView(
|
||||||
|
children: [
|
||||||
|
_buildUserList(_followingUsers),
|
||||||
|
_buildUserList(_fansUsers),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildUserList(List<Map<String, dynamic>> users) {
|
||||||
|
return ListView.separated(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
itemCount: users.length,
|
||||||
|
separatorBuilder: (_, __) => const SizedBox(height: 10),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final user = users[index];
|
||||||
|
final isFollowing = user['isFollowing'] as bool;
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(14),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 22,
|
||||||
|
backgroundColor: const Color(0xFFFFE7CF),
|
||||||
|
backgroundImage: NetworkImage('https://i.pravatar.cc/50?img=${user['avatar']}'),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
user['name'] as String,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF333333),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 34,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () => _toggleFollow(users, index),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
backgroundColor: isFollowing ? Colors.white : const Color(0xFFFF8A3D),
|
||||||
|
foregroundColor: isFollowing ? const Color(0xFFFF8A3D) : Colors.white,
|
||||||
|
side: const BorderSide(color: Color(0xFFFF8A3D)),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 14),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(18)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
isFollowing ? '已关注' : '关注',
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 13),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,32 +3,111 @@ import 'package:flutter/material.dart';
|
|||||||
class MessagesScreen extends StatelessWidget {
|
class MessagesScreen extends StatelessWidget {
|
||||||
const MessagesScreen({super.key});
|
const MessagesScreen({super.key});
|
||||||
|
|
||||||
|
static final List<Map<String, dynamic>> _mockMessages = [
|
||||||
|
{'name': '王阿姨', 'preview': '今天的太极活动您要来吗?', 'time': '09:40', 'avatar': 8, 'unread': 2},
|
||||||
|
{'name': '李老师', 'preview': '书法课作业我已经发群里啦。', 'time': '昨天', 'avatar': 15, 'unread': 0},
|
||||||
|
{'name': '陈叔', 'preview': '周末一起去人民公园拍照吧。', 'time': '昨天', 'avatar': 21, 'unread': 1},
|
||||||
|
{'name': '健康服务助手', 'preview': '您的问诊报告已更新,请及时查看。', 'time': '周日', 'avatar': 29, 'unread': 0},
|
||||||
|
{'name': '张姐', 'preview': '广场舞队今晚7点老地方集合。', 'time': '周六', 'avatar': 35, 'unread': 5},
|
||||||
|
{'name': '社区活动中心', 'preview': '您报名的茶话会还有2个名额。', 'time': '02/12', 'avatar': 42, 'unread': 0},
|
||||||
|
{'name': '赵大哥', 'preview': '下棋那局改天再战,哈哈。', 'time': '02/09', 'avatar': 47, 'unread': 0},
|
||||||
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
backgroundColor: const Color(0xFFFFF8F0),
|
||||||
appBar: AppBar(title: const Text('消息')),
|
appBar: AppBar(title: const Text('消息')),
|
||||||
body: ListView(
|
body: ListView.separated(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
children: [
|
itemCount: _mockMessages.length,
|
||||||
_notificationTile(Icons.event, '活动提醒', '您报名的「太极晨练」明天7:00开始', '10分钟前', const Color(0xFF1976D2)),
|
separatorBuilder: (_, __) => const SizedBox(height: 10),
|
||||||
_notificationTile(Icons.check_circle, '报名成功', '您已成功报名「周末茶话会」', '1小时前', const Color(0xFF4CAF50)),
|
itemBuilder: (context, index) => _buildMessageTile(_mockMessages[index]),
|
||||||
_notificationTile(Icons.payment, '支付通知', '挂号费¥50已支付成功', '昨天', const Color(0xFFFF9800)),
|
|
||||||
_notificationTile(Icons.chat, '问诊回复', '王医生已回复您的问诊', '昨天', const Color(0xFF9C27B0)),
|
|
||||||
_notificationTile(Icons.campaign, '系统通知', '欢迎使用伴享!完善资料赢取积分', '2天前', const Color(0xFF607D8B)),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _notificationTile(IconData icon, String title, String content, String time, Color color) {
|
Widget _buildMessageTile(Map<String, dynamic> message) {
|
||||||
return Card(
|
final unread = message['unread'] as int;
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
return InkWell(
|
||||||
child: ListTile(
|
borderRadius: BorderRadius.circular(14),
|
||||||
leading: CircleAvatar(backgroundColor: color.withOpacity(0.1), child: Icon(icon, color: color)),
|
onTap: () {
|
||||||
title: Text(title, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
|
// TODO: 跳转会话详情页
|
||||||
subtitle: Text(content, style: const TextStyle(fontSize: 14, color: Color(0xFF666666))),
|
},
|
||||||
trailing: Text(time, style: const TextStyle(fontSize: 12, color: Color(0xFF999999))),
|
child: Container(
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(14),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 24,
|
||||||
|
backgroundColor: const Color(0xFFFFE7CF),
|
||||||
|
backgroundImage: NetworkImage('https://i.pravatar.cc/50?img=${message['avatar']}'),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
message['name'] as String,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Color(0xFF333333),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
message['preview'] as String,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Color(0xFF8A8A8A),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
message['time'] as String,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Color(0xFF999999),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
unread > 0
|
||||||
|
? Container(
|
||||||
|
width: 18,
|
||||||
|
height: 18,
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Color(0xFFFF4D4F),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
'$unread',
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox(height: 18),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,22 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import 'profile_setup_screen.dart';
|
||||||
|
|
||||||
class ProfileScreen extends StatefulWidget {
|
class ProfileScreen extends StatefulWidget {
|
||||||
|
const ProfileScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ProfileScreen> createState() => _ProfileScreenState();
|
State<ProfileScreen> createState() => _ProfileScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ProfileScreenState extends State<ProfileScreen> {
|
class _ProfileScreenState extends State<ProfileScreen> {
|
||||||
final _nicknameController = TextEditingController();
|
String _nickname = '伴享用户';
|
||||||
String? _selectedCity;
|
List<String> _interests = [];
|
||||||
List<String> _selectedInterests = [];
|
String? _avatarPath;
|
||||||
|
bool _loading = true;
|
||||||
final _cities = ['北京', '上海', '广州', '深圳', '成都', '重庆'];
|
|
||||||
final _interests = ['太极', '晨练', '书法', '摄影', '舞蹈', '旅游', '茶艺', '手工', '唱歌', '棋牌'];
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -20,83 +24,129 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
_loadProfile();
|
_loadProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _loadProfile() async {
|
Future<void> _loadProfile() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
if (!mounted) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
_nicknameController.text = prefs.getString('nickname') ?? '';
|
_nickname = prefs.getString('user_nickname') ?? prefs.getString('nickname') ?? '伴享用户';
|
||||||
_selectedCity = prefs.getString('city');
|
_interests = prefs.getStringList('user_interests') ?? prefs.getStringList('interests') ?? [];
|
||||||
_selectedInterests = prefs.getStringList('interests') ?? [];
|
_avatarPath = prefs.getString('user_avatar_path');
|
||||||
|
_loading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _save() async {
|
bool get _hasAvatar {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final path = _avatarPath;
|
||||||
await prefs.setString('nickname', _nicknameController.text);
|
return path != null && path.isNotEmpty && File(path).existsSync();
|
||||||
if (_selectedCity != null) await prefs.setString('city', _selectedCity!);
|
}
|
||||||
await prefs.setStringList('interests', _selectedInterests);
|
|
||||||
|
Future<void> _openProfileSetup() async {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
await Navigator.push(
|
||||||
SnackBar(content: Text('保存成功')),
|
context,
|
||||||
|
MaterialPageRoute(builder: (_) => const ProfileSetupScreen()),
|
||||||
);
|
);
|
||||||
|
_loadProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text('个人资料')),
|
backgroundColor: const Color(0xFFFFF8F0),
|
||||||
body: ListView(
|
appBar: AppBar(title: const Text('我的资料')),
|
||||||
padding: EdgeInsets.all(16),
|
body: SafeArea(
|
||||||
children: [
|
child: Column(
|
||||||
TextField(
|
children: [
|
||||||
controller: _nicknameController,
|
Expanded(
|
||||||
decoration: InputDecoration(
|
child: _loading
|
||||||
labelText: '昵称',
|
? const Center(child: CircularProgressIndicator())
|
||||||
border: OutlineInputBorder(),
|
: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.fromLTRB(24, 28, 24, 12),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
child: ClipOval(
|
||||||
|
child: _hasAvatar
|
||||||
|
? Image.file(File(_avatarPath!), fit: BoxFit.cover)
|
||||||
|
: Container(
|
||||||
|
color: const Color(0xFFFFE7CF),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 42,
|
||||||
|
color: Color(0xFFCC7A2F),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
_nickname.isEmpty ? '伴享用户' : _nickname,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 28,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Color(0xFF333333),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 28),
|
||||||
|
if (_interests.isNotEmpty)
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
spacing: 8,
|
||||||
|
runSpacing: 8,
|
||||||
|
children: _interests
|
||||||
|
.map(
|
||||||
|
(interest) => Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFFFB84D),
|
||||||
|
borderRadius: BorderRadius.circular(18),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
interest,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
const Text(
|
||||||
|
'还没有设置兴趣标签',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Color(0xFF999999),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Padding(
|
||||||
SizedBox(height: 20),
|
padding: const EdgeInsets.fromLTRB(24, 0, 24, 24),
|
||||||
DropdownButtonFormField<String>(
|
child: SizedBox(
|
||||||
value: _selectedCity,
|
width: double.infinity,
|
||||||
decoration: InputDecoration(
|
height: 52,
|
||||||
labelText: '居住城市',
|
child: ElevatedButton(
|
||||||
border: OutlineInputBorder(),
|
onPressed: _openProfileSetup,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color(0xFFFF8A3D),
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
'编辑资料',
|
||||||
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
items: _cities.map((city) => DropdownMenuItem(value: city, child: Text(city))).toList(),
|
],
|
||||||
onChanged: (val) => setState(() => _selectedCity = val),
|
),
|
||||||
),
|
|
||||||
SizedBox(height: 20),
|
|
||||||
Text('兴趣爱好(最多5个)', style: TextStyle(fontSize: 16)),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
Wrap(
|
|
||||||
spacing: 8,
|
|
||||||
children: _interests.map((interest) {
|
|
||||||
final selected = _selectedInterests.contains(interest);
|
|
||||||
return FilterChip(
|
|
||||||
label: Text(interest),
|
|
||||||
selected: selected,
|
|
||||||
onSelected: (val) {
|
|
||||||
setState(() {
|
|
||||||
if (val && _selectedInterests.length < 5) {
|
|
||||||
_selectedInterests.add(interest);
|
|
||||||
} else {
|
|
||||||
_selectedInterests.remove(interest);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
SizedBox(height: 40),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: _save,
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: Color(0xFF333333),
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 16),
|
|
||||||
),
|
|
||||||
child: Text('保存', style: TextStyle(fontSize: 16)),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,7 @@ class _ProfileSetupScreenState extends State<ProfileSetupScreen> {
|
|||||||
void _finishSetup() async {
|
void _finishSetup() async {
|
||||||
await AuthService.updateProfile(
|
await AuthService.updateProfile(
|
||||||
nickname: _nicknameController.text.trim().isEmpty ? null : _nicknameController.text.trim(),
|
nickname: _nicknameController.text.trim().isEmpty ? null : _nicknameController.text.trim(),
|
||||||
|
avatar: _avatar?.path,
|
||||||
birthYear: _birthYear,
|
birthYear: _birthYear,
|
||||||
gender: _gender,
|
gender: _gender,
|
||||||
interests: _selectedInterests.toList(),
|
interests: _selectedInterests.toList(),
|
||||||
|
|||||||
@ -5,6 +5,9 @@ class AuthService {
|
|||||||
static const _tokenKey = 'auth_token';
|
static const _tokenKey = 'auth_token';
|
||||||
static const _phoneKey = 'user_phone';
|
static const _phoneKey = 'user_phone';
|
||||||
static const _nicknameKey = 'user_nickname';
|
static const _nicknameKey = 'user_nickname';
|
||||||
|
static const _avatarKey = 'user_avatar_path';
|
||||||
|
static const _cityKey = 'user_city';
|
||||||
|
static const _interestsKey = 'user_interests';
|
||||||
|
|
||||||
static User? _currentUser;
|
static User? _currentUser;
|
||||||
static User? get currentUser => _currentUser;
|
static User? get currentUser => _currentUser;
|
||||||
@ -18,7 +21,9 @@ class AuthService {
|
|||||||
id: '1',
|
id: '1',
|
||||||
phone: prefs.getString(_phoneKey) ?? '',
|
phone: prefs.getString(_phoneKey) ?? '',
|
||||||
nickname: prefs.getString(_nicknameKey),
|
nickname: prefs.getString(_nicknameKey),
|
||||||
city: '成都',
|
avatar: prefs.getString(_avatarKey),
|
||||||
|
city: prefs.getString(_cityKey) ?? '成都',
|
||||||
|
interests: prefs.getStringList(_interestsKey) ?? [],
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -52,6 +57,7 @@ class AuthService {
|
|||||||
|
|
||||||
static Future<void> updateProfile({
|
static Future<void> updateProfile({
|
||||||
String? nickname,
|
String? nickname,
|
||||||
|
String? avatar,
|
||||||
int? birthYear,
|
int? birthYear,
|
||||||
String? gender,
|
String? gender,
|
||||||
String? city,
|
String? city,
|
||||||
@ -61,10 +67,20 @@ class AuthService {
|
|||||||
if (nickname != null) {
|
if (nickname != null) {
|
||||||
await prefs.setString(_nicknameKey, nickname);
|
await prefs.setString(_nicknameKey, nickname);
|
||||||
}
|
}
|
||||||
|
if (avatar != null) {
|
||||||
|
await prefs.setString(_avatarKey, avatar);
|
||||||
|
}
|
||||||
|
if (city != null) {
|
||||||
|
await prefs.setString(_cityKey, city);
|
||||||
|
}
|
||||||
|
if (interests != null) {
|
||||||
|
await prefs.setStringList(_interestsKey, interests);
|
||||||
|
}
|
||||||
_currentUser = User(
|
_currentUser = User(
|
||||||
id: _currentUser?.id ?? '1',
|
id: _currentUser?.id ?? '1',
|
||||||
phone: _currentUser?.phone ?? '',
|
phone: _currentUser?.phone ?? '',
|
||||||
nickname: nickname ?? _currentUser?.nickname,
|
nickname: nickname ?? _currentUser?.nickname,
|
||||||
|
avatar: avatar ?? _currentUser?.avatar,
|
||||||
birthYear: birthYear ?? _currentUser?.birthYear,
|
birthYear: birthYear ?? _currentUser?.birthYear,
|
||||||
gender: gender ?? _currentUser?.gender,
|
gender: gender ?? _currentUser?.gender,
|
||||||
city: city ?? _currentUser?.city ?? '成都',
|
city: city ?? _currentUser?.city ?? '成都',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user