diff --git a/lib/widgets/category_picker.dart b/lib/widgets/category_picker.dart deleted file mode 100644 index f6e6973..0000000 --- a/lib/widgets/category_picker.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:pheno_ui/interface/data/entry.dart'; -import 'package:pheno_ui/interface/strapi.dart'; -import 'package:pheno_ui_tester/widgets/picker_state.dart'; -import 'package:pheno_ui_tester/widgets/screen_picker.dart'; - -class CategoryPicker extends PickerWidget { - @override - get getList => _getList; - - @override - get builder => _builder; - - @override - get title => 'Category'; - - const CategoryPicker({ super.key }); - - Widget _builder(PhenoDataEntry entry, BuildContext context, _) { - return ScreenPicker(entry: entry); - } - - Future> _getList() { - return Strapi().getCategoryList(); - } - - @override - State createState() => PickerState(); -} \ No newline at end of file diff --git a/lib/widgets/layout_picker.dart b/lib/widgets/layout_picker.dart new file mode 100644 index 0000000..f9a4427 --- /dev/null +++ b/lib/widgets/layout_picker.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; +import 'package:pheno_ui/interface/strapi.dart'; +import 'package:pheno_ui_tester/widgets/picker_state.dart'; + +import 'render_layout.dart'; + +class LayoutPicker extends PickerWidget { + @override + get getList => _getList; + + @override + get builder => _builder; + + @override + get title => entry != null ? entry!.path : 'Category'; + + final PickerEntry? entry; + + const LayoutPicker({ super.key, this.entry }); + + Widget _builder(PickerEntry entry, BuildContext context, _) { + if (entry.type == PickerEntryType.tag) { + return LayoutPicker(entry: entry); + } + return RenderLayout( + tagId: this.entry!.id, + initialRoute: entry.name, + ); + } + + Future> _getList() async { + List entries = []; + final tagList = await Strapi().getCategoryList(entry?.id); + for (var tagEntry in tagList) { + entries.add(PickerEntry(tagEntry, PickerEntryType.tag)); + } + + if (entry != null) { + final layoutList = await Strapi().getScreenList(entry!.id); + for (var layoutEntry in layoutList) { + entries.add(PickerEntry(layoutEntry, PickerEntryType.layout)); + } + } + + return entries; + } + + @override + State createState() => PickerState(); +} \ No newline at end of file diff --git a/lib/widgets/login.dart b/lib/widgets/login.dart index e8a51f1..2884b36 100644 --- a/lib/widgets/login.dart +++ b/lib/widgets/login.dart @@ -3,7 +3,7 @@ import 'package:pheno_ui/interface/strapi.dart'; import 'package:pheno_ui_tester/widgets/loading_screen.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'category_picker.dart'; +import 'layout_picker.dart'; class Login extends StatefulWidget { const Login({super.key}); @@ -183,7 +183,7 @@ class LoginState extends State { settings: const RouteSettings(name: 'category_picker'), transitionDuration: Duration.zero, reverseTransitionDuration: Duration.zero, - pageBuilder: (context, _, __) => const CategoryPicker(), + pageBuilder: (context, _, __) => const LayoutPicker(), )); }, child: const Text('Continue'), diff --git a/lib/widgets/picker_state.dart b/lib/widgets/picker_state.dart index 43ce495..34a18a5 100644 --- a/lib/widgets/picker_state.dart +++ b/lib/widgets/picker_state.dart @@ -5,16 +5,33 @@ import 'package:pheno_ui_tester/widgets/top_bar.dart'; import 'loading_screen.dart'; +enum PickerEntryType { + tag, + layout, +} + +class PickerEntry { + final PhenoDataEntry pde; + final PickerEntryType type; + + const PickerEntry(this.pde, this.type); + + String get id => pde.id; + String get uid => pde.uid; + String get name => pde.name; + String get path => pde.data['path']; +} + abstract class PickerWidget extends StatefulWidget { const PickerWidget({super.key}); - Future> Function() get getList; - Widget Function(PhenoDataEntry, BuildContext, List) get builder; - Future Function(PhenoDataEntry)? get delete => null; + Future> Function() get getList; + Widget Function(PickerEntry, BuildContext, List) get builder; + Future Function(PickerEntry)? get delete => null; String get title; } class PickerState extends State { - List? entries; + List? entries; bool _loading = false; PickerState(); @@ -39,8 +56,8 @@ class PickerState extends State { } List children = (entries as List).map((e) => ListTile( - leading: const Icon( - Icons.screenshot, + leading: Icon( + e.type == PickerEntryType.tag ? Icons.folder_outlined : Icons.file_open_outlined, size: 20, ), trailing: widget.delete == null? null :IconButton( diff --git a/lib/widgets/render_layout.dart b/lib/widgets/render_layout.dart index 3888676..22b3171 100644 --- a/lib/widgets/render_layout.dart +++ b/lib/widgets/render_layout.dart @@ -2,18 +2,17 @@ import 'package:flutter/material.dart'; import 'package:pheno_ui/interface/data/entry.dart'; import 'package:pheno_ui/interface/data/strapi_provider.dart'; import 'package:pheno_ui/pheno_ui.dart'; +import 'package:pheno_ui_tester/widgets/picker_state.dart'; import 'package:pheno_ui_tester/widgets/top_bar.dart'; class RenderLayout extends StatefulWidget { - final String category; + final String tagId; final String initialRoute; - final List entries; const RenderLayout({ super.key, - required this.category, + required this.tagId, required this.initialRoute, - required this.entries, }); @override @@ -32,7 +31,7 @@ class RenderLayoutState extends State { @override void initState() { super.initState(); - var dataProvider = StrapiDataProvider(sourceId: Strapi().server, category: widget.category); + var dataProvider = StrapiDataProvider(sourceId: Strapi().server, category: widget.tagId); FigmaScreens().setProvider(dataProvider).then((_) => setState(() { _initialized = true; })); diff --git a/lib/widgets/screen_picker.dart b/lib/widgets/screen_picker.dart deleted file mode 100644 index 58fdc73..0000000 --- a/lib/widgets/screen_picker.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:pheno_ui/interface/data/entry.dart'; -import 'package:pheno_ui/interface/screens.dart'; -import 'package:pheno_ui/interface/strapi.dart'; -import 'package:pheno_ui_tester/widgets/picker_state.dart'; -import 'package:pheno_ui_tester/widgets/render_layout.dart'; - -class ScreenPicker extends PickerWidget { - @override - get getList => _getList; - - @override - get builder => _builder; - - @override - get delete => _delete; - - @override - get title => 'Layout'; - - final PhenoDataEntry entry; - - const ScreenPicker({ super.key, required this.entry }); - - Widget _builder(PhenoDataEntry entry, BuildContext context, List entries) { - return RenderLayout( - category: this.entry.name, - initialRoute: entry.name, - entries: entries - ); - } - - Future _delete(PhenoDataEntry entry) async { - if (!Strapi().isLoggedIn) { - throw Exception('You must be logged in to delete a screen'); - } - await Strapi().deleteScreen(entry.id); - } - - Future> _getList() async { - await FigmaScreens().refreshScreens(); - return await Strapi().getScreenList(entry.id); - } - - @override - State createState() => PickerState(); -} \ No newline at end of file diff --git a/lib/widgets/top_bar.dart b/lib/widgets/top_bar.dart index e500664..7220cb3 100644 --- a/lib/widgets/top_bar.dart +++ b/lib/widgets/top_bar.dart @@ -36,13 +36,16 @@ Widget topBar(BuildContext context, [String? title, void Function()? refresh, Bo var centerChildren = []; if (title != null) { - centerChildren.add(Text( - title, - textAlign: TextAlign.center, - style: const TextStyle( - color: Colors.white, - fontSize: 21, - overflow: TextOverflow.ellipsis, + centerChildren.add(FittedBox( + fit: BoxFit.fitWidth, + child: Text( + title, + textAlign: TextAlign.center, + style: const TextStyle( + color: Colors.white, + fontSize: 21, + overflow: TextOverflow.ellipsis, + ), ), )); } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 7b133d0..2ae59c0 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,11 +8,13 @@ import Foundation import path_provider_foundation import screen_retriever import shared_preferences_foundation +import webview_flutter_wkwebview import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + FLTWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "FLTWebViewFlutterPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 511dc0c..92d08fb 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -8,6 +8,9 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS + - webview_flutter_wkwebview (0.0.1): + - Flutter + - FlutterMacOS - window_manager (0.2.0): - FlutterMacOS @@ -16,6 +19,7 @@ DEPENDENCIES: - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - webview_flutter_wkwebview (from `Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin`) - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) EXTERNAL SOURCES: @@ -27,14 +31,17 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos shared_preferences_foundation: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + webview_flutter_wkwebview: + :path: Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin window_manager: :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 - shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 + webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4 window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index d53ef64..8e02df2 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import Cocoa import FlutterMacOS -@NSApplicationMain +@main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true diff --git a/package/pheno_ui/lib/interface/data/entry.dart b/package/pheno_ui/lib/interface/data/entry.dart index 4d96c5e..87875dc 100644 --- a/package/pheno_ui/lib/interface/data/entry.dart +++ b/package/pheno_ui/lib/interface/data/entry.dart @@ -1,6 +1,7 @@ class PhenoDataEntry { - final int id; - final String uid; - const PhenoDataEntry(this.id, this.uid); - String get name => uid; + final Map data; + const PhenoDataEntry(this.data); + String get id => data['id']; + String get uid => data['path']; + String get name => data['name']; } \ No newline at end of file diff --git a/package/pheno_ui/lib/interface/data/provider.dart b/package/pheno_ui/lib/interface/data/provider.dart index 0c426e9..ace4027 100644 --- a/package/pheno_ui/lib/interface/data/provider.dart +++ b/package/pheno_ui/lib/interface/data/provider.dart @@ -12,7 +12,7 @@ abstract class PhenoDataProvider { final String sourceId; final String category; - final Map> _screenSpecCache = {}; + final Map> _screenSpecCache = {}; final Map> _componentSpecCache = {}; final Map> _animationCache = {}; List? _screenList; @@ -39,7 +39,7 @@ abstract class PhenoDataProvider { } @nonVirtual - Future loadScreenLayout(int id) async { + Future loadScreenLayout(String id) async { if (_screenSpecCache.containsKey(id)) { return await _screenSpecCache[id]!; } @@ -69,10 +69,10 @@ abstract class PhenoDataProvider { } Future> doGetScreenList(); - Future doLoadScreenLayout(int id); + Future doLoadScreenLayout(String id); Future doLoadComponentSpec(String name); - Future doLoadAnimation(String path); + Future doLoadAnimation(String id); - Image loadImage(String path, { required BoxFit fit }); - SvgPicture loadSvg(String path, { required BoxFit fit }); + Image loadImage(String id, { required BoxFit fit }); + SvgPicture loadSvg(String id, { required BoxFit fit }); } \ No newline at end of file diff --git a/package/pheno_ui/lib/interface/data/screen_spec.dart b/package/pheno_ui/lib/interface/data/screen_spec.dart index b697ee7..fc52cb2 100644 --- a/package/pheno_ui/lib/interface/data/screen_spec.dart +++ b/package/pheno_ui/lib/interface/data/screen_spec.dart @@ -1,5 +1,5 @@ class PhenoScreenSpec { - final int id; + final String id; final String name; final String slug; final Map spec; @@ -8,10 +8,10 @@ class PhenoScreenSpec { factory PhenoScreenSpec.fromJson(Map json) { return PhenoScreenSpec( - json['id'].toInt(), - json['attributes']['name'], - json['attributes']['slug'], - json['attributes']['spec'] + json['id'], + json['name'], + json['tag']['path'] + '/' + json['name'], + json['data'] ); } } \ No newline at end of file diff --git a/package/pheno_ui/lib/interface/data/strapi_provider.dart b/package/pheno_ui/lib/interface/data/strapi_provider.dart index 4af9df8..d00ef8a 100644 --- a/package/pheno_ui/lib/interface/data/strapi_provider.dart +++ b/package/pheno_ui/lib/interface/data/strapi_provider.dart @@ -41,7 +41,7 @@ class StrapiDataProvider extends PhenoDataProvider { } @override - Future doLoadScreenLayout(int id) async { + Future doLoadScreenLayout(String id) async { return await Strapi().loadScreenLayoutById(id); } @@ -51,47 +51,38 @@ class StrapiDataProvider extends PhenoDataProvider { } @override - Image loadImage(String path, { required BoxFit fit }) { - // make sure that the path is retrieving the image from the server - // configured in the strapi class - Uri uri = Uri.parse(path); - Uri strapiServer = Uri.parse(Strapi().server); - Uri newUri = Uri( - scheme: strapiServer.scheme, - host: strapiServer.host, - port: strapiServer.port, - path: uri.path, + Image loadImage(String id, { required BoxFit fit }) { + Uri server = Uri.parse(Strapi().server); + Uri url = Uri( + scheme: server.scheme, + host: server.host, + port: server.port, + path: 'phui/media/file/id/$id', ); - return Image.network(newUri.toString(), fit: fit); + return Image.network(url.toString(), fit: fit); } @override - SvgPicture loadSvg(String path, { required BoxFit fit }) { - // make sure that the path is retrieving the image from the server - // configured in the strapi class - Uri uri = Uri.parse(path); - Uri strapiServer = Uri.parse(Strapi().server); - Uri newUri = Uri( - scheme: strapiServer.scheme, - host: strapiServer.host, - port: strapiServer.port, - path: uri.path, + SvgPicture loadSvg(String id, { required BoxFit fit }) { + Uri server = Uri.parse(Strapi().server); + Uri url = Uri( + scheme: server.scheme, + host: server.host, + port: server.port, + path: 'phui/media/file/id/$id', ); - return SvgPicture.network(newUri.toString(), fit: fit); + return SvgPicture.network(url.toString(), fit: fit); } @override - Future doLoadAnimation(String path) async { - // make sure that the path is retrieving the image from the server - // configured in the strapi class - Uri uri = Uri.parse(path); - Uri strapiServer = Uri.parse(Strapi().server); - Uri newUri = Uri( - scheme: strapiServer.scheme, - host: strapiServer.host, - port: strapiServer.port, - path: uri.path, + Future doLoadAnimation(String id) async { + Uri server = Uri.parse(Strapi().server); + Uri url = Uri( + scheme: server.scheme, + host: server.host, + port: server.port, + path: 'phui/media/file/id/$id', ); - return NetworkLottie(newUri.toString()).load(); + return NetworkLottie(url.toString()).load(); } } \ No newline at end of file diff --git a/package/pheno_ui/lib/interface/screens.dart b/package/pheno_ui/lib/interface/screens.dart index a8aa38f..4ea8ba8 100644 --- a/package/pheno_ui/lib/interface/screens.dart +++ b/package/pheno_ui/lib/interface/screens.dart @@ -43,8 +43,8 @@ class FigmaScreens { } var screens = await _provider!.getScreenList(true); for (var screen in screens) { - print('id:${screen.id} uid:${screen.uid}'); - this.screens[screen.uid] = screen; + print('id:${screen.id} uid:${screen.uid} name:${screen.name}'); + this.screens[screen.name] = screen; } } diff --git a/package/pheno_ui/lib/interface/strapi.dart b/package/pheno_ui/lib/interface/strapi.dart index 0cf8270..53cf21b 100644 --- a/package/pheno_ui/lib/interface/strapi.dart +++ b/package/pheno_ui/lib/interface/strapi.dart @@ -25,7 +25,7 @@ class Strapi { return _singleton; } - Strapi._internal() : _server = Uri.parse('http://127.0.0.1:1337'); + Strapi._internal() : _server = Uri.parse('http://127.0.0.1:8090'); Future login(Uri server, String user, String password) async { if (user.isNotEmpty && password.isNotEmpty) { @@ -34,7 +34,7 @@ class Strapi { scheme: _server.scheme, host: _server.host, port: _server.port, - path: '/api/auth/local', + path: '/api/admins/auth-with-password', ); var response = await http.post( @@ -43,15 +43,15 @@ class Strapi { 'Content-Type': 'application/json', }, body: jsonEncode({ - 'identifier': user, + 'identity': user, 'password': password, }) ); var body = jsonDecode(response.body) as Map; - if (body.containsKey('jwt')) { + if (body.containsKey('token')) { _user = user; - _jwt = body['jwt']; + _jwt = body['token']; return _jwt!; } else if (body.containsKey('error')) { throw Exception(body['error']['message']); @@ -73,11 +73,11 @@ class Strapi { scheme: _server.scheme, host: _server.host, port: _server.port, - path: '/api/users/me', + path: '/api/admins/auth-refresh', ); try { - var response = await http.get( + var response = await http.post( url, headers: { 'Authorization': 'Bearer $jwt', @@ -85,9 +85,9 @@ class Strapi { ); var body = jsonDecode(response.body) as Map; - if (body.containsKey('username')) { - _user = body['username']; - _jwt = jwt; + if (body.containsKey('token')) { + _user = body['admin']['email']; + _jwt = body['token']; return true; } } catch (e) { @@ -102,7 +102,7 @@ class Strapi { _jwt = null; } - Future getCategory(String name, [String collection = 'screen-categories']) async { + Future _getCategory_(String name, [String collection = 'screen-categories']) async { Uri url = Uri( scheme: _server.scheme, host: _server.host, @@ -114,108 +114,85 @@ class Strapi { var response = await http.get(url); var body = jsonDecode(response.body) as Map; var data = body['data'][0]; - var entry = PhenoDataEntry(data['id'], data['attributes']['uid']); + var entry = PhenoDataEntry(data); return entry; } - Future> getCategoryList([String collection = 'screen-categories']) async { + Future> _getEntryList(String path) async { Uri url = Uri( scheme: _server.scheme, host: _server.host, port: _server.port, - path: 'api/$collection', + path: path, ); var response = await http.get(url); + if (response.statusCode != 200) { + throw Exception('Failed to load list'); + } + var body = jsonDecode(response.body) as Map; - var entries = body['data'].map((e) => PhenoDataEntry(e['id'], e['attributes']['uid'])); + var entries = body['items'].map((e) => PhenoDataEntry(e)); var result = List.from(entries); return result; } - Future> getScreenList([dynamic category]) async { - category ??= this.category; - int id = category is int ? category : (await getCategory(category)).id; - - Uri url = Uri( - scheme: _server.scheme, - host: _server.host, - port: _server.port, - path: 'api/screen-categories/$id', - query: 'populate[screens][fields][0]=name', - ); + Future> getCategoryList([String? parentId]) async { + return _getEntryList('phui/tag/list${parentId != null ? '/$parentId' : ''}'); + } - var response = await http.get(url); - var body = jsonDecode(response.body) as Map; - var screens = body['data']['attributes']['screens']['data']; - var entries = screens.map((e) => PhenoDataEntry(e['id'], e['attributes']['name'])); - var result = List.from(entries); - return result; + Future> getScreenList(String tagId) async { + return _getEntryList('phui/layout/list/$tagId'); } - Future> getComponentList([dynamic category]) async { - category ??= this.category; - int id = category is int ? category : (await getCategory(category, 'figma-widget-categories')).id; - - Uri url = Uri( - scheme: _server.scheme, - host: _server.host, - port: _server.port, - path: 'api/figma-widget-categories/$id', - query: 'populate[figma_widgets][fields][0]=name', - ); - var response = await http.get(url); - var body = jsonDecode(response.body) as Map; - var components = body['data']['attributes']['figma_widgets']['data']; - var entries = components.map((e) => - PhenoDataEntry(e['id'], e['attributes']['name'])); - var result = List.from(entries); - return result; + Future> getComponentList(String tagId) async { + return _getEntryList('phui/widget/list/$tagId'); } Future loadScreenLayout(dynamic nameOrId, String? category) async { if (nameOrId is String && category != null) { return loadScreenLayoutByName(nameOrId, category); - } else if (nameOrId is int) { + } else if (nameOrId is String) { return loadScreenLayoutById(nameOrId); } throw Exception('Invalid name or id'); } Future loadScreenLayoutByName(String name, String category) async { - PhenoDataEntry entry = await getCategory(category); - Uri url = Uri( scheme: _server.scheme, host: _server.host, port: _server.port, - path: 'api/screens', - queryParameters: { - 'filters[name][\$eq]': name, - 'populate': 'category', - 'filters[category][id][\$eq]': entry.id.toString(), - } + path: 'phui/layout/tag/$category/$name', ); var response = await http.get(url); + if (response.statusCode != 200) { + throw Exception('Failed to load list'); + } + var json = jsonDecode(response.body) as Map; - return PhenoScreenSpec.fromJson(json['data'][0]); + return PhenoScreenSpec.fromJson(json); } - Future loadScreenLayoutById(int id) async { + Future loadScreenLayoutById(String id) async { Uri url = Uri( scheme: _server.scheme, host: _server.host, port: _server.port, - path: 'api/screens/$id', + path: 'phui/layout/id/$id', ); var response = await http.get(url); + if (response.statusCode != 200) { + throw Exception('Failed to load list'); + } var json = jsonDecode(response.body) as Map; - return PhenoScreenSpec.fromJson(json['data']); + return PhenoScreenSpec.fromJson(json); } - Future deleteScreen(int id) async { + Future deleteScreen(String id) async { + throw Exception('Not implemented'); Uri url = Uri( scheme: _server.scheme, host: _server.host, @@ -241,23 +218,19 @@ class Strapi { } Future loadComponentSpecByName(String name, String category) async { - PhenoDataEntry entry = await getCategory(category, 'figma-widget-categories'); - Uri url = Uri( scheme: _server.scheme, host: _server.host, port: _server.port, - path: 'api/figma-widgets', - queryParameters: { - 'filters[name][\$eq]': name, - 'populate': 'category', - 'filters[category][id][\$eq]': entry.id.toString(), - } + path: 'phui/widget/tag/$category/$name', ); var response = await http.get(url); + if (response.statusCode != 200) { + throw Exception('Failed to load list'); + } var json = jsonDecode(response.body) as Map; - return PhenoComponentSpec.fromJson(json['data'][0]); + return PhenoComponentSpec.fromJson(json); } Future loadComponentSpecById(int id) async { @@ -265,11 +238,14 @@ class Strapi { scheme: _server.scheme, host: _server.host, port: _server.port, - path: 'api/figma-widgets/$id', + path: 'phui/widget/id/$id', ); var response = await http.get(url); + if (response.statusCode != 200) { + throw Exception('Failed to load list'); + } var json = jsonDecode(response.body) as Map; - return PhenoComponentSpec.fromJson(json['data']); + return PhenoComponentSpec.fromJson(json); } } \ No newline at end of file diff --git a/package/pheno_ui/pubspec.yaml b/package/pheno_ui/pubspec.yaml index 24e6ced..4a7c5cc 100644 --- a/package/pheno_ui/pubspec.yaml +++ b/package/pheno_ui/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: google_fonts: ^6.1.0 http: ^1.2.0 jwt_decoder: ^2.0.1 - logger: ^1.4.0 + logger: ^2.4.0 lottie: ^3.1.0 webview_flutter: ^4.7.0 webview_flutter_web: ^0.2.2+4 @@ -23,7 +23,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^2.0.0 + flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/pubspec.lock b/pubspec.lock index cddaa09..5a4c136 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: archive - sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d url: "https://pub.dev" source: hosted - version: "3.4.10" + version: "3.6.1" args: dependency: transitive description: name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.6.0" async: dependency: transitive description: @@ -57,30 +57,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.6" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.8" fake_async: dependency: transitive description: @@ -93,18 +85,18 @@ packages: dependency: transitive description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -114,10 +106,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "5.0.0" flutter_svg: dependency: transitive description: @@ -148,18 +140,18 @@ packages: dependency: transitive description: name: google_fonts - sha256: "5b1726fee554d1cc9db1baef8061b126567ff0a1140a03ed7de936e62f2ab98b" + sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.1" http: dependency: transitive description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" http_parser: dependency: transitive description: @@ -176,14 +168,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.19.0" - js: - dependency: transitive - description: - name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf - url: "https://pub.dev" - source: hosted - version: "0.7.1" jwt_decoder: dependency: transitive description: @@ -196,18 +180,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -220,10 +204,10 @@ packages: dependency: transitive description: name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "5.0.0" logger: dependency: transitive description: @@ -236,10 +220,10 @@ packages: dependency: transitive description: name: lottie - sha256: ce2bb2605753915080e4ee47f036a64228c88dc7f56f7bc1dbe912d75b55b1e2 + sha256: "7afc60865a2429d994144f7d66ced2ae4305fe35d82890b8766e3359872d872c" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.3" matcher: dependency: transitive description: @@ -252,18 +236,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" path: dependency: transitive description: @@ -284,26 +268,26 @@ packages: dependency: transitive description: name: path_provider - sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.12" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -324,10 +308,10 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" petitparser: dependency: transitive description: @@ -347,10 +331,10 @@ packages: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -359,14 +343,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" - pointycastle: - dependency: transitive - description: - name: pointycastle - sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" - url: "https://pub.dev" - source: hosted - version: "3.7.4" screen_retriever: dependency: transitive description: @@ -379,58 +355,58 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" + sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.3" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" + sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d" url: "https://pub.dev" source: hosted - version: "2.3.5" + version: "2.5.3" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" sky_engine: dependency: transitive description: flutter @@ -480,18 +456,18 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" typed_data: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" vector_graphics: dependency: transitive description: @@ -528,34 +504,34 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.4" web: dependency: transitive description: name: web - sha256: "1d9158c616048c38f712a6646e317a3426da10e884447626167240d45209cbad" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "1.1.0" webview_flutter: dependency: transitive description: name: webview_flutter - sha256: "25e1b6e839e8cbfbd708abc6f85ed09d1727e24e08e08c6b8590d7c65c9a8932" + sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec" url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.10.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "3e5f4e9d818086b0d01a66fb1ff9cc72ab0cc58c71980e3d3661c5685ea0efb0" + sha256: "74693a212d990b32e0b7055d27db973a18abf31c53942063948cdfaaef9787ba" url: "https://pub.dev" source: hosted - version: "3.15.0" + version: "4.0.0" webview_flutter_platform_interface: dependency: transitive description: @@ -568,42 +544,34 @@ packages: dependency: transitive description: name: webview_flutter_web - sha256: "7f7cb8cfe5a5dee3b55d660a367c00838be56540ccb4097e84601bb6cb354af3" + sha256: cbe1efe45e1be8470fdef7ddb75e2e2998c7ca47b75c09b9354934d20eca146b url: "https://pub.dev" source: hosted - version: "0.2.2+4" + version: "0.2.3+2" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "9bf168bccdf179ce90450b5f37e36fe263f591c9338828d6bf09b6f8d0f57f86" - url: "https://pub.dev" - source: hosted - version: "3.12.0" - win32: - dependency: transitive - description: - name: win32 - sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" + sha256: d4034901d96357beb1b6717ebf7d583c88e40cfc6eb85fe76dd1bf0979a9f251 url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "3.16.0" window_manager: dependency: "direct main" description: name: window_manager - sha256: b3c895bdf936c77b83c5254bec2e6b3f066710c1f89c38b20b8acc382b525494 + sha256: ab8b2a7f97543d3db2b506c9d875e637149d48ee0c6a5cb5f5fd6e0dac463792 url: "https://pub.dev" source: hosted - version: "0.3.8" + version: "0.4.2" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" xml: dependency: transitive description: @@ -613,5 +581,5 @@ packages: source: hosted version: "6.5.0" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3eed58b..89772e2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,7 +37,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 - window_manager: ^0.3.8 + window_manager: ^0.4.2 shared_preferences: ^2.2.2 dev_dependencies: @@ -49,7 +49,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^2.0.0 + flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec