mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
merge master
This commit is contained in:
commit
cc17529977
Makefile.tomlpubspec.lockpubspec.yamlpubspec.lock
app_flowy
.vscode
analysis_options.yamlassets/images
lib
startup
user
application
domain
infrastructure
presentation/sign_in
welcome
workspace
application
doc
menu
domain
infrastructure
presentation
macos
packages
flowy_editor/lib/src
flowy_infra/lib
flowy_infra_ui
example
lib
style_widget
styled_hover.dartstyled_icon_button.dartstyled_navigation_list.dartstyled_progress_indicator.dartstyled_text.dartstyled_text_button.dart
widget
flowy_sdk/lib
rust-lib
dart-ffi/src
flowy-derive/src/derive_cache
flowy-dispatch/src
flowy-editor/src
@ -10,7 +10,7 @@ CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
|||||||
DEV = true
|
DEV = true
|
||||||
LIB_OUT_DIR = "debug"
|
LIB_OUT_DIR = "debug"
|
||||||
RELEASE = false
|
RELEASE = false
|
||||||
TARGET_OS = "unknown"
|
#TARGET_OS = "unknown"
|
||||||
|
|
||||||
[tasks.setup-crate-type]
|
[tasks.setup-crate-type]
|
||||||
private = true
|
private = true
|
||||||
|
3
app_flowy/.vscode/launch.json
vendored
3
app_flowy/.vscode/launch.json
vendored
@ -9,7 +9,8 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/lib/main.dart",
|
"program": "${workspaceRoot}/lib/main.dart",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
// "preLaunchTask": "build rust sdk"
|
"preLaunchTask": "build_flowy_sdk",
|
||||||
|
"cwd": "${workspaceRoot}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "app_flowy (profile mode)",
|
"name": "app_flowy (profile mode)",
|
||||||
|
21
app_flowy/.vscode/tasks.json
vendored
21
app_flowy/.vscode/tasks.json
vendored
@ -1,7 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
// https://code.visualstudio.com/docs/editor/tasks
|
// https://code.visualstudio.com/docs/editor/tasks
|
||||||
//https://gist.github.com/deadalusai/9e13e36d61ec7fb72148
|
//https://gist.github.com/deadalusai/9e13e36d61ec7fb72148
|
||||||
|
|
||||||
@ -11,9 +9,22 @@
|
|||||||
// ${fileDirname}: the current opened file's dirname
|
// ${fileDirname}: the current opened file's dirname
|
||||||
// ${fileExtname}: the current opened file's extension
|
// ${fileExtname}: the current opened file's extension
|
||||||
// ${cwd}: the current working directory of the spawned process
|
// ${cwd}: the current working directory of the spawned process
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "sh ${workspaceFolder}/../scripts/build_sdk.sh",
|
"command": "sh ./scripts/build_sdk.sh",
|
||||||
|
"group": "build",
|
||||||
|
"options": {
|
||||||
|
"cwd": "${workspaceFolder}/../"
|
||||||
|
},
|
||||||
|
// "problemMatcher": [
|
||||||
|
// "$rustc"
|
||||||
|
// ],
|
||||||
|
"label": "build_flowy_sdk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"command": "sh ./scripts/code_gen.sh",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"options": {
|
"options": {
|
||||||
"cwd": "${workspaceFolder}/../"
|
"cwd": "${workspaceFolder}/../"
|
||||||
@ -21,7 +32,7 @@
|
|||||||
"problemMatcher": [
|
"problemMatcher": [
|
||||||
"$rustc"
|
"$rustc"
|
||||||
],
|
],
|
||||||
"label": "build rust sdk"
|
"label": "generate events"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ analyzer:
|
|||||||
- "**/*.g.dart"
|
- "**/*.g.dart"
|
||||||
- "**/*.freezed.dart"
|
- "**/*.freezed.dart"
|
||||||
- "packages/flowy_editor/**"
|
- "packages/flowy_editor/**"
|
||||||
- "packages/flowy_infra_ui/**"
|
# - "packages/flowy_infra_ui/**"
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
# The lint rules applied to this project can be customized in the
|
# The lint rules applied to this project can be customized in the
|
||||||
|
BIN
app_flowy/assets/images/app_flowy_logo.jpg
Normal file
BIN
app_flowy/assets/images/app_flowy_logo.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 30 KiB |
BIN
app_flowy/assets/images/avatar.jpg
Normal file
BIN
app_flowy/assets/images/avatar.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 7.6 KiB |
BIN
app_flowy/assets/images/file_icon.jpg
Normal file
BIN
app_flowy/assets/images/file_icon.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 18 KiB |
@ -15,7 +15,7 @@ Future<void> initGetIt(
|
|||||||
getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK());
|
getIt.registerLazySingleton<FlowySDK>(() => const FlowySDK());
|
||||||
getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt));
|
getIt.registerLazySingleton<AppLauncher>(() => AppLauncher(env, getIt));
|
||||||
|
|
||||||
await WelcomeDepsResolver.resolve(getIt);
|
|
||||||
await UserDepsResolver.resolve(getIt);
|
await UserDepsResolver.resolve(getIt);
|
||||||
|
await WelcomeDepsResolver.resolve(getIt);
|
||||||
await HomeDepsResolver.resolve(getIt);
|
await HomeDepsResolver.resolve(getIt);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class ApplicationBlocObserver extends BlocObserver {
|
|||||||
@override
|
@override
|
||||||
// ignore: unnecessary_overrides
|
// ignore: unnecessary_overrides
|
||||||
void onTransition(Bloc bloc, Transition transition) {
|
void onTransition(Bloc bloc, Transition transition) {
|
||||||
// Log.debug(transition);
|
Log.debug(transition);
|
||||||
super.onTransition(bloc, transition);
|
super.onTransition(bloc, transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,9 +50,3 @@ class ApplicationBlocObserver extends BlocObserver {
|
|||||||
super.onError(bloc, error, stackTrace);
|
super.onError(bloc, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EngineBlocConfig {
|
|
||||||
static void setup() {
|
|
||||||
Bloc.observer = ApplicationBlocObserver();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -22,10 +22,10 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
emailChanged: (EmailChanged value) async* {
|
emailChanged: (EmailChanged value) async* {
|
||||||
yield state.copyWith(email: value.email, signInFailure: none());
|
yield state.copyWith(email: value.email, successOrFail: none());
|
||||||
},
|
},
|
||||||
passwordChanged: (PasswordChanged value) async* {
|
passwordChanged: (PasswordChanged value) async* {
|
||||||
yield state.copyWith(password: value.password, signInFailure: none());
|
yield state.copyWith(password: value.password, successOrFail: none());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -36,17 +36,34 @@ class SignInBloc extends Bloc<SignInEvent, SignInState> {
|
|||||||
final result = await authImpl.signIn(state.email, state.password);
|
final result = await authImpl.signIn(state.email, state.password);
|
||||||
yield result.fold(
|
yield result.fold(
|
||||||
(userDetail) => state.copyWith(
|
(userDetail) => state.copyWith(
|
||||||
isSubmitting: false, signInFailure: some(left(userDetail))),
|
isSubmitting: false, successOrFail: some(left(userDetail))),
|
||||||
(s) => state.copyWith(isSubmitting: false, signInFailure: some(right(s))),
|
(error) => stateFromCode(error),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SignInState stateFromCode(UserError error) {
|
||||||
|
switch (error.code) {
|
||||||
|
case UserErrCode.EmailInvalid:
|
||||||
|
return state.copyWith(
|
||||||
|
isSubmitting: false,
|
||||||
|
emailError: some(error.msg),
|
||||||
|
passwordError: none());
|
||||||
|
case UserErrCode.PasswordInvalid:
|
||||||
|
return state.copyWith(
|
||||||
|
isSubmitting: false,
|
||||||
|
passwordError: some(error.msg),
|
||||||
|
emailError: none());
|
||||||
|
default:
|
||||||
|
return state.copyWith(
|
||||||
|
isSubmitting: false, successOrFail: some(right(error)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
abstract class SignInEvent with _$SignInEvent {
|
abstract class SignInEvent with _$SignInEvent {
|
||||||
const factory SignInEvent.signedInWithUserEmailAndPassword() =
|
const factory SignInEvent.signedInWithUserEmailAndPassword() =
|
||||||
SignedInWithUserEmailAndPassword;
|
SignedInWithUserEmailAndPassword;
|
||||||
|
|
||||||
const factory SignInEvent.emailChanged(String email) = EmailChanged;
|
const factory SignInEvent.emailChanged(String email) = EmailChanged;
|
||||||
const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
|
const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
|
||||||
}
|
}
|
||||||
@ -57,11 +74,15 @@ abstract class SignInState with _$SignInState {
|
|||||||
String? email,
|
String? email,
|
||||||
String? password,
|
String? password,
|
||||||
required bool isSubmitting,
|
required bool isSubmitting,
|
||||||
required Option<Either<UserDetail, UserError>> signInFailure,
|
required Option<String> passwordError,
|
||||||
|
required Option<String> emailError,
|
||||||
|
required Option<Either<UserDetail, UserError>> successOrFail,
|
||||||
}) = _SignInState;
|
}) = _SignInState;
|
||||||
|
|
||||||
factory SignInState.initial() => SignInState(
|
factory SignInState.initial() => SignInState(
|
||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
signInFailure: none(),
|
passwordError: none(),
|
||||||
|
emailError: none(),
|
||||||
|
successOrFail: none(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -438,12 +438,16 @@ class _$SignInStateTearOff {
|
|||||||
{String? email,
|
{String? email,
|
||||||
String? password,
|
String? password,
|
||||||
required bool isSubmitting,
|
required bool isSubmitting,
|
||||||
required Option<Either<UserDetail, UserError>> signInFailure}) {
|
required Option<String> passwordError,
|
||||||
|
required Option<String> emailError,
|
||||||
|
required Option<Either<UserDetail, UserError>> successOrFail}) {
|
||||||
return _SignInState(
|
return _SignInState(
|
||||||
email: email,
|
email: email,
|
||||||
password: password,
|
password: password,
|
||||||
isSubmitting: isSubmitting,
|
isSubmitting: isSubmitting,
|
||||||
signInFailure: signInFailure,
|
passwordError: passwordError,
|
||||||
|
emailError: emailError,
|
||||||
|
successOrFail: successOrFail,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,7 +460,9 @@ mixin _$SignInState {
|
|||||||
String? get email => throw _privateConstructorUsedError;
|
String? get email => throw _privateConstructorUsedError;
|
||||||
String? get password => throw _privateConstructorUsedError;
|
String? get password => throw _privateConstructorUsedError;
|
||||||
bool get isSubmitting => throw _privateConstructorUsedError;
|
bool get isSubmitting => throw _privateConstructorUsedError;
|
||||||
Option<Either<UserDetail, UserError>> get signInFailure =>
|
Option<String> get passwordError => throw _privateConstructorUsedError;
|
||||||
|
Option<String> get emailError => throw _privateConstructorUsedError;
|
||||||
|
Option<Either<UserDetail, UserError>> get successOrFail =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@ -473,7 +479,9 @@ abstract class $SignInStateCopyWith<$Res> {
|
|||||||
{String? email,
|
{String? email,
|
||||||
String? password,
|
String? password,
|
||||||
bool isSubmitting,
|
bool isSubmitting,
|
||||||
Option<Either<UserDetail, UserError>> signInFailure});
|
Option<String> passwordError,
|
||||||
|
Option<String> emailError,
|
||||||
|
Option<Either<UserDetail, UserError>> successOrFail});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -489,7 +497,9 @@ class _$SignInStateCopyWithImpl<$Res> implements $SignInStateCopyWith<$Res> {
|
|||||||
Object? email = freezed,
|
Object? email = freezed,
|
||||||
Object? password = freezed,
|
Object? password = freezed,
|
||||||
Object? isSubmitting = freezed,
|
Object? isSubmitting = freezed,
|
||||||
Object? signInFailure = freezed,
|
Object? passwordError = freezed,
|
||||||
|
Object? emailError = freezed,
|
||||||
|
Object? successOrFail = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
email: email == freezed
|
email: email == freezed
|
||||||
@ -504,9 +514,17 @@ class _$SignInStateCopyWithImpl<$Res> implements $SignInStateCopyWith<$Res> {
|
|||||||
? _value.isSubmitting
|
? _value.isSubmitting
|
||||||
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
signInFailure: signInFailure == freezed
|
passwordError: passwordError == freezed
|
||||||
? _value.signInFailure
|
? _value.passwordError
|
||||||
: signInFailure // ignore: cast_nullable_to_non_nullable
|
: passwordError // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<String>,
|
||||||
|
emailError: emailError == freezed
|
||||||
|
? _value.emailError
|
||||||
|
: emailError // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<String>,
|
||||||
|
successOrFail: successOrFail == freezed
|
||||||
|
? _value.successOrFail
|
||||||
|
: successOrFail // ignore: cast_nullable_to_non_nullable
|
||||||
as Option<Either<UserDetail, UserError>>,
|
as Option<Either<UserDetail, UserError>>,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -523,7 +541,9 @@ abstract class _$SignInStateCopyWith<$Res>
|
|||||||
{String? email,
|
{String? email,
|
||||||
String? password,
|
String? password,
|
||||||
bool isSubmitting,
|
bool isSubmitting,
|
||||||
Option<Either<UserDetail, UserError>> signInFailure});
|
Option<String> passwordError,
|
||||||
|
Option<String> emailError,
|
||||||
|
Option<Either<UserDetail, UserError>> successOrFail});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -541,7 +561,9 @@ class __$SignInStateCopyWithImpl<$Res> extends _$SignInStateCopyWithImpl<$Res>
|
|||||||
Object? email = freezed,
|
Object? email = freezed,
|
||||||
Object? password = freezed,
|
Object? password = freezed,
|
||||||
Object? isSubmitting = freezed,
|
Object? isSubmitting = freezed,
|
||||||
Object? signInFailure = freezed,
|
Object? passwordError = freezed,
|
||||||
|
Object? emailError = freezed,
|
||||||
|
Object? successOrFail = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_SignInState(
|
return _then(_SignInState(
|
||||||
email: email == freezed
|
email: email == freezed
|
||||||
@ -556,9 +578,17 @@ class __$SignInStateCopyWithImpl<$Res> extends _$SignInStateCopyWithImpl<$Res>
|
|||||||
? _value.isSubmitting
|
? _value.isSubmitting
|
||||||
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
signInFailure: signInFailure == freezed
|
passwordError: passwordError == freezed
|
||||||
? _value.signInFailure
|
? _value.passwordError
|
||||||
: signInFailure // ignore: cast_nullable_to_non_nullable
|
: passwordError // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<String>,
|
||||||
|
emailError: emailError == freezed
|
||||||
|
? _value.emailError
|
||||||
|
: emailError // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<String>,
|
||||||
|
successOrFail: successOrFail == freezed
|
||||||
|
? _value.successOrFail
|
||||||
|
: successOrFail // ignore: cast_nullable_to_non_nullable
|
||||||
as Option<Either<UserDetail, UserError>>,
|
as Option<Either<UserDetail, UserError>>,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -571,7 +601,9 @@ class _$_SignInState implements _SignInState {
|
|||||||
{this.email,
|
{this.email,
|
||||||
this.password,
|
this.password,
|
||||||
required this.isSubmitting,
|
required this.isSubmitting,
|
||||||
required this.signInFailure});
|
required this.passwordError,
|
||||||
|
required this.emailError,
|
||||||
|
required this.successOrFail});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String? email;
|
final String? email;
|
||||||
@ -580,11 +612,15 @@ class _$_SignInState implements _SignInState {
|
|||||||
@override
|
@override
|
||||||
final bool isSubmitting;
|
final bool isSubmitting;
|
||||||
@override
|
@override
|
||||||
final Option<Either<UserDetail, UserError>> signInFailure;
|
final Option<String> passwordError;
|
||||||
|
@override
|
||||||
|
final Option<String> emailError;
|
||||||
|
@override
|
||||||
|
final Option<Either<UserDetail, UserError>> successOrFail;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SignInState(email: $email, password: $password, isSubmitting: $isSubmitting, signInFailure: $signInFailure)';
|
return 'SignInState(email: $email, password: $password, isSubmitting: $isSubmitting, passwordError: $passwordError, emailError: $emailError, successOrFail: $successOrFail)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -599,9 +635,15 @@ class _$_SignInState implements _SignInState {
|
|||||||
(identical(other.isSubmitting, isSubmitting) ||
|
(identical(other.isSubmitting, isSubmitting) ||
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other.isSubmitting, isSubmitting)) &&
|
.equals(other.isSubmitting, isSubmitting)) &&
|
||||||
(identical(other.signInFailure, signInFailure) ||
|
(identical(other.passwordError, passwordError) ||
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other.signInFailure, signInFailure)));
|
.equals(other.passwordError, passwordError)) &&
|
||||||
|
(identical(other.emailError, emailError) ||
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other.emailError, emailError)) &&
|
||||||
|
(identical(other.successOrFail, successOrFail) ||
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other.successOrFail, successOrFail)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -610,7 +652,9 @@ class _$_SignInState implements _SignInState {
|
|||||||
const DeepCollectionEquality().hash(email) ^
|
const DeepCollectionEquality().hash(email) ^
|
||||||
const DeepCollectionEquality().hash(password) ^
|
const DeepCollectionEquality().hash(password) ^
|
||||||
const DeepCollectionEquality().hash(isSubmitting) ^
|
const DeepCollectionEquality().hash(isSubmitting) ^
|
||||||
const DeepCollectionEquality().hash(signInFailure);
|
const DeepCollectionEquality().hash(passwordError) ^
|
||||||
|
const DeepCollectionEquality().hash(emailError) ^
|
||||||
|
const DeepCollectionEquality().hash(successOrFail);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -623,7 +667,9 @@ abstract class _SignInState implements SignInState {
|
|||||||
{String? email,
|
{String? email,
|
||||||
String? password,
|
String? password,
|
||||||
required bool isSubmitting,
|
required bool isSubmitting,
|
||||||
required Option<Either<UserDetail, UserError>> signInFailure}) =
|
required Option<String> passwordError,
|
||||||
|
required Option<String> emailError,
|
||||||
|
required Option<Either<UserDetail, UserError>> successOrFail}) =
|
||||||
_$_SignInState;
|
_$_SignInState;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -633,7 +679,11 @@ abstract class _SignInState implements SignInState {
|
|||||||
@override
|
@override
|
||||||
bool get isSubmitting => throw _privateConstructorUsedError;
|
bool get isSubmitting => throw _privateConstructorUsedError;
|
||||||
@override
|
@override
|
||||||
Option<Either<UserDetail, UserError>> get signInFailure =>
|
Option<String> get passwordError => throw _privateConstructorUsedError;
|
||||||
|
@override
|
||||||
|
Option<String> get emailError => throw _privateConstructorUsedError;
|
||||||
|
@override
|
||||||
|
Option<Either<UserDetail, UserError>> get successOrFail =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
abstract class IAuth {
|
abstract class IAuth {
|
||||||
Future<Either<UserDetail, UserError>> signIn(String? email, String? password);
|
Future<Either<UserDetail, UserError>> signIn(String? email, String? password);
|
||||||
@ -8,3 +9,9 @@ abstract class IAuth {
|
|||||||
|
|
||||||
Future<Either<Unit, UserError>> signOut();
|
Future<Either<Unit, UserError>> signOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class IAuthRouter {
|
||||||
|
void showHomeScreen(BuildContext context, UserDetail user);
|
||||||
|
void showSignUpScreen(BuildContext context);
|
||||||
|
void showForgetPasswordScreen(BuildContext context);
|
||||||
|
}
|
||||||
|
@ -6,10 +6,11 @@ import 'package:get_it/get_it.dart';
|
|||||||
|
|
||||||
class UserDepsResolver {
|
class UserDepsResolver {
|
||||||
static Future<void> resolve(GetIt getIt) async {
|
static Future<void> resolve(GetIt getIt) async {
|
||||||
getIt.registerLazySingleton<AuthRepository>(() => AuthRepository());
|
getIt.registerFactory<AuthRepository>(() => AuthRepository());
|
||||||
|
|
||||||
//Interface implementation
|
//Interface implementation
|
||||||
getIt.registerFactory<IAuth>(() => AuthImpl(repo: getIt<AuthRepository>()));
|
getIt.registerFactory<IAuth>(() => AuthImpl(repo: getIt<AuthRepository>()));
|
||||||
|
getIt.registerFactory<IAuthRouter>(() => AuthRouterImpl());
|
||||||
|
|
||||||
//Bloc
|
//Bloc
|
||||||
getIt.registerFactory<SignInBloc>(() => SignInBloc(getIt<IAuth>()));
|
getIt.registerFactory<SignInBloc>(() => SignInBloc(getIt<IAuth>()));
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/route/animation.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||||
import 'package:app_flowy/user/domain/i_auth.dart';
|
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||||
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AuthImpl extends IAuth {
|
class AuthImpl extends IAuth {
|
||||||
AuthRepository repo;
|
AuthRepository repo;
|
||||||
@ -26,3 +29,20 @@ class AuthImpl extends IAuth {
|
|||||||
return repo.signOut();
|
return repo.signOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AuthRouterImpl extends IAuthRouter {
|
||||||
|
@override
|
||||||
|
void showForgetPasswordScreen(BuildContext context) {
|
||||||
|
// TODO: implement showForgetPasswordScreen
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void showHomeScreen(BuildContext context, UserDetail user) {
|
||||||
|
Navigator.of(context).push(PageRoutes.fade(() => HomeScreen(user)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void showSignUpScreen(BuildContext context) {
|
||||||
|
// TODO: implement showSignUpScreen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,19 +1,217 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:app_flowy/user/application/sign_in/sign_in_bloc.dart';
|
import 'package:app_flowy/user/application/sign_in/sign_in_bloc.dart';
|
||||||
import 'package:app_flowy/user/presentation/sign_in/widgets/body.dart';
|
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||||
|
import 'package:app_flowy/user/presentation/sign_in/widgets/background.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.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 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
class SignInScreen extends StatelessWidget {
|
class SignInScreen extends StatelessWidget {
|
||||||
const SignInScreen({Key? key}) : super(key: key);
|
final IAuthRouter router;
|
||||||
|
const SignInScreen({Key? key, required this.router}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => getIt<SignInBloc>(),
|
create: (context) => getIt<SignInBloc>(),
|
||||||
child: const Scaffold(
|
child: BlocListener<SignInBloc, SignInState>(
|
||||||
body: Body(),
|
listener: (context, state) {
|
||||||
|
state.successOrFail.fold(
|
||||||
|
() => null,
|
||||||
|
(result) => _handleSuccessOrFail(result, context),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
body: SignInForm(router: router),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleSuccessOrFail(
|
||||||
|
Either<UserDetail, UserError> result, BuildContext context) {
|
||||||
|
result.fold(
|
||||||
|
(user) => router.showHomeScreen(context, user),
|
||||||
|
(error) => _showErrorMessage(context, error.msg),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showErrorMessage(BuildContext context, String msg) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(msg),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SignInForm extends StatelessWidget {
|
||||||
|
final IAuthRouter router;
|
||||||
|
const SignInForm({
|
||||||
|
Key? key,
|
||||||
|
required this.router,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: SignInFormContainer(
|
||||||
|
children: [
|
||||||
|
const SignInTitle(
|
||||||
|
title: 'Login to Appflowy',
|
||||||
|
logoSize: Size(60, 60),
|
||||||
|
),
|
||||||
|
const VSpace(30),
|
||||||
|
const EmailTextField(),
|
||||||
|
const PasswordTextField(),
|
||||||
|
ForgetPasswordButton(router: router),
|
||||||
|
const LoginButton(),
|
||||||
|
const VSpace(10),
|
||||||
|
SignUpPrompt(router: router),
|
||||||
|
if (context.read<SignInBloc>().state.isSubmitting) ...[
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
const LinearProgressIndicator(value: null),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SignUpPrompt extends StatelessWidget {
|
||||||
|
const SignUpPrompt({
|
||||||
|
Key? key,
|
||||||
|
required this.router,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final IAuthRouter router;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
const Text("Dont't have an account",
|
||||||
|
style: TextStyle(color: Colors.blueGrey, fontSize: 12)),
|
||||||
|
TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
textStyle: const TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
onPressed: () => router.showSignUpScreen(context),
|
||||||
|
child: const Text(
|
||||||
|
'Sign Up',
|
||||||
|
style: TextStyle(color: Colors.lightBlue),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoginButton extends StatelessWidget {
|
||||||
|
const LoginButton({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return RoundedTextButton(
|
||||||
|
title: 'Login',
|
||||||
|
height: 45,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: Colors.lightBlue,
|
||||||
|
press: () {
|
||||||
|
context
|
||||||
|
.read<SignInBloc>()
|
||||||
|
.add(const SignInEvent.signedInWithUserEmailAndPassword());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ForgetPasswordButton extends StatelessWidget {
|
||||||
|
const ForgetPasswordButton({
|
||||||
|
Key? key,
|
||||||
|
required this.router,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final IAuthRouter router;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TextButton(
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
textStyle: const TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
onPressed: () => router.showForgetPasswordScreen(context),
|
||||||
|
child: const Text(
|
||||||
|
'Forgot Password?',
|
||||||
|
style: TextStyle(color: Colors.lightBlue),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PasswordTextField extends StatelessWidget {
|
||||||
|
const PasswordTextField({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<SignInBloc, SignInState>(
|
||||||
|
buildWhen: (previous, current) =>
|
||||||
|
previous.passwordError != current.passwordError,
|
||||||
|
builder: (context, state) {
|
||||||
|
return RoundedInputField(
|
||||||
|
obscureText: true,
|
||||||
|
hintText: 'password',
|
||||||
|
normalBorderColor: Colors.green,
|
||||||
|
highlightBorderColor: Colors.red,
|
||||||
|
errorText: context
|
||||||
|
.read<SignInBloc>()
|
||||||
|
.state
|
||||||
|
.passwordError
|
||||||
|
.fold(() => "", (error) => error),
|
||||||
|
onChanged: (value) => context
|
||||||
|
.read<SignInBloc>()
|
||||||
|
.add(SignInEvent.passwordChanged(value)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmailTextField extends StatelessWidget {
|
||||||
|
const EmailTextField({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<SignInBloc, SignInState>(
|
||||||
|
buildWhen: (previous, current) =>
|
||||||
|
previous.emailError != current.emailError,
|
||||||
|
builder: (context, state) {
|
||||||
|
return RoundedInputField(
|
||||||
|
hintText: 'email',
|
||||||
|
normalBorderColor: Colors.green,
|
||||||
|
highlightBorderColor: Colors.red,
|
||||||
|
errorText: context
|
||||||
|
.read<SignInBloc>()
|
||||||
|
.state
|
||||||
|
.emailError
|
||||||
|
.fold(() => "", (error) => error),
|
||||||
|
onChanged: (value) =>
|
||||||
|
context.read<SignInBloc>().add(SignInEvent.emailChanged(value)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,29 +1,57 @@
|
|||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SignInBackground extends StatelessWidget {
|
class SignInFormContainer extends StatelessWidget {
|
||||||
final Widget child;
|
final List<Widget> children;
|
||||||
const SignInBackground({
|
const SignInFormContainer({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.child,
|
required this.children,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var size = MediaQuery.of(context).size;
|
final size = MediaQuery.of(context).size;
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: size.height,
|
width: size.width * 0.3,
|
||||||
width: double.infinity,
|
child: Column(
|
||||||
child: Stack(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
alignment: Alignment.center,
|
children: children,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SignInTitle extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final Size logoSize;
|
||||||
|
const SignInTitle({
|
||||||
|
Key? key,
|
||||||
|
required this.title,
|
||||||
|
required this.logoSize,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Image(
|
Image(
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
width: size.width,
|
width: logoSize.width,
|
||||||
height: size.height,
|
height: logoSize.height,
|
||||||
image: const AssetImage(
|
image: const AssetImage('assets/images/app_flowy_logo.jpg')),
|
||||||
'assets/images/appflowy_launch_splash.jpg')),
|
const VSpace(30),
|
||||||
child,
|
Text(
|
||||||
|
title,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
));
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
|
||||||
import 'package:app_flowy/user/application/sign_in/sign_in_bloc.dart';
|
|
||||||
import 'package:app_flowy/user/presentation/sign_in/widgets/background.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
|
|
||||||
class Body extends StatelessWidget {
|
|
||||||
const Body({Key? key}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocProvider(
|
|
||||||
create: (context) => getIt<SignInBloc>(),
|
|
||||||
child: const SignInBackground(
|
|
||||||
child: SignInForm(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SignInForm extends StatelessWidget {
|
|
||||||
const SignInForm({
|
|
||||||
Key? key,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocConsumer<SignInBloc, SignInState>(
|
|
||||||
listenWhen: (p, c) => p != c,
|
|
||||||
listener: (context, state) {
|
|
||||||
state.signInFailure.fold(
|
|
||||||
() {},
|
|
||||||
(result) => _handleStateErrors(result, context),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
builder: (context, state) {
|
|
||||||
return SignInFormBackground(
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
RoundedInputField(
|
|
||||||
icon: Icons.person,
|
|
||||||
hintText: 'email',
|
|
||||||
onChanged: (value) => context
|
|
||||||
.read<SignInBloc>()
|
|
||||||
.add(SignInEvent.emailChanged(value)),
|
|
||||||
),
|
|
||||||
RoundedInputField(
|
|
||||||
icon: Icons.lock,
|
|
||||||
obscureText: true,
|
|
||||||
hintText: 'password',
|
|
||||||
onChanged: (value) => context
|
|
||||||
.read<SignInBloc>()
|
|
||||||
.add(SignInEvent.passwordChanged(value)),
|
|
||||||
),
|
|
||||||
RoundedButton(
|
|
||||||
title: 'LOGIN',
|
|
||||||
press: () {
|
|
||||||
context
|
|
||||||
.read<SignInBloc>()
|
|
||||||
.add(const SignInEvent.signedInWithUserEmailAndPassword());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (state.isSubmitting) ...[
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
const LinearProgressIndicator(value: null),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleStateErrors(
|
|
||||||
Either<UserDetail, UserError> some, BuildContext context) {
|
|
||||||
some.fold(
|
|
||||||
(userDetail) => showHomeScreen(context, userDetail),
|
|
||||||
(result) => _showErrorMessage(context, result.msg),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showErrorMessage(BuildContext context, String msg) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(msg),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void showHomeScreen(BuildContext context, UserDetail userDetail) {
|
|
||||||
Navigator.pushReplacement(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) {
|
|
||||||
return HomeScreen(userDetail);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SignInFormBackground extends StatelessWidget {
|
|
||||||
final List<Widget> children;
|
|
||||||
const SignInFormBackground({
|
|
||||||
Key? key,
|
|
||||||
required this.children,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final size = MediaQuery.of(context).size;
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
width: size.width * 0.4,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center, children: children),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,7 +13,7 @@ class WelcomeBloc extends Bloc<WelcomeEvent, WelcomeState> {
|
|||||||
Stream<WelcomeState> mapEventToState(WelcomeEvent event) async* {
|
Stream<WelcomeState> mapEventToState(WelcomeEvent event) async* {
|
||||||
yield* event.map(
|
yield* event.map(
|
||||||
getUser: (val) async* {
|
getUser: (val) async* {
|
||||||
final authState = await authImpl.currentUserState();
|
final authState = await authImpl.currentUserDetail();
|
||||||
yield state.copyWith(auth: authState);
|
yield state.copyWith(auth: authState);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'auth_state.dart';
|
import 'auth_state.dart';
|
||||||
|
|
||||||
abstract class IWelcomeAuth {
|
abstract class IWelcomeAuth {
|
||||||
Future<AuthState> currentUserState();
|
Future<AuthState> currentUserDetail();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IWelcomeRoute {
|
abstract class IWelcomeRoute {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
|
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||||
import 'package:app_flowy/user/presentation/sign_in/sign_in_screen.dart';
|
import 'package:app_flowy/user/presentation/sign_in/sign_in_screen.dart';
|
||||||
import 'package:app_flowy/welcome/domain/auth_state.dart';
|
import 'package:app_flowy/welcome/domain/auth_state.dart';
|
||||||
import 'package:app_flowy/welcome/domain/i_welcome.dart';
|
import 'package:app_flowy/welcome/domain/i_welcome.dart';
|
||||||
@ -11,7 +13,7 @@ export 'package:app_flowy/welcome/domain/i_welcome.dart';
|
|||||||
|
|
||||||
class WelcomeAuthImpl implements IWelcomeAuth {
|
class WelcomeAuthImpl implements IWelcomeAuth {
|
||||||
@override
|
@override
|
||||||
Future<AuthState> currentUserState() {
|
Future<AuthState> currentUserDetail() {
|
||||||
final result = UserEventGetStatus().send();
|
final result = UserEventGetStatus().send();
|
||||||
return result.then((result) {
|
return result.then((result) {
|
||||||
return result.fold(
|
return result.fold(
|
||||||
@ -34,6 +36,6 @@ class WelcomeRoute implements IWelcomeRoute {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget pushSignInScreen() {
|
Widget pushSignInScreen() {
|
||||||
return const SignInScreen();
|
return SignInScreen(router: getIt<IAuthRouter>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
|||||||
Stream<DocState> mapEventToState(DocEvent event) async* {
|
Stream<DocState> mapEventToState(DocEvent event) async* {
|
||||||
yield* event.map(
|
yield* event.map(
|
||||||
initial: (e) async* {},
|
initial: (e) async* {},
|
||||||
save: (Save value) async* {},
|
|
||||||
close: (Close value) async* {},
|
close: (Close value) async* {},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -23,7 +22,6 @@ class DocBloc extends Bloc<DocEvent, DocState> {
|
|||||||
@freezed
|
@freezed
|
||||||
abstract class DocEvent with _$DocEvent {
|
abstract class DocEvent with _$DocEvent {
|
||||||
const factory DocEvent.initial() = Initial;
|
const factory DocEvent.initial() = Initial;
|
||||||
const factory DocEvent.save(String jsonStr) = Save;
|
|
||||||
const factory DocEvent.close() = Close;
|
const factory DocEvent.close() = Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,6 @@ class _$DocEventTearOff {
|
|||||||
return const Initial();
|
return const Initial();
|
||||||
}
|
}
|
||||||
|
|
||||||
Save save(String jsonStr) {
|
|
||||||
return Save(
|
|
||||||
jsonStr,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Close close() {
|
Close close() {
|
||||||
return const Close();
|
return const Close();
|
||||||
}
|
}
|
||||||
@ -39,14 +33,12 @@ mixin _$DocEvent {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function(String jsonStr) save,
|
|
||||||
required TResult Function() close,
|
required TResult Function() close,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function(String jsonStr)? save,
|
|
||||||
TResult Function()? close,
|
TResult Function()? close,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
@ -54,14 +46,12 @@ mixin _$DocEvent {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Initial value) initial,
|
required TResult Function(Initial value) initial,
|
||||||
required TResult Function(Save value) save,
|
|
||||||
required TResult Function(Close value) close,
|
required TResult Function(Close value) close,
|
||||||
}) =>
|
}) =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Initial value)? initial,
|
TResult Function(Initial value)? initial,
|
||||||
TResult Function(Save value)? save,
|
|
||||||
TResult Function(Close value)? close,
|
TResult Function(Close value)? close,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) =>
|
}) =>
|
||||||
@ -121,7 +111,6 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function(String jsonStr) save,
|
|
||||||
required TResult Function() close,
|
required TResult Function() close,
|
||||||
}) {
|
}) {
|
||||||
return initial();
|
return initial();
|
||||||
@ -131,7 +120,6 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function(String jsonStr)? save,
|
|
||||||
TResult Function()? close,
|
TResult Function()? close,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
@ -145,7 +133,6 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Initial value) initial,
|
required TResult Function(Initial value) initial,
|
||||||
required TResult Function(Save value) save,
|
|
||||||
required TResult Function(Close value) close,
|
required TResult Function(Close value) close,
|
||||||
}) {
|
}) {
|
||||||
return initial(this);
|
return initial(this);
|
||||||
@ -155,7 +142,6 @@ class _$Initial implements Initial {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Initial value)? initial,
|
TResult Function(Initial value)? initial,
|
||||||
TResult Function(Save value)? save,
|
|
||||||
TResult Function(Close value)? close,
|
TResult Function(Close value)? close,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
@ -170,122 +156,6 @@ abstract class Initial implements DocEvent {
|
|||||||
const factory Initial() = _$Initial;
|
const factory Initial() = _$Initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $SaveCopyWith<$Res> {
|
|
||||||
factory $SaveCopyWith(Save value, $Res Function(Save) then) =
|
|
||||||
_$SaveCopyWithImpl<$Res>;
|
|
||||||
$Res call({String jsonStr});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$SaveCopyWithImpl<$Res> extends _$DocEventCopyWithImpl<$Res>
|
|
||||||
implements $SaveCopyWith<$Res> {
|
|
||||||
_$SaveCopyWithImpl(Save _value, $Res Function(Save) _then)
|
|
||||||
: super(_value, (v) => _then(v as Save));
|
|
||||||
|
|
||||||
@override
|
|
||||||
Save get _value => super._value as Save;
|
|
||||||
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? jsonStr = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(Save(
|
|
||||||
jsonStr == freezed
|
|
||||||
? _value.jsonStr
|
|
||||||
: jsonStr // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$Save implements Save {
|
|
||||||
const _$Save(this.jsonStr);
|
|
||||||
|
|
||||||
@override
|
|
||||||
final String jsonStr;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'DocEvent.save(jsonStr: $jsonStr)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(dynamic other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other is Save &&
|
|
||||||
(identical(other.jsonStr, jsonStr) ||
|
|
||||||
const DeepCollectionEquality().equals(other.jsonStr, jsonStr)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
runtimeType.hashCode ^ const DeepCollectionEquality().hash(jsonStr);
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
|
||||||
@override
|
|
||||||
$SaveCopyWith<Save> get copyWith =>
|
|
||||||
_$SaveCopyWithImpl<Save>(this, _$identity);
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() initial,
|
|
||||||
required TResult Function(String jsonStr) save,
|
|
||||||
required TResult Function() close,
|
|
||||||
}) {
|
|
||||||
return save(jsonStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? initial,
|
|
||||||
TResult Function(String jsonStr)? save,
|
|
||||||
TResult Function()? close,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (save != null) {
|
|
||||||
return save(jsonStr);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(Initial value) initial,
|
|
||||||
required TResult Function(Save value) save,
|
|
||||||
required TResult Function(Close value) close,
|
|
||||||
}) {
|
|
||||||
return save(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(Initial value)? initial,
|
|
||||||
TResult Function(Save value)? save,
|
|
||||||
TResult Function(Close value)? close,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (save != null) {
|
|
||||||
return save(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class Save implements DocEvent {
|
|
||||||
const factory Save(String jsonStr) = _$Save;
|
|
||||||
|
|
||||||
String get jsonStr => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(ignore: true)
|
|
||||||
$SaveCopyWith<Save> get copyWith => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class $CloseCopyWith<$Res> {
|
abstract class $CloseCopyWith<$Res> {
|
||||||
factory $CloseCopyWith(Close value, $Res Function(Close) then) =
|
factory $CloseCopyWith(Close value, $Res Function(Close) then) =
|
||||||
@ -324,7 +194,6 @@ class _$Close implements Close {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult when<TResult extends Object?>({
|
TResult when<TResult extends Object?>({
|
||||||
required TResult Function() initial,
|
required TResult Function() initial,
|
||||||
required TResult Function(String jsonStr) save,
|
|
||||||
required TResult Function() close,
|
required TResult Function() close,
|
||||||
}) {
|
}) {
|
||||||
return close();
|
return close();
|
||||||
@ -334,7 +203,6 @@ class _$Close implements Close {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
TResult Function()? initial,
|
TResult Function()? initial,
|
||||||
TResult Function(String jsonStr)? save,
|
|
||||||
TResult Function()? close,
|
TResult Function()? close,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
@ -348,7 +216,6 @@ class _$Close implements Close {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult map<TResult extends Object?>({
|
TResult map<TResult extends Object?>({
|
||||||
required TResult Function(Initial value) initial,
|
required TResult Function(Initial value) initial,
|
||||||
required TResult Function(Save value) save,
|
|
||||||
required TResult Function(Close value) close,
|
required TResult Function(Close value) close,
|
||||||
}) {
|
}) {
|
||||||
return close(this);
|
return close(this);
|
||||||
@ -358,7 +225,6 @@ class _$Close implements Close {
|
|||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
TResult maybeMap<TResult extends Object?>({
|
TResult maybeMap<TResult extends Object?>({
|
||||||
TResult Function(Initial value)? initial,
|
TResult Function(Initial value)? initial,
|
||||||
TResult Function(Save value)? save,
|
|
||||||
TResult Function(Close value)? close,
|
TResult Function(Close value)? close,
|
||||||
required TResult orElse(),
|
required TResult orElse(),
|
||||||
}) {
|
}) {
|
||||||
|
@ -40,9 +40,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* {
|
Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* {
|
||||||
await iWorkspaceImpl
|
iWorkspaceImpl.createApp(name: event.name, desc: event.desc).then((result) {
|
||||||
.createApp(name: event.name, desc: event.desc)
|
|
||||||
.then((result) async* {
|
|
||||||
result.fold(
|
result.fold(
|
||||||
(app) => {},
|
(app) => {},
|
||||||
(error) async* {
|
(error) async* {
|
||||||
|
60
app_flowy/lib/workspace/application/menu/menu_user_bloc.dart
Normal file
60
app_flowy/lib/workspace/application/menu/menu_user_bloc.dart
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import 'package:app_flowy/workspace/domain/i_user.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
|
part 'menu_user_bloc.freezed.dart';
|
||||||
|
|
||||||
|
class MenuUserBloc extends Bloc<MenuUserEvent, MenuUserState> {
|
||||||
|
final IUser iUserImpl;
|
||||||
|
|
||||||
|
MenuUserBloc(this.iUserImpl) : super(MenuUserState.initial(iUserImpl.user));
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<MenuUserState> mapEventToState(MenuUserEvent event) async* {
|
||||||
|
yield* event.map(
|
||||||
|
initial: (_) async* {
|
||||||
|
// fetch workspaces
|
||||||
|
iUserImpl.fetchWorkspaces().then((result) {
|
||||||
|
result.fold(
|
||||||
|
(workspaces) async* {
|
||||||
|
yield state.copyWith(workspaces: some(workspaces));
|
||||||
|
},
|
||||||
|
(error) async* {
|
||||||
|
yield state.copyWith(successOrFailure: right(error.msg));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fetchWorkspaces: (_FetchWorkspaces value) async* {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() async {
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class MenuUserEvent with _$MenuUserEvent {
|
||||||
|
const factory MenuUserEvent.initial() = _Initial;
|
||||||
|
const factory MenuUserEvent.fetchWorkspaces() = _FetchWorkspaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class MenuUserState with _$MenuUserState {
|
||||||
|
const factory MenuUserState({
|
||||||
|
required UserDetail user,
|
||||||
|
required Option<List<Workspace>> workspaces,
|
||||||
|
required Either<Unit, String> successOrFailure,
|
||||||
|
}) = _MenuUserState;
|
||||||
|
|
||||||
|
factory MenuUserState.initial(UserDetail user) => MenuUserState(
|
||||||
|
user: user,
|
||||||
|
workspaces: none(),
|
||||||
|
successOrFailure: left(unit),
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,432 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
|
||||||
|
|
||||||
|
part of 'menu_user_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$MenuUserEventTearOff {
|
||||||
|
const _$MenuUserEventTearOff();
|
||||||
|
|
||||||
|
_Initial initial() {
|
||||||
|
return const _Initial();
|
||||||
|
}
|
||||||
|
|
||||||
|
_FetchWorkspaces fetchWorkspaces() {
|
||||||
|
return const _FetchWorkspaces();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
const $MenuUserEvent = _$MenuUserEventTearOff();
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$MenuUserEvent {
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() fetchWorkspaces,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? fetchWorkspaces,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_FetchWorkspaces value) fetchWorkspaces,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_FetchWorkspaces value)? fetchWorkspaces,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $MenuUserEventCopyWith<$Res> {
|
||||||
|
factory $MenuUserEventCopyWith(
|
||||||
|
MenuUserEvent value, $Res Function(MenuUserEvent) then) =
|
||||||
|
_$MenuUserEventCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$MenuUserEventCopyWithImpl<$Res>
|
||||||
|
implements $MenuUserEventCopyWith<$Res> {
|
||||||
|
_$MenuUserEventCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
final MenuUserEvent _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function(MenuUserEvent) _then;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$InitialCopyWith<$Res> {
|
||||||
|
factory _$InitialCopyWith(_Initial value, $Res Function(_Initial) then) =
|
||||||
|
__$InitialCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$InitialCopyWithImpl<$Res> extends _$MenuUserEventCopyWithImpl<$Res>
|
||||||
|
implements _$InitialCopyWith<$Res> {
|
||||||
|
__$InitialCopyWithImpl(_Initial _value, $Res Function(_Initial) _then)
|
||||||
|
: super(_value, (v) => _then(v as _Initial));
|
||||||
|
|
||||||
|
@override
|
||||||
|
_Initial get _value => super._value as _Initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$_Initial implements _Initial {
|
||||||
|
const _$_Initial();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'MenuUserEvent.initial()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) || (other is _Initial);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() fetchWorkspaces,
|
||||||
|
}) {
|
||||||
|
return initial();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? fetchWorkspaces,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (initial != null) {
|
||||||
|
return initial();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_FetchWorkspaces value) fetchWorkspaces,
|
||||||
|
}) {
|
||||||
|
return initial(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_FetchWorkspaces value)? fetchWorkspaces,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (initial != null) {
|
||||||
|
return initial(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _Initial implements MenuUserEvent {
|
||||||
|
const factory _Initial() = _$_Initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$FetchWorkspacesCopyWith<$Res> {
|
||||||
|
factory _$FetchWorkspacesCopyWith(
|
||||||
|
_FetchWorkspaces value, $Res Function(_FetchWorkspaces) then) =
|
||||||
|
__$FetchWorkspacesCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$FetchWorkspacesCopyWithImpl<$Res>
|
||||||
|
extends _$MenuUserEventCopyWithImpl<$Res>
|
||||||
|
implements _$FetchWorkspacesCopyWith<$Res> {
|
||||||
|
__$FetchWorkspacesCopyWithImpl(
|
||||||
|
_FetchWorkspaces _value, $Res Function(_FetchWorkspaces) _then)
|
||||||
|
: super(_value, (v) => _then(v as _FetchWorkspaces));
|
||||||
|
|
||||||
|
@override
|
||||||
|
_FetchWorkspaces get _value => super._value as _FetchWorkspaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$_FetchWorkspaces implements _FetchWorkspaces {
|
||||||
|
const _$_FetchWorkspaces();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'MenuUserEvent.fetchWorkspaces()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) || (other is _FetchWorkspaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() initial,
|
||||||
|
required TResult Function() fetchWorkspaces,
|
||||||
|
}) {
|
||||||
|
return fetchWorkspaces();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? initial,
|
||||||
|
TResult Function()? fetchWorkspaces,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fetchWorkspaces != null) {
|
||||||
|
return fetchWorkspaces();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(_Initial value) initial,
|
||||||
|
required TResult Function(_FetchWorkspaces value) fetchWorkspaces,
|
||||||
|
}) {
|
||||||
|
return fetchWorkspaces(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(_Initial value)? initial,
|
||||||
|
TResult Function(_FetchWorkspaces value)? fetchWorkspaces,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fetchWorkspaces != null) {
|
||||||
|
return fetchWorkspaces(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _FetchWorkspaces implements MenuUserEvent {
|
||||||
|
const factory _FetchWorkspaces() = _$_FetchWorkspaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$MenuUserStateTearOff {
|
||||||
|
const _$MenuUserStateTearOff();
|
||||||
|
|
||||||
|
_MenuUserState call(
|
||||||
|
{required UserDetail user,
|
||||||
|
required Option<List<Workspace>> workspaces,
|
||||||
|
required Either<Unit, String> successOrFailure}) {
|
||||||
|
return _MenuUserState(
|
||||||
|
user: user,
|
||||||
|
workspaces: workspaces,
|
||||||
|
successOrFailure: successOrFailure,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
const $MenuUserState = _$MenuUserStateTearOff();
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$MenuUserState {
|
||||||
|
UserDetail get user => throw _privateConstructorUsedError;
|
||||||
|
Option<List<Workspace>> get workspaces => throw _privateConstructorUsedError;
|
||||||
|
Either<Unit, String> get successOrFailure =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$MenuUserStateCopyWith<MenuUserState> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $MenuUserStateCopyWith<$Res> {
|
||||||
|
factory $MenuUserStateCopyWith(
|
||||||
|
MenuUserState value, $Res Function(MenuUserState) then) =
|
||||||
|
_$MenuUserStateCopyWithImpl<$Res>;
|
||||||
|
$Res call(
|
||||||
|
{UserDetail user,
|
||||||
|
Option<List<Workspace>> workspaces,
|
||||||
|
Either<Unit, String> successOrFailure});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$MenuUserStateCopyWithImpl<$Res>
|
||||||
|
implements $MenuUserStateCopyWith<$Res> {
|
||||||
|
_$MenuUserStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
final MenuUserState _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function(MenuUserState) _then;
|
||||||
|
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? user = freezed,
|
||||||
|
Object? workspaces = freezed,
|
||||||
|
Object? successOrFailure = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
user: user == freezed
|
||||||
|
? _value.user
|
||||||
|
: user // ignore: cast_nullable_to_non_nullable
|
||||||
|
as UserDetail,
|
||||||
|
workspaces: workspaces == freezed
|
||||||
|
? _value.workspaces
|
||||||
|
: workspaces // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<List<Workspace>>,
|
||||||
|
successOrFailure: successOrFailure == freezed
|
||||||
|
? _value.successOrFailure
|
||||||
|
: successOrFailure // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Either<Unit, String>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$MenuUserStateCopyWith<$Res>
|
||||||
|
implements $MenuUserStateCopyWith<$Res> {
|
||||||
|
factory _$MenuUserStateCopyWith(
|
||||||
|
_MenuUserState value, $Res Function(_MenuUserState) then) =
|
||||||
|
__$MenuUserStateCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
$Res call(
|
||||||
|
{UserDetail user,
|
||||||
|
Option<List<Workspace>> workspaces,
|
||||||
|
Either<Unit, String> successOrFailure});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$MenuUserStateCopyWithImpl<$Res>
|
||||||
|
extends _$MenuUserStateCopyWithImpl<$Res>
|
||||||
|
implements _$MenuUserStateCopyWith<$Res> {
|
||||||
|
__$MenuUserStateCopyWithImpl(
|
||||||
|
_MenuUserState _value, $Res Function(_MenuUserState) _then)
|
||||||
|
: super(_value, (v) => _then(v as _MenuUserState));
|
||||||
|
|
||||||
|
@override
|
||||||
|
_MenuUserState get _value => super._value as _MenuUserState;
|
||||||
|
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? user = freezed,
|
||||||
|
Object? workspaces = freezed,
|
||||||
|
Object? successOrFailure = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_MenuUserState(
|
||||||
|
user: user == freezed
|
||||||
|
? _value.user
|
||||||
|
: user // ignore: cast_nullable_to_non_nullable
|
||||||
|
as UserDetail,
|
||||||
|
workspaces: workspaces == freezed
|
||||||
|
? _value.workspaces
|
||||||
|
: workspaces // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<List<Workspace>>,
|
||||||
|
successOrFailure: successOrFailure == freezed
|
||||||
|
? _value.successOrFailure
|
||||||
|
: successOrFailure // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Either<Unit, String>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$_MenuUserState implements _MenuUserState {
|
||||||
|
const _$_MenuUserState(
|
||||||
|
{required this.user,
|
||||||
|
required this.workspaces,
|
||||||
|
required this.successOrFailure});
|
||||||
|
|
||||||
|
@override
|
||||||
|
final UserDetail user;
|
||||||
|
@override
|
||||||
|
final Option<List<Workspace>> workspaces;
|
||||||
|
@override
|
||||||
|
final Either<Unit, String> successOrFailure;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'MenuUserState(user: $user, workspaces: $workspaces, successOrFailure: $successOrFailure)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other is _MenuUserState &&
|
||||||
|
(identical(other.user, user) ||
|
||||||
|
const DeepCollectionEquality().equals(other.user, user)) &&
|
||||||
|
(identical(other.workspaces, workspaces) ||
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other.workspaces, workspaces)) &&
|
||||||
|
(identical(other.successOrFailure, successOrFailure) ||
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other.successOrFailure, successOrFailure)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
runtimeType.hashCode ^
|
||||||
|
const DeepCollectionEquality().hash(user) ^
|
||||||
|
const DeepCollectionEquality().hash(workspaces) ^
|
||||||
|
const DeepCollectionEquality().hash(successOrFailure);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
_$MenuUserStateCopyWith<_MenuUserState> get copyWith =>
|
||||||
|
__$MenuUserStateCopyWithImpl<_MenuUserState>(this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _MenuUserState implements MenuUserState {
|
||||||
|
const factory _MenuUserState(
|
||||||
|
{required UserDetail user,
|
||||||
|
required Option<List<Workspace>> workspaces,
|
||||||
|
required Either<Unit, String> successOrFailure}) = _$_MenuUserState;
|
||||||
|
|
||||||
|
@override
|
||||||
|
UserDetail get user => throw _privateConstructorUsedError;
|
||||||
|
@override
|
||||||
|
Option<List<Workspace>> get workspaces => throw _privateConstructorUsedError;
|
||||||
|
@override
|
||||||
|
Either<Unit, String> get successOrFailure =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$MenuUserStateCopyWith<_MenuUserState> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
18
app_flowy/lib/workspace/domain/i_user.dart
Normal file
18
app_flowy/lib/workspace/domain/i_user.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart';
|
||||||
|
|
||||||
|
export 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart';
|
||||||
|
export 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||||
|
export 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
export 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
|
|
||||||
|
abstract class IUser {
|
||||||
|
UserDetail get user;
|
||||||
|
Future<Either<UserDetail, UserError>> fetchUserDetail(String userId);
|
||||||
|
Future<Either<List<Workspace>, WorkspaceError>> fetchWorkspaces();
|
||||||
|
Future<Either<Unit, WorkspaceError>> deleteWorkspace(String workspaceId);
|
||||||
|
Future<Either<Unit, UserError>> signOut();
|
||||||
|
}
|
16
app_flowy/lib/workspace/domain/image.dart
Normal file
16
app_flowy/lib/workspace/domain/image.dart
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
AssetImage assetImageForViewType(ViewType type) {
|
||||||
|
final imageName = imageNameForViewType(type);
|
||||||
|
return AssetImage('assets/images/$imageName');
|
||||||
|
}
|
||||||
|
|
||||||
|
String imageNameForViewType(ViewType type) {
|
||||||
|
switch (type) {
|
||||||
|
case ViewType.Doc:
|
||||||
|
return "file_icon.jpg";
|
||||||
|
default:
|
||||||
|
return "file_icon.jpg";
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,8 @@ class HomePageStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setStackView(HomeStackView? stackView) {
|
void setStackView(HomeStackView? stackView) {
|
||||||
_bloc.add(PageStackEvent.setStackView(stackView ?? const BlankStackView()));
|
_bloc.add(PageStackEvent.setStackView(
|
||||||
|
stackView ?? const AnnouncementStackView()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget stackTopBar() {
|
Widget stackTopBar() {
|
||||||
@ -32,7 +33,7 @@ class HomePageStack {
|
|||||||
child: BlocBuilder<PageStackBloc, PageStackState>(
|
child: BlocBuilder<PageStackBloc, PageStackState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return HomeTopBar(
|
return HomeTopBar(
|
||||||
title: state.stackView.title,
|
view: state.stackView,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -61,14 +62,17 @@ List<Widget> _buildStackWidget(HomeStackView stackView) {
|
|||||||
if (viewType == stackView.type) {
|
if (viewType == stackView.type) {
|
||||||
switch (stackView.type) {
|
switch (stackView.type) {
|
||||||
case ViewType.Blank:
|
case ViewType.Blank:
|
||||||
return BlankPage(stackView: stackView as BlankStackView);
|
return AnnouncementPage(
|
||||||
|
stackView: stackView as AnnouncementStackView);
|
||||||
case ViewType.Doc:
|
case ViewType.Doc:
|
||||||
return DocPage(stackView: stackView as DocPageStackView);
|
final docView = stackView as DocPageStackView;
|
||||||
|
return DocPage(key: ValueKey(docView.view.id), stackView: docView);
|
||||||
default:
|
default:
|
||||||
return BlankPage(stackView: stackView as BlankStackView);
|
return AnnouncementPage(
|
||||||
|
stackView: stackView as AnnouncementStackView);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return const BlankPage(stackView: BlankStackView());
|
return const AnnouncementPage(stackView: AnnouncementStackView());
|
||||||
}
|
}
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
@ -76,11 +80,11 @@ List<Widget> _buildStackWidget(HomeStackView stackView) {
|
|||||||
HomeStackView stackViewFromView(View view) {
|
HomeStackView stackViewFromView(View view) {
|
||||||
switch (view.viewType) {
|
switch (view.viewType) {
|
||||||
case ViewType.Blank:
|
case ViewType.Blank:
|
||||||
return const BlankStackView();
|
return const AnnouncementStackView();
|
||||||
case ViewType.Doc:
|
case ViewType.Doc:
|
||||||
return DocPageStackView(view);
|
return DocPageStackView(view);
|
||||||
default:
|
default:
|
||||||
return const BlankStackView();
|
return const AnnouncementStackView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,6 @@ abstract class PageStackState implements _$PageStackState {
|
|||||||
}) = _PageStackState;
|
}) = _PageStackState;
|
||||||
|
|
||||||
factory PageStackState.initial() => const PageStackState(
|
factory PageStackState.initial() => const PageStackState(
|
||||||
stackView: BlankStackView(),
|
stackView: AnnouncementStackView(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import 'package:app_flowy/workspace/application/app/app_bloc.dart';
|
|||||||
import 'package:app_flowy/workspace/application/app/app_watch_bloc.dart';
|
import 'package:app_flowy/workspace/application/app/app_watch_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
|
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
|
import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
|
||||||
import 'package:app_flowy/workspace/application/view/doc_watch_bloc.dart';
|
import 'package:app_flowy/workspace/application/view/doc_watch_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
|
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
|
||||||
@ -15,8 +16,11 @@ import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart';
|
|||||||
import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart';
|
import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart';
|
||||||
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
||||||
import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
|
import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
|
||||||
|
import 'package:flowy_editor/flowy_editor.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
|
|
||||||
|
import 'i_user_impl.dart';
|
||||||
import 'i_view_impl.dart';
|
import 'i_view_impl.dart';
|
||||||
|
|
||||||
class HomeDepsResolver {
|
class HomeDepsResolver {
|
||||||
@ -31,10 +35,10 @@ class HomeDepsResolver {
|
|||||||
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
|
(appId, _) => IAppWatchImpl(repo: AppWatchRepository(appId: appId)));
|
||||||
|
|
||||||
//workspace
|
//workspace
|
||||||
getIt.registerFactoryParam<IWorkspace, String, void>((workspaceId, _) =>
|
getIt.registerFactoryParam<IWorkspace, UserDetail, void>(
|
||||||
IWorkspaceImpl(repo: WorkspaceRepo(workspaceId: workspaceId)));
|
(user, _) => IWorkspaceImpl(repo: WorkspaceRepo(user: user)));
|
||||||
getIt.registerFactoryParam<IWorkspaceWatch, String, void>((workspacId, _) =>
|
getIt.registerFactoryParam<IWorkspaceWatch, UserDetail, void>(
|
||||||
IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(workspaceId: workspacId)));
|
(user, _) => IWorkspaceWatchImpl(repo: WorkspaceWatchRepo(user: user)));
|
||||||
|
|
||||||
// View
|
// View
|
||||||
getIt.registerFactoryParam<IView, String, void>(
|
getIt.registerFactoryParam<IView, String, void>(
|
||||||
@ -46,12 +50,20 @@ class HomeDepsResolver {
|
|||||||
getIt.registerFactoryParam<IDoc, String, void>(
|
getIt.registerFactoryParam<IDoc, String, void>(
|
||||||
(docId, _) => IDocImpl(repo: DocRepository(docId: docId)));
|
(docId, _) => IDocImpl(repo: DocRepository(docId: docId)));
|
||||||
|
|
||||||
//Bloc
|
// User
|
||||||
getIt.registerFactoryParam<MenuBloc, String, void>(
|
getIt.registerFactoryParam<IUser, UserDetail, void>(
|
||||||
(workspaceId, _) => MenuBloc(getIt<IWorkspace>(param1: workspaceId)));
|
(user, _) => IUserImpl(repo: UserRepo(user: user)));
|
||||||
getIt.registerFactoryParam<MenuWatchBloc, String, void>((workspaceId, _) =>
|
|
||||||
MenuWatchBloc(getIt<IWorkspaceWatch>(param1: workspaceId)));
|
|
||||||
|
|
||||||
|
//Menu Bloc
|
||||||
|
getIt.registerFactoryParam<MenuBloc, UserDetail, void>(
|
||||||
|
(user, _) => MenuBloc(getIt<IWorkspace>(param1: user)));
|
||||||
|
getIt.registerFactoryParam<MenuWatchBloc, UserDetail, void>(
|
||||||
|
(user, _) => MenuWatchBloc(getIt<IWorkspaceWatch>(param1: user)));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<MenuUserBloc, UserDetail, void>(
|
||||||
|
(user, _) => MenuUserBloc(getIt<IUser>(param1: user)));
|
||||||
|
|
||||||
|
//
|
||||||
getIt.registerFactoryParam<AppBloc, String, void>(
|
getIt.registerFactoryParam<AppBloc, String, void>(
|
||||||
(appId, _) => AppBloc(getIt<IApp>(param1: appId)));
|
(appId, _) => AppBloc(getIt<IApp>(param1: appId)));
|
||||||
getIt.registerFactoryParam<AppWatchBloc, String, void>(
|
getIt.registerFactoryParam<AppWatchBloc, String, void>(
|
||||||
@ -66,6 +78,9 @@ class HomeDepsResolver {
|
|||||||
getIt.registerFactoryParam<DocBloc, String, void>(
|
getIt.registerFactoryParam<DocBloc, String, void>(
|
||||||
(docId, _) => DocBloc(getIt<IDoc>(param1: docId)));
|
(docId, _) => DocBloc(getIt<IDoc>(param1: docId)));
|
||||||
|
|
||||||
|
// editor
|
||||||
|
getIt.registerFactoryParam<EditorPersistence, String, void>(
|
||||||
|
(docId, _) => EditorPersistenceImpl(repo: DocRepository(docId: docId)));
|
||||||
// getIt.registerFactoryParam<ViewBloc, String, void>(
|
// getIt.registerFactoryParam<ViewBloc, String, void>(
|
||||||
// (viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId)));
|
// (viewId, _) => ViewBloc(iViewImpl: getIt<IView>(param1: viewId)));
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,7 @@ class IAppImpl extends IApp {
|
|||||||
final result = await docRepo.createDoc(
|
final result = await docRepo.createDoc(
|
||||||
name: view.name, desc: "", text: "[{\"insert\":\"\\n\"}]");
|
name: view.name, desc: "", text: "[{\"insert\":\"\\n\"}]");
|
||||||
return result.fold((l) => left(view), (r) {
|
return result.fold((l) => left(view), (r) {
|
||||||
return right(
|
return right(WorkspaceError(code: WsErrCode.Unknown, msg: r.msg));
|
||||||
WorkspaceError(code: WorkspaceErrorCode.Unknown, msg: r.msg));
|
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return left(view);
|
return left(view);
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_editor/flowy_editor.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-editor/errors.pb.dart';
|
||||||
|
|
||||||
import 'package:app_flowy/workspace/domain/i_doc.dart';
|
import 'package:app_flowy/workspace/domain/i_doc.dart';
|
||||||
import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart';
|
import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart';
|
||||||
import 'package:flowy_editor/flowy_editor.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-editor/errors.pb.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
|
|
||||||
class IDocImpl extends IDoc {
|
class IDocImpl extends IDoc {
|
||||||
DocRepository repo;
|
DocRepository repo;
|
||||||
@ -49,3 +50,21 @@ class IDocImpl extends IDoc {
|
|||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EditorPersistenceImpl extends EditorPersistence {
|
||||||
|
DocRepository repo;
|
||||||
|
EditorPersistenceImpl({
|
||||||
|
required this.repo,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> save(List<dynamic> jsonList) async {
|
||||||
|
final json = jsonEncode(jsonList);
|
||||||
|
return repo.updateDoc(text: json).then((result) {
|
||||||
|
return result.fold(
|
||||||
|
(l) => true,
|
||||||
|
(r) => false,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
36
app_flowy/lib/workspace/infrastructure/i_user_impl.dart
Normal file
36
app_flowy/lib/workspace/infrastructure/i_user_impl.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
|
import 'package:app_flowy/workspace/domain/i_user.dart';
|
||||||
|
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
|
||||||
|
export 'package:app_flowy/workspace/domain/i_user.dart';
|
||||||
|
export 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
|
||||||
|
|
||||||
|
class IUserImpl extends IUser {
|
||||||
|
UserRepo repo;
|
||||||
|
IUserImpl({
|
||||||
|
required this.repo,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Unit, WorkspaceError>> deleteWorkspace(String workspaceId) {
|
||||||
|
return repo.deleteWorkspace(workspaceId: workspaceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<UserDetail, UserError>> fetchUserDetail(String userId) {
|
||||||
|
return repo.fetchUserDetail(userId: userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<Unit, UserError>> signOut() {
|
||||||
|
return repo.signOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
UserDetail get user => repo.user;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Either<List<Workspace>, WorkspaceError>> fetchWorkspaces() {
|
||||||
|
return repo.fetchWorkspaces();
|
||||||
|
}
|
||||||
|
}
|
36
app_flowy/lib/workspace/infrastructure/repos/user_repo.dart
Normal file
36
app_flowy/lib/workspace/infrastructure/repos/user_repo.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_create.pb.dart';
|
||||||
|
|
||||||
|
class UserRepo {
|
||||||
|
final UserDetail user;
|
||||||
|
UserRepo({
|
||||||
|
required this.user,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<Either<UserDetail, UserError>> fetchUserDetail(
|
||||||
|
{required String userId}) {
|
||||||
|
return UserEventGetStatus().send();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Either<Unit, WorkspaceError>> deleteWorkspace(
|
||||||
|
{required String workspaceId}) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Either<Unit, UserError>> signOut() {
|
||||||
|
return UserEventSignOut().send();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Either<List<Workspace>, WorkspaceError>> fetchWorkspaces() {
|
||||||
|
return WorkspaceEventReadAllWorkspace().send().then((result) {
|
||||||
|
return result.fold(
|
||||||
|
(workspaces) => left(workspaces.items),
|
||||||
|
(r) => right(r),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import 'package:dartz/dartz.dart';
|
|||||||
import 'package:flowy_infra/flowy_logger.dart';
|
import 'package:flowy_infra/flowy_logger.dart';
|
||||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-observable/subject.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-observable/subject.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/observable.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/observable.pb.dart';
|
||||||
@ -13,9 +14,9 @@ import 'package:flowy_sdk/protobuf/flowy-workspace/workspace_query.pb.dart';
|
|||||||
import 'package:flowy_sdk/rust_stream.dart';
|
import 'package:flowy_sdk/rust_stream.dart';
|
||||||
|
|
||||||
class WorkspaceRepo {
|
class WorkspaceRepo {
|
||||||
String workspaceId;
|
UserDetail user;
|
||||||
WorkspaceRepo({
|
WorkspaceRepo({
|
||||||
required this.workspaceId,
|
required this.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<Either<App, WorkspaceError>> createApp(String appName, String desc) {
|
Future<Either<App, WorkspaceError>> createApp(String appName, String desc) {
|
||||||
@ -38,7 +39,7 @@ class WorkspaceRepo {
|
|||||||
Future<Either<Workspace, WorkspaceError>> getWorkspace(
|
Future<Either<Workspace, WorkspaceError>> getWorkspace(
|
||||||
{bool readApps = false}) {
|
{bool readApps = false}) {
|
||||||
final request = QueryWorkspaceRequest.create()
|
final request = QueryWorkspaceRequest.create()
|
||||||
..workspaceId = workspaceId
|
..workspaceId = user.workspace
|
||||||
..readApps = readApps;
|
..readApps = readApps;
|
||||||
|
|
||||||
return WorkspaceEventGetWorkspace(request).send().then((result) {
|
return WorkspaceEventGetWorkspace(request).send().then((result) {
|
||||||
@ -54,13 +55,13 @@ class WorkspaceWatchRepo {
|
|||||||
StreamSubscription<ObservableSubject>? _subscription;
|
StreamSubscription<ObservableSubject>? _subscription;
|
||||||
WorkspaceAddAppCallback? _addAppCallback;
|
WorkspaceAddAppCallback? _addAppCallback;
|
||||||
WorkspaceUpdatedCallback? _updatedCallback;
|
WorkspaceUpdatedCallback? _updatedCallback;
|
||||||
final String workspaceId;
|
final UserDetail user;
|
||||||
late WorkspaceRepo _repo;
|
late WorkspaceRepo _repo;
|
||||||
|
|
||||||
WorkspaceWatchRepo({
|
WorkspaceWatchRepo({
|
||||||
required this.workspaceId,
|
required this.user,
|
||||||
}) {
|
}) {
|
||||||
_repo = WorkspaceRepo(workspaceId: workspaceId);
|
_repo = WorkspaceRepo(user: user);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startWatching(
|
void startWatching(
|
||||||
@ -70,7 +71,7 @@ class WorkspaceWatchRepo {
|
|||||||
_updatedCallback = updatedCallback;
|
_updatedCallback = updatedCallback;
|
||||||
|
|
||||||
_subscription = RustStreamReceiver.listen((observable) {
|
_subscription = RustStreamReceiver.listen((observable) {
|
||||||
if (observable.subjectId != workspaceId) {
|
if (observable.subjectId != user.workspace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,32 @@
|
|||||||
import 'package:app_flowy/workspace/application/app/app_bloc.dart';
|
import 'package:app_flowy/workspace/application/app/app_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/application/app/app_watch_bloc.dart';
|
import 'package:app_flowy/workspace/application/app/app_watch_bloc.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/app/view_list.dart';
|
import 'package:app_flowy/workspace/presentation/app/view_list.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_size.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_text_button.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_icon_button.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.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 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
|
|
||||||
class AppWidget extends StatelessWidget {
|
class AppWidgetSize {
|
||||||
|
static double expandedIconSize = 24;
|
||||||
|
static double expandedIconRightSpace = 8;
|
||||||
|
|
||||||
|
static double scale = 1;
|
||||||
|
|
||||||
|
static double get expandedPadding =>
|
||||||
|
expandedIconSize * scale + expandedIconRightSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppWidget extends MenuItem {
|
||||||
final App app;
|
final App app;
|
||||||
const AppWidget(this.app, {Key? key}) : super(key: key);
|
AppWidget(this.app, {Key? key}) : super(key: ValueKey(app.id));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -35,11 +47,9 @@ class AppWidget extends StatelessWidget {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final child = state.map(
|
final child = state.map(
|
||||||
initial: (_) => BlocBuilder<AppBloc, AppState>(
|
initial: (_) => BlocBuilder<AppBloc, AppState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) => _renderViewList(state.views),
|
||||||
return ViewList(state.views);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
loadViews: (s) => ViewList(some(s.views)),
|
loadViews: (s) => _renderViewList(some(s.views)),
|
||||||
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -54,8 +64,6 @@ class AppWidget extends StatelessWidget {
|
|||||||
child: ScrollOnExpand(
|
child: ScrollOnExpand(
|
||||||
scrollOnExpand: true,
|
scrollOnExpand: true,
|
||||||
scrollOnCollapse: false,
|
scrollOnCollapse: false,
|
||||||
child: Card(
|
|
||||||
clipBehavior: Clip.antiAlias,
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ExpandablePanel(
|
ExpandablePanel(
|
||||||
@ -63,22 +71,29 @@ class AppWidget extends StatelessWidget {
|
|||||||
headerAlignment: ExpandablePanelHeaderAlignment.center,
|
headerAlignment: ExpandablePanelHeaderAlignment.center,
|
||||||
tapBodyToExpand: false,
|
tapBodyToExpand: false,
|
||||||
tapBodyToCollapse: false,
|
tapBodyToCollapse: false,
|
||||||
|
tapHeaderToExpand: false,
|
||||||
iconPadding: EdgeInsets.zero,
|
iconPadding: EdgeInsets.zero,
|
||||||
hasIcon: false,
|
hasIcon: false,
|
||||||
),
|
),
|
||||||
header: AppHeader(app),
|
header: AppHeader(app),
|
||||||
expanded: Padding(
|
expanded: child,
|
||||||
padding: EdgeInsets.only(left: Sizes.iconMed),
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
collapsed: const SizedBox(),
|
collapsed: const SizedBox(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _renderViewList(Option<List<View>> views) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: ViewList(views),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
MenuItemType get type => MenuItemType.app;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppHeader extends StatelessWidget {
|
class AppHeader extends StatelessWidget {
|
||||||
@ -90,46 +105,53 @@ class AppHeader extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Row(
|
||||||
color: Colors.white,
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: Insets.m),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
ExpandableIcon(
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
ExpandableController.of(context,
|
||||||
|
rebuildOnChange: false, required: true)
|
||||||
|
?.toggle();
|
||||||
|
},
|
||||||
|
child: ExpandableIcon(
|
||||||
theme: ExpandableThemeData(
|
theme: ExpandableThemeData(
|
||||||
expandIcon: Icons.arrow_right,
|
expandIcon: Icons.arrow_drop_up,
|
||||||
collapseIcon: Icons.arrow_drop_down,
|
collapseIcon: Icons.arrow_drop_down,
|
||||||
iconColor: Colors.black,
|
iconColor: Colors.black,
|
||||||
iconSize: HomeMenuSize.collapseIconSize,
|
iconSize: AppWidgetSize.expandedIconSize,
|
||||||
iconPadding: EdgeInsets.zero,
|
iconPadding: EdgeInsets.zero,
|
||||||
hasIcon: false,
|
hasIcon: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
|
||||||
child: Text(app.name),
|
|
||||||
),
|
),
|
||||||
SizedBox(
|
HSpace(AppWidgetSize.expandedIconRightSpace),
|
||||||
height: HomeMenuSize.createViewButtonSize,
|
Expanded(
|
||||||
child: createViewPopupMenu(context),
|
child: StyledTextButton(
|
||||||
|
app.name,
|
||||||
|
onPressed: () {
|
||||||
|
debugPrint('show app document');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
StyledIconButton(
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
onPressed: () {
|
||||||
|
debugPrint('add view');
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget createViewPopupMenu(BuildContext context) {
|
// return PopupMenuButton(
|
||||||
return PopupMenuButton(
|
// iconSize: 20,
|
||||||
iconSize: 24,
|
// tooltip: 'create new view',
|
||||||
tooltip: 'create new view',
|
// icon: const Icon(Icons.add),
|
||||||
icon: const Icon(Icons.add),
|
// padding: EdgeInsets.zero,
|
||||||
padding: EdgeInsets.zero,
|
// onSelected: (viewType) => _createView(viewType as ViewType, context),
|
||||||
onSelected: (viewType) => _createView(viewType as ViewType, context),
|
// itemBuilder: (context) => menuItemBuilder());
|
||||||
itemBuilder: (context) => menuItemBuilder());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PopupMenuEntry> menuItemBuilder() {
|
List<PopupMenuEntry> menuItemBuilder() {
|
||||||
return ViewType.values
|
return ViewType.values
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import 'package:app_flowy/workspace/presentation/view/view_widget.dart';
|
import 'package:app_flowy/workspace/presentation/view/view_widget.dart';
|
||||||
import 'package:flowy_infra/flowy_logger.dart';
|
import 'package:flowy_infra/flowy_logger.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
|
||||||
|
|
||||||
class ViewList extends StatelessWidget {
|
class ViewList extends StatelessWidget {
|
||||||
final Option<List<View>> views;
|
final Option<List<View>> views;
|
||||||
@ -15,24 +13,24 @@ class ViewList extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Log.info('ViewList build');
|
Log.info('ViewList build');
|
||||||
return views.fold(
|
return views.fold(
|
||||||
() => const SizedBox(
|
() => const SizedBox(),
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
(views) {
|
(views) {
|
||||||
return Column(
|
return Column(
|
||||||
children: buildViewWidgets(views),
|
children: _renderViews(views),
|
||||||
).padding(vertical: Insets.sm);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ViewWidget> buildViewWidgets(List<View> views) {
|
List<Widget> _renderViews(List<View> views) {
|
||||||
var targetViews = views.map((view) {
|
var targetViews = views.map((view) {
|
||||||
return ViewWidget(
|
return Padding(
|
||||||
icon: const Icon(Icons.file_copy),
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||||
|
child: ViewWidget(
|
||||||
view: view,
|
view: view,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}).toList(growable: true);
|
}).toList(growable: false);
|
||||||
return targetViews;
|
return targetViews;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import 'package:flowy_infra_ui/widget/error_page.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.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 'package:flowy_infra_ui/style_widget/styled_progress_indicator.dart';
|
||||||
|
|
||||||
class DocPage extends HomeStackWidget {
|
class DocPage extends HomeStackWidget {
|
||||||
const DocPage({Key? key, required DocPageStackView stackView})
|
const DocPage({Key? key, required DocPageStackView stackView})
|
||||||
@ -29,13 +30,28 @@ class _DocPageState extends State<DocPage> {
|
|||||||
BlocBuilder<DocWatchBloc, DocWatchState>(builder: (context, state) {
|
BlocBuilder<DocWatchBloc, DocWatchState>(builder: (context, state) {
|
||||||
assert(widget.stackView is DocPageStackView);
|
assert(widget.stackView is DocPageStackView);
|
||||||
return state.map(
|
return state.map(
|
||||||
loading: (_) => const CircularProgressIndicator.adaptive(),
|
loading: (_) => const StyledProgressIndicator(),
|
||||||
loadDoc: (s) => EditorWdiget(doc: s.doc),
|
loadDoc: (s) => EditorWdiget(doc: s.doc),
|
||||||
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void deactivate() {
|
||||||
|
super.deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant DocPage oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DocPageStackView extends HomeStackView {
|
class DocPageStackView extends HomeStackView {
|
||||||
|
@ -16,6 +16,7 @@ class EditorWdiget extends StatelessWidget {
|
|||||||
controller = EditorController(
|
controller = EditorController(
|
||||||
document: doc.data,
|
document: doc.data,
|
||||||
selection: const TextSelection.collapsed(offset: 0),
|
selection: const TextSelection.collapsed(offset: 0),
|
||||||
|
persistence: getIt<EditorPersistence>(param1: doc.info.id),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,12 +24,16 @@ class EditorWdiget extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => getIt<DocBloc>(param1: doc.info.id),
|
create: (context) => getIt<DocBloc>(param1: doc.info.id),
|
||||||
child: Column(
|
child: BlocBuilder<DocBloc, DocState>(
|
||||||
|
builder: (ctx, state) {
|
||||||
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
_renderEditor(controller),
|
_renderEditor(controller),
|
||||||
_renderToolbar(controller),
|
_renderToolbar(controller),
|
||||||
],
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -45,7 +50,9 @@ class EditorWdiget extends StatelessWidget {
|
|||||||
scrollBottomInset: 0,
|
scrollBottomInset: 0,
|
||||||
scrollController: ScrollController(),
|
scrollController: ScrollController(),
|
||||||
);
|
);
|
||||||
return Expanded(child: editor);
|
return Expanded(
|
||||||
|
child: Padding(padding: const EdgeInsets.all(10), child: editor),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderToolbar(EditorController controller) {
|
Widget _renderToolbar(EditorController controller) {
|
||||||
|
@ -23,7 +23,7 @@ class HomeLayout {
|
|||||||
|
|
||||||
showEditPannel = homeBlocState.editContext.isSome();
|
showEditPannel = homeBlocState.editContext.isSome();
|
||||||
|
|
||||||
menuWidth = Sizes.sideBarSm;
|
menuWidth = Sizes.sideBarMed;
|
||||||
if (context.widthPx >= PageBreaks.desktop) {
|
if (context.widthPx >= PageBreaks.desktop) {
|
||||||
menuWidth = Sizes.sideBarLg;
|
menuWidth = Sizes.sideBarLg;
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ import 'home_layout.dart';
|
|||||||
|
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
||||||
final UserDetail userDetail;
|
final UserDetail user;
|
||||||
const HomeScreen(this.userDetail, {Key? key}) : super(key: key);
|
const HomeScreen(this.user, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -31,7 +31,8 @@ class HomeScreen extends StatelessWidget {
|
|||||||
buildWhen: (previous, current) => previous != current,
|
buildWhen: (previous, current) => previous != current,
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return StyledContainer(
|
return StyledContainer(
|
||||||
Theme.of(context).colorScheme.background,
|
Theme.of(context).colorScheme.surface,
|
||||||
|
// Colors.white,
|
||||||
child: _buildBody(
|
child: _buildBody(
|
||||||
state, context.read<HomeBloc>().state.forceCollapse),
|
state, context.read<HomeBloc>().state.forceCollapse),
|
||||||
);
|
);
|
||||||
@ -74,7 +75,7 @@ class HomeScreen extends StatelessWidget {
|
|||||||
isCollapseChanged: (isCollapse) {
|
isCollapseChanged: (isCollapse) {
|
||||||
homeBloc.add(HomeEvent.forceCollapse(isCollapse));
|
homeBloc.add(HomeEvent.forceCollapse(isCollapse));
|
||||||
},
|
},
|
||||||
workspaceId: userDetail.workspace,
|
user: user,
|
||||||
);
|
);
|
||||||
homeMenu = RepaintBoundary(child: homeMenu);
|
homeMenu = RepaintBoundary(child: homeMenu);
|
||||||
homeMenu = FocusTraversalGroup(child: homeMenu);
|
homeMenu = FocusTraversalGroup(child: homeMenu);
|
||||||
|
@ -1,32 +1,67 @@
|
|||||||
import 'package:app_flowy/startup/startup.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
|
import 'package:app_flowy/workspace/domain/image.dart';
|
||||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_icon_button.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_hover.dart';
|
||||||
|
|
||||||
class ViewWidget extends StatelessWidget {
|
class ViewWidget extends StatelessWidget {
|
||||||
final View view;
|
final View view;
|
||||||
final Widget icon;
|
const ViewWidget({Key? key, required this.view}) : super(key: key);
|
||||||
const ViewWidget({Key? key, required this.view, required this.icon})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return InkWell(onTap: _openView(context), child: buildContent());
|
return InkWell(
|
||||||
|
onTap: _openView(context),
|
||||||
|
child: StyledHover(
|
||||||
|
color: Colors.grey.shade300,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
builder: (context, onHover) => _render(context, onHover),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Row buildContent() {
|
Widget _render(BuildContext context, bool onHover) {
|
||||||
return Row(
|
const double width = 20;
|
||||||
children: [
|
List<Widget> children = [
|
||||||
icon,
|
Image(
|
||||||
const SizedBox(
|
fit: BoxFit.cover,
|
||||||
width: 4,
|
width: width,
|
||||||
),
|
height: width,
|
||||||
|
image: assetImageForViewType(view.viewType)),
|
||||||
|
const HSpace(6),
|
||||||
Text(
|
Text(
|
||||||
view.name,
|
view.name,
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
style: const TextStyle(fontSize: 15),
|
style: const TextStyle(fontSize: 15),
|
||||||
)
|
),
|
||||||
],
|
];
|
||||||
|
|
||||||
|
if (onHover) {
|
||||||
|
children.add(const Spacer());
|
||||||
|
|
||||||
|
children.add(Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: StyledMore(
|
||||||
|
width: width,
|
||||||
|
onPressed: () {},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
final padding = EdgeInsets.only(
|
||||||
|
left: AppWidgetSize.expandedPadding,
|
||||||
|
top: 5,
|
||||||
|
bottom: 5,
|
||||||
|
right: 5,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: padding,
|
||||||
|
child: Row(children: children),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,30 +2,30 @@ import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
|||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class BlankStackView extends HomeStackView {
|
class AnnouncementStackView extends HomeStackView {
|
||||||
const BlankStackView() : super(type: ViewType.Blank, title: 'Blank');
|
const AnnouncementStackView() : super(type: ViewType.Blank, title: 'Blank');
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlankPage extends HomeStackWidget {
|
class AnnouncementPage extends HomeStackWidget {
|
||||||
const BlankPage({Key? key, required BlankStackView stackView})
|
const AnnouncementPage({Key? key, required AnnouncementStackView stackView})
|
||||||
: super(key: key, stackView: stackView);
|
: super(key: key, stackView: stackView);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _BlankPageState();
|
State<StatefulWidget> createState() => _AnnouncementPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BlankPageState extends State<BlankPage> {
|
class _AnnouncementPage extends State<AnnouncementPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return SizedBox.expand(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
child: Container(
|
||||||
child: const Center(
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: Text(
|
child: Padding(
|
||||||
'Hello AppFlowy',
|
padding: const EdgeInsets.all(10),
|
||||||
style: TextStyle(fontSize: 60),
|
child: Container(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1,49 +1,91 @@
|
|||||||
|
import 'package:app_flowy/workspace/domain/image.dart';
|
||||||
|
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||||
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pbenum.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_icon_button.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_text.dart';
|
||||||
|
|
||||||
class HomeTopBar extends StatelessWidget {
|
class HomeTopBar extends StatelessWidget {
|
||||||
final String title;
|
final HomeStackView view;
|
||||||
const HomeTopBar({Key? key, required this.title}) : super(key: key);
|
const HomeTopBar({Key? key, required this.view}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return SizedBox(
|
||||||
padding: EdgeInsets.symmetric(horizontal: HomeInsets.topBarTitlePadding),
|
|
||||||
height: HomeSizes.topBarHeight,
|
height: HomeSizes.topBarHeight,
|
||||||
child: Column(
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(width: 0.5, color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(horizontal: HomeInsets.topBarTitlePadding),
|
||||||
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
HomeTitle(title: title),
|
HomeTitle(title: view.title, type: view.type),
|
||||||
|
const Spacer(),
|
||||||
|
_renderShareButton(),
|
||||||
|
_renderMoreButton(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderShareButton() {
|
||||||
|
return RoundedTextButton(
|
||||||
|
title: 'Share',
|
||||||
|
height: 30,
|
||||||
|
width: 60,
|
||||||
|
fontSize: 12,
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
|
color: Colors.lightBlue,
|
||||||
|
press: () {
|
||||||
|
debugPrint('share page');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderMoreButton() {
|
||||||
|
return StyledMore(
|
||||||
|
width: 24,
|
||||||
|
onPressed: () {
|
||||||
|
debugPrint('show more');
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomeTitle extends StatelessWidget {
|
class HomeTitle extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final _editingController = TextEditingController(
|
final ViewType type;
|
||||||
text: '',
|
|
||||||
);
|
|
||||||
|
|
||||||
HomeTitle({
|
const HomeTitle({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.title,
|
required this.title,
|
||||||
|
required this.type,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
_editingController.text = title;
|
return Flexible(
|
||||||
|
child: Row(
|
||||||
return Expanded(
|
children: [
|
||||||
child: TextField(
|
Image(
|
||||||
controller: _editingController,
|
fit: BoxFit.scaleDown,
|
||||||
textAlign: TextAlign.left,
|
width: 15,
|
||||||
style: const TextStyle(fontSize: 28.0),
|
height: 15,
|
||||||
decoration: const InputDecoration(
|
image: assetImageForViewType(type)),
|
||||||
hintText: 'Name the view',
|
const HSpace(6),
|
||||||
border: UnderlineInputBorder(borderSide: BorderSide.none),
|
StyledText(title, fontSize: 16),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
|
|
||||||
import 'package:expandable/expandable.dart';
|
|
||||||
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
|
|
||||||
class AppList extends StatelessWidget {
|
|
||||||
final Option<List<App>> apps;
|
|
||||||
const AppList({required this.apps, Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return apps.fold(() {
|
|
||||||
return const Expanded(child: Text('You have no apps, create one?'));
|
|
||||||
}, (apps) {
|
|
||||||
return ExpandableTheme(
|
|
||||||
data: const ExpandableThemeData(
|
|
||||||
iconColor: Colors.blue,
|
|
||||||
useInkWell: true,
|
|
||||||
),
|
|
||||||
child: Expanded(
|
|
||||||
child: ListView(
|
|
||||||
physics: const BouncingScrollPhysics(),
|
|
||||||
children: apps.map((app) => AppWidget(app)).toList(),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,65 @@
|
|||||||
|
import 'package:app_flowy/startup/tasks/application_task.dart';
|
||||||
|
import 'package:flowy_infra/size.dart';
|
||||||
|
import 'package:flowy_infra/text_style.dart';
|
||||||
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_text_input.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/buttons/ok_cancel_button.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/dialog/dialog_context.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
// ignore: implementation_imports
|
||||||
|
import 'package:provider/src/provider.dart';
|
||||||
|
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class CreateAppDialogContext extends DialogContext {
|
||||||
|
String appName;
|
||||||
|
final Function(String)? confirm;
|
||||||
|
|
||||||
|
CreateAppDialogContext({this.appName = "", this.confirm})
|
||||||
|
: super(identifier: 'CreateAppDialogContext');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildWiget(BuildContext context) {
|
||||||
|
final theme = context.watch<AppTheme>();
|
||||||
|
return StyledDialog(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
...[
|
||||||
|
Text('Create App'.toUpperCase(),
|
||||||
|
style: TextStyles.T1.textColor(theme.bg1)),
|
||||||
|
VSpace(Insets.sm * 1.5),
|
||||||
|
// Container(color: theme.greyWeak.withOpacity(.35), height: 1),
|
||||||
|
VSpace(Insets.m * 1.5),
|
||||||
|
],
|
||||||
|
StyledFormTextInput(
|
||||||
|
hintText: "App name",
|
||||||
|
onChanged: (text) {
|
||||||
|
appName = text;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: Insets.l),
|
||||||
|
OkCancelButton(
|
||||||
|
onOkPressed: () {
|
||||||
|
if (confirm != null) {
|
||||||
|
confirm!(appName);
|
||||||
|
AppGlobals.nav.pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCancelPressed: () {
|
||||||
|
AppGlobals.nav.pop();
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [identifier];
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get barrierDismissable => false;
|
||||||
|
}
|
@ -1,34 +1,34 @@
|
|||||||
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_new_app.dart';
|
||||||
import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_top_bar.dart';
|
||||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
|
||||||
import 'package:app_flowy/startup/startup.dart';
|
|
||||||
import 'package:app_flowy/startup/tasks/application_task.dart';
|
|
||||||
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
import 'package:dartz/dartz.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
import 'package:flowy_infra/text_style.dart';
|
|
||||||
import 'package:flowy_infra/theme.dart';
|
|
||||||
import 'package:flowy_infra_ui/style_widget/styled_text_input.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/buttons/ok_cancel_button.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.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 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
|
||||||
import 'app_list.dart';
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/menu/menu_watch.dart';
|
||||||
|
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/app/app_widget.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_user.dart';
|
||||||
|
|
||||||
|
import 'menu_list.dart';
|
||||||
|
|
||||||
class HomeMenu extends StatelessWidget {
|
class HomeMenu extends StatelessWidget {
|
||||||
final Function(HomeStackView?) pageContextChanged;
|
final Function(HomeStackView?) pageContextChanged;
|
||||||
final Function(bool) isCollapseChanged;
|
final Function(bool) isCollapseChanged;
|
||||||
final String workspaceId;
|
final UserDetail user;
|
||||||
|
|
||||||
const HomeMenu(
|
const HomeMenu(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.pageContextChanged,
|
required this.pageContextChanged,
|
||||||
required this.isCollapseChanged,
|
required this.isCollapseChanged,
|
||||||
required this.workspaceId})
|
required this.user})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -36,10 +36,10 @@ class HomeMenu extends StatelessWidget {
|
|||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider<MenuBloc>(
|
BlocProvider<MenuBloc>(
|
||||||
create: (context) => getIt<MenuBloc>(param1: workspaceId)
|
create: (context) =>
|
||||||
..add(const MenuEvent.initial())),
|
getIt<MenuBloc>(param1: user)..add(const MenuEvent.initial())),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => getIt<MenuWatchBloc>(param1: workspaceId)
|
create: (context) => getIt<MenuWatchBloc>(param1: user)
|
||||||
..add(const MenuWatchEvent.started())),
|
..add(const MenuWatchEvent.started())),
|
||||||
],
|
],
|
||||||
child: MultiBlocListener(
|
child: MultiBlocListener(
|
||||||
@ -61,161 +61,82 @@ class HomeMenu extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderBody(BuildContext context) {
|
Widget _renderBody(BuildContext context) {
|
||||||
|
// nested cloumn: https://siddharthmolleti.com/flutter-box-constraints-nested-column-s-row-s-3dfacada7361
|
||||||
return Container(
|
return Container(
|
||||||
color: Theme.of(context).colorScheme.primaryVariant,
|
color: Theme.of(context).colorScheme.background,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const MenuTopBar(),
|
Expanded(
|
||||||
_renderAppList(context),
|
child: Column(
|
||||||
_renderNewButton(context),
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_renderTopBar(context),
|
||||||
|
_renderMenuList(context),
|
||||||
],
|
],
|
||||||
).padding(horizontal: Insets.sm),
|
).padding(horizontal: Insets.l),
|
||||||
|
),
|
||||||
|
_renderNewAppButton(context),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderAppList(BuildContext context) {
|
Widget _renderMenuList(BuildContext context) {
|
||||||
return BlocBuilder<MenuWatchBloc, MenuWatchState>(
|
return BlocBuilder<MenuWatchBloc, MenuWatchState>(
|
||||||
builder: (context, state) => state.map(
|
|
||||||
initial: (_) => BlocBuilder<MenuBloc, MenuState>(
|
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return AppList(apps: state.apps);
|
return state.map(
|
||||||
},
|
initial: (_) => MenuList(
|
||||||
|
menuItems: menuItemsWithApps(context.read<MenuBloc>().state.apps),
|
||||||
|
),
|
||||||
|
loadApps: (s) => MenuList(
|
||||||
|
menuItems: menuItemsWithApps(some(s.apps)),
|
||||||
),
|
),
|
||||||
loadApps: (s) => AppList(apps: some(s.apps)),
|
|
||||||
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
||||||
),
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _renderNewButton(BuildContext context) {
|
Widget _renderNewAppButton(BuildContext context) {
|
||||||
return NewAppButton(
|
return NewAppButton(
|
||||||
createAppCallback: (appName) =>
|
press: (appName) =>
|
||||||
context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
|
context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class MenuTopBar extends StatelessWidget {
|
Widget _renderTopBar(BuildContext context) {
|
||||||
const MenuTopBar({Key? key}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocBuilder<MenuBloc, MenuState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: HomeSizes.menuTopBarHeight,
|
height: HomeSizes.menuTopBarHeight,
|
||||||
child: Row(
|
child: const MenuTopBar(),
|
||||||
children: [
|
|
||||||
const Text(
|
|
||||||
'AppFlowy',
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
|
||||||
).constrained(minWidth: 100),
|
|
||||||
const Spacer(),
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.arrow_left),
|
|
||||||
onPressed: () =>
|
|
||||||
context.read<MenuBloc>().add(const MenuEvent.collapse()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewAppButton extends StatelessWidget {
|
|
||||||
final Function(String)? createAppCallback;
|
|
||||||
|
|
||||||
const NewAppButton({this.createAppCallback, Key? key}) : super(key: key);
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox(
|
|
||||||
height: HomeSizes.menuAddButtonHeight,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const Icon(Icons.add),
|
|
||||||
const SizedBox(
|
|
||||||
width: 10,
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () async => await _showCreateAppDialog(context),
|
|
||||||
child: _buttonTitle(),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buttonTitle() {
|
List<MenuItem> menuItemsWithApps(Option<List<App>> someApps) {
|
||||||
return const Text('New App',
|
return MenuItemBuilder().withUser(user).withApps(someApps).build();
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 20,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _showCreateAppDialog(BuildContext context) async {
|
|
||||||
await Dialogs.showWithContext(CreateAppDialogContext(
|
|
||||||
confirm: (appName) {
|
|
||||||
if (appName.isNotEmpty && createAppCallback != null) {
|
|
||||||
createAppCallback!(appName);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
), context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//ignore: must_be_immutable
|
class MenuItemBuilder {
|
||||||
class CreateAppDialogContext extends DialogContext {
|
List<MenuItem> items = [];
|
||||||
String appName;
|
|
||||||
final Function(String)? confirm;
|
|
||||||
|
|
||||||
CreateAppDialogContext({this.appName = "", this.confirm})
|
MenuItemBuilder();
|
||||||
: super(identifier: 'CreateAppDialogContext');
|
|
||||||
|
|
||||||
@override
|
MenuItemBuilder withUser(UserDetail user) {
|
||||||
Widget buildWiget(BuildContext context) {
|
items.add(MenuUser(user));
|
||||||
final theme = context.watch<AppTheme>();
|
return this;
|
||||||
return StyledDialog(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
...[
|
|
||||||
Text('Create App'.toUpperCase(),
|
|
||||||
style: TextStyles.T1.textColor(theme.accent1Darker)),
|
|
||||||
VSpace(Insets.sm * 1.5),
|
|
||||||
// Container(color: theme.greyWeak.withOpacity(.35), height: 1),
|
|
||||||
VSpace(Insets.m * 1.5),
|
|
||||||
],
|
|
||||||
StyledFormTextInput(
|
|
||||||
hintText: "App name",
|
|
||||||
onChanged: (text) {
|
|
||||||
appName = text;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(height: Insets.l),
|
|
||||||
OkCancelButton(
|
|
||||||
onOkPressed: () {
|
|
||||||
if (confirm != null) {
|
|
||||||
confirm!(appName);
|
|
||||||
AppGlobals.nav.pop();
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
onCancelPressed: () {
|
MenuItemBuilder withApps(Option<List<App>> someApps) {
|
||||||
AppGlobals.nav.pop();
|
List<MenuItem> appWidgets = someApps.foldRight(
|
||||||
},
|
[],
|
||||||
)
|
(apps, _) => apps.map((app) => AppWidget(app)).toList(),
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
items.addAll(appWidgets);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
List<MenuItem> build() {
|
||||||
List<Object> get props => [identifier];
|
return items;
|
||||||
|
}
|
||||||
@override
|
|
||||||
bool get barrierDismissable => false;
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
import 'package:expandable/expandable.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flowy_infra/time/duration.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
enum MenuItemType {
|
||||||
|
userProfile,
|
||||||
|
dashboard,
|
||||||
|
favorites,
|
||||||
|
app,
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MenuItem extends StatelessWidget {
|
||||||
|
const MenuItem({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
MenuItemType get type;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MenuList extends StatelessWidget {
|
||||||
|
final List<MenuItem> menuItems;
|
||||||
|
const MenuList({required this.menuItems, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ExpandableTheme(
|
||||||
|
data: ExpandableThemeData(
|
||||||
|
useInkWell: true, animationDuration: Durations.medium),
|
||||||
|
child: Expanded(
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: menuItems.length,
|
||||||
|
separatorBuilder: (context, index) => const VSpace(10),
|
||||||
|
physics: const BouncingScrollPhysics(),
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return menuItems[index];
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/widgets/menu/create_app_dialog.dart';
|
||||||
|
import 'package:flowy_infra/size.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
class NewAppButton extends StatelessWidget {
|
||||||
|
final Function(String)? press;
|
||||||
|
|
||||||
|
const NewAppButton({this.press, Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
top: BorderSide(width: 1, color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: HomeSizes.menuAddButtonHeight,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.add_circle_rounded, size: 30),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async => await _showCreateAppDialog(context),
|
||||||
|
child: const Text(
|
||||||
|
'New App',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
).padding(horizontal: Insets.l),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _showCreateAppDialog(BuildContext context) async {
|
||||||
|
await Dialogs.showWithContext(CreateAppDialogContext(
|
||||||
|
confirm: (appName) {
|
||||||
|
if (appName.isNotEmpty && press != null) {
|
||||||
|
press!(appName);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
), context);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +0,0 @@
|
|||||||
class HomeMenuSize {
|
|
||||||
static double get createViewButtonSize => 30;
|
|
||||||
static double get collapseIconSize => 24;
|
|
||||||
}
|
|
@ -0,0 +1,37 @@
|
|||||||
|
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class MenuTopBar extends StatelessWidget {
|
||||||
|
const MenuTopBar({Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<MenuBloc, MenuState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
const Image(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
width: 25,
|
||||||
|
height: 25,
|
||||||
|
image: AssetImage('assets/images/app_flowy_logo.jpg')),
|
||||||
|
const HSpace(8),
|
||||||
|
const Text(
|
||||||
|
'AppFlowy',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.arrow_left),
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
onPressed: () =>
|
||||||
|
context.read<MenuBloc>().add(const MenuEvent.collapse()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
import 'package:app_flowy/startup/startup.dart';
|
||||||
|
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
|
||||||
|
import 'package:app_flowy/workspace/presentation/widgets/menu/menu_list.dart';
|
||||||
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
|
import 'package:flowy_sdk/protobuf/flowy-user/user_detail.pb.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_text.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_icon_button.dart';
|
||||||
|
|
||||||
|
class MenuUser extends MenuItem {
|
||||||
|
final UserDetail user;
|
||||||
|
MenuUser(this.user, {Key? key}) : super(key: ValueKey(user.id));
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider<MenuUserBloc>(
|
||||||
|
create: (context) =>
|
||||||
|
getIt<MenuUserBloc>(param1: user)..add(const MenuUserEvent.initial()),
|
||||||
|
child: BlocBuilder<MenuUserBloc, MenuUserState>(
|
||||||
|
builder: (context, state) => Row(children: [
|
||||||
|
_renderAvatar(context),
|
||||||
|
const HSpace(10),
|
||||||
|
_renderUserName(context),
|
||||||
|
const HSpace(10),
|
||||||
|
_renderDropButton(context),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderAvatar(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
child: const Image(image: AssetImage('assets/images/avatar.jpg')),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderUserName(BuildContext context) {
|
||||||
|
String name = context.read<MenuUserBloc>().state.user.name;
|
||||||
|
if (name.isEmpty) {
|
||||||
|
name = context.read<MenuUserBloc>().state.user.email;
|
||||||
|
}
|
||||||
|
return Flexible(
|
||||||
|
child: StyledText(name, fontSize: 18),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _renderDropButton(BuildContext context) {
|
||||||
|
return StyledIconButton(
|
||||||
|
width: 30,
|
||||||
|
iconRatio: 0.8,
|
||||||
|
icon: const Icon(Icons.arrow_drop_down),
|
||||||
|
onPressed: () {
|
||||||
|
debugPrint('show user profile');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
MenuItemType get type => MenuItemType.userProfile;
|
||||||
|
}
|
@ -1,2 +1 @@
|
|||||||
export 'menu.dart';
|
export 'menu.dart';
|
||||||
export 'menu_size.dart';
|
|
||||||
|
@ -49,4 +49,4 @@ SPEC CHECKSUMS:
|
|||||||
|
|
||||||
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
|
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
|
||||||
|
|
||||||
COCOAPODS: 1.9.3
|
COCOAPODS: 1.10.1
|
||||||
|
@ -10,10 +10,16 @@ import '../model/document/document.dart';
|
|||||||
import '../model/document/style.dart';
|
import '../model/document/style.dart';
|
||||||
import '../model/document/node/embed.dart';
|
import '../model/document/node/embed.dart';
|
||||||
|
|
||||||
|
abstract class EditorPersistence {
|
||||||
|
Future<bool> save(List<dynamic> jsonList);
|
||||||
|
}
|
||||||
|
|
||||||
class EditorController extends ChangeNotifier {
|
class EditorController extends ChangeNotifier {
|
||||||
|
final EditorPersistence? persistence;
|
||||||
EditorController({
|
EditorController({
|
||||||
required this.document,
|
required this.document,
|
||||||
required this.selection,
|
required this.selection,
|
||||||
|
this.persistence,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory EditorController.basic() {
|
factory EditorController.basic() {
|
||||||
@ -38,7 +44,8 @@ class EditorController extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Style getSelectionStyle() =>
|
Style getSelectionStyle() =>
|
||||||
document.collectStyle(selection.start, selection.end - selection.start)..mergeAll(toggledStyle);
|
document.collectStyle(selection.start, selection.end - selection.start)
|
||||||
|
..mergeAll(toggledStyle);
|
||||||
|
|
||||||
bool get hasUndo => document.hasUndo;
|
bool get hasUndo => document.hasUndo;
|
||||||
|
|
||||||
@ -58,10 +65,10 @@ class EditorController extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> save() async {
|
void save() {
|
||||||
document.toDelta().toJson();
|
if (persistence != null) {
|
||||||
// TODO: vedon - Save document to database
|
persistence!.save(document.toDelta().toJson());
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -80,7 +87,9 @@ class EditorController extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void formatText(int index, int length, Attribute? attribute) {
|
void formatText(int index, int length, Attribute? attribute) {
|
||||||
if (length == 0 && attribute!.isInline && attribute.key != Attribute.link.key) {
|
if (length == 0 &&
|
||||||
|
attribute!.isInline &&
|
||||||
|
attribute.key != Attribute.link.key) {
|
||||||
toggledStyle = toggledStyle.put(attribute);
|
toggledStyle = toggledStyle.put(attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,16 +104,25 @@ class EditorController extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
void replaceText(int index, int length, Object? data, TextSelection? textSelection) {
|
void replaceText(
|
||||||
|
int index, int length, Object? data, TextSelection? textSelection) {
|
||||||
assert(data is String || data is Embeddable);
|
assert(data is String || data is Embeddable);
|
||||||
|
|
||||||
Delta? delta;
|
Delta? delta;
|
||||||
if (length > 0 || data is! String || data.isNotEmpty) {
|
if (length > 0 || data is! String || data.isNotEmpty) {
|
||||||
delta = document.replace(index, length, data);
|
delta = document.replace(index, length, data);
|
||||||
var shouldRetainDelta = toggledStyle.isNotEmpty && delta.isNotEmpty && delta.length <= 2 && delta.last.isInsert;
|
print(delta);
|
||||||
if (shouldRetainDelta && toggledStyle.isNotEmpty && delta.length == 2 && delta.last.data == '\n') {
|
var shouldRetainDelta = toggledStyle.isNotEmpty &&
|
||||||
|
delta.isNotEmpty &&
|
||||||
|
delta.length <= 2 &&
|
||||||
|
delta.last.isInsert;
|
||||||
|
if (shouldRetainDelta &&
|
||||||
|
toggledStyle.isNotEmpty &&
|
||||||
|
delta.length == 2 &&
|
||||||
|
delta.last.data == '\n') {
|
||||||
// if all attributes are inline, shouldRetainDelta should be false
|
// if all attributes are inline, shouldRetainDelta should be false
|
||||||
final anyAttributeNotInline = toggledStyle.values.any((attr) => !attr.isInline);
|
final anyAttributeNotInline =
|
||||||
|
toggledStyle.values.any((attr) => !attr.isInline);
|
||||||
shouldRetainDelta &= anyAttributeNotInline;
|
shouldRetainDelta &= anyAttributeNotInline;
|
||||||
}
|
}
|
||||||
if (shouldRetainDelta) {
|
if (shouldRetainDelta) {
|
||||||
@ -146,7 +164,8 @@ class EditorController extends ChangeNotifier {
|
|||||||
|
|
||||||
textSelection = selection.copyWith(
|
textSelection = selection.copyWith(
|
||||||
baseOffset: delta.transformPosition(selection.baseOffset, force: false),
|
baseOffset: delta.transformPosition(selection.baseOffset, force: false),
|
||||||
extentOffset: delta.transformPosition(selection.extentOffset, force: false),
|
extentOffset:
|
||||||
|
delta.transformPosition(selection.extentOffset, force: false),
|
||||||
);
|
);
|
||||||
if (selection != textSelection) {
|
if (selection != textSelection) {
|
||||||
_updateSelection(textSelection, source);
|
_updateSelection(textSelection, source);
|
||||||
|
@ -60,7 +60,8 @@ class RawEditor extends StatefulWidget {
|
|||||||
this.embedBuilder,
|
this.embedBuilder,
|
||||||
) : assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
|
) : assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
|
||||||
assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'),
|
assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'),
|
||||||
assert(maxHeight == null || minHeight == null || maxHeight >= minHeight),
|
assert(
|
||||||
|
maxHeight == null || minHeight == null || maxHeight >= minHeight),
|
||||||
showCursor = showCursor ?? true,
|
showCursor = showCursor ?? true,
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
@ -111,7 +112,10 @@ abstract class EditorState extends State<RawEditor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _RawEditorState extends EditorState
|
class _RawEditorState extends EditorState
|
||||||
with AutomaticKeepAliveClientMixin<RawEditor>, WidgetsBindingObserver, TickerProviderStateMixin<RawEditor>
|
with
|
||||||
|
AutomaticKeepAliveClientMixin<RawEditor>,
|
||||||
|
WidgetsBindingObserver,
|
||||||
|
TickerProviderStateMixin<RawEditor>
|
||||||
implements TextSelectionDelegate, TextInputClient {
|
implements TextSelectionDelegate, TextInputClient {
|
||||||
final GlobalKey _editorKey = GlobalKey();
|
final GlobalKey _editorKey = GlobalKey();
|
||||||
final List<TextEditingValue> _sentRemoteValues = [];
|
final List<TextEditingValue> _sentRemoteValues = [];
|
||||||
@ -129,7 +133,8 @@ class _RawEditorState extends EditorState
|
|||||||
bool _didAutoFocus = false;
|
bool _didAutoFocus = false;
|
||||||
bool _keyboardVisible = false;
|
bool _keyboardVisible = false;
|
||||||
DefaultStyles? _styles;
|
DefaultStyles? _styles;
|
||||||
final ClipboardStatusNotifier? _clipboardStatus = kIsWeb ? null : ClipboardStatusNotifier();
|
final ClipboardStatusNotifier? _clipboardStatus =
|
||||||
|
kIsWeb ? null : ClipboardStatusNotifier();
|
||||||
final LayerLink _toolbarLayerLink = LayerLink();
|
final LayerLink _toolbarLayerLink = LayerLink();
|
||||||
final LayerLink _startHandleLayerLink = LayerLink();
|
final LayerLink _startHandleLayerLink = LayerLink();
|
||||||
final LayerLink _endHandleLayerLink = LayerLink();
|
final LayerLink _endHandleLayerLink = LayerLink();
|
||||||
@ -177,57 +182,78 @@ class _RawEditorState extends EditorState
|
|||||||
downKey = key == LogicalKeyboardKey.arrowDown;
|
downKey = key == LogicalKeyboardKey.arrowDown;
|
||||||
|
|
||||||
if ((rightKey || leftKey) && !(rightKey && leftKey)) {
|
if ((rightKey || leftKey) && !(rightKey && leftKey)) {
|
||||||
newSelection =
|
newSelection = _jumpToBeginOrEndOfWord(newSelection, wordModifier,
|
||||||
_jumpToBeginOrEndOfWord(newSelection, wordModifier, leftKey, rightKey, plainText, lineModifier, shift);
|
leftKey, rightKey, plainText, lineModifier, shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downKey || upKey) {
|
if (downKey || upKey) {
|
||||||
newSelection = _handleMovingCursorVertically(upKey, downKey, shift, selection, newSelection, plainText);
|
newSelection = _handleMovingCursorVertically(
|
||||||
|
upKey, downKey, shift, selection, newSelection, plainText);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shift) {
|
if (!shift) {
|
||||||
newSelection = _placeCollapsedSelection(selection, newSelection, leftKey, rightKey);
|
newSelection =
|
||||||
|
_placeCollapsedSelection(selection, newSelection, leftKey, rightKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.controller.updateSelection(newSelection, ChangeSource.LOCAL);
|
widget.controller.updateSelection(newSelection, ChangeSource.LOCAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection _placeCollapsedSelection(
|
TextSelection _placeCollapsedSelection(TextSelection selection,
|
||||||
TextSelection selection, TextSelection newSelection, bool leftKey, bool rightKey) {
|
TextSelection newSelection, bool leftKey, bool rightKey) {
|
||||||
var newOffset = newSelection.extentOffset;
|
var newOffset = newSelection.extentOffset;
|
||||||
if (!selection.isCollapsed) {
|
if (!selection.isCollapsed) {
|
||||||
if (leftKey) {
|
if (leftKey) {
|
||||||
newOffset =
|
newOffset = newSelection.baseOffset < newSelection.extentOffset
|
||||||
newSelection.baseOffset < newSelection.extentOffset ? newSelection.baseOffset : newSelection.extentOffset;
|
? newSelection.baseOffset
|
||||||
|
: newSelection.extentOffset;
|
||||||
} else if (rightKey) {
|
} else if (rightKey) {
|
||||||
newOffset =
|
newOffset = newSelection.baseOffset > newSelection.extentOffset
|
||||||
newSelection.baseOffset > newSelection.extentOffset ? newSelection.baseOffset : newSelection.extentOffset;
|
? newSelection.baseOffset
|
||||||
|
: newSelection.extentOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TextSelection.fromPosition(TextPosition(offset: newOffset));
|
return TextSelection.fromPosition(TextPosition(offset: newOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection _handleMovingCursorVertically(
|
TextSelection _handleMovingCursorVertically(
|
||||||
bool upKey, bool downKey, bool shift, TextSelection selection, TextSelection newSelection, String plainText) {
|
bool upKey,
|
||||||
final originPosition = TextPosition(offset: upKey ? selection.baseOffset : selection.extentOffset);
|
bool downKey,
|
||||||
|
bool shift,
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelection newSelection,
|
||||||
|
String plainText) {
|
||||||
|
final originPosition = TextPosition(
|
||||||
|
offset: upKey ? selection.baseOffset : selection.extentOffset);
|
||||||
|
|
||||||
final child = getRenderEditor()!.childAtPosition(originPosition);
|
final child = getRenderEditor()!.childAtPosition(originPosition);
|
||||||
final localPosition = TextPosition(offset: originPosition.offset - child.container.documentOffset);
|
final localPosition = TextPosition(
|
||||||
|
offset: originPosition.offset - child.container.documentOffset);
|
||||||
|
|
||||||
var position = upKey ? child.getPositionAbove(localPosition) : child.getPositionBelow(localPosition);
|
var position = upKey
|
||||||
|
? child.getPositionAbove(localPosition)
|
||||||
|
: child.getPositionBelow(localPosition);
|
||||||
|
|
||||||
if (position == null) {
|
if (position == null) {
|
||||||
final sibling = upKey ? getRenderEditor()!.childBefore(child) : getRenderEditor()!.childAfter(child);
|
final sibling = upKey
|
||||||
|
? getRenderEditor()!.childBefore(child)
|
||||||
|
: getRenderEditor()!.childAfter(child);
|
||||||
if (sibling == null) {
|
if (sibling == null) {
|
||||||
position = TextPosition(offset: upKey ? 0 : plainText.length - 1);
|
position = TextPosition(offset: upKey ? 0 : plainText.length - 1);
|
||||||
} else {
|
} else {
|
||||||
final finalOffset = Offset(child.getOffsetForCaret(localPosition).dx,
|
final finalOffset = Offset(
|
||||||
sibling.getOffsetForCaret(TextPosition(offset: upKey ? sibling.container.length - 1 : 0)).dy);
|
child.getOffsetForCaret(localPosition).dx,
|
||||||
|
sibling
|
||||||
|
.getOffsetForCaret(TextPosition(
|
||||||
|
offset: upKey ? sibling.container.length - 1 : 0))
|
||||||
|
.dy);
|
||||||
final siblingPosition = sibling.getPositionForOffset(finalOffset);
|
final siblingPosition = sibling.getPositionForOffset(finalOffset);
|
||||||
position = TextPosition(offset: sibling.container.documentOffset + siblingPosition.offset);
|
position = TextPosition(
|
||||||
|
offset: sibling.container.documentOffset + siblingPosition.offset);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
position = TextPosition(offset: child.container.documentOffset + position.offset);
|
position = TextPosition(
|
||||||
|
offset: child.container.documentOffset + position.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position.offset == newSelection.extentOffset) {
|
if (position.offset == newSelection.extentOffset) {
|
||||||
@ -250,33 +276,47 @@ class _RawEditorState extends EditorState
|
|||||||
return newSelection;
|
return newSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection _jumpToBeginOrEndOfWord(TextSelection newSelection, bool wordModifier, bool leftKey, bool rightKey,
|
TextSelection _jumpToBeginOrEndOfWord(
|
||||||
String plainText, bool lineModifier, bool shift) {
|
TextSelection newSelection,
|
||||||
|
bool wordModifier,
|
||||||
|
bool leftKey,
|
||||||
|
bool rightKey,
|
||||||
|
String plainText,
|
||||||
|
bool lineModifier,
|
||||||
|
bool shift) {
|
||||||
if (wordModifier) {
|
if (wordModifier) {
|
||||||
if (leftKey) {
|
if (leftKey) {
|
||||||
final textSelection = getRenderEditor()!.selectWordAtPosition(
|
final textSelection = getRenderEditor()!.selectWordAtPosition(
|
||||||
TextPosition(offset: _previousCharacter(newSelection.extentOffset, plainText, false)));
|
TextPosition(
|
||||||
|
offset: _previousCharacter(
|
||||||
|
newSelection.extentOffset, plainText, false)));
|
||||||
return newSelection.copyWith(extentOffset: textSelection.baseOffset);
|
return newSelection.copyWith(extentOffset: textSelection.baseOffset);
|
||||||
}
|
}
|
||||||
final textSelection = getRenderEditor()!
|
final textSelection = getRenderEditor()!.selectWordAtPosition(
|
||||||
.selectWordAtPosition(TextPosition(offset: _nextCharacter(newSelection.extentOffset, plainText, false)));
|
TextPosition(
|
||||||
|
offset:
|
||||||
|
_nextCharacter(newSelection.extentOffset, plainText, false)));
|
||||||
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
|
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
|
||||||
} else if (lineModifier) {
|
} else if (lineModifier) {
|
||||||
if (leftKey) {
|
if (leftKey) {
|
||||||
final textSelection = getRenderEditor()!.selectLineAtPosition(
|
final textSelection = getRenderEditor()!.selectLineAtPosition(
|
||||||
TextPosition(offset: _previousCharacter(newSelection.extentOffset, plainText, false)));
|
TextPosition(
|
||||||
|
offset: _previousCharacter(
|
||||||
|
newSelection.extentOffset, plainText, false)));
|
||||||
return newSelection.copyWith(extentOffset: textSelection.baseOffset);
|
return newSelection.copyWith(extentOffset: textSelection.baseOffset);
|
||||||
}
|
}
|
||||||
final startPoint = newSelection.extentOffset;
|
final startPoint = newSelection.extentOffset;
|
||||||
if (startPoint < plainText.length) {
|
if (startPoint < plainText.length) {
|
||||||
final textSelection = getRenderEditor()!.selectLineAtPosition(TextPosition(offset: startPoint));
|
final textSelection = getRenderEditor()!
|
||||||
|
.selectLineAtPosition(TextPosition(offset: startPoint));
|
||||||
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
|
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
|
||||||
}
|
}
|
||||||
return newSelection;
|
return newSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rightKey && newSelection.extentOffset < plainText.length) {
|
if (rightKey && newSelection.extentOffset < plainText.length) {
|
||||||
final nextExtent = _nextCharacter(newSelection.extentOffset, plainText, true);
|
final nextExtent =
|
||||||
|
_nextCharacter(newSelection.extentOffset, plainText, true);
|
||||||
final distance = nextExtent - newSelection.extentOffset;
|
final distance = nextExtent - newSelection.extentOffset;
|
||||||
newSelection = newSelection.copyWith(extentOffset: nextExtent);
|
newSelection = newSelection.copyWith(extentOffset: nextExtent);
|
||||||
if (shift) {
|
if (shift) {
|
||||||
@ -286,7 +326,8 @@ class _RawEditorState extends EditorState
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (leftKey && newSelection.extentOffset > 0) {
|
if (leftKey && newSelection.extentOffset > 0) {
|
||||||
final previousExtent = _previousCharacter(newSelection.extentOffset, plainText, true);
|
final previousExtent =
|
||||||
|
_previousCharacter(newSelection.extentOffset, plainText, true);
|
||||||
final distance = newSelection.extentOffset - previousExtent;
|
final distance = newSelection.extentOffset - previousExtent;
|
||||||
newSelection = newSelection.copyWith(extentOffset: previousExtent);
|
newSelection = newSelection.copyWith(extentOffset: previousExtent);
|
||||||
if (shift) {
|
if (shift) {
|
||||||
@ -326,7 +367,9 @@ class _RawEditorState extends EditorState
|
|||||||
var count = 0;
|
var count = 0;
|
||||||
int? lastNonWhitespace;
|
int? lastNonWhitespace;
|
||||||
for (final currentString in string.characters) {
|
for (final currentString in string.characters) {
|
||||||
if (!includeWhitespace && !WHITE_SPACE.contains(currentString.characters.first.toString().codeUnitAt(0))) {
|
if (!includeWhitespace &&
|
||||||
|
!WHITE_SPACE.contains(
|
||||||
|
currentString.characters.first.toString().codeUnitAt(0))) {
|
||||||
lastNonWhitespace = count;
|
lastNonWhitespace = count;
|
||||||
}
|
}
|
||||||
if (count + currentString.length >= index) {
|
if (count + currentString.length >= index) {
|
||||||
@ -337,7 +380,8 @@ class _RawEditorState extends EditorState
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get hasConnection => _textInputConnection != null && _textInputConnection!.attached;
|
bool get hasConnection =>
|
||||||
|
_textInputConnection != null && _textInputConnection!.attached;
|
||||||
|
|
||||||
void openConnectionIfNeeded() {
|
void openConnectionIfNeeded() {
|
||||||
if (!shouldCreateInputConnection) {
|
if (!shouldCreateInputConnection) {
|
||||||
@ -388,7 +432,8 @@ class _RawEditorState extends EditorState
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final shouldRemember = textEditingValue.text != _lastKnownRemoteTextEditingValue!.text;
|
final shouldRemember =
|
||||||
|
textEditingValue.text != _lastKnownRemoteTextEditingValue!.text;
|
||||||
_lastKnownRemoteTextEditingValue = actualValue;
|
_lastKnownRemoteTextEditingValue = actualValue;
|
||||||
_textInputConnection!.setEditingState(actualValue);
|
_textInputConnection!.setEditingState(actualValue);
|
||||||
if (shouldRemember) {
|
if (shouldRemember) {
|
||||||
@ -397,7 +442,8 @@ class _RawEditorState extends EditorState
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TextEditingValue? get currentTextEditingValue => _lastKnownRemoteTextEditingValue;
|
TextEditingValue? get currentTextEditingValue =>
|
||||||
|
_lastKnownRemoteTextEditingValue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
AutofillScope? get currentAutofillScope => null;
|
AutofillScope? get currentAutofillScope => null;
|
||||||
@ -429,7 +475,8 @@ class _RawEditorState extends EditorState
|
|||||||
final text = value.text;
|
final text = value.text;
|
||||||
final cursorPosition = value.selection.extentOffset;
|
final cursorPosition = value.selection.extentOffset;
|
||||||
final diff = getDiff(oldText, text, cursorPosition);
|
final diff = getDiff(oldText, text, cursorPosition);
|
||||||
widget.controller.replaceText(diff.start, diff.deleted.length, diff.inserted, value.selection);
|
widget.controller.replaceText(
|
||||||
|
diff.start, diff.deleted.length, diff.inserted, value.selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -479,8 +526,11 @@ class _RawEditorState extends EditorState
|
|||||||
super.build(context);
|
super.build(context);
|
||||||
|
|
||||||
var _doc = widget.controller.document;
|
var _doc = widget.controller.document;
|
||||||
if (_doc.isEmpty() && !widget.focusNode.hasFocus && widget.placeholder != null) {
|
if (_doc.isEmpty() &&
|
||||||
_doc = Document.fromJson(jsonDecode('[{"attributes":{"placeholder":true},"insert":"${widget.placeholder}\\n"}]'));
|
!widget.focusNode.hasFocus &&
|
||||||
|
widget.placeholder != null) {
|
||||||
|
_doc = Document.fromJson(jsonDecode(
|
||||||
|
'[{"attributes":{"placeholder":true},"insert":"${widget.placeholder}\\n"}]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget child = CompositedTransformTarget(
|
Widget child = CompositedTransformTarget(
|
||||||
@ -503,7 +553,8 @@ class _RawEditorState extends EditorState
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (widget.scrollable) {
|
if (widget.scrollable) {
|
||||||
final baselinePadding = EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.item1);
|
final baselinePadding =
|
||||||
|
EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.item1);
|
||||||
child = BaselineProxy(
|
child = BaselineProxy(
|
||||||
textStyle: _styles!.paragraph!.style,
|
textStyle: _styles!.paragraph!.style,
|
||||||
padding: baselinePadding,
|
padding: baselinePadding,
|
||||||
@ -534,7 +585,8 @@ class _RawEditorState extends EditorState
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleSelectionChanged(TextSelection selection, SelectionChangedCause cause) {
|
void _handleSelectionChanged(
|
||||||
|
TextSelection selection, SelectionChangedCause cause) {
|
||||||
widget.controller.updateSelection(selection, ChangeSource.LOCAL);
|
widget.controller.updateSelection(selection, ChangeSource.LOCAL);
|
||||||
|
|
||||||
_selectionOverlay?.handlesVisible = _shouldShowSelectionHandles();
|
_selectionOverlay?.handlesVisible = _shouldShowSelectionHandles();
|
||||||
@ -563,7 +615,9 @@ class _RawEditorState extends EditorState
|
|||||||
_styles,
|
_styles,
|
||||||
widget.enableInteractiveSelection,
|
widget.enableInteractiveSelection,
|
||||||
_hasFocus,
|
_hasFocus,
|
||||||
attrs.containsKey(Attribute.codeBlock.key) ? const EdgeInsets.all(16) : null,
|
attrs.containsKey(Attribute.codeBlock.key)
|
||||||
|
? const EdgeInsets.all(16)
|
||||||
|
: null,
|
||||||
widget.embedBuilder,
|
widget.embedBuilder,
|
||||||
_cursorController,
|
_cursorController,
|
||||||
indentLevelCounts);
|
indentLevelCounts);
|
||||||
@ -575,7 +629,8 @@ class _RawEditorState extends EditorState
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditableTextLine _getEditableTextLineFromNode(Line node, BuildContext context) {
|
EditableTextLine _getEditableTextLineFromNode(
|
||||||
|
Line node, BuildContext context) {
|
||||||
final textLine = TextLine(
|
final textLine = TextLine(
|
||||||
line: node,
|
line: node,
|
||||||
textDirection: _textDirection,
|
textDirection: _textDirection,
|
||||||
@ -598,7 +653,8 @@ class _RawEditorState extends EditorState
|
|||||||
return editableTextLine;
|
return editableTextLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple2<double, double> _getVerticalSpacingForLine(Line line, DefaultStyles? defaultStyles) {
|
Tuple2<double, double> _getVerticalSpacingForLine(
|
||||||
|
Line line, DefaultStyles? defaultStyles) {
|
||||||
final attrs = line.style.attributes;
|
final attrs = line.style.attributes;
|
||||||
if (attrs.containsKey(Attribute.header.key)) {
|
if (attrs.containsKey(Attribute.header.key)) {
|
||||||
final int? level = attrs[Attribute.header.key]!.value;
|
final int? level = attrs[Attribute.header.key]!.value;
|
||||||
@ -623,7 +679,8 @@ class _RawEditorState extends EditorState
|
|||||||
return defaultStyles!.paragraph!.verticalSpacing;
|
return defaultStyles!.paragraph!.verticalSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple2<double, double> _getVerticalSpacingForBlock(Block node, DefaultStyles? defaultStyles) {
|
Tuple2<double, double> _getVerticalSpacingForBlock(
|
||||||
|
Block node, DefaultStyles? defaultStyles) {
|
||||||
final attrs = node.style.attributes;
|
final attrs = node.style.attributes;
|
||||||
if (attrs.containsKey(Attribute.quoteBlock.key)) {
|
if (attrs.containsKey(Attribute.quoteBlock.key)) {
|
||||||
return defaultStyles!.quote!.verticalSpacing;
|
return defaultStyles!.quote!.verticalSpacing;
|
||||||
@ -666,7 +723,8 @@ class _RawEditorState extends EditorState
|
|||||||
} else {
|
} else {
|
||||||
_keyboardVisibilityController = KeyboardVisibilityController();
|
_keyboardVisibilityController = KeyboardVisibilityController();
|
||||||
_keyboardVisible = _keyboardVisibilityController!.isVisible;
|
_keyboardVisible = _keyboardVisibilityController!.isVisible;
|
||||||
_keyboardVisibilitySubscription = _keyboardVisibilityController?.onChange.listen((visible) {
|
_keyboardVisibilitySubscription =
|
||||||
|
_keyboardVisibilityController?.onChange.listen((visible) {
|
||||||
_keyboardVisible = visible;
|
_keyboardVisible = visible;
|
||||||
if (visible) {
|
if (visible) {
|
||||||
_onChangeTextEditingValue();
|
_onChangeTextEditingValue();
|
||||||
@ -689,7 +747,9 @@ class _RawEditorState extends EditorState
|
|||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
final parentStyles = EditorStyles.getStyles(context, true);
|
final parentStyles = EditorStyles.getStyles(context, true);
|
||||||
final defaultStyles = DefaultStyles.getInstance(context);
|
final defaultStyles = DefaultStyles.getInstance(context);
|
||||||
_styles = (parentStyles != null) ? defaultStyles.merge(parentStyles) : defaultStyles;
|
_styles = (parentStyles != null)
|
||||||
|
? defaultStyles.merge(parentStyles)
|
||||||
|
: defaultStyles;
|
||||||
|
|
||||||
if (widget.customStyles != null) {
|
if (widget.customStyles != null) {
|
||||||
_styles = _styles!.merge(widget.customStyles!);
|
_styles = _styles!.merge(widget.customStyles!);
|
||||||
@ -749,7 +809,8 @@ class _RawEditorState extends EditorState
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool _shouldShowSelectionHandles() {
|
bool _shouldShowSelectionHandles() {
|
||||||
return widget.showSelectionHandles && !widget.controller.selection.isCollapsed;
|
return widget.showSelectionHandles &&
|
||||||
|
!widget.controller.selection.isCollapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDelete(bool forward) {
|
void handleDelete(bool forward) {
|
||||||
@ -760,7 +821,8 @@ class _RawEditorState extends EditorState
|
|||||||
var textAfter = selection.textAfter(plainText);
|
var textAfter = selection.textAfter(plainText);
|
||||||
if (selection.isCollapsed) {
|
if (selection.isCollapsed) {
|
||||||
if (!forward && textBefore.isNotEmpty) {
|
if (!forward && textBefore.isNotEmpty) {
|
||||||
final characterBoundary = _previousCharacter(textBefore.length, textBefore, true);
|
final characterBoundary =
|
||||||
|
_previousCharacter(textBefore.length, textBefore, true);
|
||||||
textBefore = textBefore.substring(0, characterBoundary);
|
textBefore = textBefore.substring(0, characterBoundary);
|
||||||
cursorPosition = characterBoundary;
|
cursorPosition = characterBoundary;
|
||||||
}
|
}
|
||||||
@ -784,15 +846,13 @@ class _RawEditorState extends EditorState
|
|||||||
final selection = widget.controller.selection;
|
final selection = widget.controller.selection;
|
||||||
final plainText = textEditingValue.text;
|
final plainText = textEditingValue.text;
|
||||||
if (shortcut == InputShortcut.SAVE) {
|
if (shortcut == InputShortcut.SAVE) {
|
||||||
bool saved = await widget.controller.save();
|
widget.controller.save();
|
||||||
if (!saved) {
|
|
||||||
log('Unabled to save document.');
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (shortcut == InputShortcut.COPY) {
|
if (shortcut == InputShortcut.COPY) {
|
||||||
if (!selection.isCollapsed) {
|
if (!selection.isCollapsed) {
|
||||||
await Clipboard.setData(ClipboardData(text: selection.textInside(plainText)));
|
await Clipboard.setData(
|
||||||
|
ClipboardData(text: selection.textInside(plainText)));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -809,7 +869,8 @@ class _RawEditorState extends EditorState
|
|||||||
);
|
);
|
||||||
|
|
||||||
textEditingValue = TextEditingValue(
|
textEditingValue = TextEditingValue(
|
||||||
text: selection.textBefore(plainText) + selection.textAfter(plainText),
|
text:
|
||||||
|
selection.textBefore(plainText) + selection.textAfter(plainText),
|
||||||
selection: TextSelection.collapsed(offset: selection.start),
|
selection: TextSelection.collapsed(offset: selection.start),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -827,7 +888,8 @@ class _RawEditorState extends EditorState
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (shortcut == InputShortcut.SELECT_ALL && widget.enableInteractiveSelection) {
|
if (shortcut == InputShortcut.SELECT_ALL &&
|
||||||
|
widget.enableInteractiveSelection) {
|
||||||
widget.controller.updateSelection(
|
widget.controller.updateSelection(
|
||||||
selection.copyWith(
|
selection.copyWith(
|
||||||
baseOffset: 0,
|
baseOffset: 0,
|
||||||
@ -881,14 +943,16 @@ class _RawEditorState extends EditorState
|
|||||||
void _onChangeTextEditingValue() {
|
void _onChangeTextEditingValue() {
|
||||||
_showCaretOnScreen();
|
_showCaretOnScreen();
|
||||||
updateRemoteValueIfNeeded();
|
updateRemoteValueIfNeeded();
|
||||||
_cursorController.startOrStopCursorTimerIfNeeded(_hasFocus, widget.controller.selection);
|
_cursorController.startOrStopCursorTimerIfNeeded(
|
||||||
|
_hasFocus, widget.controller.selection);
|
||||||
if (hasConnection) {
|
if (hasConnection) {
|
||||||
_cursorController
|
_cursorController
|
||||||
..stopCursorTimer(resetCharTicks: false)
|
..stopCursorTimer(resetCharTicks: false)
|
||||||
..startCursorTimer();
|
..startCursorTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
SchedulerBinding.instance!.addPostFrameCallback((_) => _updateOrDisposeSelectionOverlayIfNeeded());
|
SchedulerBinding.instance!.addPostFrameCallback(
|
||||||
|
(_) => _updateOrDisposeSelectionOverlayIfNeeded());
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
// Use widget.controller.value in build()
|
// Use widget.controller.value in build()
|
||||||
@ -931,7 +995,8 @@ class _RawEditorState extends EditorState
|
|||||||
|
|
||||||
void _handleFocusChanged() {
|
void _handleFocusChanged() {
|
||||||
openOrCloseConnection();
|
openOrCloseConnection();
|
||||||
_cursorController.startOrStopCursorTimerIfNeeded(_hasFocus, widget.controller.selection);
|
_cursorController.startOrStopCursorTimerIfNeeded(
|
||||||
|
_hasFocus, widget.controller.selection);
|
||||||
_updateOrDisposeSelectionOverlayIfNeeded();
|
_updateOrDisposeSelectionOverlayIfNeeded();
|
||||||
if (_hasFocus) {
|
if (_hasFocus) {
|
||||||
WidgetsBinding.instance!.addObserver(this);
|
WidgetsBinding.instance!.addObserver(this);
|
||||||
@ -962,7 +1027,8 @@ class _RawEditorState extends EditorState
|
|||||||
_showCaretOnScreenScheduled = false;
|
_showCaretOnScreenScheduled = false;
|
||||||
|
|
||||||
final viewport = RenderAbstractViewport.of(getRenderEditor())!;
|
final viewport = RenderAbstractViewport.of(getRenderEditor())!;
|
||||||
final editorOffset = getRenderEditor()!.localToGlobal(const Offset(0, 0), ancestor: viewport);
|
final editorOffset = getRenderEditor()!
|
||||||
|
.localToGlobal(const Offset(0, 0), ancestor: viewport);
|
||||||
final offsetInViewport = _scrollController!.offset + editorOffset.dy;
|
final offsetInViewport = _scrollController!.offset + editorOffset.dy;
|
||||||
|
|
||||||
final offset = getRenderEditor()!.getOffsetToRevealCursor(
|
final offset = getRenderEditor()!.getOffsetToRevealCursor(
|
||||||
@ -1045,7 +1111,8 @@ class _RawEditorState extends EditorState
|
|||||||
final value = textEditingValue;
|
final value = textEditingValue;
|
||||||
final data = await Clipboard.getData(Clipboard.kTextPlain);
|
final data = await Clipboard.getData(Clipboard.kTextPlain);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
final length = textEditingValue.selection.end - textEditingValue.selection.start;
|
final length =
|
||||||
|
textEditingValue.selection.end - textEditingValue.selection.start;
|
||||||
widget.controller.replaceText(
|
widget.controller.replaceText(
|
||||||
value.selection.start,
|
value.selection.start,
|
||||||
length,
|
length,
|
||||||
@ -1054,7 +1121,9 @@ class _RawEditorState extends EditorState
|
|||||||
);
|
);
|
||||||
// move cursor to the end of pasted text selection
|
// move cursor to the end of pasted text selection
|
||||||
widget.controller.updateSelection(
|
widget.controller.updateSelection(
|
||||||
TextSelection.collapsed(offset: value.selection.start + data.text!.length), ChangeSource.LOCAL);
|
TextSelection.collapsed(
|
||||||
|
offset: value.selection.start + data.text!.length),
|
||||||
|
ChangeSource.LOCAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1064,7 +1133,8 @@ class _RawEditorState extends EditorState
|
|||||||
if (data == null) {
|
if (data == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return textEditingValue.text.length - value.text.length == data.text!.length;
|
return textEditingValue.text.length - value.text.length ==
|
||||||
|
data.text!.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1097,7 +1167,8 @@ class _RawEditorState extends EditorState
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void userUpdateTextEditingValue(TextEditingValue value, SelectionChangedCause cause) {
|
void userUpdateTextEditingValue(
|
||||||
|
TextEditingValue value, SelectionChangedCause cause) {
|
||||||
// TODO: implement userUpdateTextEditingValue
|
// TODO: implement userUpdateTextEditingValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1147,7 +1218,8 @@ class _Editor extends MultiChildRenderObjectWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void updateRenderObject(BuildContext context, covariant RenderEditor renderObject) {
|
void updateRenderObject(
|
||||||
|
BuildContext context, covariant RenderEditor renderObject) {
|
||||||
renderObject
|
renderObject
|
||||||
..document = document
|
..document = document
|
||||||
..container = document.root
|
..container = document.root
|
||||||
|
@ -54,7 +54,7 @@ class Sizes {
|
|||||||
|
|
||||||
static double get sideBarSm => 200 * hitScale;
|
static double get sideBarSm => 200 * hitScale;
|
||||||
|
|
||||||
static double get sideBarMed => 220 * hitScale;
|
static double get sideBarMed => 240 * hitScale;
|
||||||
|
|
||||||
static double get sideBarLg => 290 * hitScale;
|
static double get sideBarLg => 290 * hitScale;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class AppTheme {
|
|||||||
switch (t) {
|
switch (t) {
|
||||||
case ThemeType.light:
|
case ThemeType.light:
|
||||||
return AppTheme(isDark: false)
|
return AppTheme(isDark: false)
|
||||||
..bg1 = const Color(0xfff1f7f0)
|
..bg1 = const Color.fromARGB(255, 247, 248, 252)
|
||||||
..bg2 = const Color(0xffc1dcbc)
|
..bg2 = const Color(0xffc1dcbc)
|
||||||
..surface = Colors.white
|
..surface = Colors.white
|
||||||
..accent1 = const Color(0xff00a086)
|
..accent1 = const Color(0xff00a086)
|
||||||
|
@ -13,4 +13,5 @@ class Durations {
|
|||||||
|
|
||||||
class RouteDurations {
|
class RouteDurations {
|
||||||
static Duration get slow => .7.seconds;
|
static Duration get slow => .7.seconds;
|
||||||
|
static Duration get medium => .35.seconds;
|
||||||
}
|
}
|
||||||
|
@ -156,6 +156,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
loading_indicator:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: loading_indicator
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
logger:
|
logger:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -296,4 +303,4 @@ packages:
|
|||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.12.0 <3.0.0"
|
dart: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.20.0"
|
flutter: ">=2.0.0"
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
// ignore: unused_import
|
||||||
|
import 'package:flowy_infra/time/duration.dart';
|
||||||
|
|
||||||
|
typedef HoverBuilder = Widget Function(BuildContext context, bool onHover);
|
||||||
|
|
||||||
|
class StyledHover extends StatefulWidget {
|
||||||
|
final Color color;
|
||||||
|
final Color borderColor;
|
||||||
|
final double borderWidth;
|
||||||
|
final BorderRadius borderRadius;
|
||||||
|
final HoverBuilder builder;
|
||||||
|
|
||||||
|
const StyledHover({
|
||||||
|
Key? key,
|
||||||
|
required this.color,
|
||||||
|
this.borderColor = Colors.transparent,
|
||||||
|
this.borderWidth = 0,
|
||||||
|
this.borderRadius = BorderRadius.zero,
|
||||||
|
required this.builder,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StyledHover> createState() => _StyledHoverState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _StyledHoverState extends State<StyledHover> {
|
||||||
|
bool _onHover = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final hoverColor =
|
||||||
|
_onHover ? widget.color : Theme.of(context).colorScheme.background;
|
||||||
|
|
||||||
|
final hoverBorder = Border.all(
|
||||||
|
color: widget.borderColor,
|
||||||
|
width: widget.borderWidth,
|
||||||
|
);
|
||||||
|
|
||||||
|
return MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.click,
|
||||||
|
onEnter: (p) => setOnHover(true),
|
||||||
|
onExit: (p) => setOnHover(false),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: hoverBorder,
|
||||||
|
color: hoverColor,
|
||||||
|
borderRadius: widget.borderRadius,
|
||||||
|
),
|
||||||
|
// duration: .1.seconds,
|
||||||
|
child: widget.builder(context, _onHover),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnHover(bool value) => setState(() => _onHover = value);
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class StyledIconButton extends StatelessWidget {
|
||||||
|
final double width;
|
||||||
|
final double? height;
|
||||||
|
final double iconRatio;
|
||||||
|
final Icon icon;
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
|
||||||
|
const StyledIconButton({
|
||||||
|
Key? key,
|
||||||
|
this.height,
|
||||||
|
this.onPressed,
|
||||||
|
this.width = 30,
|
||||||
|
required this.icon,
|
||||||
|
this.iconRatio = 0.5,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
width: width,
|
||||||
|
height: height ?? width,
|
||||||
|
child: IconButton(
|
||||||
|
icon: icon,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
iconSize: width * iconRatio,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
onPressed: onPressed,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StyledMore extends StatelessWidget {
|
||||||
|
final double width;
|
||||||
|
final double? height;
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
|
||||||
|
const StyledMore({
|
||||||
|
Key? key,
|
||||||
|
this.height,
|
||||||
|
this.onPressed,
|
||||||
|
required this.width,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return StyledIconButton(
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
icon: const Icon(Icons.more_vert),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
typedef NaviAction = void Function(String);
|
||||||
|
|
||||||
|
abstract class NaviItem {
|
||||||
|
String get identifier;
|
||||||
|
NaviAction get action;
|
||||||
|
}
|
||||||
|
|
||||||
|
class StyledNavigationController extends ChangeNotifier {
|
||||||
|
List<NaviItem> naviItems;
|
||||||
|
StyledNavigationController({this.naviItems = const []});
|
||||||
|
}
|
||||||
|
|
||||||
|
class StyledNavigationList extends StatelessWidget {
|
||||||
|
const StyledNavigationList({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MultiProvider(
|
||||||
|
providers: [
|
||||||
|
ChangeNotifierProvider(create: (_) => StyledNavigationController()),
|
||||||
|
],
|
||||||
|
child: Consumer(builder: (ctx, StyledNavigationController ctrl, child) {
|
||||||
|
return Row(
|
||||||
|
children: _buildNaviItemWidget(ctrl.naviItems),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildNaviItemWidget(List<NaviItem> items) {
|
||||||
|
if (items.isEmpty) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NaviItem> newItems = _selectNaviItem(items);
|
||||||
|
Widget last = NaviItemWidget(newItems.removeLast());
|
||||||
|
|
||||||
|
List<Widget> widgets = newItems
|
||||||
|
.map(
|
||||||
|
(item) => NaviItemDivider(
|
||||||
|
child: NaviItemWidget(item),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
widgets.add(last);
|
||||||
|
|
||||||
|
return widgets;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NaviItem> _selectNaviItem(List<NaviItem> items) {
|
||||||
|
final length = items.length;
|
||||||
|
if (length > 4) {
|
||||||
|
final ellipsisItems = items.getRange(1, length - 2).toList();
|
||||||
|
return [
|
||||||
|
items[0],
|
||||||
|
EllipsisNaviItem(items: ellipsisItems),
|
||||||
|
items[length - 2],
|
||||||
|
items[length - 1]
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NaviItemWidget extends StatelessWidget {
|
||||||
|
final NaviItem item;
|
||||||
|
const NaviItemWidget(this.item, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
child: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NaviItemDivider extends StatelessWidget {
|
||||||
|
final Widget child;
|
||||||
|
const NaviItemDivider({Key? key, required this.child}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [child, const Text('/')],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EllipsisNaviItem extends NaviItem {
|
||||||
|
final List<NaviItem> items;
|
||||||
|
EllipsisNaviItem({
|
||||||
|
required this.items,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
// TODO: implement action
|
||||||
|
NaviAction get action => throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
// TODO: implement identifier
|
||||||
|
String get identifier => throw UnimplementedError();
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:loading_indicator/loading_indicator.dart';
|
||||||
|
|
||||||
|
List<Color> _kDefaultRainbowColors = const [
|
||||||
|
Colors.red,
|
||||||
|
Colors.orange,
|
||||||
|
Colors.yellow,
|
||||||
|
Colors.green,
|
||||||
|
Colors.blue,
|
||||||
|
Colors.indigo,
|
||||||
|
Colors.purple,
|
||||||
|
];
|
||||||
|
|
||||||
|
// CircularProgressIndicator()
|
||||||
|
class StyledProgressIndicator extends StatelessWidget {
|
||||||
|
const StyledProgressIndicator({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox.expand(
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 60,
|
||||||
|
child: LoadingIndicator(
|
||||||
|
indicatorType: Indicator.pacman,
|
||||||
|
colors: _kDefaultRainbowColors,
|
||||||
|
strokeWidth: 4.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class StyledText extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final TextOverflow overflow;
|
||||||
|
final double fontSize;
|
||||||
|
const StyledText(
|
||||||
|
this.title, {
|
||||||
|
Key? key,
|
||||||
|
this.overflow = TextOverflow.ellipsis,
|
||||||
|
this.fontSize = 16,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Text(
|
||||||
|
title,
|
||||||
|
overflow: overflow,
|
||||||
|
softWrap: false,
|
||||||
|
style: TextStyle(fontSize: fontSize),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
import 'package:flowy_infra_ui/style_widget/styled_hover.dart';
|
||||||
|
import 'package:flowy_infra_ui/style_widget/styled_text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class StyledTextButton extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
final double fontSize;
|
||||||
|
final VoidCallback? onPressed;
|
||||||
|
final EdgeInsets padding;
|
||||||
|
const StyledTextButton(this.text,
|
||||||
|
{Key? key,
|
||||||
|
this.onPressed,
|
||||||
|
this.fontSize = 16,
|
||||||
|
this.padding = const EdgeInsets.symmetric(horizontal: 8, vertical: 6)})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: onPressed,
|
||||||
|
child: StyledHover(
|
||||||
|
color: Colors.grey.shade300,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
builder: (context, onHover) => _render(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _render() {
|
||||||
|
return Padding(
|
||||||
|
padding: padding,
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: StyledText(text, fontSize: fontSize),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return TextButton(
|
||||||
|
// style: ButtonStyle(
|
||||||
|
// textStyle: MaterialStateProperty.all(TextStyle(fontSize: fontSize)),
|
||||||
|
// alignment: Alignment.centerLeft,
|
||||||
|
// foregroundColor: MaterialStateProperty.all(Colors.black),
|
||||||
|
// padding: MaterialStateProperty.all<EdgeInsets>(
|
||||||
|
// const EdgeInsets.symmetric(horizontal: 2)),
|
||||||
|
// ),
|
||||||
|
// onPressed: onPressed,
|
||||||
|
// child: Text(
|
||||||
|
// text,
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
// softWrap: false,
|
||||||
|
// ),
|
||||||
|
// );
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
typedef HoverBuilder = Widget Function(BuildContext context, bool isHovering);
|
typedef HoverBuilder = Widget Function(BuildContext context, bool onHover);
|
||||||
|
|
||||||
class MouseHoverBuilder extends StatefulWidget {
|
class MouseHoverBuilder extends StatefulWidget {
|
||||||
final bool isClickable;
|
final bool isClickable;
|
||||||
@ -15,17 +15,17 @@ class MouseHoverBuilder extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MouseHoverBuilderState extends State<MouseHoverBuilder> {
|
class _MouseHoverBuilderState extends State<MouseHoverBuilder> {
|
||||||
bool isOver = false;
|
bool _onHover = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MouseRegion(
|
return MouseRegion(
|
||||||
cursor: widget.isClickable ? SystemMouseCursors.click : SystemMouseCursors.basic,
|
cursor: widget.isClickable ? SystemMouseCursors.click : SystemMouseCursors.basic,
|
||||||
onEnter: (p) => setOver(true),
|
onEnter: (p) => setOnHover(true),
|
||||||
onExit: (p) => setOver(false),
|
onExit: (p) => setOnHover(false),
|
||||||
child: widget.builder(context, isOver),
|
child: widget.builder(context, _onHover),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOver(bool value) => setState(() => isOver = value);
|
void setOnHover(bool value) => setState(() => _onHover = value);
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,90 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class RoundedButton extends StatelessWidget {
|
class RoundedTextButton extends StatelessWidget {
|
||||||
final VoidCallback? press;
|
final VoidCallback? press;
|
||||||
final String? title;
|
final String? title;
|
||||||
final Size? size;
|
final double? width;
|
||||||
|
final double? height;
|
||||||
|
final BorderRadius borderRadius;
|
||||||
|
final Color borderColor;
|
||||||
|
final Color color;
|
||||||
|
final Color textColor;
|
||||||
|
final double fontSize;
|
||||||
|
|
||||||
const RoundedButton({
|
const RoundedTextButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.press,
|
this.press,
|
||||||
this.title,
|
this.title,
|
||||||
this.size,
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.borderRadius = BorderRadius.zero,
|
||||||
|
this.borderColor = Colors.transparent,
|
||||||
|
this.color = Colors.transparent,
|
||||||
|
this.textColor = Colors.white,
|
||||||
|
this.fontSize = 16,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minWidth: 100,
|
minWidth: 10,
|
||||||
maxWidth: size?.width ?? double.infinity,
|
maxWidth: width ?? double.infinity,
|
||||||
minHeight: 50,
|
minHeight: 10,
|
||||||
maxHeight: size?.height ?? double.infinity,
|
maxHeight: height ?? 60,
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 10),
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: borderColor),
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
color: color,
|
||||||
|
),
|
||||||
|
child: SizedBox.expand(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
child: Text(title ?? ''),
|
child: Text(
|
||||||
|
title ?? '',
|
||||||
|
style: TextStyle(color: textColor, fontSize: fontSize),
|
||||||
|
),
|
||||||
onPressed: press,
|
onPressed: press,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoundedImageButton extends StatelessWidget {
|
||||||
|
final VoidCallback? press;
|
||||||
|
final double size;
|
||||||
|
final BorderRadius borderRadius;
|
||||||
|
final Color borderColor;
|
||||||
|
final Color color;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const RoundedImageButton({
|
||||||
|
Key? key,
|
||||||
|
this.press,
|
||||||
|
required this.size,
|
||||||
|
this.borderRadius = BorderRadius.zero,
|
||||||
|
this.borderColor = Colors.transparent,
|
||||||
|
this.color = Colors.transparent,
|
||||||
|
required this.child,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: press,
|
||||||
|
style: ButtonStyle(
|
||||||
|
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||||
|
RoundedRectangleBorder(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
))),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,96 @@
|
|||||||
|
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||||
import 'package:flowy_infra_ui/widget/text_field_container.dart';
|
import 'package:flowy_infra_ui/widget/text_field_container.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flowy_infra/time/duration.dart';
|
||||||
|
|
||||||
class RoundedInputField extends StatelessWidget {
|
// ignore: must_be_immutable
|
||||||
|
class RoundedInputField extends StatefulWidget {
|
||||||
final String? hintText;
|
final String? hintText;
|
||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
final bool obscureText;
|
final bool obscureText;
|
||||||
|
final Color normalBorderColor;
|
||||||
|
final Color highlightBorderColor;
|
||||||
|
final String errorText;
|
||||||
final ValueChanged<String>? onChanged;
|
final ValueChanged<String>? onChanged;
|
||||||
|
late bool enableObscure;
|
||||||
|
|
||||||
const RoundedInputField({
|
RoundedInputField({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.hintText,
|
this.hintText,
|
||||||
this.icon = Icons.person,
|
this.icon,
|
||||||
this.obscureText = false,
|
this.obscureText = false,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
}) : super(key: key);
|
this.normalBorderColor = Colors.transparent,
|
||||||
|
this.highlightBorderColor = Colors.transparent,
|
||||||
|
this.errorText = "",
|
||||||
|
}) : super(key: key) {
|
||||||
|
enableObscure = obscureText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RoundedInputField> createState() => _RoundedInputFieldState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TextFieldContainer(
|
final Icon? newIcon = widget.icon == null
|
||||||
child: TextFormField(
|
? null
|
||||||
onChanged: onChanged,
|
: Icon(
|
||||||
cursorColor: const Color(0xFF6F35A5),
|
widget.icon!,
|
||||||
obscureText: obscureText,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
icon: Icon(
|
|
||||||
icon,
|
|
||||||
color: const Color(0xFF6F35A5),
|
color: const Color(0xFF6F35A5),
|
||||||
),
|
);
|
||||||
hintText: hintText,
|
|
||||||
|
var borderColor = widget.normalBorderColor;
|
||||||
|
if (widget.errorText.isNotEmpty) {
|
||||||
|
borderColor = widget.highlightBorderColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> children = [
|
||||||
|
TextFieldContainer(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderColor: borderColor,
|
||||||
|
child: TextFormField(
|
||||||
|
onChanged: widget.onChanged,
|
||||||
|
cursorColor: const Color(0xFF6F35A5),
|
||||||
|
obscureText: widget.enableObscure,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
icon: newIcon,
|
||||||
|
hintText: widget.hintText,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
|
suffixIcon: suffixIcon(),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (widget.errorText.isNotEmpty) {
|
||||||
|
children.add(Text(
|
||||||
|
widget.errorText,
|
||||||
|
style: TextStyle(color: widget.highlightBorderColor),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return AnimatedSize(
|
||||||
|
duration: .4.seconds,
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
child: Column(
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget? suffixIcon() {
|
||||||
|
if (widget.obscureText == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return RoundedImageButton(
|
||||||
|
size: 20,
|
||||||
|
press: () {
|
||||||
|
widget.enableObscure = !widget.enableObscure;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.password, size: 15),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,32 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class TextFieldContainer extends StatelessWidget {
|
class TextFieldContainer extends StatelessWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
final BorderRadius borderRadius;
|
||||||
|
final Color borderColor;
|
||||||
|
final double? height;
|
||||||
|
final double? width;
|
||||||
const TextFieldContainer({
|
const TextFieldContainer({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.child,
|
required this.child,
|
||||||
|
this.borderRadius = BorderRadius.zero,
|
||||||
|
this.borderColor = Colors.white,
|
||||||
|
this.height,
|
||||||
|
this.width,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 10),
|
margin: const EdgeInsets.symmetric(vertical: 10),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
height: height,
|
||||||
|
width: width,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: borderColor),
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: borderRadius,
|
||||||
),
|
),
|
||||||
child: child,
|
child: Align(alignment: Alignment.center, child: child),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ packages:
|
|||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.7.0"
|
version: "2.6.1"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -35,7 +35,7 @@ packages:
|
|||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.2.0"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -142,6 +142,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
loading_indicator:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: loading_indicator
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
logger:
|
logger:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -162,7 +169,7 @@ packages:
|
|||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
version: "1.3.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -244,7 +251,7 @@ packages:
|
|||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.1"
|
version: "0.3.0"
|
||||||
textstyle_extensions:
|
textstyle_extensions:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -282,4 +289,4 @@ packages:
|
|||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.12.0 <3.0.0"
|
dart: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.20.0"
|
flutter: ">=2.0.0"
|
||||||
|
@ -19,6 +19,7 @@ dependencies:
|
|||||||
styled_widget: '>=0.3.1'
|
styled_widget: '>=0.3.1'
|
||||||
equatable: '>=2.0.2'
|
equatable: '>=2.0.2'
|
||||||
animations: ^2.0.0
|
animations: ^2.0.0
|
||||||
|
loading_indicator: ^3.0.1
|
||||||
|
|
||||||
# Federated Platform Interface
|
# Federated Platform Interface
|
||||||
flowy_infra_ui_platform_interface:
|
flowy_infra_ui_platform_interface:
|
||||||
|
@ -118,6 +118,20 @@ class WorkspaceEventGetWorkspace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WorkspaceEventReadAllWorkspace {
|
||||||
|
WorkspaceEventReadAllWorkspace();
|
||||||
|
|
||||||
|
Future<Either<Workspaces, WorkspaceError>> send() {
|
||||||
|
final request = FFIRequest.create()
|
||||||
|
..event = WorkspaceEvent.ReadAllWorkspace.toString();
|
||||||
|
|
||||||
|
return Dispatch.asyncRequest(request).then((bytesResult) => bytesResult.fold(
|
||||||
|
(okBytes) => left(Workspaces.fromBuffer(okBytes)),
|
||||||
|
(errBytes) => right(WorkspaceError.fromBuffer(errBytes)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class WorkspaceEventCreateApp {
|
class WorkspaceEventCreateApp {
|
||||||
CreateAppRequest request;
|
CreateAppRequest request;
|
||||||
WorkspaceEventCreateApp(this.request);
|
WorkspaceEventCreateApp(this.request);
|
||||||
|
@ -15,14 +15,14 @@ export 'errors.pbenum.dart';
|
|||||||
|
|
||||||
class UserError extends $pb.GeneratedMessage {
|
class UserError extends $pb.GeneratedMessage {
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserError', createEmptyInstance: create)
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UserError', createEmptyInstance: create)
|
||||||
..e<UserErrorCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: UserErrorCode.Unknown, valueOf: UserErrorCode.valueOf, enumValues: UserErrorCode.values)
|
..e<UserErrCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: UserErrCode.Unknown, valueOf: UserErrCode.valueOf, enumValues: UserErrCode.values)
|
||||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
|
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
||||||
UserError._() : super();
|
UserError._() : super();
|
||||||
factory UserError({
|
factory UserError({
|
||||||
UserErrorCode? code,
|
UserErrCode? code,
|
||||||
$core.String? msg,
|
$core.String? msg,
|
||||||
}) {
|
}) {
|
||||||
final _result = create();
|
final _result = create();
|
||||||
@ -56,9 +56,9 @@ class UserError extends $pb.GeneratedMessage {
|
|||||||
static UserError? _defaultInstance;
|
static UserError? _defaultInstance;
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
UserErrorCode get code => $_getN(0);
|
UserErrCode get code => $_getN(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
set code(UserErrorCode v) { setField(1, v); }
|
set code(UserErrCode v) { setField(1, v); }
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.bool hasCode() => $_has(0);
|
$core.bool hasCode() => $_has(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
|
@ -9,26 +9,26 @@
|
|||||||
import 'dart:core' as $core;
|
import 'dart:core' as $core;
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
class UserErrorCode extends $pb.ProtobufEnum {
|
class UserErrCode extends $pb.ProtobufEnum {
|
||||||
static const UserErrorCode Unknown = UserErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
|
static const UserErrCode Unknown = UserErrCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
|
||||||
static const UserErrorCode UserDatabaseInitFailed = UserErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInitFailed');
|
static const UserErrCode UserDatabaseInitFailed = UserErrCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInitFailed');
|
||||||
static const UserErrorCode UserDatabaseWriteLocked = UserErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseWriteLocked');
|
static const UserErrCode UserDatabaseWriteLocked = UserErrCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseWriteLocked');
|
||||||
static const UserErrorCode UserDatabaseReadLocked = UserErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseReadLocked');
|
static const UserErrCode UserDatabaseReadLocked = UserErrCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseReadLocked');
|
||||||
static const UserErrorCode UserDatabaseDidNotMatch = UserErrorCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseDidNotMatch');
|
static const UserErrCode UserDatabaseDidNotMatch = UserErrCode._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseDidNotMatch');
|
||||||
static const UserErrorCode UserDatabaseInternalError = UserErrorCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInternalError');
|
static const UserErrCode UserDatabaseInternalError = UserErrCode._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserDatabaseInternalError');
|
||||||
static const UserErrorCode SqlInternalError = UserErrorCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SqlInternalError');
|
static const UserErrCode SqlInternalError = UserErrCode._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'SqlInternalError');
|
||||||
static const UserErrorCode UserNotLoginYet = UserErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
|
static const UserErrCode UserNotLoginYet = UserErrCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
|
||||||
static const UserErrorCode ReadCurrentIdFailed = UserErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadCurrentIdFailed');
|
static const UserErrCode ReadCurrentIdFailed = UserErrCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadCurrentIdFailed');
|
||||||
static const UserErrorCode WriteCurrentIdFailed = UserErrorCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WriteCurrentIdFailed');
|
static const UserErrCode WriteCurrentIdFailed = UserErrCode._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WriteCurrentIdFailed');
|
||||||
static const UserErrorCode EmailInvalid = UserErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailInvalid');
|
static const UserErrCode EmailInvalid = UserErrCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EmailInvalid');
|
||||||
static const UserErrorCode PasswordInvalid = UserErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordInvalid');
|
static const UserErrCode PasswordInvalid = UserErrCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PasswordInvalid');
|
||||||
static const UserErrorCode UserNameInvalid = UserErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameInvalid');
|
static const UserErrCode UserNameInvalid = UserErrCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNameInvalid');
|
||||||
static const UserErrorCode UserWorkspaceInvalid = UserErrorCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserWorkspaceInvalid');
|
static const UserErrCode UserWorkspaceInvalid = UserErrCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserWorkspaceInvalid');
|
||||||
static const UserErrorCode UserIdInvalid = UserErrorCode._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
|
static const UserErrCode UserIdInvalid = UserErrCode._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserIdInvalid');
|
||||||
static const UserErrorCode CreateDefaultWorkspaceFailed = UserErrorCode._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultWorkspaceFailed');
|
static const UserErrCode CreateDefaultWorkspaceFailed = UserErrCode._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateDefaultWorkspaceFailed');
|
||||||
static const UserErrorCode DefaultWorkspaceAlreadyExist = UserErrorCode._(26, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DefaultWorkspaceAlreadyExist');
|
static const UserErrCode DefaultWorkspaceAlreadyExist = UserErrCode._(26, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DefaultWorkspaceAlreadyExist');
|
||||||
|
|
||||||
static const $core.List<UserErrorCode> values = <UserErrorCode> [
|
static const $core.List<UserErrCode> values = <UserErrCode> [
|
||||||
Unknown,
|
Unknown,
|
||||||
UserDatabaseInitFailed,
|
UserDatabaseInitFailed,
|
||||||
UserDatabaseWriteLocked,
|
UserDatabaseWriteLocked,
|
||||||
@ -48,9 +48,9 @@ class UserErrorCode extends $pb.ProtobufEnum {
|
|||||||
DefaultWorkspaceAlreadyExist,
|
DefaultWorkspaceAlreadyExist,
|
||||||
];
|
];
|
||||||
|
|
||||||
static final $core.Map<$core.int, UserErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
static final $core.Map<$core.int, UserErrCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||||
static UserErrorCode? valueOf($core.int value) => _byValue[value];
|
static UserErrCode? valueOf($core.int value) => _byValue[value];
|
||||||
|
|
||||||
const UserErrorCode._($core.int v, $core.String n) : super(v, n);
|
const UserErrCode._($core.int v, $core.String n) : super(v, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
import 'dart:core' as $core;
|
import 'dart:core' as $core;
|
||||||
import 'dart:convert' as $convert;
|
import 'dart:convert' as $convert;
|
||||||
import 'dart:typed_data' as $typed_data;
|
import 'dart:typed_data' as $typed_data;
|
||||||
@$core.Deprecated('Use userErrorCodeDescriptor instead')
|
@$core.Deprecated('Use userErrCodeDescriptor instead')
|
||||||
const UserErrorCode$json = const {
|
const UserErrCode$json = const {
|
||||||
'1': 'UserErrorCode',
|
'1': 'UserErrCode',
|
||||||
'2': const [
|
'2': const [
|
||||||
const {'1': 'Unknown', '2': 0},
|
const {'1': 'Unknown', '2': 0},
|
||||||
const {'1': 'UserDatabaseInitFailed', '2': 1},
|
const {'1': 'UserDatabaseInitFailed', '2': 1},
|
||||||
@ -32,16 +32,16 @@ const UserErrorCode$json = const {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `UserErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
/// Descriptor for `UserErrCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||||
final $typed_data.Uint8List userErrorCodeDescriptor = $convert.base64Decode('Cg1Vc2VyRXJyb3JDb2RlEgsKB1Vua25vd24QABIaChZVc2VyRGF0YWJhc2VJbml0RmFpbGVkEAESGwoXVXNlckRhdGFiYXNlV3JpdGVMb2NrZWQQAhIaChZVc2VyRGF0YWJhc2VSZWFkTG9ja2VkEAMSGwoXVXNlckRhdGFiYXNlRGlkTm90TWF0Y2gQBBIdChlVc2VyRGF0YWJhc2VJbnRlcm5hbEVycm9yEAUSFAoQU3FsSW50ZXJuYWxFcnJvchAGEhMKD1VzZXJOb3RMb2dpbllldBAKEhcKE1JlYWRDdXJyZW50SWRGYWlsZWQQCxIYChRXcml0ZUN1cnJlbnRJZEZhaWxlZBAMEhAKDEVtYWlsSW52YWxpZBAUEhMKD1Bhc3N3b3JkSW52YWxpZBAVEhMKD1VzZXJOYW1lSW52YWxpZBAWEhgKFFVzZXJXb3Jrc3BhY2VJbnZhbGlkEBcSEQoNVXNlcklkSW52YWxpZBAYEiAKHENyZWF0ZURlZmF1bHRXb3Jrc3BhY2VGYWlsZWQQGRIgChxEZWZhdWx0V29ya3NwYWNlQWxyZWFkeUV4aXN0EBo=');
|
final $typed_data.Uint8List userErrCodeDescriptor = $convert.base64Decode('CgtVc2VyRXJyQ29kZRILCgdVbmtub3duEAASGgoWVXNlckRhdGFiYXNlSW5pdEZhaWxlZBABEhsKF1VzZXJEYXRhYmFzZVdyaXRlTG9ja2VkEAISGgoWVXNlckRhdGFiYXNlUmVhZExvY2tlZBADEhsKF1VzZXJEYXRhYmFzZURpZE5vdE1hdGNoEAQSHQoZVXNlckRhdGFiYXNlSW50ZXJuYWxFcnJvchAFEhQKEFNxbEludGVybmFsRXJyb3IQBhITCg9Vc2VyTm90TG9naW5ZZXQQChIXChNSZWFkQ3VycmVudElkRmFpbGVkEAsSGAoUV3JpdGVDdXJyZW50SWRGYWlsZWQQDBIQCgxFbWFpbEludmFsaWQQFBITCg9QYXNzd29yZEludmFsaWQQFRITCg9Vc2VyTmFtZUludmFsaWQQFhIYChRVc2VyV29ya3NwYWNlSW52YWxpZBAXEhEKDVVzZXJJZEludmFsaWQQGBIgChxDcmVhdGVEZWZhdWx0V29ya3NwYWNlRmFpbGVkEBkSIAocRGVmYXVsdFdvcmtzcGFjZUFscmVhZHlFeGlzdBAa');
|
||||||
@$core.Deprecated('Use userErrorDescriptor instead')
|
@$core.Deprecated('Use userErrorDescriptor instead')
|
||||||
const UserError$json = const {
|
const UserError$json = const {
|
||||||
'1': 'UserError',
|
'1': 'UserError',
|
||||||
'2': const [
|
'2': const [
|
||||||
const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.UserErrorCode', '10': 'code'},
|
const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.UserErrCode', '10': 'code'},
|
||||||
const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'},
|
const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `UserError`. Decode as a `google.protobuf.DescriptorProto`.
|
/// Descriptor for `UserError`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
final $typed_data.Uint8List userErrorDescriptor = $convert.base64Decode('CglVc2VyRXJyb3ISIgoEY29kZRgBIAEoDjIOLlVzZXJFcnJvckNvZGVSBGNvZGUSEAoDbXNnGAIgASgJUgNtc2c=');
|
final $typed_data.Uint8List userErrorDescriptor = $convert.base64Decode('CglVc2VyRXJyb3ISIAoEY29kZRgBIAEoDjIMLlVzZXJFcnJDb2RlUgRjb2RlEhAKA21zZxgCIAEoCVIDbXNn');
|
||||||
|
@ -15,14 +15,14 @@ export 'errors.pbenum.dart';
|
|||||||
|
|
||||||
class WorkspaceError extends $pb.GeneratedMessage {
|
class WorkspaceError extends $pb.GeneratedMessage {
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'WorkspaceError', createEmptyInstance: create)
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'WorkspaceError', createEmptyInstance: create)
|
||||||
..e<WorkspaceErrorCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: WorkspaceErrorCode.Unknown, valueOf: WorkspaceErrorCode.valueOf, enumValues: WorkspaceErrorCode.values)
|
..e<WsErrCode>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code', $pb.PbFieldType.OE, defaultOrMaker: WsErrCode.Unknown, valueOf: WsErrCode.valueOf, enumValues: WsErrCode.values)
|
||||||
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
|
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'msg')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
||||||
WorkspaceError._() : super();
|
WorkspaceError._() : super();
|
||||||
factory WorkspaceError({
|
factory WorkspaceError({
|
||||||
WorkspaceErrorCode? code,
|
WsErrCode? code,
|
||||||
$core.String? msg,
|
$core.String? msg,
|
||||||
}) {
|
}) {
|
||||||
final _result = create();
|
final _result = create();
|
||||||
@ -56,9 +56,9 @@ class WorkspaceError extends $pb.GeneratedMessage {
|
|||||||
static WorkspaceError? _defaultInstance;
|
static WorkspaceError? _defaultInstance;
|
||||||
|
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
WorkspaceErrorCode get code => $_getN(0);
|
WsErrCode get code => $_getN(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
set code(WorkspaceErrorCode v) { setField(1, v); }
|
set code(WsErrCode v) { setField(1, v); }
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
$core.bool hasCode() => $_has(0);
|
$core.bool hasCode() => $_has(0);
|
||||||
@$pb.TagNumber(1)
|
@$pb.TagNumber(1)
|
||||||
|
@ -9,23 +9,23 @@
|
|||||||
import 'dart:core' as $core;
|
import 'dart:core' as $core;
|
||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
class WorkspaceErrorCode extends $pb.ProtobufEnum {
|
class WsErrCode extends $pb.ProtobufEnum {
|
||||||
static const WorkspaceErrorCode Unknown = WorkspaceErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
|
static const WsErrCode Unknown = WsErrCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Unknown');
|
||||||
static const WorkspaceErrorCode WorkspaceNameInvalid = WorkspaceErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceNameInvalid');
|
static const WsErrCode WorkspaceNameInvalid = WsErrCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceNameInvalid');
|
||||||
static const WorkspaceErrorCode WorkspaceIdInvalid = WorkspaceErrorCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceIdInvalid');
|
static const WsErrCode WorkspaceIdInvalid = WsErrCode._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceIdInvalid');
|
||||||
static const WorkspaceErrorCode AppColorStyleInvalid = WorkspaceErrorCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppColorStyleInvalid');
|
static const WsErrCode AppColorStyleInvalid = WsErrCode._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppColorStyleInvalid');
|
||||||
static const WorkspaceErrorCode AppIdInvalid = WorkspaceErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppIdInvalid');
|
static const WsErrCode AppIdInvalid = WsErrCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppIdInvalid');
|
||||||
static const WorkspaceErrorCode AppNameInvalid = WorkspaceErrorCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppNameInvalid');
|
static const WsErrCode AppNameInvalid = WsErrCode._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'AppNameInvalid');
|
||||||
static const WorkspaceErrorCode ViewNameInvalid = WorkspaceErrorCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewNameInvalid');
|
static const WsErrCode ViewNameInvalid = WsErrCode._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewNameInvalid');
|
||||||
static const WorkspaceErrorCode ViewThumbnailInvalid = WorkspaceErrorCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewThumbnailInvalid');
|
static const WsErrCode ViewThumbnailInvalid = WsErrCode._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewThumbnailInvalid');
|
||||||
static const WorkspaceErrorCode ViewIdInvalid = WorkspaceErrorCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewIdInvalid');
|
static const WsErrCode ViewIdInvalid = WsErrCode._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewIdInvalid');
|
||||||
static const WorkspaceErrorCode ViewDescInvalid = WorkspaceErrorCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewDescInvalid');
|
static const WsErrCode ViewDescInvalid = WsErrCode._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ViewDescInvalid');
|
||||||
static const WorkspaceErrorCode DatabaseConnectionFail = WorkspaceErrorCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseConnectionFail');
|
static const WsErrCode DatabaseConnectionFail = WsErrCode._(100, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DatabaseConnectionFail');
|
||||||
static const WorkspaceErrorCode WorkspaceDatabaseError = WorkspaceErrorCode._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDatabaseError');
|
static const WsErrCode WorkspaceDatabaseError = WsErrCode._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WorkspaceDatabaseError');
|
||||||
static const WorkspaceErrorCode UserInternalError = WorkspaceErrorCode._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserInternalError');
|
static const WsErrCode UserInternalError = WsErrCode._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserInternalError');
|
||||||
static const WorkspaceErrorCode UserNotLoginYet = WorkspaceErrorCode._(103, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
|
static const WsErrCode UserNotLoginYet = WsErrCode._(103, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserNotLoginYet');
|
||||||
|
|
||||||
static const $core.List<WorkspaceErrorCode> values = <WorkspaceErrorCode> [
|
static const $core.List<WsErrCode> values = <WsErrCode> [
|
||||||
Unknown,
|
Unknown,
|
||||||
WorkspaceNameInvalid,
|
WorkspaceNameInvalid,
|
||||||
WorkspaceIdInvalid,
|
WorkspaceIdInvalid,
|
||||||
@ -42,9 +42,9 @@ class WorkspaceErrorCode extends $pb.ProtobufEnum {
|
|||||||
UserNotLoginYet,
|
UserNotLoginYet,
|
||||||
];
|
];
|
||||||
|
|
||||||
static final $core.Map<$core.int, WorkspaceErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
static final $core.Map<$core.int, WsErrCode> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||||
static WorkspaceErrorCode? valueOf($core.int value) => _byValue[value];
|
static WsErrCode? valueOf($core.int value) => _byValue[value];
|
||||||
|
|
||||||
const WorkspaceErrorCode._($core.int v, $core.String n) : super(v, n);
|
const WsErrCode._($core.int v, $core.String n) : super(v, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
import 'dart:core' as $core;
|
import 'dart:core' as $core;
|
||||||
import 'dart:convert' as $convert;
|
import 'dart:convert' as $convert;
|
||||||
import 'dart:typed_data' as $typed_data;
|
import 'dart:typed_data' as $typed_data;
|
||||||
@$core.Deprecated('Use workspaceErrorCodeDescriptor instead')
|
@$core.Deprecated('Use wsErrCodeDescriptor instead')
|
||||||
const WorkspaceErrorCode$json = const {
|
const WsErrCode$json = const {
|
||||||
'1': 'WorkspaceErrorCode',
|
'1': 'WsErrCode',
|
||||||
'2': const [
|
'2': const [
|
||||||
const {'1': 'Unknown', '2': 0},
|
const {'1': 'Unknown', '2': 0},
|
||||||
const {'1': 'WorkspaceNameInvalid', '2': 1},
|
const {'1': 'WorkspaceNameInvalid', '2': 1},
|
||||||
@ -29,16 +29,16 @@ const WorkspaceErrorCode$json = const {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `WorkspaceErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
/// Descriptor for `WsErrCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||||
final $typed_data.Uint8List workspaceErrorCodeDescriptor = $convert.base64Decode('ChJXb3Jrc3BhY2VFcnJvckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIQCgxBcHBJZEludmFsaWQQChISCg5BcHBOYW1lSW52YWxpZBALEhMKD1ZpZXdOYW1lSW52YWxpZBAUEhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEBUSEQoNVmlld0lkSW52YWxpZBAWEhMKD1ZpZXdEZXNjSW52YWxpZBAXEhoKFkRhdGFiYXNlQ29ubmVjdGlvbkZhaWwQZBIaChZXb3Jrc3BhY2VEYXRhYmFzZUVycm9yEGUSFQoRVXNlckludGVybmFsRXJyb3IQZhITCg9Vc2VyTm90TG9naW5ZZXQQZw==');
|
final $typed_data.Uint8List wsErrCodeDescriptor = $convert.base64Decode('CglXc0VyckNvZGUSCwoHVW5rbm93bhAAEhgKFFdvcmtzcGFjZU5hbWVJbnZhbGlkEAESFgoSV29ya3NwYWNlSWRJbnZhbGlkEAISGAoUQXBwQ29sb3JTdHlsZUludmFsaWQQAxIQCgxBcHBJZEludmFsaWQQChISCg5BcHBOYW1lSW52YWxpZBALEhMKD1ZpZXdOYW1lSW52YWxpZBAUEhgKFFZpZXdUaHVtYm5haWxJbnZhbGlkEBUSEQoNVmlld0lkSW52YWxpZBAWEhMKD1ZpZXdEZXNjSW52YWxpZBAXEhoKFkRhdGFiYXNlQ29ubmVjdGlvbkZhaWwQZBIaChZXb3Jrc3BhY2VEYXRhYmFzZUVycm9yEGUSFQoRVXNlckludGVybmFsRXJyb3IQZhITCg9Vc2VyTm90TG9naW5ZZXQQZw==');
|
||||||
@$core.Deprecated('Use workspaceErrorDescriptor instead')
|
@$core.Deprecated('Use workspaceErrorDescriptor instead')
|
||||||
const WorkspaceError$json = const {
|
const WorkspaceError$json = const {
|
||||||
'1': 'WorkspaceError',
|
'1': 'WorkspaceError',
|
||||||
'2': const [
|
'2': const [
|
||||||
const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.WorkspaceErrorCode', '10': 'code'},
|
const {'1': 'code', '3': 1, '4': 1, '5': 14, '6': '.WsErrCode', '10': 'code'},
|
||||||
const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'},
|
const {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `WorkspaceError`. Decode as a `google.protobuf.DescriptorProto`.
|
/// Descriptor for `WorkspaceError`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
final $typed_data.Uint8List workspaceErrorDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFcnJvchInCgRjb2RlGAEgASgOMhMuV29ya3NwYWNlRXJyb3JDb2RlUgRjb2RlEhAKA21zZxgCIAEoCVIDbXNn');
|
final $typed_data.Uint8List workspaceErrorDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFcnJvchIeCgRjb2RlGAEgASgOMgouV3NFcnJDb2RlUgRjb2RlEhAKA21zZxgCIAEoCVIDbXNn');
|
||||||
|
@ -13,6 +13,7 @@ class WorkspaceEvent extends $pb.ProtobufEnum {
|
|||||||
static const WorkspaceEvent CreateWorkspace = WorkspaceEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateWorkspace');
|
static const WorkspaceEvent CreateWorkspace = WorkspaceEvent._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateWorkspace');
|
||||||
static const WorkspaceEvent GetCurWorkspace = WorkspaceEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetCurWorkspace');
|
static const WorkspaceEvent GetCurWorkspace = WorkspaceEvent._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetCurWorkspace');
|
||||||
static const WorkspaceEvent GetWorkspace = WorkspaceEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetWorkspace');
|
static const WorkspaceEvent GetWorkspace = WorkspaceEvent._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetWorkspace');
|
||||||
|
static const WorkspaceEvent ReadAllWorkspace = WorkspaceEvent._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ReadAllWorkspace');
|
||||||
static const WorkspaceEvent CreateApp = WorkspaceEvent._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateApp');
|
static const WorkspaceEvent CreateApp = WorkspaceEvent._(101, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateApp');
|
||||||
static const WorkspaceEvent GetApp = WorkspaceEvent._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetApp');
|
static const WorkspaceEvent GetApp = WorkspaceEvent._(102, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetApp');
|
||||||
static const WorkspaceEvent CreateView = WorkspaceEvent._(201, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateView');
|
static const WorkspaceEvent CreateView = WorkspaceEvent._(201, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateView');
|
||||||
@ -23,6 +24,7 @@ class WorkspaceEvent extends $pb.ProtobufEnum {
|
|||||||
CreateWorkspace,
|
CreateWorkspace,
|
||||||
GetCurWorkspace,
|
GetCurWorkspace,
|
||||||
GetWorkspace,
|
GetWorkspace,
|
||||||
|
ReadAllWorkspace,
|
||||||
CreateApp,
|
CreateApp,
|
||||||
GetApp,
|
GetApp,
|
||||||
CreateView,
|
CreateView,
|
||||||
|
@ -15,6 +15,7 @@ const WorkspaceEvent$json = const {
|
|||||||
const {'1': 'CreateWorkspace', '2': 0},
|
const {'1': 'CreateWorkspace', '2': 0},
|
||||||
const {'1': 'GetCurWorkspace', '2': 1},
|
const {'1': 'GetCurWorkspace', '2': 1},
|
||||||
const {'1': 'GetWorkspace', '2': 2},
|
const {'1': 'GetWorkspace', '2': 2},
|
||||||
|
const {'1': 'ReadAllWorkspace', '2': 3},
|
||||||
const {'1': 'CreateApp', '2': 101},
|
const {'1': 'CreateApp', '2': 101},
|
||||||
const {'1': 'GetApp', '2': 102},
|
const {'1': 'GetApp', '2': 102},
|
||||||
const {'1': 'CreateView', '2': 201},
|
const {'1': 'CreateView', '2': 201},
|
||||||
@ -24,4 +25,4 @@ const WorkspaceEvent$json = const {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
/// Descriptor for `WorkspaceEvent`. Decode as a `google.protobuf.EnumDescriptorProto`.
|
||||||
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABITCg9HZXRDdXJXb3Jrc3BhY2UQARIQCgxHZXRXb3Jrc3BhY2UQAhINCglDcmVhdGVBcHAQZRIKCgZHZXRBcHAQZhIPCgpDcmVhdGVWaWV3EMkBEg0KCFJlYWRWaWV3EMoBEg8KClVwZGF0ZVZpZXcQywE=');
|
final $typed_data.Uint8List workspaceEventDescriptor = $convert.base64Decode('Cg5Xb3Jrc3BhY2VFdmVudBITCg9DcmVhdGVXb3Jrc3BhY2UQABITCg9HZXRDdXJXb3Jrc3BhY2UQARIQCgxHZXRXb3Jrc3BhY2UQAhIUChBSZWFkQWxsV29ya3NwYWNlEAMSDQoJQ3JlYXRlQXBwEGUSCgoGR2V0QXBwEGYSDwoKQ3JlYXRlVmlldxDJARINCghSZWFkVmlldxDKARIPCgpVcGRhdGVWaWV3EMsB');
|
||||||
|
@ -10,17 +10,25 @@ import 'dart:core' as $core;
|
|||||||
import 'package:protobuf/protobuf.dart' as $pb;
|
import 'package:protobuf/protobuf.dart' as $pb;
|
||||||
|
|
||||||
class ViewType extends $pb.ProtobufEnum {
|
class ViewType extends $pb.ProtobufEnum {
|
||||||
static const ViewType Blank = ViewType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Blank');
|
static const ViewType Blank = ViewType._(
|
||||||
static const ViewType Doc = ViewType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Doc');
|
0,
|
||||||
|
const $core.bool.fromEnvironment('protobuf.omit_enum_names')
|
||||||
|
? ''
|
||||||
|
: 'Blank');
|
||||||
|
static const ViewType Doc = ViewType._(
|
||||||
|
1,
|
||||||
|
const $core.bool.fromEnvironment('protobuf.omit_enum_names')
|
||||||
|
? ''
|
||||||
|
: 'Doc');
|
||||||
|
|
||||||
static const $core.List<ViewType> values = <ViewType>[
|
static const $core.List<ViewType> values = <ViewType>[
|
||||||
Blank,
|
Blank,
|
||||||
Doc,
|
Doc,
|
||||||
];
|
];
|
||||||
|
|
||||||
static final $core.Map<$core.int, ViewType> _byValue = $pb.ProtobufEnum.initByValue(values);
|
static final $core.Map<$core.int, ViewType> _byValue =
|
||||||
|
$pb.ProtobufEnum.initByValue(values);
|
||||||
static ViewType? valueOf($core.int value) => _byValue[value];
|
static ViewType? valueOf($core.int value) => _byValue[value];
|
||||||
|
|
||||||
const ViewType._($core.int v, $core.String n) : super(v, n);
|
const ViewType._($core.int v, $core.String n) : super(v, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,3 +163,44 @@ class Workspace extends $pb.GeneratedMessage {
|
|||||||
$0.RepeatedApp ensureApps() => $_ensure(3);
|
$0.RepeatedApp ensureApps() => $_ensure(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Workspaces extends $pb.GeneratedMessage {
|
||||||
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Workspaces', createEmptyInstance: create)
|
||||||
|
..pc<Workspace>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'items', $pb.PbFieldType.PM, subBuilder: Workspace.create)
|
||||||
|
..hasRequiredFields = false
|
||||||
|
;
|
||||||
|
|
||||||
|
Workspaces._() : super();
|
||||||
|
factory Workspaces({
|
||||||
|
$core.Iterable<Workspace>? items,
|
||||||
|
}) {
|
||||||
|
final _result = create();
|
||||||
|
if (items != null) {
|
||||||
|
_result.items.addAll(items);
|
||||||
|
}
|
||||||
|
return _result;
|
||||||
|
}
|
||||||
|
factory Workspaces.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
|
||||||
|
factory Workspaces.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
Workspaces clone() => Workspaces()..mergeFromMessage(this);
|
||||||
|
@$core.Deprecated(
|
||||||
|
'Using this can add significant overhead to your binary. '
|
||||||
|
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
|
||||||
|
'Will be removed in next major version')
|
||||||
|
Workspaces copyWith(void Function(Workspaces) updates) => super.copyWith((message) => updates(message as Workspaces)) as Workspaces; // ignore: deprecated_member_use
|
||||||
|
$pb.BuilderInfo get info_ => _i;
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static Workspaces create() => Workspaces._();
|
||||||
|
Workspaces createEmptyInstance() => create();
|
||||||
|
static $pb.PbList<Workspaces> createRepeated() => $pb.PbList<Workspaces>();
|
||||||
|
@$core.pragma('dart2js:noInline')
|
||||||
|
static Workspaces getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Workspaces>(create);
|
||||||
|
static Workspaces? _defaultInstance;
|
||||||
|
|
||||||
|
@$pb.TagNumber(1)
|
||||||
|
$core.List<Workspace> get items => $_getList(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -32,3 +32,13 @@ const Workspace$json = const {
|
|||||||
|
|
||||||
/// Descriptor for `Workspace`. Decode as a `google.protobuf.DescriptorProto`.
|
/// Descriptor for `Workspace`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
final $typed_data.Uint8List workspaceDescriptor = $convert.base64Decode('CglXb3Jrc3BhY2USDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIgCgRhcHBzGAQgASgLMgwuUmVwZWF0ZWRBcHBSBGFwcHM=');
|
final $typed_data.Uint8List workspaceDescriptor = $convert.base64Decode('CglXb3Jrc3BhY2USDgoCaWQYASABKAlSAmlkEhIKBG5hbWUYAiABKAlSBG5hbWUSEgoEZGVzYxgDIAEoCVIEZGVzYxIgCgRhcHBzGAQgASgLMgwuUmVwZWF0ZWRBcHBSBGFwcHM=');
|
||||||
|
@$core.Deprecated('Use workspacesDescriptor instead')
|
||||||
|
const Workspaces$json = const {
|
||||||
|
'1': 'Workspaces',
|
||||||
|
'2': const [
|
||||||
|
const {'1': 'items', '3': 1, '4': 3, '5': 11, '6': '.Workspace', '10': 'items'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Descriptor for `Workspaces`. Decode as a `google.protobuf.DescriptorProto`.
|
||||||
|
final $typed_data.Uint8List workspacesDescriptor = $convert.base64Decode('CgpXb3Jrc3BhY2VzEiAKBWl0ZW1zGAEgAygLMgouV29ya3NwYWNlUgVpdGVtcw==');
|
||||||
|
@ -5,231 +5,231 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: _fe_analyzer_shared
|
name: _fe_analyzer_shared
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "22.0.0"
|
version: "23.0.0"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: analyzer
|
name: analyzer
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.1"
|
version: "2.0.0"
|
||||||
animations:
|
animations:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: animations
|
name: animations
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.2.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.1"
|
version: "2.7.0"
|
||||||
bloc:
|
bloc:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: bloc
|
name: bloc
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
build:
|
build:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build
|
name: build
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
build_config:
|
build_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_config
|
name: build_config
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
build_daemon:
|
build_daemon:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.0"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_resolvers
|
name: build_resolvers
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
version: "2.0.4"
|
||||||
build_runner:
|
build_runner:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.6"
|
version: "2.0.6"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_collection
|
name: built_collection
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.0"
|
version: "5.1.0"
|
||||||
built_value:
|
built_value:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.1"
|
version: "8.1.1"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.3.1"
|
||||||
checked_yaml:
|
checked_yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: checked_yaml
|
name: checked_yaml
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
cli_util:
|
cli_util:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cli_util
|
name: cli_util
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.3"
|
version: "0.3.3"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
code_builder:
|
code_builder:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: code_builder
|
name: code_builder
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.1.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.15.0"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dart_style
|
name: dart_style
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.3"
|
||||||
dartz:
|
dartz:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dartz
|
name: dartz
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.0-nullsafety.2"
|
version: "0.10.0-nullsafety.2"
|
||||||
equatable:
|
equatable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: equatable
|
name: equatable
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
expandable:
|
expandable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: expandable
|
name: expandable
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.1"
|
version: "5.0.1"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.2"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.2"
|
version: "6.1.2"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
flowy_editor:
|
flowy_editor:
|
||||||
@ -283,42 +283,42 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_bloc
|
name: flutter_bloc
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
flutter_colorpicker:
|
flutter_colorpicker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_colorpicker
|
name: flutter_colorpicker
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.0"
|
version: "0.5.0"
|
||||||
flutter_keyboard_visibility:
|
flutter_keyboard_visibility:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_keyboard_visibility
|
name: flutter_keyboard_visibility
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.2"
|
version: "5.0.3"
|
||||||
flutter_keyboard_visibility_platform_interface:
|
flutter_keyboard_visibility_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_keyboard_visibility_platform_interface
|
name: flutter_keyboard_visibility_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
flutter_keyboard_visibility_web:
|
flutter_keyboard_visibility_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_keyboard_visibility_web
|
name: flutter_keyboard_visibility_web
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -335,196 +335,203 @@ packages:
|
|||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: freezed
|
name: freezed
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.14.2"
|
version: "0.14.3"
|
||||||
freezed_annotation:
|
freezed_annotation:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: freezed_annotation
|
name: freezed_annotation
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.14.2"
|
version: "0.14.3"
|
||||||
frontend_server_client:
|
frontend_server_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: frontend_server_client
|
name: frontend_server_client
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
get_it:
|
get_it:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: get_it
|
name: get_it
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.0"
|
version: "7.2.0"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: glob
|
name: glob
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_multi_server
|
name: http_multi_server
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: io
|
name: io
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3"
|
||||||
isolates:
|
isolates:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: isolates
|
name: isolates
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.3+8"
|
version: "3.0.3+8"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.3"
|
version: "0.6.3"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.1"
|
version: "4.1.0"
|
||||||
lint:
|
lint:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lint
|
name: lint
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.3"
|
version: "1.5.3"
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
loading_indicator:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: loading_indicator
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
logger:
|
logger:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logger
|
name: logger
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.10"
|
version: "0.12.10"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.7.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
nested:
|
nested:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: nested
|
name: nested
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_config
|
name: package_config
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0"
|
version: "1.8.0"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
path_provider_macos:
|
path_provider_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_macos
|
name: path_provider_macos
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pedantic
|
name: pedantic
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.1"
|
version: "1.11.1"
|
||||||
photo_view:
|
photo_view:
|
||||||
@ -540,91 +547,91 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.0"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pool
|
name: pool
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0"
|
version: "1.5.0"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: process
|
name: process
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.1"
|
version: "4.2.3"
|
||||||
protobuf:
|
protobuf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: protobuf
|
name: protobuf
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
provider:
|
provider:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.0"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pub_semver
|
name: pub_semver
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
pubspec_parse:
|
pubspec_parse:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: quiver
|
name: quiver
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
quiver_hashcode:
|
quiver_hashcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: quiver_hashcode
|
name: quiver_hashcode
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf
|
name: shelf
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
shelf_web_socket:
|
shelf_web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
sized_context:
|
sized_context:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: sized_context
|
name: sized_context
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0+1"
|
version: "1.0.0+1"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
@ -636,189 +643,189 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_gen
|
name: source_gen
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.5"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.8.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.10.0"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
stream_transform:
|
stream_transform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_transform
|
name: stream_transform
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
string_validator:
|
string_validator:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_validator
|
name: string_validator
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.3.0"
|
||||||
styled_widget:
|
styled_widget:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: styled_widget
|
name: styled_widget
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.1+2"
|
version: "0.3.1+2"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.4.1"
|
||||||
textstyle_extensions:
|
textstyle_extensions:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: textstyle_extensions
|
name: textstyle_extensions
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0-nullsafety"
|
version: "2.0.0-nullsafety"
|
||||||
time:
|
time:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: time
|
name: time
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: timing
|
name: timing
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
tuple:
|
tuple:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: tuple
|
name: tuple
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
universal_platform:
|
universal_platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: universal_platform
|
name: universal_platform
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0+1"
|
version: "1.0.0+1"
|
||||||
url_launcher:
|
url_launcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher
|
name: url_launcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.9"
|
version: "6.0.9"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_linux
|
name: url_launcher_linux
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_macos
|
name: url_launcher_macos
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
url_launcher_platform_interface:
|
url_launcher_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_platform_interface
|
name: url_launcher_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
version: "2.0.4"
|
||||||
url_launcher_web:
|
url_launcher_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
url_launcher_windows:
|
url_launcher_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_windows
|
name: url_launcher_windows
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
uuid:
|
uuid:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.4"
|
version: "3.0.4"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: watcher
|
name: watcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.5"
|
version: "2.2.5"
|
||||||
window_size:
|
window_size:
|
||||||
@ -834,14 +841,14 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
use flowy_sdk::*;
|
use flowy_sdk::*;
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use std::{ffi::CStr, os::raw::c_char};
|
use std::{ffi::CStr, os::raw::c_char};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||||
use flowy_dispatch::prelude::{DispatchError, EventResponse, Payload, StatusCode};
|
use flowy_dispatch::prelude::{EventResponse, Payload, StatusCode};
|
||||||
|
|
||||||
#[derive(ProtoBuf_Enum, Clone, Copy)]
|
#[derive(ProtoBuf_Enum, Clone, Copy)]
|
||||||
pub enum FFIStatusCode {
|
pub enum FFIStatusCode {
|
||||||
|
@ -33,6 +33,7 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
|
|||||||
| "UpdateWorkspaceRequest"
|
| "UpdateWorkspaceRequest"
|
||||||
| "CreateWorkspaceRequest"
|
| "CreateWorkspaceRequest"
|
||||||
| "Workspace"
|
| "Workspace"
|
||||||
|
| "Workspaces"
|
||||||
| "QueryWorkspaceRequest"
|
| "QueryWorkspaceRequest"
|
||||||
| "CurrentWorkspace"
|
| "CurrentWorkspace"
|
||||||
| "UpdateViewRequest"
|
| "UpdateViewRequest"
|
||||||
@ -56,12 +57,12 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
|
|||||||
| "EditorErrorCode"
|
| "EditorErrorCode"
|
||||||
| "ViewType"
|
| "ViewType"
|
||||||
| "WorkspaceEvent"
|
| "WorkspaceEvent"
|
||||||
| "WorkspaceErrorCode"
|
| "WsErrCode"
|
||||||
| "WorkspaceObservable"
|
| "WorkspaceObservable"
|
||||||
| "FFIStatusCode"
|
| "FFIStatusCode"
|
||||||
| "UserStatus"
|
| "UserStatus"
|
||||||
| "UserEvent"
|
| "UserEvent"
|
||||||
| "UserErrorCode"
|
| "UserErrCode"
|
||||||
=> TypeCategory::Enum,
|
=> TypeCategory::Enum,
|
||||||
|
|
||||||
"Option" => TypeCategory::Opt,
|
"Option" => TypeCategory::Opt,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
byte_trait::FromBytes,
|
byte_trait::FromBytes,
|
||||||
request::EventRequest,
|
request::EventRequest,
|
||||||
response::{EventResponse, ResponseBuilder, StatusCode},
|
response::{EventResponse, ResponseBuilder},
|
||||||
};
|
};
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::DispatchError,
|
|
||||||
request::Payload,
|
request::Payload,
|
||||||
response::{EventResponse, StatusCode},
|
response::{EventResponse, StatusCode},
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
services::{doc_controller::DocController, file_manager::FileManager},
|
services::{doc_controller::DocController, file_manager::FileManager},
|
||||||
};
|
};
|
||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
use std::{convert::TryInto, path::Path, sync::Arc};
|
use std::{convert::TryInto, path::Path};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
#[tracing::instrument(name = "create_doc", skip(data, controller, manager))]
|
#[tracing::instrument(name = "create_doc", skip(data, controller, manager))]
|
||||||
@ -67,7 +67,8 @@ pub async fn update_doc(
|
|||||||
manager
|
manager
|
||||||
.write()
|
.write()
|
||||||
.await
|
.await
|
||||||
.save(Path::new(&doc_desc.path), &s, params.id.clone());
|
.save(Path::new(&doc_desc.path), &s, params.id.clone())
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.name.is_some() || params.desc.is_some() {
|
if params.name.is_some() || params.desc.is_some() {
|
||||||
|
@ -2,10 +2,7 @@ use crate::{
|
|||||||
errors::EditorError,
|
errors::EditorError,
|
||||||
event::EditorEvent,
|
event::EditorEvent,
|
||||||
handlers::*,
|
handlers::*,
|
||||||
services::{
|
services::{doc_controller::DocController, file_manager::FileManager},
|
||||||
doc_controller::DocController,
|
|
||||||
file_manager::{create_dir_if_not_exist, FileManager},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use flowy_database::DBConnection;
|
use flowy_database::DBConnection;
|
||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
entities::doc::{CreateDocParams, DocData, DocInfo, QueryDocParams, UpdateDocParams},
|
entities::doc::{CreateDocParams, DocInfo, UpdateDocParams},
|
||||||
errors::EditorError,
|
errors::EditorError,
|
||||||
module::EditorDatabase,
|
module::EditorDatabase,
|
||||||
sql_tables::doc::{DocTable, DocTableChangeset, DocTableSql},
|
sql_tables::doc::{DocTable, DocTableChangeset, DocTableSql},
|
||||||
|
@ -6,7 +6,6 @@ use std::{
|
|||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str,
|
str,
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
|
||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -117,6 +116,7 @@ pub(crate) fn try_decode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn create_dir_if_not_exist(dir: &str) -> Result<(), io::Error> {
|
pub(crate) fn create_dir_if_not_exist(dir: &str) -> Result<(), io::Error> {
|
||||||
let _ = fs::create_dir_all(dir)?;
|
let _ = fs::create_dir_all(dir)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use crate::{module::EditorUser, services::file_manager::*};
|
use crate::{module::EditorUser, services::file_manager::*};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io,
|
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{Arc, PoisonError, RwLock, RwLockReadGuard},
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct FileManager {
|
pub struct FileManager {
|
||||||
@ -49,6 +48,7 @@ impl FileManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn close<T>(&mut self, id: T)
|
pub(crate) fn close<T>(&mut self, id: T)
|
||||||
where
|
where
|
||||||
T: Into<FileId>,
|
T: Into<FileId>,
|
||||||
@ -71,12 +71,15 @@ impl FileManager {
|
|||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn get_info(&self, id: &FileId) -> Option<&FileInfo> { self.file_info.get(id) }
|
pub(crate) fn get_info(&self, id: &FileId) -> Option<&FileInfo> { self.file_info.get(id) }
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn get_file_id(&self, path: &Path) -> Option<FileId> {
|
pub(crate) fn get_file_id(&self, path: &Path) -> Option<FileId> {
|
||||||
self.open_files.get(path).cloned()
|
self.open_files.get(path).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn check_file(&mut self, path: &Path, id: &FileId) -> bool {
|
pub fn check_file(&mut self, path: &Path, id: &FileId) -> bool {
|
||||||
if let Some(info) = self.file_info.get_mut(&id) {
|
if let Some(info) = self.file_info.get_mut(&id) {
|
||||||
let modified_time = get_modified_time(path);
|
let modified_time = get_modified_time(path);
|
||||||
|
@ -36,5 +36,5 @@ impl DocTableSql {
|
|||||||
Ok(doc_table)
|
Ok(doc_table)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn delete_doc(&self, view_id: &str) -> Result<(), EditorError> { unimplemented!() }
|
pub(crate) fn delete_doc(&self, _view_id: &str) -> Result<(), EditorError> { unimplemented!() }
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::entities::doc::{CreateDocParams, DocInfo, UpdateDocParams};
|
use crate::entities::doc::{CreateDocParams, DocInfo, UpdateDocParams};
|
||||||
use flowy_database::schema::doc_table;
|
use flowy_database::schema::doc_table;
|
||||||
use flowy_infra::{timestamp, uuid};
|
use flowy_infra::timestamp;
|
||||||
use std::convert::TryInto;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)]
|
#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)]
|
||||||
#[table_name = "doc_table"]
|
#[table_name = "doc_table"]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
mod doc_sql;
|
mod doc_sql;
|
||||||
mod doc_table;
|
mod doc_table;
|
||||||
|
|
||||||
pub use doc_sql::*;
|
pub(crate) use doc_sql::*;
|
||||||
pub use doc_table::*;
|
pub(crate) use doc_table::*;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user