-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add PlatformWidgetBuilder. (#319)
* feat: Add PlatformWidgetBuilder. This widget abstracts the functionality to detect the platform used by the user. Related to #139. * feat: Add basic test for PlatformWidgetBuilder. * chore: Spell check. * refactor: Switch name from `PlatformWidgetBuilder` to `PlatformAwareBuilder`. * refactor: Use platform identifiers to select proper data to be used. * refactor: Use `PlatformKey` enum for platform identifiers. * docs: Add `PlatformAwareBuilder` documentation. * docs: Improve `PlatformAwareBuilder` description.
- Loading branch information
Showing
9 changed files
with
177 additions
and
1 deletion.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
catalyst_voices/packages/catalyst_voices_shared/lib/src/catalyst_voices_shared.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export 'platform/catalyst_platform.dart'; | ||
export 'platform_aware_builder/platform_aware_builder.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
catalyst_voices/packages/catalyst_voices_shared/lib/src/platform/platform_key.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
enum PlatformKey { | ||
android, | ||
desktop, | ||
fuchsia, | ||
iOS, | ||
linux, | ||
macOS, | ||
mobile, | ||
mobileWeb, | ||
web, | ||
webDesktop, | ||
windows, | ||
other, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
...ackages/catalyst_voices_shared/lib/src/platform_aware_builder/platform_aware_builder.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import 'package:catalyst_voices_shared/src/platform/catalyst_platform.dart'; | ||
import 'package:catalyst_voices_shared/src/platform/platform_key.dart'; | ||
import 'package:flutter/widgets.dart'; | ||
|
||
// A [PlatformAwareBuilder] is a StatelessWidget that is aware of the current | ||
// platform. | ||
// | ||
// This is an abstract widget that has a required argument [builder] that can | ||
// consume platform-specific data automatically based on platform that is | ||
// detected. | ||
// | ||
// The platform detection happens in [CatalystPlatform]. | ||
// | ||
// The widget accepts an argument for each specific platform defined in | ||
// [PlatformKey]. The platform specific [data] is selected when two conditions | ||
// are verified at the same time: | ||
// - the platform is detected | ||
// - the platform-specific argument is present | ||
// In case those conditions are not verified the [other] argument is used (and | ||
// because of this it is required). | ||
// The type of the platform specific data is generic. | ||
// | ||
// A simple usage is to render a string based on the platform: | ||
// | ||
// ```dart | ||
// PlatformWidgetBuilder<String>( | ||
// android: 'This is an Android platform.', | ||
// other: 'This is an other platform.', | ||
// builder: (context, title) => Text(title!), | ||
// ); | ||
// ``` | ||
// | ||
// or to have a specific Padding: | ||
// | ||
// ```dart | ||
// PlatformWidgetBuilder<EdgeInsetsGeometry>( | ||
// android: EdgeInsets.all(10.0), | ||
// other: EdgeInsets.all(40.0), | ||
// builder: (context, padding) => Padding( | ||
// padding: padding, | ||
// child: Text('This is an example.') | ||
// ), | ||
// ); | ||
// ``` | ||
|
||
class PlatformAwareBuilder<T> extends StatelessWidget { | ||
final Widget Function(BuildContext context, T? data) builder; | ||
final Map<PlatformKey, T?> _platformData; | ||
|
||
PlatformAwareBuilder({ | ||
super.key, | ||
required this.builder, | ||
T? android, | ||
T? desktop, | ||
T? fuchsia, | ||
T? iOS, | ||
T? linux, | ||
T? macOS, | ||
T? mobile, | ||
T? mobileWeb, | ||
T? web, | ||
T? webDesktop, | ||
T? windows, | ||
required T other, | ||
}) : _platformData = { | ||
PlatformKey.android: android, | ||
PlatformKey.desktop: desktop, | ||
PlatformKey.fuchsia: fuchsia, | ||
PlatformKey.iOS: iOS, | ||
PlatformKey.linux: linux, | ||
PlatformKey.macOS: macOS, | ||
PlatformKey.mobile: mobile, | ||
PlatformKey.mobileWeb: mobileWeb, | ||
PlatformKey.web: web, | ||
PlatformKey.webDesktop: webDesktop, | ||
PlatformKey.windows: windows, | ||
PlatformKey.other: other, | ||
}; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return builder(context, _getPlatformData()); | ||
} | ||
|
||
T _getPlatformData() { | ||
final currentPlatformKey = CatalystPlatform.identifiers.entries | ||
.firstWhere( | ||
// We select the platform only if the platform-specific data | ||
// is also present. | ||
(entry) => entry.value && (_platformData[entry.key] != null), | ||
orElse: () => const MapEntry(PlatformKey.other, true), | ||
) | ||
.key; | ||
return _platformData[currentPlatformKey]!; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
catalyst_voices/packages/catalyst_voices_shared/test/src/catalyst_voices_shared_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
void main() {} | ||
export 'platform_aware_builder/platform_aware_builder_test.dart'; |
26 changes: 26 additions & 0 deletions
26
...s/catalyst_voices_shared/test/src/platform_aware_builder/platform_aware_builder_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import 'package:catalyst_voices_shared/src/catalyst_voices_shared.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
|
||
void main() { | ||
|
||
Widget buildApp() => MaterialApp( | ||
home: Scaffold( | ||
body: PlatformAwareBuilder<String>( | ||
other: 'other', | ||
builder: (context, platformData) => Text(platformData!), | ||
), | ||
), | ||
); | ||
|
||
group('Test platform detection', () { | ||
testWidgets('PlatformWidgetBuilder fallbacks to other', (tester) async { | ||
await tester.pumpWidget(buildApp()); | ||
// Verify the Widget renders properly | ||
expect(find.byType(Text), findsOneWidget); | ||
// Check the output contains the platform that was tested. | ||
expect(find.text('other'), findsOneWidget); | ||
|
||
}); | ||
}); | ||
} |