mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: login session (#3149)
This commit is contained in:
@ -0,0 +1,64 @@
|
|||||||
|
import 'package:appflowy/user/application/user_service.dart';
|
||||||
|
import 'package:appflowy_backend/log.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-user/auth.pb.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'historical_user_bloc.freezed.dart';
|
||||||
|
|
||||||
|
class HistoricalUserBloc
|
||||||
|
extends Bloc<HistoricalUserEvent, HistoricalUserState> {
|
||||||
|
HistoricalUserBloc() : super(HistoricalUserState.initial()) {
|
||||||
|
on<HistoricalUserEvent>((event, emit) async {
|
||||||
|
await event.when(
|
||||||
|
initial: () async {
|
||||||
|
await _loadHistoricalUsers();
|
||||||
|
},
|
||||||
|
didLoadHistoricalUsers: (List<HistoricalUserPB> historicalUsers) {
|
||||||
|
emit(state.copyWith(historicalUsers: historicalUsers));
|
||||||
|
},
|
||||||
|
openHistoricalUser: (HistoricalUserPB historicalUser) async {
|
||||||
|
await UserBackendService.openHistoricalUser(historicalUser);
|
||||||
|
emit(state.copyWith(openedHistoricalUser: historicalUser));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadHistoricalUsers() async {
|
||||||
|
final result = await UserBackendService.loadHistoricalUsers();
|
||||||
|
result.fold(
|
||||||
|
(historicalUsers) {
|
||||||
|
historicalUsers
|
||||||
|
.retainWhere((element) => element.authType == AuthTypePB.Local);
|
||||||
|
add(HistoricalUserEvent.didLoadHistoricalUsers(historicalUsers));
|
||||||
|
},
|
||||||
|
(error) => Log.error(error),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class HistoricalUserEvent with _$HistoricalUserEvent {
|
||||||
|
const factory HistoricalUserEvent.initial() = _Initial;
|
||||||
|
const factory HistoricalUserEvent.didLoadHistoricalUsers(
|
||||||
|
List<HistoricalUserPB> historicalUsers,
|
||||||
|
) = _DidLoadHistoricalUsers;
|
||||||
|
const factory HistoricalUserEvent.openHistoricalUser(
|
||||||
|
HistoricalUserPB historicalUser,
|
||||||
|
) = _OpenHistoricalUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class HistoricalUserState with _$HistoricalUserState {
|
||||||
|
const factory HistoricalUserState({
|
||||||
|
required List<HistoricalUserPB> historicalUsers,
|
||||||
|
required HistoricalUserPB? openedHistoricalUser,
|
||||||
|
}) = _HistoricalUserState;
|
||||||
|
|
||||||
|
factory HistoricalUserState.initial() => const HistoricalUserState(
|
||||||
|
historicalUsers: [],
|
||||||
|
openedHistoricalUser: null,
|
||||||
|
);
|
||||||
|
}
|
@ -70,7 +70,7 @@ class UserBackendService {
|
|||||||
return UserEventInitUser().send();
|
return UserEventInitUser().send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<List<HistoricalUserPB>, FlowyError>>
|
static Future<Either<List<HistoricalUserPB>, FlowyError>>
|
||||||
loadHistoricalUsers() async {
|
loadHistoricalUsers() async {
|
||||||
return UserEventGetHistoricalUsers().send().then(
|
return UserEventGetHistoricalUsers().send().then(
|
||||||
(result) {
|
(result) {
|
||||||
@ -82,7 +82,7 @@ class UserBackendService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> openHistoricalUser(
|
static Future<Either<Unit, FlowyError>> openHistoricalUser(
|
||||||
HistoricalUserPB user,
|
HistoricalUserPB user,
|
||||||
) async {
|
) async {
|
||||||
return UserEventOpenHistoricalUser(user).send();
|
return UserEventOpenHistoricalUser(user).send();
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/user/application/historical_user_bloc.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class HistoricalUserList extends StatelessWidget {
|
||||||
|
final VoidCallback didOpenUser;
|
||||||
|
const HistoricalUserList({required this.didOpenUser, super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) => HistoricalUserBloc()
|
||||||
|
..add(
|
||||||
|
const HistoricalUserEvent.initial(),
|
||||||
|
),
|
||||||
|
child: BlocBuilder<HistoricalUserBloc, HistoricalUserState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state.historicalUsers.isEmpty) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
} else {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Opacity(
|
||||||
|
opacity: 0.6,
|
||||||
|
child: FlowyText.regular(
|
||||||
|
LocaleKeys.settings_menu_historicalUserListTooltip.tr(),
|
||||||
|
fontSize: 13,
|
||||||
|
maxLines: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const VSpace(6),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final user = state.historicalUsers[index];
|
||||||
|
return HistoricalUserItem(
|
||||||
|
key: ValueKey(user.userId),
|
||||||
|
user: user,
|
||||||
|
isSelected: false,
|
||||||
|
didOpenUser: didOpenUser,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: state.historicalUsers.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HistoricalUserItem extends StatelessWidget {
|
||||||
|
final VoidCallback didOpenUser;
|
||||||
|
final bool isSelected;
|
||||||
|
final HistoricalUserPB user;
|
||||||
|
const HistoricalUserItem({
|
||||||
|
required this.user,
|
||||||
|
required this.isSelected,
|
||||||
|
required this.didOpenUser,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final icon = isSelected ? const FlowySvg(name: "grid/checkmark") : null;
|
||||||
|
final isDisabled = isSelected || user.authType != AuthTypePB.Local;
|
||||||
|
final outputFormat = DateFormat('MM/dd/yyyy hh:mm a');
|
||||||
|
final date =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(user.lastTime.toInt() * 1000);
|
||||||
|
final lastTime = outputFormat.format(date);
|
||||||
|
final desc = "${user.userName}\t ${user.authType}\t$lastTime";
|
||||||
|
final child = SizedBox(
|
||||||
|
height: 30,
|
||||||
|
child: FlowyButton(
|
||||||
|
disable: isDisabled,
|
||||||
|
text: FlowyText.medium(
|
||||||
|
desc,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
rightIcon: icon,
|
||||||
|
onTap: () {
|
||||||
|
context
|
||||||
|
.read<HistoricalUserBloc>()
|
||||||
|
.add(HistoricalUserEvent.openHistoricalUser(user));
|
||||||
|
didOpenUser();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
import 'package:appflowy/core/config/kv.dart';
|
import 'package:appflowy/core/config/kv.dart';
|
||||||
import 'package:appflowy/core/config/kv_keys.dart';
|
import 'package:appflowy/core/config/kv_keys.dart';
|
||||||
import 'package:appflowy/core/frameless_window.dart';
|
import 'package:appflowy/core/frameless_window.dart';
|
||||||
|
import 'package:appflowy/startup/entry_point.dart';
|
||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
|
import 'package:appflowy/user/application/historical_user_bloc.dart';
|
||||||
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
||||||
import 'package:appflowy/user/presentation/router.dart';
|
import 'package:appflowy/user/presentation/router.dart';
|
||||||
import 'package:appflowy/user/presentation/widgets/background.dart';
|
import 'package:appflowy/user/presentation/widgets/background.dart';
|
||||||
@ -118,7 +120,18 @@ class SignInForm extends StatelessWidget {
|
|||||||
: [
|
: [
|
||||||
const VSpace(indicatorMinHeight * 2.0)
|
const VSpace(indicatorMinHeight * 2.0)
|
||||||
], // add the same space when there's no loading status.
|
], // add the same space when there's no loading status.
|
||||||
const VSpace(20)
|
// ConstrainedBox(
|
||||||
|
// constraints: const BoxConstraints(maxHeight: 140),
|
||||||
|
// child: HistoricalUserList(
|
||||||
|
// didOpenUser: () async {
|
||||||
|
// await FlowyRunner.run(
|
||||||
|
// FlowyApp(),
|
||||||
|
// integrationEnv(),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
const VSpace(20),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -183,15 +196,50 @@ class SignInAsGuestButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) => HistoricalUserBloc()
|
||||||
|
..add(
|
||||||
|
const HistoricalUserEvent.initial(),
|
||||||
|
),
|
||||||
|
child: BlocListener<HistoricalUserBloc, HistoricalUserState>(
|
||||||
|
listenWhen: (previous, current) =>
|
||||||
|
previous.openedHistoricalUser != current.openedHistoricalUser,
|
||||||
|
listener: (context, state) async {
|
||||||
|
await FlowyRunner.run(
|
||||||
|
FlowyApp(),
|
||||||
|
integrationEnv(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: BlocBuilder<HistoricalUserBloc, HistoricalUserState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (state.historicalUsers.isEmpty) {
|
||||||
return RoundedTextButton(
|
return RoundedTextButton(
|
||||||
title: LocaleKeys.signIn_loginAsGuestButtonText.tr(),
|
title: LocaleKeys.signIn_loginAsGuestButtonText.tr(),
|
||||||
height: 48,
|
height: 48,
|
||||||
borderRadius: Corners.s6Border,
|
borderRadius: Corners.s6Border,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
getIt<KeyValueStorage>().set(KVKeys.loginType, 'local');
|
getIt<KeyValueStorage>().set(KVKeys.loginType, 'local');
|
||||||
context.read<SignInBloc>().add(const SignInEvent.signedInAsGuest());
|
context
|
||||||
|
.read<SignInBloc>()
|
||||||
|
.add(const SignInEvent.signedInAsGuest());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return RoundedTextButton(
|
||||||
|
title: LocaleKeys.signIn_continueAnonymousUser.tr(),
|
||||||
|
height: 48,
|
||||||
|
borderRadius: Corners.s6Border,
|
||||||
|
onPressed: () {
|
||||||
|
final bloc = context.read<HistoricalUserBloc>();
|
||||||
|
final user = bloc.state.historicalUsers.first;
|
||||||
|
bloc.add(HistoricalUserEvent.openHistoricalUser(user));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
|
|||||||
emit(state.copyWith(historicalUsers: historicalUsers));
|
emit(state.copyWith(historicalUsers: historicalUsers));
|
||||||
},
|
},
|
||||||
openHistoricalUser: (HistoricalUserPB historicalUser) async {
|
openHistoricalUser: (HistoricalUserPB historicalUser) async {
|
||||||
await _userService.openHistoricalUser(historicalUser);
|
await UserBackendService.openHistoricalUser(historicalUser);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -74,7 +74,7 @@ class SettingsUserViewBloc extends Bloc<SettingsUserEvent, SettingsUserState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadHistoricalUsers() async {
|
Future<void> _loadHistoricalUsers() async {
|
||||||
final result = await _userService.loadHistoricalUsers();
|
final result = await UserBackendService.loadHistoricalUsers();
|
||||||
result.fold(
|
result.fold(
|
||||||
(historicalUsers) {
|
(historicalUsers) {
|
||||||
add(SettingsUserEvent.didLoadHistoricalUsers(historicalUsers));
|
add(SettingsUserEvent.didLoadHistoricalUsers(historicalUsers));
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
|
||||||
import 'package:appflowy/workspace/application/user/settings_user_bloc.dart';
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flowy_infra/image.dart';
|
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
|
|
||||||
class HistoricalUserList extends StatelessWidget {
|
|
||||||
final VoidCallback didOpenUser;
|
|
||||||
const HistoricalUserList({required this.didOpenUser, super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocBuilder<SettingsUserViewBloc, SettingsUserState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(maxHeight: 200),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
FlowyText.medium(
|
|
||||||
LocaleKeys.settings_menu_historicalUserList.tr(),
|
|
||||||
fontSize: 13,
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
Tooltip(
|
|
||||||
message:
|
|
||||||
LocaleKeys.settings_menu_historicalUserListTooltip.tr(),
|
|
||||||
child: const Icon(
|
|
||||||
Icons.question_mark_rounded,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: ListView.builder(
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final user = state.historicalUsers[index];
|
|
||||||
return HistoricalUserItem(
|
|
||||||
key: ValueKey(user.userId),
|
|
||||||
user: user,
|
|
||||||
isSelected: state.userProfile.id == user.userId,
|
|
||||||
didOpenUser: didOpenUser,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
itemCount: state.historicalUsers.length,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HistoricalUserItem extends StatelessWidget {
|
|
||||||
final VoidCallback didOpenUser;
|
|
||||||
final bool isSelected;
|
|
||||||
final HistoricalUserPB user;
|
|
||||||
const HistoricalUserItem({
|
|
||||||
required this.user,
|
|
||||||
required this.isSelected,
|
|
||||||
required this.didOpenUser,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final icon = isSelected ? const FlowySvg(name: "grid/checkmark") : null;
|
|
||||||
final isDisabled = isSelected || user.authType != AuthTypePB.Local;
|
|
||||||
final outputFormat = DateFormat('MM/dd/yyyy');
|
|
||||||
final date =
|
|
||||||
DateTime.fromMillisecondsSinceEpoch(user.lastTime.toInt() * 1000);
|
|
||||||
final lastTime = outputFormat.format(date);
|
|
||||||
final desc = "${user.userName} ${user.authType} $lastTime";
|
|
||||||
final child = SizedBox(
|
|
||||||
height: 30,
|
|
||||||
child: FlowyButton(
|
|
||||||
disable: isDisabled,
|
|
||||||
text: FlowyText.medium(desc),
|
|
||||||
rightIcon: icon,
|
|
||||||
onTap: () {
|
|
||||||
if (user.userId ==
|
|
||||||
context.read<SettingsUserViewBloc>().userProfile.id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
context
|
|
||||||
.read<SettingsUserViewBloc>()
|
|
||||||
.add(SettingsUserEvent.openHistoricalUser(user));
|
|
||||||
didOpenUser();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isSelected) {
|
|
||||||
return child;
|
|
||||||
} else {
|
|
||||||
return Tooltip(
|
|
||||||
message: LocaleKeys.settings_menu_openHistoricalUser.tr(),
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -31,7 +31,11 @@ class SettingThirdPartyLogin extends StatelessWidget {
|
|||||||
builder: (_, __) => Column(
|
builder: (_, __) => Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
FlowyText.medium(LocaleKeys.signIn_signInWith.tr()),
|
FlowyText.medium(
|
||||||
|
LocaleKeys.signIn_signInWith.tr(),
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
const VSpace(6),
|
||||||
const ThirdPartySignInButtons(
|
const ThirdPartySignInButtons(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
),
|
),
|
||||||
|
@ -16,7 +16,6 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import 'historical_user.dart';
|
|
||||||
import 'setting_third_party_login.dart';
|
import 'setting_third_party_login.dart';
|
||||||
|
|
||||||
const defaultUserAvatar = '1F600';
|
const defaultUserAvatar = '1F600';
|
||||||
@ -56,7 +55,7 @@ class SettingsUserView extends StatelessWidget {
|
|||||||
const VSpace(20),
|
const VSpace(20),
|
||||||
_renderCurrentOpenaiKey(context),
|
_renderCurrentOpenaiKey(context),
|
||||||
const VSpace(20),
|
const VSpace(20),
|
||||||
_renderHistoricalUser(context),
|
// _renderHistoricalUser(context),
|
||||||
_renderLoginOrLogoutButton(context, state),
|
_renderLoginOrLogoutButton(context, state),
|
||||||
const VSpace(20),
|
const VSpace(20),
|
||||||
],
|
],
|
||||||
@ -129,16 +128,6 @@ class SettingsUserView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderHistoricalUser(BuildContext context) {
|
|
||||||
return BlocBuilder<SettingsUserViewBloc, SettingsUserState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return HistoricalUserList(
|
|
||||||
didOpenUser: didOpenUser,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"loginTitle": "Login to @:appName",
|
"loginTitle": "Login to @:appName",
|
||||||
"loginButtonText": "Login",
|
"loginButtonText": "Login",
|
||||||
"loginAsGuestButtonText": "Get Started",
|
"loginAsGuestButtonText": "Get Started",
|
||||||
|
"continueAnonymousUser": "Continue in an anonymous session",
|
||||||
"buttonText": "Sign In",
|
"buttonText": "Sign In",
|
||||||
"forgotPassword": "Forgot Password?",
|
"forgotPassword": "Forgot Password?",
|
||||||
"emailHint": "Email",
|
"emailHint": "Email",
|
||||||
@ -227,9 +228,9 @@
|
|||||||
"logoutPrompt": "Are you sure to logout?",
|
"logoutPrompt": "Are you sure to logout?",
|
||||||
"syncSetting": "Sync Setting",
|
"syncSetting": "Sync Setting",
|
||||||
"enableSync": "Enable sync",
|
"enableSync": "Enable sync",
|
||||||
"historicalUserList": "User history",
|
"historicalUserList": "User login history",
|
||||||
"historicalUserListTooltip": "This list shows your login history. You can click to login if it's a local user",
|
"historicalUserListTooltip": "This list displays your anonymous accounts. You can click on an account to view its details. Anonymous accounts are created by clicking the 'Get Started' button",
|
||||||
"openHistoricalUser": "Click to open user"
|
"openHistoricalUser": "Click to open the anonymous account"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"fontFamily": {
|
"fontFamily": {
|
||||||
|
@ -616,6 +616,7 @@ impl UserSession {
|
|||||||
user_id: uid,
|
user_id: uid,
|
||||||
user_workspace,
|
user_workspace,
|
||||||
};
|
};
|
||||||
|
self.cloud_services.set_auth_type(AuthType::Local);
|
||||||
self.set_current_session(Some(session))?;
|
self.set_current_session(Some(session))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user