fix: add icon_url in migration

This commit is contained in:
Ian Su 2022-08-08 22:19:05 +08:00
parent db19337609
commit d56e8c7673
9 changed files with 79 additions and 53 deletions

View File

@ -11,7 +11,8 @@ class UserService {
UserService({
required this.userId,
});
Future<Either<UserProfilePB, FlowyError>> getUserProfile({required String userId}) {
Future<Either<UserProfilePB, FlowyError>> getUserProfile(
{required String userId}) {
return UserEventGetUserProfile().send();
}
@ -19,7 +20,7 @@ class UserService {
String? name,
String? password,
String? email,
String? icon,
String? iconUrl,
}) {
var payload = UpdateUserProfilePayloadPB.create()..id = userId;
@ -35,14 +36,15 @@ class UserService {
payload.email = email;
}
if (icon != null) {
payload.icon = icon;
if (iconUrl != null) {
payload.iconUrl = iconUrl;
}
return UserEventUpdateUserProfile(payload).send();
}
Future<Either<Unit, FlowyError>> deleteWorkspace({required String workspaceId}) {
Future<Either<Unit, FlowyError>> deleteWorkspace(
{required String workspaceId}) {
throw UnimplementedError();
}
@ -75,7 +77,8 @@ class UserService {
});
}
Future<Either<WorkspacePB, FlowyError>> createWorkspace(String name, String desc) {
Future<Either<WorkspacePB, FlowyError>> createWorkspace(
String name, String desc) {
final request = CreateWorkspacePayloadPB.create()
..name = name
..desc = desc;

View File

@ -35,8 +35,8 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
);
});
},
updateUserIcon: (String icon) {
_userService.updateUserProfile(icon: icon).then((result) {
updateUserIcon: (String iconUrl) {
_userService.updateUserProfile(iconUrl: iconUrl).then((result) {
result.fold(
(l) => null,
(err) => Log.error(err),
@ -60,7 +60,8 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
void _profileUpdated(Either<UserProfilePB, FlowyError> userProfileOrFailed) {
userProfileOrFailed.fold(
(newUserProfile) => add(SettingsUserEvent.didReceiveUserProfile(newUserProfile)),
(newUserProfile) =>
add(SettingsUserEvent.didReceiveUserProfile(newUserProfile)),
(err) => Log.error(err),
);
}
@ -70,8 +71,10 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
class SettingsUserEvent with _$SettingsUserEvent {
const factory SettingsUserEvent.initial() = _Initial;
const factory SettingsUserEvent.updateUserName(String name) = _UpdateUserName;
const factory SettingsUserEvent.updateUserIcon(String icon) = _UpdateUserIcon;
const factory SettingsUserEvent.didReceiveUserProfile(UserProfilePB newUserProfile) = _DidReceiveUserProfile;
const factory SettingsUserEvent.updateUserIcon(String iconUrl) =
_UpdateUserIcon;
const factory SettingsUserEvent.didReceiveUserProfile(
UserProfilePB newUserProfile) = _DidReceiveUserProfile;
}
@freezed
@ -81,7 +84,8 @@ class SettingsUserState with _$SettingsUserState {
required Either<Unit, String> successOrFailure,
}) = _SettingsUserState;
factory SettingsUserState.initial(UserProfilePB userProfile) => SettingsUserState(
factory SettingsUserState.initial(UserProfilePB userProfile) =>
SettingsUserState(
userProfile: userProfile,
successOrFailure: left(unit),
);

View File

@ -40,7 +40,7 @@ class MenuUser extends StatelessWidget {
}
Widget _renderAvatar(BuildContext context) {
String icon = context.read<MenuUserBloc>().state.userProfile.icon;
String iconUrl = context.read<MenuUserBloc>().state.userProfile.iconUrl;
return SizedBox(
width: 25,
@ -49,7 +49,7 @@ class MenuUser extends StatelessWidget {
borderRadius: Corners.s5Border,
child: CircleAvatar(
backgroundColor: Colors.transparent,
child: svgWidget('emoji/$icon'),
child: svgWidget('emoji/$iconUrl'),
)),
);
}

View File

@ -15,12 +15,17 @@ class SettingsUserView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider<SettingsUserViewBloc>(
create: (context) => getIt<SettingsUserViewBloc>(param1: user)..add(const SettingsUserEvent.initial()),
create: (context) => getIt<SettingsUserViewBloc>(param1: user)
..add(const SettingsUserEvent.initial()),
child: BlocBuilder<SettingsUserViewBloc, SettingsUserState>(
builder: (context, state) => SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [_renderUserNameInput(context), const VSpace(20), _renderCurrentIcon(context)],
children: [
_renderUserNameInput(context),
const VSpace(20),
_renderCurrentIcon(context)
],
),
),
),
@ -33,8 +38,9 @@ class SettingsUserView extends StatelessWidget {
}
Widget _renderCurrentIcon(BuildContext context) {
String icon = context.read<SettingsUserViewBloc>().state.userProfile.icon;
return _CurrentIcon(icon);
String iconUrl =
context.read<SettingsUserViewBloc>().state.userProfile.iconUrl;
return _CurrentIcon(iconUrl);
}
}
@ -53,19 +59,23 @@ class _UserNameInput extends StatelessWidget {
labelText: 'Name',
),
onSubmitted: (val) {
context.read<SettingsUserViewBloc>().add(SettingsUserEvent.updateUserName(val));
context
.read<SettingsUserViewBloc>()
.add(SettingsUserEvent.updateUserName(val));
});
}
}
class _CurrentIcon extends StatelessWidget {
final String icon;
const _CurrentIcon(this.icon, {Key? key}) : super(key: key);
final String iconUrl;
const _CurrentIcon(this.iconUrl, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
_setIcon(String icon) {
context.read<SettingsUserViewBloc>().add(SettingsUserEvent.updateUserIcon(icon));
_setIcon(String iconUrl) {
context
.read<SettingsUserViewBloc>()
.add(SettingsUserEvent.updateUserIcon(iconUrl));
Navigator.of(context).pop();
}
@ -78,7 +88,10 @@ class _CurrentIcon extends StatelessWidget {
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Select an Icon'),
children: <Widget>[SizedBox(height: 300, width: 300, child: IconGallery(_setIcon))]);
children: <Widget>[
SizedBox(
height: 300, width: 300, child: IconGallery(_setIcon))
]);
},
);
},
@ -93,8 +106,9 @@ class _CurrentIcon extends StatelessWidget {
alignment: Alignment.centerLeft,
child: Container(
margin: const EdgeInsets.all(5.0),
decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
child: svgWithSize('emoji/$icon', const Size(60, 60)),
decoration:
BoxDecoration(border: Border.all(color: Colors.grey)),
child: svgWithSize('emoji/$iconUrl', const Size(60, 60)),
)),
])),
);
@ -106,16 +120,18 @@ class IconGallery extends StatelessWidget {
const IconGallery(this.setIcon, {Key? key}) : super(key: key);
Future<List<String>> _getIcons(BuildContext context) async {
final manifestContent = await DefaultAssetBundle.of(context).loadString('AssetManifest.json');
final manifestContent =
await DefaultAssetBundle.of(context).loadString('AssetManifest.json');
final Map<String, dynamic> manifestMap = json.decode(manifestContent);
final icons = manifestMap.keys
.where((String key) => key.startsWith('assets/images/emoji/') && key.endsWith('.svg'))
final iconUrls = manifestMap.keys
.where((String key) =>
key.startsWith('assets/images/emoji/') && key.endsWith('.svg'))
.map((String key) => key.split('/').last.split('.').first)
.toList();
return icons;
return iconUrls;
}
@override
@ -127,8 +143,8 @@ class IconGallery extends StatelessWidget {
return GridView.count(
padding: const EdgeInsets.all(20),
crossAxisCount: 5,
children: (snapshot.data ?? []).map((String icon) {
return IconOption(icon, setIcon);
children: (snapshot.data ?? []).map((String iconUrl) {
return IconOption(iconUrl, setIcon);
}).toList(),
);
} else {
@ -142,10 +158,11 @@ class IconGallery extends StatelessWidget {
}
class IconOption extends StatelessWidget {
final String icon;
final String iconUrl;
final Function setIcon;
IconOption(this.icon, this.setIcon, {Key? key}) : super(key: ValueKey(icon));
IconOption(this.iconUrl, this.setIcon, {Key? key})
: super(key: ValueKey(iconUrl));
@override
Widget build(BuildContext context) {
@ -153,9 +170,9 @@ class IconOption extends StatelessWidget {
color: Colors.transparent,
child: GestureDetector(
onTap: () {
setIcon(icon);
setIcon(iconUrl);
},
child: svgWidget('emoji/$icon'),
child: svgWidget('emoji/$iconUrl'),
),
);
}

View File

@ -0,0 +1 @@
ALTER TABLE user_table DROP COLUMN icon_url;

View File

@ -0,0 +1 @@
ALTER TABLE user_table ADD COLUMN icon_url TEXT NOT NULL DEFAULT '';

View File

@ -87,8 +87,8 @@ table! {
name -> Text,
token -> Text,
email -> Text,
icon -> Text,
workspace -> Text,
icon_url -> Text,
}
}

View File

@ -27,7 +27,7 @@ pub struct UserProfilePB {
pub token: String,
#[pb(index = 5)]
pub icon: String,
pub icon_url: String,
}
#[derive(ProtoBuf, Default)]
@ -45,7 +45,7 @@ pub struct UpdateUserProfilePayloadPB {
pub password: Option<String>,
#[pb(index = 5, one_of)]
pub icon: Option<String>,
pub icon_url: Option<String>,
}
impl UpdateUserProfilePayloadPB {
@ -71,8 +71,8 @@ impl UpdateUserProfilePayloadPB {
self
}
pub fn icon(mut self, icon: &str) -> Self {
self.icon = Some(icon.to_owned());
pub fn icon_url(mut self, icon_url: &str) -> Self {
self.icon_url = Some(icon_url.to_owned());
self
}
}
@ -92,7 +92,7 @@ pub struct UpdateUserProfileParams {
pub password: Option<String>,
#[pb(index = 5, one_of)]
pub icon: Option<String>,
pub icon_url: Option<String>,
}
impl UpdateUserProfileParams {
@ -102,7 +102,7 @@ impl UpdateUserProfileParams {
name: None,
email: None,
password: None,
icon: None,
icon_url: None,
}
}
@ -121,8 +121,8 @@ impl UpdateUserProfileParams {
self
}
pub fn icon(mut self, icon: &str) -> Self {
self.icon = Some(icon.to_owned());
pub fn icon_url(mut self, icon_url: &str) -> Self {
self.icon_url = Some(icon_url.to_owned());
self
}
}
@ -148,9 +148,9 @@ impl TryInto<UpdateUserProfileParams> for UpdateUserProfilePayloadPB {
Some(password) => Some(UserPassword::parse(password)?.0),
};
let icon = match self.icon {
let icon_url = match self.icon_url {
None => None,
Some(icon) => Some(UserIcon::parse(icon)?.0),
Some(icon_url) => Some(UserIcon::parse(icon_url)?.0),
};
Ok(UpdateUserProfileParams {
@ -158,7 +158,7 @@ impl TryInto<UpdateUserProfileParams> for UpdateUserProfilePayloadPB {
name,
email,
password,
icon,
icon_url,
})
}
}

View File

@ -81,8 +81,8 @@ pub struct UserTable {
pub(crate) name: String,
pub(crate) token: String,
pub(crate) email: String,
pub(crate) icon: String,
pub(crate) workspace: String, // deprecated
pub(crate) icon_url: String,
}
impl UserTable {
@ -92,7 +92,7 @@ impl UserTable {
name,
email,
token,
icon: "".to_owned(),
icon_url: "".to_owned(),
workspace: "".to_owned(),
}
}
@ -122,7 +122,7 @@ impl std::convert::From<UserTable> for UserProfilePB {
email: table.email,
name: table.name,
token: table.token,
icon: table.icon,
icon_url: table.icon_url,
}
}
}
@ -134,7 +134,7 @@ pub struct UserTableChangeset {
pub workspace: Option<String>, // deprecated
pub name: Option<String>,
pub email: Option<String>,
pub icon: Option<String>,
pub icon_url: Option<String>,
}
impl UserTableChangeset {
@ -144,7 +144,7 @@ impl UserTableChangeset {
workspace: None,
name: params.name,
email: params.email,
icon: params.icon,
icon_url: params.icon_url,
}
}
}