mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
migrate to flutter_bloc 8.0
This commit is contained in:
parent
96f6a1d37c
commit
b354fb79c8
@ -18,14 +18,17 @@ class AppWidgetTask extends LaunchTask {
|
|||||||
Future<void> initialize(LaunchContext context) {
|
Future<void> initialize(LaunchContext context) {
|
||||||
final widget = context.getIt<EntryPoint>().create();
|
final widget = context.getIt<EntryPoint>().create();
|
||||||
final app = ApplicationWidget(child: widget);
|
final app = ApplicationWidget(child: widget);
|
||||||
Bloc.observer = ApplicationBlocObserver();
|
BlocOverrides.runZoned(
|
||||||
|
() {
|
||||||
runApp(
|
runApp(
|
||||||
EasyLocalization(
|
EasyLocalization(
|
||||||
supportedLocales: const [Locale('en'), Locale('zh_CN'), Locale('it_IT')],
|
supportedLocales: const [Locale('en'), Locale('zh_CN'), Locale('it_IT')],
|
||||||
path: 'assets/translations',
|
path: 'assets/translations',
|
||||||
fallbackLocale: const Locale('en'),
|
fallbackLocale: const Locale('en'),
|
||||||
child: app),
|
child: app),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
blocObserver: ApplicationBlocObserver(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return Future(() => {});
|
return Future(() => {});
|
||||||
|
@ -9,35 +9,33 @@ part 'sign_in_bloc.freezed.dart';
|
|||||||
|
|
||||||
class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
||||||
final IAuth authManager;
|
final IAuth authManager;
|
||||||
SignInBloc(this.authManager) : super(SignInState.initial());
|
SignInBloc(this.authManager) : super(SignInState.initial()) {
|
||||||
|
on<SignInEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<SignInState> mapEventToState(
|
signedInWithUserEmailAndPassword: (e) async {
|
||||||
SignInEvent event,
|
await _performActionOnSignIn(
|
||||||
) async* {
|
state,
|
||||||
yield* event.map(
|
emit,
|
||||||
signedInWithUserEmailAndPassword: (e) async* {
|
);
|
||||||
yield* _performActionOnSignIn(
|
},
|
||||||
state,
|
emailChanged: (EmailChanged value) async {
|
||||||
);
|
emit(state.copyWith(email: value.email, emailError: none(), successOrFail: none()));
|
||||||
},
|
},
|
||||||
emailChanged: (EmailChanged value) async* {
|
passwordChanged: (PasswordChanged value) async {
|
||||||
yield state.copyWith(email: value.email, emailError: none(), successOrFail: none());
|
emit(state.copyWith(password: value.password, passwordError: none(), successOrFail: none()));
|
||||||
},
|
},
|
||||||
passwordChanged: (PasswordChanged value) async* {
|
);
|
||||||
yield state.copyWith(password: value.password, passwordError: none(), successOrFail: none());
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<SignInState> _performActionOnSignIn(SignInState state) async* {
|
Future<void> _performActionOnSignIn(SignInState state, Emitter<SignInState> emit) async {
|
||||||
yield state.copyWith(isSubmitting: true, emailError: none(), passwordError: none(), successOrFail: none());
|
emit(state.copyWith(isSubmitting: true, emailError: none(), passwordError: none(), successOrFail: none()));
|
||||||
|
|
||||||
final result = await authManager.signIn(state.email, state.password);
|
final result = await authManager.signIn(state.email, state.password);
|
||||||
yield result.fold(
|
emit(result.fold(
|
||||||
(userProfile) => state.copyWith(isSubmitting: false, successOrFail: some(left(userProfile))),
|
(userProfile) => state.copyWith(isSubmitting: false, successOrFail: some(left(userProfile))),
|
||||||
(error) => stateFromCode(error),
|
(error) => stateFromCode(error),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
SignInState stateFromCode(FlowyError error) {
|
SignInState stateFromCode(FlowyError error) {
|
||||||
|
@ -11,62 +11,59 @@ part 'sign_up_bloc.freezed.dart';
|
|||||||
|
|
||||||
class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
|
class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
|
||||||
final IAuth authManager;
|
final IAuth authManager;
|
||||||
SignUpBloc(this.authManager) : super(SignUpState.initial());
|
SignUpBloc(this.authManager) : super(SignUpState.initial()) {
|
||||||
|
on<SignUpEvent>((event, emit) async {
|
||||||
@override
|
await event.map(signUpWithUserEmailAndPassword: (e) async {
|
||||||
Stream<SignUpState> mapEventToState(
|
await _performActionOnSignUp(emit);
|
||||||
SignUpEvent event,
|
}, emailChanged: (EmailChanged value) async {
|
||||||
) async* {
|
emit(state.copyWith(email: value.email, emailError: none(), successOrFail: none()));
|
||||||
yield* event.map(signUpWithUserEmailAndPassword: (e) async* {
|
}, passwordChanged: (PasswordChanged value) async {
|
||||||
yield* _performActionOnSignUp();
|
emit(state.copyWith(password: value.password, passwordError: none(), successOrFail: none()));
|
||||||
}, emailChanged: (EmailChanged value) async* {
|
}, repeatPasswordChanged: (RepeatPasswordChanged value) async {
|
||||||
yield state.copyWith(email: value.email, emailError: none(), successOrFail: none());
|
emit(state.copyWith(repeatedPassword: value.password, repeatPasswordError: none(), successOrFail: none()));
|
||||||
}, passwordChanged: (PasswordChanged value) async* {
|
});
|
||||||
yield state.copyWith(password: value.password, passwordError: none(), successOrFail: none());
|
|
||||||
}, repeatPasswordChanged: (RepeatPasswordChanged value) async* {
|
|
||||||
yield state.copyWith(repeatedPassword: value.password, repeatPasswordError: none(), successOrFail: none());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<SignUpState> _performActionOnSignUp() async* {
|
Future<void> _performActionOnSignUp(Emitter<SignUpState> emit) async {
|
||||||
yield state.copyWith(
|
emit(state.copyWith(
|
||||||
isSubmitting: true,
|
isSubmitting: true,
|
||||||
successOrFail: none(),
|
successOrFail: none(),
|
||||||
);
|
));
|
||||||
|
|
||||||
final password = state.password;
|
final password = state.password;
|
||||||
final repeatedPassword = state.repeatedPassword;
|
final repeatedPassword = state.repeatedPassword;
|
||||||
if (password == null) {
|
if (password == null) {
|
||||||
yield state.copyWith(
|
emit(state.copyWith(
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
passwordError: some(LocaleKeys.signUp_emptyPasswordError.tr()),
|
passwordError: some(LocaleKeys.signUp_emptyPasswordError.tr()),
|
||||||
);
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repeatedPassword == null) {
|
if (repeatedPassword == null) {
|
||||||
yield state.copyWith(
|
emit(state.copyWith(
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
repeatPasswordError: some(LocaleKeys.signUp_repeatPasswordEmptyError.tr()),
|
repeatPasswordError: some(LocaleKeys.signUp_repeatPasswordEmptyError.tr()),
|
||||||
);
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password != repeatedPassword) {
|
if (password != repeatedPassword) {
|
||||||
yield state.copyWith(
|
emit(state.copyWith(
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
repeatPasswordError: some(LocaleKeys.signUp_unmatchedPasswordError.tr()),
|
repeatPasswordError: some(LocaleKeys.signUp_unmatchedPasswordError.tr()),
|
||||||
);
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield state.copyWith(
|
emit(state.copyWith(
|
||||||
passwordError: none(),
|
passwordError: none(),
|
||||||
repeatPasswordError: none(),
|
repeatPasswordError: none(),
|
||||||
);
|
));
|
||||||
|
|
||||||
final result = await authManager.signUp(state.email, state.password, state.email);
|
final result = await authManager.signUp(state.email, state.password, state.email);
|
||||||
yield result.fold(
|
emit(result.fold(
|
||||||
(profile) => state.copyWith(
|
(profile) => state.copyWith(
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
successOrFail: some(left(profile)),
|
successOrFail: some(left(profile)),
|
||||||
@ -75,7 +72,7 @@ class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
|
|||||||
repeatPasswordError: none(),
|
repeatPasswordError: none(),
|
||||||
),
|
),
|
||||||
(error) => stateFromCode(error),
|
(error) => stateFromCode(error),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
SignUpState stateFromCode(FlowyError error) {
|
SignUpState stateFromCode(FlowyError error) {
|
||||||
|
@ -7,16 +7,15 @@ part 'splash_bloc.freezed.dart';
|
|||||||
|
|
||||||
class SplashBloc extends Bloc<SplashEvent, SplashState> {
|
class SplashBloc extends Bloc<SplashEvent, SplashState> {
|
||||||
final ISplashUser authImpl;
|
final ISplashUser authImpl;
|
||||||
SplashBloc(this.authImpl) : super(SplashState.initial());
|
SplashBloc(this.authImpl) : super(SplashState.initial()) {
|
||||||
|
on<SplashEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<SplashState> mapEventToState(SplashEvent event) async* {
|
getUser: (val) async {
|
||||||
yield* event.map(
|
final authState = await authImpl.currentUserProfile();
|
||||||
getUser: (val) async* {
|
emit(state.copyWith(auth: authState));
|
||||||
final authState = await authImpl.currentUserProfile();
|
},
|
||||||
yield state.copyWith(auth: authState);
|
);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ class SplashUserImpl implements ISplashUser {
|
|||||||
(userProfile) {
|
(userProfile) {
|
||||||
return AuthState.authenticated(userProfile);
|
return AuthState.authenticated(userProfile);
|
||||||
},
|
},
|
||||||
(FlowyError) {
|
(error) {
|
||||||
return AuthState.unauthenticated(FlowyError);
|
return AuthState.unauthenticated(error);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -12,46 +12,43 @@ part 'app_bloc.freezed.dart';
|
|||||||
class AppBloc extends Bloc<AppEvent, AppState> {
|
class AppBloc extends Bloc<AppEvent, AppState> {
|
||||||
final IApp appManager;
|
final IApp appManager;
|
||||||
final IAppListenr listener;
|
final IAppListenr listener;
|
||||||
AppBloc({required App app, required this.appManager, required this.listener}) : super(AppState.initial(app));
|
AppBloc({required App app, required this.appManager, required this.listener}) : super(AppState.initial(app)) {
|
||||||
|
on<AppEvent>((event, emit) async {
|
||||||
@override
|
await event.map(initial: (e) async {
|
||||||
Stream<AppState> mapEventToState(
|
listener.start(
|
||||||
AppEvent event,
|
viewsChangeCallback: _handleViewsChanged,
|
||||||
) async* {
|
updatedCallback: (app) => add(AppEvent.appDidUpdate(app)),
|
||||||
yield* event.map(initial: (e) async* {
|
);
|
||||||
listener.start(
|
await _fetchViews(emit);
|
||||||
viewsChangeCallback: _handleViewsChanged,
|
}, createView: (CreateView value) async {
|
||||||
updatedCallback: (app) => add(AppEvent.appDidUpdate(app)),
|
final viewOrFailed = await appManager.createView(name: value.name, desc: value.desc, viewType: value.viewType);
|
||||||
);
|
viewOrFailed.fold(
|
||||||
yield* _fetchViews();
|
(view) => emit(state.copyWith(
|
||||||
}, createView: (CreateView value) async* {
|
latestCreatedView: view,
|
||||||
final viewOrFailed = await appManager.createView(name: value.name, desc: value.desc, viewType: value.viewType);
|
successOrFailure: left(unit),
|
||||||
yield viewOrFailed.fold(
|
)),
|
||||||
(view) => state.copyWith(
|
(error) {
|
||||||
latestCreatedView: view,
|
Log.error(error);
|
||||||
successOrFailure: left(unit),
|
emit(state.copyWith(successOrFailure: right(error)));
|
||||||
),
|
},
|
||||||
(error) {
|
);
|
||||||
Log.error(error);
|
}, didReceiveViews: (e) async {
|
||||||
return state.copyWith(successOrFailure: right(error));
|
await handleDidReceiveViews(e.views, emit);
|
||||||
},
|
}, delete: (e) async {
|
||||||
);
|
final result = await appManager.delete();
|
||||||
}, didReceiveViews: (e) async* {
|
result.fold(
|
||||||
yield* handleDidReceiveViews(e.views);
|
(unit) => emit(state.copyWith(successOrFailure: left(unit))),
|
||||||
}, delete: (e) async* {
|
(error) => emit(state.copyWith(successOrFailure: right(error))),
|
||||||
final result = await appManager.delete();
|
);
|
||||||
yield result.fold(
|
}, rename: (e) async {
|
||||||
(unit) => state.copyWith(successOrFailure: left(unit)),
|
final result = await appManager.rename(e.newName);
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
result.fold(
|
||||||
);
|
(l) => emit(state.copyWith(successOrFailure: left(unit))),
|
||||||
}, rename: (e) async* {
|
(error) => emit(state.copyWith(successOrFailure: right(error))),
|
||||||
final result = await appManager.rename(e.newName);
|
);
|
||||||
yield result.fold(
|
}, appDidUpdate: (e) async {
|
||||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
emit(state.copyWith(app: e.app));
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
});
|
||||||
);
|
|
||||||
}, appDidUpdate: (e) async* {
|
|
||||||
yield state.copyWith(app: e.app);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +67,7 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<AppState> handleDidReceiveViews(List<View> views) async* {
|
Future<void> handleDidReceiveViews(List<View> views, Emitter<AppState> emit) async {
|
||||||
final latestCreatedView = state.latestCreatedView;
|
final latestCreatedView = state.latestCreatedView;
|
||||||
AppState newState = state.copyWith(views: views);
|
AppState newState = state.copyWith(views: views);
|
||||||
if (latestCreatedView != null) {
|
if (latestCreatedView != null) {
|
||||||
@ -80,16 +77,16 @@ class AppBloc extends Bloc<AppEvent, AppState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield newState;
|
emit(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<AppState> _fetchViews() async* {
|
Future<void> _fetchViews(Emitter<AppState> emit) async {
|
||||||
final viewsOrFailed = await appManager.getViews();
|
final viewsOrFailed = await appManager.getViews();
|
||||||
yield viewsOrFailed.fold(
|
viewsOrFailed.fold(
|
||||||
(apps) => state.copyWith(views: apps),
|
(apps) => emit(state.copyWith(views: apps)),
|
||||||
(error) {
|
(error) {
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
return state.copyWith(successOrFailure: right(error));
|
emit(state.copyWith(successOrFailure: right(error)));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -27,31 +27,30 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
|||||||
required this.docManager,
|
required this.docManager,
|
||||||
required this.listener,
|
required this.listener,
|
||||||
required this.trasnManager,
|
required this.trasnManager,
|
||||||
}) : super(DocState.initial());
|
}) : super(DocState.initial()) {
|
||||||
|
on<DocEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<DocState> mapEventToState(DocEvent event) async* {
|
initial: (Initial value) async {
|
||||||
yield* event.map(
|
await _initial(value, emit);
|
||||||
initial: _initial,
|
},
|
||||||
deleted: (Deleted value) async* {
|
deleted: (Deleted value) async {
|
||||||
yield state.copyWith(isDeleted: true);
|
emit(state.copyWith(isDeleted: true));
|
||||||
},
|
},
|
||||||
restore: (Restore value) async* {
|
restore: (Restore value) async {
|
||||||
yield state.copyWith(isDeleted: false);
|
emit(state.copyWith(isDeleted: false));
|
||||||
},
|
},
|
||||||
deletePermanently: (DeletePermanently value) async* {
|
deletePermanently: (DeletePermanently value) async {
|
||||||
final result = await trasnManager.deleteViews([Tuple2(view.id, TrashType.View)]);
|
final result = await trasnManager.deleteViews([Tuple2(view.id, TrashType.View)]);
|
||||||
yield result.fold((l) => state.copyWith(forceClose: true), (r) {
|
final newState = result.fold((l) => state.copyWith(forceClose: true), (r) => state);
|
||||||
return state;
|
emit(newState);
|
||||||
});
|
},
|
||||||
},
|
restorePage: (RestorePage value) async {
|
||||||
restorePage: (RestorePage value) async* {
|
final result = await trasnManager.putback(view.id);
|
||||||
final result = await trasnManager.putback(view.id);
|
final newState = result.fold((l) => state.copyWith(isDeleted: false), (r) => state);
|
||||||
yield result.fold((l) => state.copyWith(isDeleted: false), (r) {
|
emit(newState);
|
||||||
return state;
|
},
|
||||||
});
|
);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -62,11 +61,11 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
|||||||
await _subscription?.cancel();
|
await _subscription?.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// docManager.closeDoc();
|
docManager.closeDoc();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<DocState> _initial(Initial value) async* {
|
Future<void> _initial(Initial value, Emitter<DocState> emit) async {
|
||||||
listener.deletedNotifier.addPublishListener((result) {
|
listener.deletedNotifier.addPublishListener((result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(view) => add(const DocEvent.deleted()),
|
(view) => add(const DocEvent.deleted()),
|
||||||
@ -82,9 +81,8 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
listener.start();
|
listener.start();
|
||||||
|
|
||||||
final result = await docManager.readDoc();
|
final result = await docManager.readDoc();
|
||||||
yield result.fold(
|
result.fold(
|
||||||
(doc) {
|
(doc) {
|
||||||
document = _decodeJsonToDocument(doc.deltaJson);
|
document = _decodeJsonToDocument(doc.deltaJson);
|
||||||
_subscription = document.changes.listen((event) {
|
_subscription = document.changes.listen((event) {
|
||||||
@ -92,10 +90,10 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
|||||||
final documentDelta = document.toDelta();
|
final documentDelta = document.toDelta();
|
||||||
_composeDelta(delta, documentDelta);
|
_composeDelta(delta, documentDelta);
|
||||||
});
|
});
|
||||||
return state.copyWith(loadState: DocLoadState.finish(left(unit)));
|
emit(state.copyWith(loadState: DocLoadState.finish(left(unit))));
|
||||||
},
|
},
|
||||||
(err) {
|
(err) {
|
||||||
return state.copyWith(loadState: DocLoadState.finish(right(err)));
|
emit(state.copyWith(loadState: DocLoadState.finish(right(err))));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,20 +7,17 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
part 'edit_pannel_bloc.freezed.dart';
|
part 'edit_pannel_bloc.freezed.dart';
|
||||||
|
|
||||||
class EditPannelBloc extends Bloc<EditPannelEvent, EditPannelState> {
|
class EditPannelBloc extends Bloc<EditPannelEvent, EditPannelState> {
|
||||||
EditPannelBloc() : super(EditPannelState.initial());
|
EditPannelBloc() : super(EditPannelState.initial()) {
|
||||||
|
on<EditPannelEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<EditPannelState> mapEventToState(
|
startEdit: (e) async {
|
||||||
EditPannelEvent event,
|
emit(state.copyWith(isEditing: true, editContext: some(e.context)));
|
||||||
) async* {
|
},
|
||||||
yield* event.map(
|
endEdit: (value) async {
|
||||||
startEdit: (e) async* {
|
emit(state.copyWith(isEditing: false, editContext: none()));
|
||||||
yield state.copyWith(isEditing: true, editContext: some(e.context));
|
},
|
||||||
},
|
);
|
||||||
endEdit: (value) async* {
|
});
|
||||||
yield state.copyWith(isEditing: false, editContext: none());
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,26 +5,23 @@ import 'package:dartz/dartz.dart';
|
|||||||
part 'home_bloc.freezed.dart';
|
part 'home_bloc.freezed.dart';
|
||||||
|
|
||||||
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
||||||
HomeBloc() : super(HomeState.initial());
|
HomeBloc() : super(HomeState.initial()) {
|
||||||
|
on<HomeEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<HomeState> mapEventToState(
|
showLoading: (e) async {
|
||||||
HomeEvent event,
|
emit(state.copyWith(isLoading: e.isLoading));
|
||||||
) async* {
|
},
|
||||||
yield* event.map(
|
setEditPannel: (e) async {
|
||||||
showLoading: (e) async* {
|
emit(state.copyWith(editContext: some(e.editContext)));
|
||||||
yield state.copyWith(isLoading: e.isLoading);
|
},
|
||||||
},
|
dismissEditPannel: (value) async {
|
||||||
setEditPannel: (e) async* {
|
emit(state.copyWith(editContext: none()));
|
||||||
yield state.copyWith(editContext: some(e.editContext));
|
},
|
||||||
},
|
forceCollapse: (e) async {
|
||||||
dismissEditPannel: (value) async* {
|
emit(state.copyWith(forceCollapse: e.forceCollapse));
|
||||||
yield state.copyWith(editContext: none());
|
},
|
||||||
},
|
);
|
||||||
forceCollapse: (e) async* {
|
});
|
||||||
yield state.copyWith(forceCollapse: e.forceCollapse);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -37,8 +34,7 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
class HomeEvent with _$HomeEvent {
|
class HomeEvent with _$HomeEvent {
|
||||||
const factory HomeEvent.showLoading(bool isLoading) = _ShowLoading;
|
const factory HomeEvent.showLoading(bool isLoading) = _ShowLoading;
|
||||||
const factory HomeEvent.forceCollapse(bool forceCollapse) = _ForceCollapse;
|
const factory HomeEvent.forceCollapse(bool forceCollapse) = _ForceCollapse;
|
||||||
const factory HomeEvent.setEditPannel(EditPannelContext editContext) =
|
const factory HomeEvent.setEditPannel(EditPannelContext editContext) = _ShowEditPannel;
|
||||||
_ShowEditPannel;
|
|
||||||
const factory HomeEvent.dismissEditPannel() = _DismissEditPannel;
|
const factory HomeEvent.dismissEditPannel() = _DismissEditPannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,22 +8,21 @@ part 'home_listen_bloc.freezed.dart';
|
|||||||
|
|
||||||
class HomeListenBloc extends Bloc<HomeListenEvent, HomeListenState> {
|
class HomeListenBloc extends Bloc<HomeListenEvent, HomeListenState> {
|
||||||
final IUserListener listener;
|
final IUserListener listener;
|
||||||
HomeListenBloc(this.listener) : super(const HomeListenState.loading());
|
HomeListenBloc(this.listener) : super(const HomeListenState.loading()) {
|
||||||
|
on<HomeListenEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<HomeListenState> mapEventToState(
|
started: (_) async {
|
||||||
HomeListenEvent event,
|
listener.authDidChangedNotifier.addPublishListener((result) {
|
||||||
) async* {
|
_authDidChanged(result);
|
||||||
yield* event.map(
|
});
|
||||||
started: (_) async* {
|
listener.start();
|
||||||
listener.authDidChangedNotifier.addPublishListener(_authDidChanged);
|
},
|
||||||
listener.start();
|
stop: (_) async {},
|
||||||
},
|
unauthorized: (e) async {
|
||||||
stop: (_) async* {},
|
emit(HomeListenState.unauthorized(e.msg));
|
||||||
unauthorized: (e) async* {
|
},
|
||||||
yield HomeListenState.unauthorized(e.msg);
|
);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -14,34 +14,31 @@ part 'menu_bloc.freezed.dart';
|
|||||||
class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
||||||
final IWorkspace workspaceManager;
|
final IWorkspace workspaceManager;
|
||||||
final IWorkspaceListener listener;
|
final IWorkspaceListener listener;
|
||||||
MenuBloc({required this.workspaceManager, required this.listener}) : super(MenuState.initial());
|
MenuBloc({required this.workspaceManager, required this.listener}) : super(MenuState.initial()) {
|
||||||
|
on<MenuEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<MenuState> mapEventToState(
|
initial: (e) async {
|
||||||
MenuEvent event,
|
listener.start(addAppCallback: _handleAppsOrFail);
|
||||||
) async* {
|
await _fetchApps(emit);
|
||||||
yield* event.map(
|
},
|
||||||
initial: (e) async* {
|
collapse: (e) async {
|
||||||
listener.start(addAppCallback: _handleAppsOrFail);
|
final isCollapse = state.isCollapse;
|
||||||
yield* _fetchApps();
|
emit(state.copyWith(isCollapse: !isCollapse));
|
||||||
},
|
},
|
||||||
collapse: (e) async* {
|
openPage: (e) async {
|
||||||
final isCollapse = state.isCollapse;
|
emit(state.copyWith(stackContext: e.context));
|
||||||
yield state.copyWith(isCollapse: !isCollapse);
|
},
|
||||||
},
|
createApp: (CreateApp event) async {
|
||||||
openPage: (e) async* {
|
await _performActionOnCreateApp(event, emit);
|
||||||
yield* _performActionOnOpenPage(e);
|
},
|
||||||
},
|
didReceiveApps: (e) async {
|
||||||
createApp: (CreateApp event) async* {
|
emit(e.appsOrFail.fold(
|
||||||
yield* _performActionOnCreateApp(event);
|
(apps) => state.copyWith(apps: some(apps), successOrFailure: left(unit)),
|
||||||
},
|
(err) => state.copyWith(successOrFailure: right(err)),
|
||||||
didReceiveApps: (e) async* {
|
));
|
||||||
yield e.appsOrFail.fold(
|
},
|
||||||
(apps) => state.copyWith(apps: some(apps), successOrFailure: left(unit)),
|
);
|
||||||
(err) => state.copyWith(successOrFailure: right(err)),
|
});
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -50,31 +47,27 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
|||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<MenuState> _performActionOnOpenPage(OpenPage e) async* {
|
Future<void> _performActionOnCreateApp(CreateApp event, Emitter<MenuState> emit) async {
|
||||||
yield state.copyWith(stackContext: e.context);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* {
|
|
||||||
final result = await workspaceManager.createApp(name: event.name, desc: event.desc);
|
final result = await workspaceManager.createApp(name: event.name, desc: event.desc);
|
||||||
yield result.fold(
|
emit(result.fold(
|
||||||
(app) => state.copyWith(apps: some([app])),
|
(app) => state.copyWith(apps: some([app])),
|
||||||
(error) {
|
(error) {
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
return state.copyWith(successOrFailure: right(error));
|
return state.copyWith(successOrFailure: right(error));
|
||||||
},
|
},
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Stream<MenuState> _fetchApps() async* {
|
Future<void> _fetchApps(Emitter<MenuState> emit) async {
|
||||||
final appsOrFail = await workspaceManager.getApps();
|
final appsOrFail = await workspaceManager.getApps();
|
||||||
yield appsOrFail.fold(
|
emit(appsOrFail.fold(
|
||||||
(apps) => state.copyWith(apps: some(apps)),
|
(apps) => state.copyWith(apps: some(apps)),
|
||||||
(error) {
|
(error) {
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
return state.copyWith(successOrFailure: right(error));
|
return state.copyWith(successOrFailure: right(error));
|
||||||
},
|
},
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleAppsOrFail(Either<List<App>, FlowyError> appsOrFail) {
|
void _handleAppsOrFail(Either<List<App>, FlowyError> appsOrFail) {
|
||||||
|
@ -12,20 +12,18 @@ class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
|
|||||||
final IUser userManager;
|
final IUser userManager;
|
||||||
final IUserListener listener;
|
final IUserListener listener;
|
||||||
|
|
||||||
MenuUserBloc(this.userManager, this.listener) : super(MenuUserState.initial(userManager.user));
|
MenuUserBloc(this.userManager, this.listener) : super(MenuUserState.initial(userManager.user)) {
|
||||||
|
on<MenuUserEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<MenuUserState> mapEventToState(MenuUserEvent event) async* {
|
initial: (_) async {
|
||||||
yield* event.map(
|
listener.profileUpdatedNotifier.addPublishListener(_profileUpdated);
|
||||||
initial: (_) async* {
|
listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
|
||||||
listener.profileUpdatedNotifier.addPublishListener(_profileUpdated);
|
listener.start();
|
||||||
listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
|
await _initUser();
|
||||||
listener.start();
|
},
|
||||||
|
fetchWorkspaces: (_FetchWorkspaces value) async {},
|
||||||
await _initUser();
|
);
|
||||||
},
|
});
|
||||||
fetchWorkspaces: (_FetchWorkspaces value) async* {},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -10,46 +10,38 @@ part 'trash_bloc.freezed.dart';
|
|||||||
class TrashBloc extends Bloc<TrashEvent, TrashState> {
|
class TrashBloc extends Bloc<TrashEvent, TrashState> {
|
||||||
final ITrash trasnManager;
|
final ITrash trasnManager;
|
||||||
final ITrashListener listener;
|
final ITrashListener listener;
|
||||||
TrashBloc({required this.trasnManager, required this.listener}) : super(TrashState.init());
|
TrashBloc({required this.trasnManager, required this.listener}) : super(TrashState.init()) {
|
||||||
|
on<TrashEvent>((event, emit) async {
|
||||||
@override
|
await event.map(initial: (e) async {
|
||||||
Stream<TrashState> mapEventToState(TrashEvent event) async* {
|
|
||||||
yield* event.map(
|
|
||||||
initial: (e) async* {
|
|
||||||
listener.start(_listenTrashUpdated);
|
listener.start(_listenTrashUpdated);
|
||||||
final result = await trasnManager.readTrash();
|
final result = await trasnManager.readTrash();
|
||||||
yield result.fold(
|
emit(result.fold(
|
||||||
(objects) => state.copyWith(objects: objects, successOrFailure: left(unit)),
|
(objects) => state.copyWith(objects: objects, successOrFailure: left(unit)),
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
(error) => state.copyWith(successOrFailure: right(error)),
|
||||||
);
|
));
|
||||||
},
|
}, didReceiveTrash: (e) async {
|
||||||
didReceiveTrash: (e) async* {
|
emit(state.copyWith(objects: e.trash));
|
||||||
yield state.copyWith(objects: e.trash);
|
}, putback: (e) async {
|
||||||
},
|
|
||||||
putback: (e) async* {
|
|
||||||
final result = await trasnManager.putback(e.trashId);
|
final result = await trasnManager.putback(e.trashId);
|
||||||
yield* _handleResult(result);
|
await _handleResult(result, emit);
|
||||||
},
|
}, delete: (e) async {
|
||||||
delete: (e) async* {
|
|
||||||
final result = await trasnManager.deleteViews([Tuple2(e.trash.id, e.trash.ty)]);
|
final result = await trasnManager.deleteViews([Tuple2(e.trash.id, e.trash.ty)]);
|
||||||
yield* _handleResult(result);
|
await _handleResult(result, emit);
|
||||||
},
|
}, deleteAll: (e) async {
|
||||||
deleteAll: (e) async* {
|
|
||||||
final result = await trasnManager.deleteAll();
|
final result = await trasnManager.deleteAll();
|
||||||
yield* _handleResult(result);
|
await _handleResult(result, emit);
|
||||||
},
|
}, restoreAll: (e) async {
|
||||||
restoreAll: (e) async* {
|
|
||||||
final result = await trasnManager.restoreAll();
|
final result = await trasnManager.restoreAll();
|
||||||
yield* _handleResult(result);
|
await _handleResult(result, emit);
|
||||||
},
|
});
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<TrashState> _handleResult(Either<dynamic, FlowyError> result) async* {
|
Future<void> _handleResult(Either<dynamic, FlowyError> result, Emitter<TrashState> emit) async {
|
||||||
yield result.fold(
|
emit(result.fold(
|
||||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
(error) => state.copyWith(successOrFailure: right(error)),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenTrashUpdated(Either<List<Trash>, FlowyError> trashOrFailed) {
|
void _listenTrashUpdated(Either<List<Trash>, FlowyError> trashOrFailed) {
|
||||||
|
@ -14,53 +14,56 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
|
|||||||
ViewBloc({
|
ViewBloc({
|
||||||
required this.viewManager,
|
required this.viewManager,
|
||||||
required this.listener,
|
required this.listener,
|
||||||
}) : super(ViewState.init(viewManager.view));
|
}) : super(ViewState.init(viewManager.view)) {
|
||||||
|
on<ViewEvent>((event, emit) async {
|
||||||
@override
|
await event.map(
|
||||||
Stream<ViewState> mapEventToState(ViewEvent event) async* {
|
initial: (e) {
|
||||||
yield* event.map(
|
// TODO: Listener can be refctored to a stream.
|
||||||
initial: (e) async* {
|
listener.updatedNotifier.addPublishListener((result) {
|
||||||
listener.updatedNotifier.addPublishListener((result) {
|
// emit.forEach(stream, onData: onData)
|
||||||
add(ViewEvent.viewDidUpdate(result));
|
add(ViewEvent.viewDidUpdate(result));
|
||||||
});
|
});
|
||||||
listener.start();
|
listener.start();
|
||||||
yield state;
|
emit(state);
|
||||||
},
|
},
|
||||||
setIsEditing: (e) async* {
|
setIsEditing: (e) {
|
||||||
yield state.copyWith(isEditing: e.isEditing);
|
emit(state.copyWith(isEditing: e.isEditing));
|
||||||
},
|
},
|
||||||
viewDidUpdate: (e) async* {
|
viewDidUpdate: (e) {
|
||||||
yield* _handleViewDidUpdate(e.result);
|
e.result.fold(
|
||||||
},
|
(view) => emit(state.copyWith(view: view, successOrFailure: left(unit))),
|
||||||
rename: (e) async* {
|
(error) => emit(state.copyWith(successOrFailure: right(error))),
|
||||||
final result = await viewManager.rename(e.newName);
|
);
|
||||||
yield result.fold(
|
},
|
||||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
rename: (e) async {
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
final result = await viewManager.rename(e.newName);
|
||||||
);
|
emit(
|
||||||
},
|
result.fold(
|
||||||
delete: (e) async* {
|
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||||
final result = await viewManager.delete();
|
(error) => state.copyWith(successOrFailure: right(error)),
|
||||||
yield result.fold(
|
),
|
||||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
);
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
},
|
||||||
);
|
delete: (e) async {
|
||||||
},
|
final result = await viewManager.delete();
|
||||||
duplicate: (e) async* {
|
emit(
|
||||||
final result = await viewManager.duplicate();
|
result.fold(
|
||||||
yield result.fold(
|
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||||
(l) => state.copyWith(successOrFailure: left(unit)),
|
(error) => state.copyWith(successOrFailure: right(error)),
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
duplicate: (e) async {
|
||||||
}
|
final result = await viewManager.duplicate();
|
||||||
|
emit(
|
||||||
Stream<ViewState> _handleViewDidUpdate(Either<View, FlowyError> result) async* {
|
result.fold(
|
||||||
yield result.fold(
|
(l) => state.copyWith(successOrFailure: left(unit)),
|
||||||
(view) => state.copyWith(view: view, successOrFailure: left(unit)),
|
(error) => state.copyWith(successOrFailure: right(error)),
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -12,27 +12,26 @@ part 'welcome_bloc.freezed.dart';
|
|||||||
class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
||||||
final UserRepo repo;
|
final UserRepo repo;
|
||||||
final IUserListener listener;
|
final IUserListener listener;
|
||||||
WelcomeBloc({required this.repo, required this.listener}) : super(WelcomeState.initial());
|
WelcomeBloc({required this.repo, required this.listener}) : super(WelcomeState.initial()) {
|
||||||
|
on<WelcomeEvent>(
|
||||||
@override
|
(event, emit) async {
|
||||||
Stream<WelcomeState> mapEventToState(
|
await event.map(initial: (e) async {
|
||||||
WelcomeEvent event,
|
listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
|
||||||
) async* {
|
listener.start();
|
||||||
yield* event.map(initial: (e) async* {
|
//
|
||||||
listener.workspaceUpdatedNotifier.addPublishListener(_workspacesUpdated);
|
await _fetchWorkspaces(emit);
|
||||||
listener.start();
|
}, openWorkspace: (e) async {
|
||||||
//
|
await _openWorkspace(e.workspace, emit);
|
||||||
yield* _fetchWorkspaces();
|
}, createWorkspace: (e) async {
|
||||||
}, openWorkspace: (e) async* {
|
await _createWorkspace(e.name, e.desc, emit);
|
||||||
yield* _openWorkspace(e.workspace);
|
}, workspacesReveived: (e) async {
|
||||||
}, createWorkspace: (e) async* {
|
emit(e.workspacesOrFail.fold(
|
||||||
yield* _createWorkspace(e.name, e.desc);
|
(workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
|
||||||
}, workspacesReveived: (e) async* {
|
(error) => state.copyWith(successOrFailure: right(error)),
|
||||||
yield e.workspacesOrFail.fold(
|
));
|
||||||
(workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
|
});
|
||||||
(error) => state.copyWith(successOrFailure: right(error)),
|
},
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -41,31 +40,31 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
|||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<WelcomeState> _fetchWorkspaces() async* {
|
Future<void> _fetchWorkspaces(Emitter<WelcomeState> emit) async {
|
||||||
final workspacesOrFailed = await repo.getWorkspaces();
|
final workspacesOrFailed = await repo.getWorkspaces();
|
||||||
yield workspacesOrFailed.fold(
|
emit(workspacesOrFailed.fold(
|
||||||
(workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
|
(workspaces) => state.copyWith(workspaces: workspaces, successOrFailure: left(unit)),
|
||||||
(error) {
|
(error) {
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
return state.copyWith(successOrFailure: right(error));
|
return state.copyWith(successOrFailure: right(error));
|
||||||
},
|
},
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<WelcomeState> _openWorkspace(Workspace workspace) async* {
|
Future<void> _openWorkspace(Workspace workspace, Emitter<WelcomeState> emit) async {
|
||||||
final result = await repo.openWorkspace(workspace.id);
|
final result = await repo.openWorkspace(workspace.id);
|
||||||
yield result.fold(
|
emit(result.fold(
|
||||||
(workspaces) => state.copyWith(successOrFailure: left(unit)),
|
(workspaces) => state.copyWith(successOrFailure: left(unit)),
|
||||||
(error) {
|
(error) {
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
return state.copyWith(successOrFailure: right(error));
|
return state.copyWith(successOrFailure: right(error));
|
||||||
},
|
},
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<WelcomeState> _createWorkspace(String name, String desc) async* {
|
Future<void> _createWorkspace(String name, String desc, Emitter<WelcomeState> emit) async {
|
||||||
final result = await repo.createWorkspace(name, desc);
|
final result = await repo.createWorkspace(name, desc);
|
||||||
yield result.fold(
|
emit(result.fold(
|
||||||
(workspace) {
|
(workspace) {
|
||||||
return state.copyWith(successOrFailure: left(unit));
|
return state.copyWith(successOrFailure: left(unit));
|
||||||
},
|
},
|
||||||
@ -73,7 +72,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
|||||||
Log.error(error);
|
Log.error(error);
|
||||||
return state.copyWith(successOrFailure: right(error));
|
return state.copyWith(successOrFailure: right(error));
|
||||||
},
|
},
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _workspacesUpdated(Either<List<Workspace>, FlowyError> workspacesOrFail) {
|
void _workspacesUpdated(Either<List<Workspace>, FlowyError> workspacesOrFail) {
|
||||||
|
@ -42,7 +42,7 @@ packages:
|
|||||||
name: bloc
|
name: bloc
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.1"
|
version: "8.0.2"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -418,7 +418,7 @@ packages:
|
|||||||
name: flutter_bloc
|
name: flutter_bloc
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.3.3"
|
version: "8.0.0"
|
||||||
flutter_colorpicker:
|
flutter_colorpicker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -50,7 +50,7 @@ dependencies:
|
|||||||
equatable: '^2.0.3'
|
equatable: '^2.0.3'
|
||||||
freezed_annotation:
|
freezed_annotation:
|
||||||
get_it: '^7.1.3'
|
get_it: '^7.1.3'
|
||||||
flutter_bloc: '^7.3.1'
|
flutter_bloc: '8.0.0'
|
||||||
provider: ^6.0.1
|
provider: ^6.0.1
|
||||||
path_provider: ^2.0.1
|
path_provider: ^2.0.1
|
||||||
window_size:
|
window_size:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user