mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: add icon_url in migration
This commit is contained in:
parent
db19337609
commit
d56e8c7673
@ -11,7 +11,8 @@ class UserService {
|
|||||||
UserService({
|
UserService({
|
||||||
required this.userId,
|
required this.userId,
|
||||||
});
|
});
|
||||||
Future<Either<UserProfilePB, FlowyError>> getUserProfile({required String userId}) {
|
Future<Either<UserProfilePB, FlowyError>> getUserProfile(
|
||||||
|
{required String userId}) {
|
||||||
return UserEventGetUserProfile().send();
|
return UserEventGetUserProfile().send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ class UserService {
|
|||||||
String? name,
|
String? name,
|
||||||
String? password,
|
String? password,
|
||||||
String? email,
|
String? email,
|
||||||
String? icon,
|
String? iconUrl,
|
||||||
}) {
|
}) {
|
||||||
var payload = UpdateUserProfilePayloadPB.create()..id = userId;
|
var payload = UpdateUserProfilePayloadPB.create()..id = userId;
|
||||||
|
|
||||||
@ -35,14 +36,15 @@ class UserService {
|
|||||||
payload.email = email;
|
payload.email = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon != null) {
|
if (iconUrl != null) {
|
||||||
payload.icon = icon;
|
payload.iconUrl = iconUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserEventUpdateUserProfile(payload).send();
|
return UserEventUpdateUserProfile(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> deleteWorkspace({required String workspaceId}) {
|
Future<Either<Unit, FlowyError>> deleteWorkspace(
|
||||||
|
{required String workspaceId}) {
|
||||||
throw UnimplementedError();
|
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()
|
final request = CreateWorkspacePayloadPB.create()
|
||||||
..name = name
|
..name = name
|
||||||
..desc = desc;
|
..desc = desc;
|
||||||
|
@ -35,8 +35,8 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateUserIcon: (String icon) {
|
updateUserIcon: (String iconUrl) {
|
||||||
_userService.updateUserProfile(icon: icon).then((result) {
|
_userService.updateUserProfile(iconUrl: iconUrl).then((result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(l) => null,
|
(l) => null,
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
@ -60,7 +60,8 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
|
|||||||
|
|
||||||
void _profileUpdated(Either<UserProfilePB, FlowyError> userProfileOrFailed) {
|
void _profileUpdated(Either<UserProfilePB, FlowyError> userProfileOrFailed) {
|
||||||
userProfileOrFailed.fold(
|
userProfileOrFailed.fold(
|
||||||
(newUserProfile) => add(SettingsUserEvent.didReceiveUserProfile(newUserProfile)),
|
(newUserProfile) =>
|
||||||
|
add(SettingsUserEvent.didReceiveUserProfile(newUserProfile)),
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -70,8 +71,10 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
|
|||||||
class SettingsUserEvent with _$SettingsUserEvent {
|
class SettingsUserEvent with _$SettingsUserEvent {
|
||||||
const factory SettingsUserEvent.initial() = _Initial;
|
const factory SettingsUserEvent.initial() = _Initial;
|
||||||
const factory SettingsUserEvent.updateUserName(String name) = _UpdateUserName;
|
const factory SettingsUserEvent.updateUserName(String name) = _UpdateUserName;
|
||||||
const factory SettingsUserEvent.updateUserIcon(String icon) = _UpdateUserIcon;
|
const factory SettingsUserEvent.updateUserIcon(String iconUrl) =
|
||||||
const factory SettingsUserEvent.didReceiveUserProfile(UserProfilePB newUserProfile) = _DidReceiveUserProfile;
|
_UpdateUserIcon;
|
||||||
|
const factory SettingsUserEvent.didReceiveUserProfile(
|
||||||
|
UserProfilePB newUserProfile) = _DidReceiveUserProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -81,7 +84,8 @@ class SettingsUserState with _$SettingsUserState {
|
|||||||
required Either<Unit, String> successOrFailure,
|
required Either<Unit, String> successOrFailure,
|
||||||
}) = _SettingsUserState;
|
}) = _SettingsUserState;
|
||||||
|
|
||||||
factory SettingsUserState.initial(UserProfilePB userProfile) => SettingsUserState(
|
factory SettingsUserState.initial(UserProfilePB userProfile) =>
|
||||||
|
SettingsUserState(
|
||||||
userProfile: userProfile,
|
userProfile: userProfile,
|
||||||
successOrFailure: left(unit),
|
successOrFailure: left(unit),
|
||||||
);
|
);
|
||||||
|
@ -40,7 +40,7 @@ class MenuUser extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderAvatar(BuildContext context) {
|
Widget _renderAvatar(BuildContext context) {
|
||||||
String icon = context.read<MenuUserBloc>().state.userProfile.icon;
|
String iconUrl = context.read<MenuUserBloc>().state.userProfile.iconUrl;
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: 25,
|
width: 25,
|
||||||
@ -49,7 +49,7 @@ class MenuUser extends StatelessWidget {
|
|||||||
borderRadius: Corners.s5Border,
|
borderRadius: Corners.s5Border,
|
||||||
child: CircleAvatar(
|
child: CircleAvatar(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
child: svgWidget('emoji/$icon'),
|
child: svgWidget('emoji/$iconUrl'),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,17 @@ class SettingsUserView extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider<SettingsUserViewBloc>(
|
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>(
|
child: BlocBuilder<SettingsUserViewBloc, SettingsUserState>(
|
||||||
builder: (context, state) => SingleChildScrollView(
|
builder: (context, state) => SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
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) {
|
Widget _renderCurrentIcon(BuildContext context) {
|
||||||
String icon = context.read<SettingsUserViewBloc>().state.userProfile.icon;
|
String iconUrl =
|
||||||
return _CurrentIcon(icon);
|
context.read<SettingsUserViewBloc>().state.userProfile.iconUrl;
|
||||||
|
return _CurrentIcon(iconUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,19 +59,23 @@ class _UserNameInput extends StatelessWidget {
|
|||||||
labelText: 'Name',
|
labelText: 'Name',
|
||||||
),
|
),
|
||||||
onSubmitted: (val) {
|
onSubmitted: (val) {
|
||||||
context.read<SettingsUserViewBloc>().add(SettingsUserEvent.updateUserName(val));
|
context
|
||||||
|
.read<SettingsUserViewBloc>()
|
||||||
|
.add(SettingsUserEvent.updateUserName(val));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CurrentIcon extends StatelessWidget {
|
class _CurrentIcon extends StatelessWidget {
|
||||||
final String icon;
|
final String iconUrl;
|
||||||
const _CurrentIcon(this.icon, {Key? key}) : super(key: key);
|
const _CurrentIcon(this.iconUrl, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
_setIcon(String icon) {
|
_setIcon(String iconUrl) {
|
||||||
context.read<SettingsUserViewBloc>().add(SettingsUserEvent.updateUserIcon(icon));
|
context
|
||||||
|
.read<SettingsUserViewBloc>()
|
||||||
|
.add(SettingsUserEvent.updateUserIcon(iconUrl));
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +88,10 @@ class _CurrentIcon extends StatelessWidget {
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
title: const Text('Select an Icon'),
|
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,
|
alignment: Alignment.centerLeft,
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.all(5.0),
|
margin: const EdgeInsets.all(5.0),
|
||||||
decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
|
decoration:
|
||||||
child: svgWithSize('emoji/$icon', const Size(60, 60)),
|
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);
|
const IconGallery(this.setIcon, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
Future<List<String>> _getIcons(BuildContext context) async {
|
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 Map<String, dynamic> manifestMap = json.decode(manifestContent);
|
||||||
|
|
||||||
final icons = manifestMap.keys
|
final iconUrls = manifestMap.keys
|
||||||
.where((String key) => key.startsWith('assets/images/emoji/') && key.endsWith('.svg'))
|
.where((String key) =>
|
||||||
|
key.startsWith('assets/images/emoji/') && key.endsWith('.svg'))
|
||||||
.map((String key) => key.split('/').last.split('.').first)
|
.map((String key) => key.split('/').last.split('.').first)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return icons;
|
return iconUrls;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -127,8 +143,8 @@ class IconGallery extends StatelessWidget {
|
|||||||
return GridView.count(
|
return GridView.count(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
crossAxisCount: 5,
|
crossAxisCount: 5,
|
||||||
children: (snapshot.data ?? []).map((String icon) {
|
children: (snapshot.data ?? []).map((String iconUrl) {
|
||||||
return IconOption(icon, setIcon);
|
return IconOption(iconUrl, setIcon);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -142,10 +158,11 @@ class IconGallery extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class IconOption extends StatelessWidget {
|
class IconOption extends StatelessWidget {
|
||||||
final String icon;
|
final String iconUrl;
|
||||||
final Function setIcon;
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -153,9 +170,9 @@ class IconOption extends StatelessWidget {
|
|||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setIcon(icon);
|
setIcon(iconUrl);
|
||||||
},
|
},
|
||||||
child: svgWidget('emoji/$icon'),
|
child: svgWidget('emoji/$iconUrl'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE user_table DROP COLUMN icon_url;
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE user_table ADD COLUMN icon_url TEXT NOT NULL DEFAULT '';
|
@ -87,8 +87,8 @@ table! {
|
|||||||
name -> Text,
|
name -> Text,
|
||||||
token -> Text,
|
token -> Text,
|
||||||
email -> Text,
|
email -> Text,
|
||||||
icon -> Text,
|
|
||||||
workspace -> Text,
|
workspace -> Text,
|
||||||
|
icon_url -> Text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ pub struct UserProfilePB {
|
|||||||
pub token: String,
|
pub token: String,
|
||||||
|
|
||||||
#[pb(index = 5)]
|
#[pb(index = 5)]
|
||||||
pub icon: String,
|
pub icon_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Default)]
|
#[derive(ProtoBuf, Default)]
|
||||||
@ -45,7 +45,7 @@ pub struct UpdateUserProfilePayloadPB {
|
|||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
|
|
||||||
#[pb(index = 5, one_of)]
|
#[pb(index = 5, one_of)]
|
||||||
pub icon: Option<String>,
|
pub icon_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpdateUserProfilePayloadPB {
|
impl UpdateUserProfilePayloadPB {
|
||||||
@ -71,8 +71,8 @@ impl UpdateUserProfilePayloadPB {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn icon(mut self, icon: &str) -> Self {
|
pub fn icon_url(mut self, icon_url: &str) -> Self {
|
||||||
self.icon = Some(icon.to_owned());
|
self.icon_url = Some(icon_url.to_owned());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ pub struct UpdateUserProfileParams {
|
|||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
|
|
||||||
#[pb(index = 5, one_of)]
|
#[pb(index = 5, one_of)]
|
||||||
pub icon: Option<String>,
|
pub icon_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UpdateUserProfileParams {
|
impl UpdateUserProfileParams {
|
||||||
@ -102,7 +102,7 @@ impl UpdateUserProfileParams {
|
|||||||
name: None,
|
name: None,
|
||||||
email: None,
|
email: None,
|
||||||
password: None,
|
password: None,
|
||||||
icon: None,
|
icon_url: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,8 +121,8 @@ impl UpdateUserProfileParams {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn icon(mut self, icon: &str) -> Self {
|
pub fn icon_url(mut self, icon_url: &str) -> Self {
|
||||||
self.icon = Some(icon.to_owned());
|
self.icon_url = Some(icon_url.to_owned());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,9 +148,9 @@ impl TryInto<UpdateUserProfileParams> for UpdateUserProfilePayloadPB {
|
|||||||
Some(password) => Some(UserPassword::parse(password)?.0),
|
Some(password) => Some(UserPassword::parse(password)?.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let icon = match self.icon {
|
let icon_url = match self.icon_url {
|
||||||
None => None,
|
None => None,
|
||||||
Some(icon) => Some(UserIcon::parse(icon)?.0),
|
Some(icon_url) => Some(UserIcon::parse(icon_url)?.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(UpdateUserProfileParams {
|
Ok(UpdateUserProfileParams {
|
||||||
@ -158,7 +158,7 @@ impl TryInto<UpdateUserProfileParams> for UpdateUserProfilePayloadPB {
|
|||||||
name,
|
name,
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
icon,
|
icon_url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,8 @@ pub struct UserTable {
|
|||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
pub(crate) token: String,
|
pub(crate) token: String,
|
||||||
pub(crate) email: String,
|
pub(crate) email: String,
|
||||||
pub(crate) icon: String,
|
|
||||||
pub(crate) workspace: String, // deprecated
|
pub(crate) workspace: String, // deprecated
|
||||||
|
pub(crate) icon_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserTable {
|
impl UserTable {
|
||||||
@ -92,7 +92,7 @@ impl UserTable {
|
|||||||
name,
|
name,
|
||||||
email,
|
email,
|
||||||
token,
|
token,
|
||||||
icon: "".to_owned(),
|
icon_url: "".to_owned(),
|
||||||
workspace: "".to_owned(),
|
workspace: "".to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ impl std::convert::From<UserTable> for UserProfilePB {
|
|||||||
email: table.email,
|
email: table.email,
|
||||||
name: table.name,
|
name: table.name,
|
||||||
token: table.token,
|
token: table.token,
|
||||||
icon: table.icon,
|
icon_url: table.icon_url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ pub struct UserTableChangeset {
|
|||||||
pub workspace: Option<String>, // deprecated
|
pub workspace: Option<String>, // deprecated
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserTableChangeset {
|
impl UserTableChangeset {
|
||||||
@ -144,7 +144,7 @@ impl UserTableChangeset {
|
|||||||
workspace: None,
|
workspace: None,
|
||||||
name: params.name,
|
name: params.name,
|
||||||
email: params.email,
|
email: params.email,
|
||||||
icon: params.icon,
|
icon_url: params.icon_url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user