diff --git a/README.md b/README.md index 2663324..2f003c4 100644 --- a/README.md +++ b/README.md @@ -163,29 +163,46 @@ SolidUI requires the following dependencies: ## Quick Start to Create an App -To create a new Solid-based app using `solidui` named `myapp` and -published by `example.com` begin with: +To quickly create a new Solid-based app, we provide a [Mason](https://pub.dev/packages/mason) template. + +### Using Mason (Recommended) + +1. Install Mason: + ```bash + dart pub global activate mason_cli + ``` +2. Initialize Mason in your project (if not already): + ```bash + mason init + ``` +3. Add the SolidUI brick: + ```bash + mason add solidui --path templates/solidui/brick + ``` +4. Create a new app from the template: + ```bash + mason make solidui + ``` + +### Template Structure + +The template app consists of several files within the +`lib/` directory: +- `main.dart`: Initialises the application and launches the app. +- `app.dart`: Implements the `App()` widget, instantiating `SolidLogin()`. +- `app_scaffold.dart`: Implements `AppScaffold()` widget using `SolidScaffold()`. +- `home.dart`: Implements the `Home()` widget for the main app functionality. +- `constants/app.dart`: App-wide constants including title and description. +- `utils/is_desktop.dart`: Desktop platform detection utility. + +### Synchronizing Template and Example + +If you are a contributor and want to update the `example/` app from the template (or vice-versa), use the provided sync script: ```bash -flutter create --template solidui --domain com.example myapp +python3 support/sync_template_to_example.py ``` -This will create a template app which we also included here under the -`example/` directory. The app consists of several files within the -`lib/` directory. `main.dart` is the main entry point to the app. Its -task in our framework is to initialise the application and then launch -the app itself. `app.dart` implements the `App()` which is typically -where we instantiate a `SolidLogin()`, often as the `child:` of a -`SolidThemeApp()`. The `SolidLogin()` provides the login page for the -app. After logging in the `AppScaffold()`, as the `child:` of the -`SolidLogin()`, is instantiated to contain the main functionality of -the app. `app_scaffold.dart` implements the `AppScaffold()` widget -which builds a `SolidScaffold()` to set up the framework for a typical -Solid app. The child is the `Home()` widget. `home.dart` implements -the `Home()` widget as the main app functionality. Constants are -defined in `constants/app.dart` and utilities such as desktop platform -detection are in `utils/is_desktop.dart`. - ## SolidScaffold The `SolidScaffold()` is the primary widget for building Solid diff --git a/example/lib/home.dart.old b/example/lib/home.dart.old new file mode 100644 index 0000000..5063372 Binary files /dev/null and b/example/lib/home.dart.old differ diff --git a/mason.yaml b/mason.yaml new file mode 100644 index 0000000..eb491cd --- /dev/null +++ b/mason.yaml @@ -0,0 +1,11 @@ +# Register bricks which can be used via mason get. +# bricks: +# sample: 0.1.0+1 +# hello: +# git: +# url: https://github.com/felangel/mason +# path: bricks/hello + +bricks: + solidui: + path: templates/solidui/brick diff --git a/support/sync_template_to_example.py b/support/sync_template_to_example.py new file mode 100644 index 0000000..0112355 --- /dev/null +++ b/support/sync_template_to_example.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +import os +import shutil +import subprocess + +def sync(): + root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + template_dir = os.path.join(root_dir, 'templates', 'solidui', 'brick') + example_dir = os.path.join(root_dir, 'example') + + print(f"Syncing template from {template_dir} to {example_dir}...") + + # 1. Ensure mason is initialized and get the brick + subprocess.run(['mason', 'get'], cwd=root_dir, check=True) + + # 2. Run mason make to a temporary directory + temp_gen_dir = os.path.join(root_dir, '.temp_template_gen') + if os.path.exists(temp_gen_dir): + shutil.rmtree(temp_gen_dir) + os.makedirs(temp_gen_dir) + + subprocess.run([ + 'mason', 'make', 'solidui', + '--projectName', 'myapp', + '--description', 'My App - A SolidUI Template Application', + '--author', 'Software Innovation Institute, ANU', + '-o', temp_gen_dir + ], cwd=root_dir, check=True) + + # 3. Copy generated files back to example + # Generated files are usually lib/, assets/, pubspec.yaml, etc. + gen_content_dir = os.path.join(temp_gen_dir) # mason make -o temp_gen_dir puts files directly there + + for item in os.listdir(gen_content_dir): + s = os.path.join(gen_content_dir, item) + d = os.path.join(example_dir, item) + if os.path.isdir(s): + if os.path.exists(d): + shutil.rmtree(d) + shutil.copytree(s, d) + print(f"Updated directory: {item}") + else: + shutil.copy2(s, d) + print(f"Updated file: {item}") + + # Clean up + shutil.rmtree(temp_gen_dir) + print("Sync complete.") + +if __name__ == "__main__": + sync() diff --git a/templates/solidui/brick/__brick__/.gitignore b/templates/solidui/brick/__brick__/.gitignore new file mode 100644 index 0000000..1ec0af9 --- /dev/null +++ b/templates/solidui/brick/__brick__/.gitignore @@ -0,0 +1,163 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release +/.metadata +/windows/flutter/CMakeLists.txt +/windows/runner/resources/app_icon.ico +/windows/runner/CMakeLists.txt +/windows/runner/flutter_window.cpp +/windows/runner/flutter_window.h +/windows/runner/main.cpp +/windows/runner/resource.h +/windows/runner/runner.exe.manifest +/windows/runner/Runner.rc +/windows/runner/utils.cpp +/windows/runner/utils.h +/windows/runner/win32_window.cpp +/windows/runner/win32_window.h +/windows/.gitignore +/windows/CMakeLists.txt +/macos/Flutter/Flutter-Debug.xcconfig +/macos/Flutter/Flutter-Release.xcconfig +/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +/macos/Runner/Base.lproj/MainMenu.xib +/macos/Runner/Configs/AppInfo.xcconfig +/macos/Runner/Configs/Debug.xcconfig +/macos/Runner/Configs/Release.xcconfig +/macos/Runner/Configs/Warnings.xcconfig +/macos/Runner/AppDelegate.swift +/macos/Runner/DebugProfile.entitlements +/macos/Runner/Info.plist +/macos/Runner/MainFlutterWindow.swift +/macos/Runner/Release.entitlements +/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +/macos/Runner.xcodeproj/project.pbxproj +/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +/macos/Runner.xcworkspace/contents.xcworkspacedata +/macos/RunnerTests/RunnerTests.swift +/macos/.gitignore +/macos/Podfile +/web/icons/Icon-192.png +/web/icons/Icon-512.png +/web/icons/Icon-maskable-192.png +/web/icons/Icon-maskable-512.png +/web/favicon.png +/web/index.html +/web/manifest.json +/linux/flutter/CMakeLists.txt +/linux/runner/CMakeLists.txt +/linux/runner/main.cc +/linux/runner/my_application.cc +/linux/runner/my_application.h +/linux/.gitignore +/linux/CMakeLists.txt +/ios/Flutter/AppFrameworkInfo.plist +/ios/Flutter/Debug.xcconfig +/ios/Flutter/Release.xcconfig +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png +/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png +/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +/ios/Runner/Base.lproj/LaunchScreen.storyboard +/ios/Runner/Base.lproj/Main.storyboard +/ios/Runner/AppDelegate.swift +/ios/Runner/Info.plist +/ios/Runner/Runner-Bridging-Header.h +/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +/ios/Runner.xcodeproj/project.pbxproj +/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +/ios/Runner.xcworkspace/contents.xcworkspacedata +/ios/RunnerTests/RunnerTests.swift +/ios/.gitignore +/ios/Podfile +/android/app/src/debug/AndroidManifest.xml +/android/app/src/main/kotlin/com/example/solidui_simple_example/MainActivity.kt +/android/app/src/main/res/drawable/launch_background.xml +/android/app/src/main/res/drawable-v21/launch_background.xml +/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +/android/app/src/main/res/values/styles.xml +/android/app/src/main/res/values-night/styles.xml +/android/app/src/main/AndroidManifest.xml +/android/app/src/profile/AndroidManifest.xml +/android/app/build.gradle.kts +/android/gradle/wrapper/gradle-wrapper.properties +/android/.gitignore +/android/build.gradle.kts +/android/gradle.properties +/android/settings.gradle.kts +/android/app/src/main/kotlin/com/example/solidui_example/MainActivity.kt diff --git a/templates/solidui/brick/__brick__/README.md b/templates/solidui/brick/__brick__/README.md new file mode 100644 index 0000000..335fe3a --- /dev/null +++ b/templates/solidui/brick/__brick__/README.md @@ -0,0 +1,18 @@ +# {{projectName.titleCase()}} + +{{description}} + +Built with [SolidUI](https://github.com/anusii/solidui). + +## Getting Started + +To run this application, make sure you have the [Flutter SDK](https://flutter.dev/docs/get-started/install) installed. + +1. Clone or initialize this project. +2. Run `flutter pub get` to install dependencies. +3. Run the application with `flutter run`. + +## License + +Copyright (C) 2025, {{author}}. +Licensed under the MIT License. diff --git a/templates/solidui/brick/__brick__/analysis_options.yaml b/templates/solidui/brick/__brick__/analysis_options.yaml new file mode 100644 index 0000000..8f58efa --- /dev/null +++ b/templates/solidui/brick/__brick__/analysis_options.yaml @@ -0,0 +1,12 @@ +include: package:flutter_lints/flutter.yaml + +analyzer: + exclude: + - build/** + +linter: + rules: + prefer_const_constructors: true + prefer_const_literals_to_create_immutables: true + prefer_final_fields: true + sort_child_properties_last: true diff --git a/templates/solidui/brick/__brick__/assets/images/app_icon.png b/templates/solidui/brick/__brick__/assets/images/app_icon.png new file mode 100644 index 0000000..5c73902 Binary files /dev/null and b/templates/solidui/brick/__brick__/assets/images/app_icon.png differ diff --git a/templates/solidui/brick/__brick__/assets/images/app_image.jpg b/templates/solidui/brick/__brick__/assets/images/app_image.jpg new file mode 100644 index 0000000..0e6059c Binary files /dev/null and b/templates/solidui/brick/__brick__/assets/images/app_image.jpg differ diff --git a/templates/solidui/brick/__brick__/lib/app.dart b/templates/solidui/brick/__brick__/lib/app.dart new file mode 100644 index 0000000..c70f8d6 --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/app.dart @@ -0,0 +1,68 @@ +/// The primary App widget. +/// +/// Copyright (C) 2025, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Tony Chen + +library; + +import 'package:flutter/material.dart'; + +import 'package:solidui/solidui.dart'; + +import 'app_scaffold.dart'; +import 'constants/app.dart'; + +// This widget is the root of the application. + +class App extends StatelessWidget { + const App({super.key}); + + @override + Widget build(BuildContext context) { + return SolidThemeApp( + // Turn off debug banner for now. + + debugShowCheckedModeBanner: false, + title: appTitle, + + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + useMaterial3: true, + ), + + home: const SolidLogin( + image: AssetImage('assets/images/app_image.jpg'), + logo: AssetImage('assets/images/app_icon.png'), + customFolderPathList: [ + 'customDir1', + 'customDir2', + 'customDir2/customDir3', + ], + child: appScaffold, + ), + ); + } +} diff --git a/templates/solidui/brick/__brick__/lib/app_scaffold.dart b/templates/solidui/brick/__brick__/lib/app_scaffold.dart new file mode 100644 index 0000000..f61c341 --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/app_scaffold.dart @@ -0,0 +1,209 @@ +/// The application scaffold configuration. +/// +/// Copyright (C) 2025, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Tony Chen + +library; + +import 'package:flutter/material.dart'; + +import 'package:solidui/solidui.dart'; + +import 'constants/app.dart'; +import 'home.dart'; +import 'screens/all_pod_files_page.dart'; +import 'screens/sample_page.dart'; + +final _scaffoldController = SolidScaffoldController(); + +const appScaffold = AppScaffold(); + +class AppScaffold extends StatelessWidget { + const AppScaffold({super.key}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return SolidScaffold( + controller: _scaffoldController, + + // MENU. + + menu: const [ + SolidMenuItem( + icon: Icons.home, + title: 'Home', + tooltip: ''' + + **Home:** Tap here to return to the main page for the app. + + ''', + child: Home(title: appTitle), + ), + SolidMenuItem( + icon: Icons.folder, + title: 'Files', + tooltip: ''' + + **Files:** Tap here to browse the files on your POD. + + ''', + child: SolidFile(), + ), + SolidMenuItem( + icon: Icons.storage, + title: 'All POD Files', + tooltip: ''' + + **All POD Files:** Tap here to browse all folders on your POD + from the root. + + ''', + child: AllPodFilesPage(), + ), + ], + + // APP BAR. + + appBar: SolidAppBarConfig( + title: appTitle.split('-')[0], + + // VERSION WIDGET. + + versionConfig: SolidVersionConfig( + changelogUrl: 'https://github.com/anusii/solidui/blob/dev/' + 'CHANGELOG.md', + showDate: true, + userTextStyle: TextStyle( + color: theme.colorScheme.onSurface, + ), + ), + + actions: [ + SolidAppBarAction( + icon: Icons.folder, + onPressed: () => _scaffoldController.navigateToSubpage( + const SolidFile(), + ), + tooltip: 'Files', + ), + SolidAppBarAction( + icon: Icons.article, + onPressed: () => _scaffoldController.navigateToSubpage( + const SamplePage(), + ), + tooltip: 'Sample Page', + ), + ], + ), + + // STATUS BAR. + + statusBar: const SolidStatusBarConfig( + serverInfo: SolidServerInfo(serverUri: SolidConfig.defaultServerUrl), + loginStatus: SolidLoginStatus(), + securityKeyStatus: SolidSecurityKeyStatus(), + ), + + // ABOUT. + + aboutConfig: SolidAboutConfig( + applicationName: appTitle.split(' - ')[0], + applicationIcon: Image.asset( + 'assets/images/app_icon.png', + width: 64, + height: 64, + ), + applicationLegalese: ''' + + © 2025 Software Innovation Institute, the Australian National University + + ''', + text: ''' + + This template app demonstrates the following key SolidUI features: + + 🧭 Responsive navigation (rail ↔ drawer); + + 🎨 Theme switching (light/dark/system); + + ℹ️ Customisable About dialogues; + + 📋 Version information display; + + 🔐 Security key management; + + 📊 Status bar integration; + + 👤 User information display. + + For more information, visit the + [SolidUI](https://github.com/anusii/solidui) GitHub repository and our + [Australian Solid Community](https://solidcommunity.au) web site. + + ''', + ), + + // THEME DARK/LIGHT Mode. + + themeToggle: const SolidThemeToggleConfig( + enabled: true, + showInAppBarActions: true, + ), + + hideNavRail: false, + + // LOGOUT. + + onLogout: (context) => SolidAuthHandler.instance.handleLogout(context), + + // SETTINGS. + + settingsWidget: IconButton( + icon: const Icon(Icons.settings), + onPressed: () => _scaffoldController.navigateToSubpage( + const _MySettings(), + ), + tooltip: 'Settings', + ), + + child: const Home(title: appTitle), + ); + } +} + +class _MySettings extends StatelessWidget { + const _MySettings(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Custom Settings')), + body: const Center(child: Text('This is a custom settings page.')), + ); + } +} diff --git a/templates/solidui/brick/__brick__/lib/constants/app.dart b/templates/solidui/brick/__brick__/lib/constants/app.dart new file mode 100644 index 0000000..5be88ea --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/constants/app.dart @@ -0,0 +1,13 @@ +/// App-wide constants. +/// +/// Copyright (C) 2025, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +/// +/// Authors: {{author}} + +library; + +const String appTitle = '{{projectName.titleCase()}} - {{description}}'; diff --git a/templates/solidui/brick/__brick__/lib/home.dart b/templates/solidui/brick/__brick__/lib/home.dart new file mode 100644 index 0000000..c073c18 --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/home.dart @@ -0,0 +1,86 @@ +/// The application's home page. +/// +/// Copyright (C) 2025, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Tony Chen + +library; + +import 'package:flutter/material.dart'; + +class Home extends StatefulWidget { + const Home({super.key, required this.title}); + + final String title; + + @override + State createState() => _HomeState(); +} + +class _HomeState extends State { + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Center( + child: Card( + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.home, + size: 64, + color: Theme.of(context).primaryColor, + ), + const SizedBox(height: 16), + Text( + widget.title, + style: Theme.of(context).textTheme.headlineMedium, + ), + const SizedBox(height: 24), + Text( + 'Welcome to the SolidUI Template App!\n\n' + 'This template demonstrates the key features of SolidUI:\n\n' + '• Responsive navigation (rail ↔ drawer)\n' + '• Theme switching (light/dark/system)\n' + '• Customisable About dialogues\n' + '• Version information display\n' + '• Security key management\n' + '• Status bar integration\n' + '• User information display\n\n' + 'Explore the different tabs to see these features in action!', + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/templates/solidui/brick/__brick__/lib/home.dart.old b/templates/solidui/brick/__brick__/lib/home.dart.old new file mode 100644 index 0000000..5063372 Binary files /dev/null and b/templates/solidui/brick/__brick__/lib/home.dart.old differ diff --git a/templates/solidui/brick/__brick__/lib/main.dart b/templates/solidui/brick/__brick__/lib/main.dart new file mode 100644 index 0000000..8d79912 --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/main.dart @@ -0,0 +1,64 @@ +/// SolidUI Template Application +/// +/// Copyright (C) 2025, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Tony Chen, Graham Williams + +library; + +import 'package:flutter/material.dart'; + +import 'package:window_manager/window_manager.dart'; + +import 'app.dart'; +import 'constants/app.dart'; +import 'utils/is_desktop.dart'; + +/// Main entry point for the [MyApp] application. + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + + // Set window options for desktop platforms (Windows, Linux, macOS). + + if (isDesktop) { + await windowManager.ensureInitialized(); + + const windowOptions = WindowOptions( + title: appTitle, + minimumSize: Size(500, 800), + backgroundColor: Colors.transparent, + skipTaskbar: false, + titleBarStyle: TitleBarStyle.normal, + ); + + await windowManager.waitUntilReadyToShow(windowOptions, () async { + await windowManager.show(); + await windowManager.focus(); + }); + } + + runApp(const App()); +} diff --git a/templates/solidui/brick/__brick__/lib/screens/all_pod_files_page.dart b/templates/solidui/brick/__brick__/lib/screens/all_pod_files_page.dart new file mode 100644 index 0000000..e779af6 --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/screens/all_pod_files_page.dart @@ -0,0 +1,49 @@ +/// All POD Files page - Displays all folders on the POD for testing. +/// +/// Copyright (C) 2026, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Tony Chen + +library; + +import 'package:flutter/material.dart'; + +import 'package:solidui/solidui.dart'; + +/// A page that browses all folders and files on the POD from the root. + +class AllPodFilesPage extends StatelessWidget { + const AllPodFilesPage({super.key}); + + @override + Widget build(BuildContext context) { + return const SolidFile( + currentPath: SolidFile.podRoot, + friendlyFolderName: 'All POD Files', + showBackButton: true, + backButtonText: 'Back to POD Root', + ); + } +} diff --git a/templates/solidui/brick/__brick__/lib/screens/sample_page.dart b/templates/solidui/brick/__brick__/lib/screens/sample_page.dart new file mode 100644 index 0000000..f4dc477 --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/screens/sample_page.dart @@ -0,0 +1,91 @@ +/// Sample page - Demonstrates AppBar-only navigation pattern. +/// +/// Copyright (C) 2026, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Tony Chen + +library; + +import 'package:flutter/material.dart'; + +/// Sample page widget demonstrating AppBar-only navigation. + +class SamplePage extends StatelessWidget { + const SamplePage({super.key}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return Center( + child: Card( + margin: const EdgeInsets.all(32.0), + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.article_outlined, + size: 64, + color: theme.colorScheme.primary, + ), + const SizedBox(height: 24), + Text( + 'Sample Page', + style: theme.textTheme.headlineMedium?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + Text( + 'AppBar-Only Navigation Demo', + style: theme.textTheme.titleMedium?.copyWith( + color: theme.colorScheme.primary, + ), + ), + const SizedBox(height: 32), + Container( + constraints: const BoxConstraints(maxWidth: 500), + child: Text( + 'The navigation buttons for this page are only placed on ' + 'the app bar, so no buttons on the navigation rail will be ' + 'highlighted when entering this page. In contrast, when ' + 'the Files button on the app bar is clicked, the ' + 'Files button on the navigation rail will be highlighted ' + 'as well, since it is laid out in both places. This button ' + 'also demonstrates the usage of the navigateToSubpage() ' + 'function.', + style: theme.textTheme.bodyLarge, + textAlign: TextAlign.left, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/templates/solidui/brick/__brick__/lib/utils/is_desktop.dart b/templates/solidui/brick/__brick__/lib/utils/is_desktop.dart new file mode 100644 index 0000000..927c758 --- /dev/null +++ b/templates/solidui/brick/__brick__/lib/utils/is_desktop.dart @@ -0,0 +1,41 @@ +/// Check if we are running a desktop (and not a browser). +/// +/// Copyright (C) 2025, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Tony Chen + +library; + +import 'dart:io' show Platform; + +import 'package:flutter/foundation.dart' show kIsWeb; + +/// Test if we are running on a desktop platform but not in a browser. + +bool get isDesktop { + if (kIsWeb) return false; + + return Platform.isLinux || Platform.isMacOS || Platform.isWindows; +} diff --git a/templates/solidui/brick/__brick__/pubspec.yaml b/templates/solidui/brick/__brick__/pubspec.yaml new file mode 100644 index 0000000..26c945c --- /dev/null +++ b/templates/solidui/brick/__brick__/pubspec.yaml @@ -0,0 +1,26 @@ +name: {{projectName.snakeCase()}} +description: {{description}} +publish_to: 'none' +version: 0.1.0+1 + +environment: + sdk: '>=3.2.3 <4.0.0' + flutter: ">=3.10.0" + +dependencies: + flutter: + sdk: flutter + markdown_tooltip: ^0.0.10 + shared_preferences: ^2.5.4 + solidpod: ^0.10.1 + solidui: ^0.2.0 + window_manager: ^0.5.1 + +dev_dependencies: + flutter_lints: ^5.0.0 + +flutter: + uses-material-design: true + + assets: + - assets/images/ diff --git a/templates/solidui/brick/brick.yaml b/templates/solidui/brick/brick.yaml new file mode 100644 index 0000000..6d85f29 --- /dev/null +++ b/templates/solidui/brick/brick.yaml @@ -0,0 +1,22 @@ +name: solidui +description: A starting point for a SolidUI application. +version: 0.0.1 +environment: + mason: 0.1.0-dev.50 + +vars: + projectName: + type: string + description: The name of the project. + default: myapp + prompt: What is the project name? + description: + type: string + description: The description of the project. + default: A SolidUI Template Application + prompt: What is the project description? + author: + type: string + description: The author of the project. + default: Software Innovation Institute, ANU + prompt: Who is the author?