100 lines
3.0 KiB
Dart
Raw Normal View History

2021-06-19 23:41:19 +08:00
import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'package:appflowy_backend/rust_stream.dart';
import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart';
2021-06-19 23:41:19 +08:00
import 'package:flutter/services.dart';
import 'package:logger/logger.dart';
2021-06-19 23:41:19 +08:00
import 'ffi.dart' as ffi;
export 'package:async/async.dart';
2022-01-28 18:34:21 +08:00
enum ExceptionType {
AppearanceSettingsIsEmpty,
}
class FlowySDKException implements Exception {
ExceptionType type;
FlowySDKException(this.type);
}
2021-06-19 23:41:19 +08:00
class FlowySDK {
static const MethodChannel _channel = MethodChannel('appflowy_backend');
2021-06-19 23:41:19 +08:00
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
feat: Customize the storage folder path (#1538) * feat: support customize folder path * feat: add l10n and optimize the logic * chore: code refactor * feat: add file read/write permission for macOS * fix: add toast for restoring path * feat: fetch apps and show them * feat: fetch apps and show them * feat: implement select document logic * feat: l10n and add select item callback * feat: add space between tile * chore: move file exporter to settings * chore: update UI * feat: support customizing folder when launching the app * feat: auto register after customizing folder * feat: l10n * feat: l10n * chore: reinitialize flowy sdk when calling init_sdk * chore: remove flowysdk const keyword to make sure it can be rebuild * chore: clear kv values when user logout * chore: replace current workspace id key in kv.db * feat: add config.name as a part of seesion_cache_key * feat: support open folder when launching * chore: fix some bugs * chore: dart fix & flutter analyze * chore: wrap 'sign up with ramdom user' as interface * feat: dismiss settings view after changing the folder * fix: read kv value after initializaing with new path * chore: remove user_id prefix from current workspace key * fix: move open latest view action to bloc * test: add test utils for integration tests * chore: move integration_test to its parent directory * test: add integration_test ci * test: switch to B from A, then switch to A again * chore: fix warings and format code and fix tests * chore: remove comment out codes * chore: rename some properties name and optimize the logic * chore: abstract logic of settings file exporter widget to cubit * chore: abstract location customizer view from file system view * chore: abstract settings page index to enum type * chore: remove the redundant underscore * test: fix integration test error * chore: enable integration test for windows and ubuntu * feat: abstract file picker as service and mock it under integration test * chore: fix bloc test Co-authored-by: nathan <nathan@appflowy.io>
2022-12-20 11:14:42 +08:00
FlowySDK();
2021-06-19 23:41:19 +08:00
Future<void> dispose() async {}
2021-06-19 23:41:19 +08:00
Future<void> init(String configuration) async {
ffi.set_stream_port(RustStreamReceiver.shared.port);
2021-06-19 23:41:19 +08:00
ffi.store_dart_post_cobject(NativeApi.postCObject);
// On iOS, VSCode can't print logs from Rust, so we need to use a different method to print logs.
// So we use a shared port to receive logs from Rust and print them using the logger. In release mode, we don't print logs.
if (Platform.isIOS && kDebugMode) {
ffi.set_log_stream_port(RustLogStreamReceiver.logShared.port);
}
// final completer = Completer<Uint8List>();
// // Create a SendPort that accepts only one message.
// final sendPort = singleCompletePort(completer);
final code = ffi.init_sdk(0, configuration.toNativeUtf8());
if (code != 0) {
throw Exception('Failed to initialize the SDK');
}
// return completer.future;
2021-06-19 23:41:19 +08:00
}
}
class RustLogStreamReceiver {
static RustLogStreamReceiver logShared = RustLogStreamReceiver._internal();
late RawReceivePort _ffiPort;
late StreamController<Uint8List> _streamController;
late StreamSubscription<Uint8List> _subscription;
int get port => _ffiPort.sendPort.nativePort;
late Logger _logger;
RustLogStreamReceiver._internal() {
_ffiPort = RawReceivePort();
_streamController = StreamController();
_ffiPort.handler = _streamController.add;
_logger = Logger(
printer: PrettyPrinter(
methodCount: 0, // number of method calls to be displayed
errorMethodCount: 8, // number of method calls if stacktrace is provided
lineLength: 120, // width of the output
colors: false, // Colorful log messages
printEmojis: false, // Print an emoji for each log message
dateTimeFormat:
DateTimeFormat.none, // Should each log print contain a timestamp
),
level: kDebugMode ? Level.trace : Level.info,
);
_subscription = _streamController.stream.listen((data) {
String decodedString = utf8.decode(data);
_logger.i(decodedString);
});
}
factory RustLogStreamReceiver() {
return logShared;
}
Future<void> dispose() async {
await _streamController.close();
await _subscription.cancel();
_ffiPort.close();
}
}