diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..e431cc88 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,18 @@ +name: Release + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + release: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: googleapis/release-please-action@v4 + with: + release-type: dart \ No newline at end of file diff --git a/lib/app.dart b/lib/app.dart index f5c12317..d7042361 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,3 +1,5 @@ +import 'dart:ui'; + import 'package:flutter/material.dart'; import 'package:flutter_localized_locales/flutter_localized_locales.dart'; import 'package:provider/provider.dart'; @@ -28,6 +30,15 @@ class UbuntuSettingsApp extends StatelessWidget { supportedLocales: AppLocalizations.supportedLocales, localizationsDelegates: AppLocalizations.localizationsDelegates + [const LocaleNamesLocalizationsDelegate()], + scrollBehavior: const MaterialScrollBehavior().copyWith( + dragDevices: { + PointerDeviceKind.mouse, + PointerDeviceKind.touch, + PointerDeviceKind.stylus, + PointerDeviceKind.unknown, + PointerDeviceKind.trackpad, + }, + ), ); }, ), diff --git a/lib/view/pages/apps/apps_page.dart b/lib/view/pages/apps/apps_page.dart index d2a25432..ee852263 100644 --- a/lib/view/pages/apps/apps_page.dart +++ b/lib/view/pages/apps/apps_page.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:settings/constants.dart'; import 'package:settings/l10n/l10n.dart'; import 'package:settings/view/pages/settings_page.dart'; import 'package:yaru/yaru.dart'; @@ -22,13 +23,16 @@ class AppsPage extends StatelessWidget { Widget build(BuildContext context) { return SettingsPage( children: [ - YaruSection( - child: YaruTile( - leading: const Text('Apps can be managed in the App Store'), - trailing: ElevatedButton.icon( - onPressed: () => Process.start('snap-store', []), - label: const Text('Open'), - icon: const Icon(YaruIcons.application_bag), + SizedBox( + width: kDefaultWidth, + child: YaruSection( + child: YaruTile( + leading: const Text('Apps can be managed in the App Store'), + trailing: ElevatedButton.icon( + onPressed: () => Process.start('snap-store', []), + label: const Text('Open'), + icon: const Icon(YaruIcons.application_bag), + ), ), ), ), diff --git a/lib/view/pages/connections/connections_page.dart b/lib/view/pages/connections/connections_page.dart index efd38a14..08d21f6e 100644 --- a/lib/view/pages/connections/connections_page.dart +++ b/lib/view/pages/connections/connections_page.dart @@ -33,23 +33,43 @@ class ConnectionsPage extends StatefulWidget { State createState() => _ConnectionsPageState(); } -class _ConnectionsPageState extends State { +class _ConnectionsPageState extends State + with SingleTickerProviderStateMixin { + late TabController _controller; + + @override + void initState() { + super.initState(); + _controller = TabController(length: 3, vsync: this); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { final wifiModel = context.watch(); - return DefaultTabController( - length: 3, - child: Scaffold( - appBar: YaruWindowTitleBar( - titleSpacing: 20, - centerTitle: true, - border: BorderSide.none, - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - title: const SizedBox( + return Scaffold( + appBar: YaruWindowTitleBar( + titleSpacing: 20, + centerTitle: true, + border: BorderSide.none, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + title: Text(context.l10n.connectionsPageTitle), + ), + body: Column( + children: [ + SizedBox( width: 400, - child: TabBar( - tabs: [ + child: YaruTabBar( + tabController: _controller, + tabs: + // TODO: localize + const [ TitleBarTab( text: 'Wi-Fi', iconData: YaruIcons.network_wireless, @@ -65,24 +85,27 @@ class _ConnectionsPageState extends State { ], ), ), - ), - body: TabBarView( - children: [ - wifiModel.isWifiDeviceAvailable - ? const WifiDevicesContent() - : const WifiAdaptorNotFound(), - const SettingsPage( - children: [ - Text('Ethernet - Please implement 🥲️'), - ], - ), - const SettingsPage( + Expanded( + child: TabBarView( + controller: _controller, children: [ - Text('Cellular - Please implement 🥲️'), + wifiModel.isWifiDeviceAvailable + ? const WifiDevicesContent() + : const WifiAdaptorNotFound(), + const SettingsPage( + children: [ + Text('Ethernet - Please implement 🥲️'), + ], + ), + const SettingsPage( + children: [ + Text('Cellular - Please implement 🥲️'), + ], + ), ], ), - ], - ), + ), + ], ), ); } diff --git a/lib/view/pages/displays/displays_page.dart b/lib/view/pages/displays/displays_page.dart index f7d16be9..2d4fb358 100644 --- a/lib/view/pages/displays/displays_page.dart +++ b/lib/view/pages/displays/displays_page.dart @@ -37,7 +37,23 @@ class DisplaysPage extends StatefulWidget { State createState() => _DisplaysPageState(); } -class _DisplaysPageState extends State { +class _DisplaysPageState extends State + with SingleTickerProviderStateMixin { + late TabController _controller; + + @override + void initState() { + super.initState(); + _controller = + TabController(length: DisplaysPageSection.values.length, vsync: this); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { final model = context.watch(); @@ -45,16 +61,19 @@ class _DisplaysPageState extends State { return ValueListenableBuilder( valueListenable: model.configuration, builder: (context, configurations, _) { - return DefaultTabController( - length: DisplaysPageSection.values.length, - child: Scaffold( - appBar: YaruWindowTitleBar( - titleSpacing: 0, - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - border: BorderSide.none, - title: SizedBox( + return Scaffold( + appBar: YaruWindowTitleBar( + titleSpacing: 0, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + border: BorderSide.none, + title: Text(context.l10n.displaysPageTitle), + ), + body: Column( + children: [ + SizedBox( width: 300, - child: TabBar( + child: YaruTabBar( + tabController: _controller, tabs: DisplaysPageSection.values .map( (e) => TitleBarTab( @@ -65,17 +84,20 @@ class _DisplaysPageState extends State { .toList(), ), ), - ), - body: TabBarView( - children: DisplaysPageSection.values - .map( - (e) => Padding( - padding: const EdgeInsets.only(top: kYaruPagePadding), - child: _buildPage(e, model, configurations), - ), - ) - .toList(), - ), + Expanded( + child: TabBarView( + controller: _controller, + children: DisplaysPageSection.values + .map( + (e) => Padding( + padding: const EdgeInsets.only(top: kYaruPagePadding), + child: _buildPage(e, model, configurations), + ), + ) + .toList(), + ), + ), + ], ), ); }, diff --git a/lib/view/pages/keyboard/keyboard_page.dart b/lib/view/pages/keyboard/keyboard_page.dart index fa9548ba..93d4b2e9 100644 --- a/lib/view/pages/keyboard/keyboard_page.dart +++ b/lib/view/pages/keyboard/keyboard_page.dart @@ -45,7 +45,7 @@ class _KeyboardPageState extends State backgroundColor: Theme.of(context).scaffoldBackgroundColor, title: const SizedBox( width: 400, - child: TabBar( + child: YaruTabBar( tabs: [ TitleBarTab( text: 'Keyboard Settings', diff --git a/lib/view/pages/privacy/privacy_page.dart b/lib/view/pages/privacy/privacy_page.dart index c2e62692..4487f16e 100644 --- a/lib/view/pages/privacy/privacy_page.dart +++ b/lib/view/pages/privacy/privacy_page.dart @@ -9,7 +9,7 @@ import 'package:settings/view/pages/privacy/screen_saver_page.dart'; import 'package:settings/view/pages/settings_page.dart'; import 'package:yaru/yaru.dart'; -class PrivacyPage extends StatelessWidget { +class PrivacyPage extends StatefulWidget { const PrivacyPage({super.key}); static Widget create(BuildContext context) => const PrivacyPage(); @@ -27,6 +27,26 @@ class PrivacyPage extends StatelessWidget { .contains(value.toLowerCase()) : false; + @override + State createState() => _PrivacyPageState(); +} + +class _PrivacyPageState extends State + with SingleTickerProviderStateMixin { + late TabController _controller; + + @override + void initState() { + super.initState(); + _controller = TabController(length: 6, vsync: this); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { final content = { @@ -60,30 +80,51 @@ class PrivacyPage extends StatelessWidget { ), }; - return DefaultTabController( - length: content.length, - child: Scaffold( - appBar: YaruWindowTitleBar( - titleSpacing: 0, - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - border: BorderSide.none, - title: TabBar( - isScrollable: true, - tabs: content.entries - .map((e) => TitleBarTab(text: e.value.$2, iconData: e.value.$1)) - .toList(), - ), - ), - body: TabBarView( - children: content.entries - .map( - (e) => Padding( - padding: const EdgeInsets.only(top: kYaruPagePadding), - child: e.key, + return Scaffold( + appBar: YaruWindowTitleBar( + titleSpacing: 0, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + border: BorderSide.none, + title: Text(context.l10n.privacyPageTitle), + ), + body: Column( + children: [ + Material( + child: SizedBox( + width: 550, + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: SizedBox( + width: 1000, + child: YaruTabBar( + tabController: _controller, + tabs: content.entries + .map( + (e) => TitleBarTab( + text: e.value.$2, + iconData: e.value.$1, + ), + ) + .toList(), + ), ), - ) - .toList(), - ), + ), + ), + ), + Expanded( + child: TabBarView( + controller: _controller, + children: content.entries + .map( + (e) => Padding( + padding: const EdgeInsets.only(top: kYaruPagePadding), + child: e.key, + ), + ) + .toList(), + ), + ), + ], ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 1b12509a..13694d4a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,7 +52,7 @@ dependencies: yaru: git: url: https://github.com/ubuntu/yaru.dart - ref: reorganize + ref: ba067738fe0a3887bf788b94295fd70a0e1cf908 dev_dependencies: build_runner: ^2.1.2