From ef5e1de2db1e1f53398447d86e45a5fa0dbe0bc7 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 26 Oct 2023 08:21:20 +0200 Subject: [PATCH] docs(neon): document various neon methods Signed-off-by: Nikolas Rimikis --- packages/neon/neon/lib/neon.dart | 3 + packages/neon/neon/lib/src/app.dart | 8 ++ .../neon/neon/lib/src/platform/android.dart | 7 ++ .../neon/neon/lib/src/platform/linux.dart | 7 ++ .../neon/neon/lib/src/platform/platform.dart | 31 +++++++ packages/neon/neon/lib/src/router.dart | 91 ++++++++++++++++++- .../neon/neon/lib/src/theme/color_scheme.dart | 1 + packages/neon/neon/lib/src/theme/theme.dart | 18 ++++ 8 files changed, 163 insertions(+), 3 deletions(-) diff --git a/packages/neon/neon/lib/neon.dart b/packages/neon/neon/lib/neon.dart index 6bf60d46..c7fe8520 100644 --- a/packages/neon/neon/lib/neon.dart +++ b/packages/neon/neon/lib/neon.dart @@ -20,6 +20,9 @@ import 'package:neon/src/utils/user_agent.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:provider/provider.dart'; +/// Runs Neon with the given [appImplementations]. +/// +/// Optionally provide a [theme] to set the default style. Future runNeon({ required final Set appImplementations, required final NeonTheme theme, diff --git a/packages/neon/neon/lib/src/app.dart b/packages/neon/neon/lib/src/app.dart index 1726389e..6ecc891c 100644 --- a/packages/neon/neon/lib/src/app.dart +++ b/packages/neon/neon/lib/src/app.dart @@ -29,13 +29,21 @@ import 'package:tray_manager/tray_manager.dart' as tray; import 'package:universal_io/io.dart'; import 'package:window_manager/window_manager.dart'; +/// Main Neon widget. +/// +/// Sets up all needed callbacks and creates a new [MaterialApp.router]. +/// This widget must be the first in the widget tree. @internal class NeonApp extends StatefulWidget { + /// Creates a new Neon app. const NeonApp({ required this.neonTheme, super.key, }); + /// The base Neon theme. + /// + /// This is used to seed the [AppTheme] used by [MaterialApp.theme]. final NeonTheme neonTheme; @override diff --git a/packages/neon/neon/lib/src/platform/android.dart b/packages/neon/neon/lib/src/platform/android.dart index 9dceed83..f6776360 100644 --- a/packages/neon/neon/lib/src/platform/android.dart +++ b/packages/neon/neon/lib/src/platform/android.dart @@ -1,13 +1,20 @@ import 'package:meta/meta.dart'; +import 'package:neon/src/platform/linux.dart'; import 'package:neon/src/platform/platform.dart'; import 'package:neon/src/utils/exceptions.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; +/// Android specific platform information. +/// +/// See: +/// * [NeonPlatform] to initialize and acquire an instance +/// * [LinuxNeonPlatform] for the Linux implementation @immutable @internal class AndroidNeonPlatform implements NeonPlatform { + /// Creates a new Android Neon platform. const AndroidNeonPlatform(); @override diff --git a/packages/neon/neon/lib/src/platform/linux.dart b/packages/neon/neon/lib/src/platform/linux.dart index b244f390..51f18797 100644 --- a/packages/neon/neon/lib/src/platform/linux.dart +++ b/packages/neon/neon/lib/src/platform/linux.dart @@ -1,12 +1,19 @@ import 'package:meta/meta.dart'; +import 'package:neon/src/platform/android.dart'; import 'package:neon/src/platform/platform.dart'; import 'package:path/path.dart' as p; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:universal_io/io.dart'; +/// Linux specific platform information. +/// +/// See: +/// * [NeonPlatform] to initialize and acquire an instance +/// * [AndroidNeonPlatform] for the Android implementation @immutable @internal class LinuxNeonPlatform implements NeonPlatform { + /// Creates a new Linux Neon platform. const LinuxNeonPlatform(); @override diff --git a/packages/neon/neon/lib/src/platform/platform.dart b/packages/neon/neon/lib/src/platform/platform.dart index ad96413d..169c40e5 100644 --- a/packages/neon/neon/lib/src/platform/platform.dart +++ b/packages/neon/neon/lib/src/platform/platform.dart @@ -6,8 +6,15 @@ import 'package:neon/src/platform/linux.dart'; import 'package:universal_io/io.dart'; /// Implements platform specific functionality and exposes the availability of certain features. +/// +/// [NeonPlatform.setup] mus be called and completed before acquiring the [instance]. +/// +/// See: +/// * [AndroidNeonPlatform] for the Android implementation +/// * [LinuxNeonPlatform] for the Linux implementation @immutable abstract interface class NeonPlatform { + /// Initializes the platform with the given mocked [platform]. @visibleForTesting factory NeonPlatform.mocked(final NeonPlatform platform) => _platform = platform; @@ -45,18 +52,39 @@ abstract interface class NeonPlatform { return _platform!; } + /// Whether this platform supports web views. + /// + /// The support depends on `https://pub.dev/packages/webview_flutter`. abstract final bool canUseWebView; + /// Whether this platform can use quick actions. + /// + /// The support depends on `https://pub.dev/packages/quick_actions`. abstract final bool canUseQuickActions; + /// Whether this platform support system trays. + /// + /// The support depends on `https://pub.dev/packages/tray_manager`. abstract final bool canUseSystemTray; + /// Whether this platform supports managing the window. + /// + /// The support depends on `https://pub.dev/packages/window_manager`. abstract final bool canUseWindowManager; + /// Whether this platform can use the camera. + /// + /// The support depends on `https://pub.dev/packages/camera`. abstract final bool canUseCamera; + /// Whether this platform can use push notifications. + /// + /// The support depends on `https://pub.dev/packages/unifiedpush`. abstract final bool canUsePushNotifications; + /// Wether this platform can use native sharing. + /// + /// The support depends on `https://pub.dev/packages/share_plus`. abstract final bool canUseSharing; /// Whether this platform should use file dialog. @@ -64,7 +92,10 @@ abstract interface class NeonPlatform { /// This is needed to compensate lacking support of `https://pub.dev/packages/file_picker`. abstract final bool shouldUseFileDialog; + /// Returns the path to a directory where the application may access top + /// level storage which can also be easily accessed by the user outside of the app. FutureOr get userAccessibleAppDataPath; + /// Initializes this platform. FutureOr init(); } diff --git a/packages/neon/neon/lib/src/router.dart b/packages/neon/neon/lib/src/router.dart index 83c20b18..5ba8289f 100644 --- a/packages/neon/neon/lib/src/router.dart +++ b/packages/neon/neon/lib/src/router.dart @@ -24,6 +24,7 @@ import 'package:neon/src/utils/stream_listenable.dart'; part 'router.g.dart'; +/// Internal router for the Neon framework. @internal GoRouter buildAppRouter({ required final GlobalKey navigatorKey, @@ -68,12 +69,19 @@ Page _buildErrorPage(final BuildContext context, final GoRouterState state ), ); +/// {@template AppRoutes.AccountSettingsRoute} +/// Route for the [AccountSettingsPage]. +/// {@endtemplate} @immutable class AccountSettingsRoute extends GoRouteData { + /// {@macro AppRoutes.AccountSettingsRoute} const AccountSettingsRoute({ required this.accountID, }); + /// The id of the account to show the settings for. + /// + /// Passed to [AccountSettingsPage.account]. final String accountID; @override @@ -88,6 +96,9 @@ class AccountSettingsRoute extends GoRouteData { } } +/// {@template AppRoutes.HomeRoute} +/// Route for the the [HomePage]. +/// {@endtemplate} @TypedGoRoute( path: '/', name: 'home', @@ -128,6 +139,7 @@ class AccountSettingsRoute extends GoRouteData { ) @immutable class HomeRoute extends GoRouteData { + /// {@macro AppRoutes.HomeRoute} const HomeRoute(); @override @@ -139,6 +151,13 @@ class HomeRoute extends GoRouteData { } } +/// {@template AppRoutes.LoginRoute} +/// Route for the the initial [LoginPage]. +/// +/// All routes related to the login flow are subroutes of this. +/// All subroutes redirect to subroutes of [HomeRoute] if a at least one +/// account is already logged in and further accounts should be added. +/// {@endtemplate} @TypedGoRoute( path: '/login', name: 'login', @@ -159,6 +178,7 @@ class HomeRoute extends GoRouteData { ) @immutable class LoginRoute extends GoRouteData { + /// {@macro AppRoutes.LoginRoute} const LoginRoute(); @override @@ -176,12 +196,22 @@ class LoginRoute extends GoRouteData { } } +/// {@template AppRoutes.LoginFlowRoute} +/// Route for the the [LoginFlowPage]. +/// +/// Redirects to [_AddAccountFlowRoute] when at least one account is already +/// logged in. +/// {@endtemplate} @immutable class LoginFlowRoute extends GoRouteData { + /// {@macro AppRoutes.LoginFlowRoute} const LoginFlowRoute({ required this.serverUrl, }); + /// {@template AppRoutes.LoginFlow.serverUrl} + /// The url of the server to initiate the login flow for. + /// {@endtemplate} final Uri serverUrl; @override @@ -199,8 +229,15 @@ class LoginFlowRoute extends GoRouteData { } } +/// {@template AppRoutes.LoginQRcodeRoute} +/// Route for the the [LoginQRcodePage]. +/// +/// Redirects to [_AddAccountQRcodeRoute] when at least one account is already +/// logged in. +/// {@endtemplate} @immutable class LoginQRcodeRoute extends GoRouteData { + /// {@macro AppRoutes.LoginQRcodeRoute} const LoginQRcodeRoute(); @override @@ -218,22 +255,47 @@ class LoginQRcodeRoute extends GoRouteData { } } +/// {@template AppRoutes.LoginCheckServerStatusRoute} +/// Route for the the [LoginCheckServerStatusPage]. +/// +/// Redirects to [_AddAccountCheckServerStatusRoute] when at least one account +/// is already logged in. +/// {@endtemplate} @immutable class LoginCheckServerStatusRoute extends GoRouteData { + /// {@macro AppRoutes.LoginCheckServerStatusRoute} + /// + /// [loginName] and [password] must both be null. + /// Use [LoginCheckServerStatusRoute.withCredentials] to specify credentials. const LoginCheckServerStatusRoute({ required this.serverUrl, this.loginName, this.password, - }); - + }) : assert( + loginName == null && password == null, + 'loginName and password must be null. Use LoginCheckServerStatusRoute.withCredentials instead.', + ); + + /// {@macro AppRoutes.LoginCheckServerStatusRoute} + /// + /// See [LoginCheckServerStatusRoute] for a route without initial credentials. const LoginCheckServerStatusRoute.withCredentials({ required this.serverUrl, required String this.loginName, required String this.password, }) : assert(!kIsWeb, 'Might leak the password to the browser history'); + /// {@macro AppRoutes.LoginFlow.serverUrl} final Uri serverUrl; + + /// {@template AppRoutes.LoginFlow.loginName} + /// The login name of the credentials. + /// {@endtemplate} final String? loginName; + + /// {@template AppRoutes.LoginFlow.password} + /// The password of the credentials. + /// {@endtemplate} final String? password; @override @@ -273,16 +335,28 @@ class LoginCheckServerStatusRoute extends GoRouteData { } } +/// {@template AppRoutes.LoginCheckAccountRoute} +/// Route for the the [LoginCheckAccountPage]. +/// +/// Redirects to [_AddAccountCheckAccountRoute] when at least one account +/// is already logged in. +/// {@endtemplate} @immutable class LoginCheckAccountRoute extends GoRouteData { + /// {@macro AppRoutes.LoginCheckAccountRoute} const LoginCheckAccountRoute({ required this.serverUrl, required this.loginName, required this.password, }) : assert(!kIsWeb, 'Might leak the password to the browser history'); + /// {@macro AppRoutes.LoginFlow.serverUrl} final Uri serverUrl; + + /// {@macro AppRoutes.LoginFlow.loginName} final String loginName; + + /// {@macro AppRoutes.LoginFlow.password} final String password; @override @@ -364,12 +438,17 @@ class _AddAccountCheckAccountRoute extends LoginCheckAccountRoute { String get password => super.password; } +/// {@template AppRoutes.NextcloudAppSettingsRoute} +/// Route for the the [NextcloudAppSettingsPage]. +/// {@endtemplate} @immutable class NextcloudAppSettingsRoute extends GoRouteData { + /// {@macro AppRoutes.NextcloudAppSettingsRoute} const NextcloudAppSettingsRoute({ required this.appid, }); + /// The id of the app to display the settings for. final String appid; @override @@ -381,9 +460,15 @@ class NextcloudAppSettingsRoute extends GoRouteData { } } +/// {@template AppRoutes.SettingsRoute} +/// Route for the the [SettingsPage]. +/// {@endtemplate} @immutable class SettingsRoute extends GoRouteData { - const SettingsRoute({this.initialCategory}); + /// {@macro AppRoutes.SettingsRoute} + const SettingsRoute({ + this.initialCategory, + }); /// The initial category to show. final SettingsCategories? initialCategory; diff --git a/packages/neon/neon/lib/src/theme/color_scheme.dart b/packages/neon/neon/lib/src/theme/color_scheme.dart index e670dd52..149bca31 100644 --- a/packages/neon/neon/lib/src/theme/color_scheme.dart +++ b/packages/neon/neon/lib/src/theme/color_scheme.dart @@ -5,6 +5,7 @@ import 'package:neon/src/theme/neon.dart'; /// A ColorScheme used in the [NeonTheme]. @immutable class NeonColorScheme { + /// Creates a new Neon color scheme. const NeonColorScheme({ this.primary = NcColors.primary, }); diff --git a/packages/neon/neon/lib/src/theme/theme.dart b/packages/neon/neon/lib/src/theme/theme.dart index a2692d61..81ac674f 100644 --- a/packages/neon/neon/lib/src/theme/theme.dart +++ b/packages/neon/neon/lib/src/theme/theme.dart @@ -5,9 +5,11 @@ import 'package:neon/src/theme/neon.dart'; import 'package:neon/src/utils/hex_color.dart'; import 'package:nextcloud/core.dart' as core; +/// Custom theme used for the Neon app. @internal @immutable class AppTheme { + /// Creates a new Neon app theme. const AppTheme( this.nextcloudTheme, { required this.neonTheme, @@ -16,10 +18,19 @@ class AppTheme { this.appThemes, }) : keepOriginalAccentColor = nextcloudTheme == null || keepOriginalAccentColor; + /// The theme provided by the Nextcloud server. final core.ThemingPublicCapabilities_Theming? nextcloudTheme; + + /// Whether to force the use of the Nextcloud accent color. final bool keepOriginalAccentColor; + + /// Whether to use [NcColors.oledBackground] in the dark theme. final bool oledAsDark; + + /// The theme extensions provided by the `AppImplementation`s. final Iterable? appThemes; + + /// The base theme for the Neon app. final NeonTheme neonTheme; ColorScheme _buildColorScheme(final Brightness brightness) { @@ -56,7 +67,14 @@ class AppTheme { ); } + /// Returns a new theme for [Brightness.light]. + /// + /// Used in [MaterialApp.theme]. ThemeData get lightTheme => _getTheme(Brightness.light); + + /// Returns a new theme for [Brightness.dark]. + /// + /// Used in [MaterialApp.darkTheme]. ThemeData get darkTheme => _getTheme(Brightness.dark); static const _snackBarTheme = SnackBarThemeData(