aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLudwig Schwiedrzik <ludwig.schwiedrzik@d-fine.com>2024-08-13 17:23:45 +0200
committerScott Murray <scott.murray@konsulko.com>2024-09-10 19:52:10 +0000
commita2dcd701777968a65d3176eaf28aa7023d97c16b (patch)
tree65a5861430a1fde81160cd116fd70fba40cd1fb3 /lib
parentd3ea8d7fa4518c258fca3c825ee895487fcaa8ec (diff)
Implementation of Persistent Storage API to the flutter homescreen
Added protobuf definition of Persistent Storage API. Generated grpc-compliant code from protobuf API definition. Set up storage_client based on similar radio_client. Updated app_confi_provider and app_provider to include new API features and prepare for implementation of persistent storage of users, user preferences. Added unit tests for all API rpcs. Bug-AGL: [SPEC-5227] Change-Id: I759501bcb9de3a70a14718f8b3a87bedcf811baa Signed-off-by: Tom Kronsbein <tom.kronsbein@d-fine.com> Signed-off-by: Ludwig Schwiedrzik <ludwig.schwiedrzik@d-fine.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/data/data_providers/app_config_provider.dart47
-rw-r--r--lib/data/data_providers/app_provider.dart13
-rw-r--r--lib/data/data_providers/storage_client.dart89
3 files changed, 146 insertions, 3 deletions
diff --git a/lib/data/data_providers/app_config_provider.dart b/lib/data/data_providers/app_config_provider.dart
index 6a4ea02..b82eb54 100644
--- a/lib/data/data_providers/app_config_provider.dart
+++ b/lib/data/data_providers/app_config_provider.dart
@@ -56,6 +56,23 @@ class RadioConfig {
}
}
+class StorageConfig {
+ final String hostname;
+ final int port;
+
+ static String defaultHostname = 'localhost';
+ static int defaultPort = 50054;
+
+ StorageConfig(
+ {required this.hostname, required this.port});
+
+ static StorageConfig defaultConfig() {
+ return StorageConfig(
+ hostname: StorageConfig.defaultHostname,
+ port: StorageConfig.defaultPort);
+ }
+}
+
class MpdConfig {
final String hostname;
final int port;
@@ -77,6 +94,7 @@ class AppConfig {
final bool randomHybridAnimation;
final KuksaConfig kuksaConfig;
final RadioConfig radioConfig;
+ final StorageConfig storageConfig;
final MpdConfig mpdConfig;
static String configFilePath = '/etc/xdg/AGL/ics-homescreen.yaml';
@@ -87,6 +105,7 @@ class AppConfig {
required this.randomHybridAnimation,
required this.kuksaConfig,
required this.radioConfig,
+ required this.storageConfig,
required this.mpdConfig});
static KuksaConfig parseKuksaConfig(YamlMap kuksaMap) {
@@ -182,6 +201,25 @@ class AppConfig {
}
}
+ static StorageConfig parseStorageConfig(YamlMap storageMap) {
+ try {
+ String hostname = StorageConfig.defaultHostname;
+ if (storageMap.containsKey('hostname')) {
+ hostname = storageMap['hostname'];
+ }
+
+ int port = StorageConfig.defaultPort;
+ if (storageMap.containsKey('port')) {
+ port = storageMap['port'];
+ }
+
+ return StorageConfig(hostname: hostname, port: port);
+ } catch (_) {
+ debugPrint("Invalid storage configuration, using defaults");
+ return StorageConfig.defaultConfig();
+ }
+ }
+
static MpdConfig parseMpdConfig(YamlMap mpdMap) {
try {
String hostname = MpdConfig.defaultHostname;
@@ -229,6 +267,13 @@ final appConfigProvider = Provider((ref) {
radioConfig = RadioConfig.defaultConfig();
}
+ StorageConfig storageConfig;
+ if (yamlMap.containsKey('storage')) {
+ storageConfig = AppConfig.parseStorageConfig(yamlMap['storage']);
+ } else {
+ storageConfig = StorageConfig.defaultConfig();
+ }
+
MpdConfig mpdConfig;
if (yamlMap.containsKey('mpd')) {
mpdConfig = AppConfig.parseMpdConfig(yamlMap['mpd']);
@@ -266,6 +311,7 @@ final appConfigProvider = Provider((ref) {
randomHybridAnimation: randomHybridAnimation,
kuksaConfig: kuksaConfig,
radioConfig: radioConfig,
+ storageConfig: storageConfig,
mpdConfig: mpdConfig);
} catch (_) {
return AppConfig(
@@ -274,6 +320,7 @@ final appConfigProvider = Provider((ref) {
randomHybridAnimation: false,
kuksaConfig: KuksaConfig.defaultConfig(),
radioConfig: RadioConfig.defaultConfig(),
+ storageConfig: StorageConfig.defaultConfig(),
mpdConfig: MpdConfig.defaultConfig());
}
});
diff --git a/lib/data/data_providers/app_provider.dart b/lib/data/data_providers/app_provider.dart
index ca2c3d4..0f7ed0c 100644
--- a/lib/data/data_providers/app_provider.dart
+++ b/lib/data/data_providers/app_provider.dart
@@ -13,6 +13,7 @@ import 'package:flutter_ics_homescreen/data/data_providers/playlist_art_notifier
import 'package:flutter_ics_homescreen/data/data_providers/val_client.dart';
import 'package:flutter_ics_homescreen/data/data_providers/app_launcher.dart';
import 'package:flutter_ics_homescreen/data/data_providers/radio_client.dart';
+import 'package:flutter_ics_homescreen/data/data_providers/storage_client.dart';
import 'package:flutter_ics_homescreen/data/data_providers/mpd_client.dart';
import 'package:flutter_ics_homescreen/data/data_providers/play_controller.dart';
import 'package:flutter_ics_homescreen/export.dart';
@@ -85,6 +86,13 @@ final radioClientProvider = Provider((ref) {
return RadioClient(config: config, ref: ref);
});
+
+final storageClientProvider = Provider((ref) {
+ StorageConfig config = ref.watch(appConfigProvider).storageConfig;
+ return StorageClient(config: config, ref: ref);
+});
+
+
final mpdClientProvider = Provider((ref) {
MpdConfig config = ref.watch(appConfigProvider).mpdConfig;
return MpdClient(config: config, ref: ref);
@@ -134,9 +142,8 @@ final playControllerProvider = Provider((ref) {
return PlayController(ref: ref);
});
-final usersProvider = StateNotifierProvider<UsersNotifier, Users>((ref) {
- return UsersNotifier(Users.initial());
-});
+final usersProvider =
+ NotifierProvider<UsersNotifier, Users>(UsersNotifier.new);
final hybridStateProvider =
StateNotifierProvider<HybridNotifier, Hybrid>((ref) {
diff --git a/lib/data/data_providers/storage_client.dart b/lib/data/data_providers/storage_client.dart
new file mode 100644
index 0000000..5c72785
--- /dev/null
+++ b/lib/data/data_providers/storage_client.dart
@@ -0,0 +1,89 @@
+import 'package:flutter_ics_homescreen/export.dart';
+import 'package:protos/storage-api.dart' as storage_api;
+
+class StorageClient{
+ final StorageConfig config;
+ final Ref ref;
+ late storage_api.ClientChannel channel;
+ late storage_api.DatabaseClient stub;
+
+ StorageClient({required this.config, required this.ref}) {
+ debugPrint(
+ "Connecting to storage service at ${config.hostname}:${config.port}");
+ storage_api.ChannelCredentials creds = const storage_api.ChannelCredentials.insecure();
+ channel = storage_api.ClientChannel(config.hostname,
+ port: config.port, options: storage_api.ChannelOptions(credentials: creds));
+ stub = storage_api.DatabaseClient(channel);
+ }
+
+
+ Future<storage_api.StandardResponse> destroyDB() async {
+ try {
+ var response = await stub.destroyDB(storage_api.DestroyArguments());
+ return response;
+ } catch (e) {
+ print(e);
+ rethrow;
+ }
+ }
+
+ Future<storage_api.StandardResponse> write(storage_api.KeyValue keyValue) async {
+ try {
+ var response = await stub.write(keyValue);
+ return response;
+ } catch (e) {
+ print(e);
+ rethrow;
+ }
+ }
+
+ Future<storage_api.ReadResponse> read(storage_api.Key key) async{
+ try{
+ var response = await stub.read(key);
+ return response;
+ } catch(e) {
+ print(e);
+ rethrow;
+ }
+ }
+
+ Future<storage_api.StandardResponse> delete(storage_api.Key key) async{
+ try{
+ var response = await stub.delete(key);
+ return response;
+ } catch(e) {
+ print(e);
+ rethrow;
+ }
+ }
+
+ Future<storage_api.ListResponse> search(storage_api.Key key) async{
+ try{
+ var response = await stub.search(key);
+ return response;
+ } catch(e) {
+ print(e);
+ rethrow;
+ }
+ }
+
+ Future<storage_api.StandardResponse> deleteNodes(storage_api.Key key) async{
+ try{
+ var response = await stub.deleteNodes(key);
+ return response;
+ } catch(e) {
+ print(e);
+ rethrow;
+ }
+ }
+
+ Future<storage_api.ListResponse> listNodes(storage_api.SubtreeInfo subtreeInfo) async{
+ try{
+ var response = await stub.listNodes(subtreeInfo);
+ return response;
+ } catch(e) {
+ print(e);
+ rethrow;
+ }
+ }
+} \ No newline at end of file