diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0b75217f..1d048cc9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -5,6 +5,9 @@ PODS: - Flutter - audio_session (0.0.1): - Flutter + - bonsoir_darwin (0.0.1): + - Flutter + - FlutterMacOS - device_info_plus (0.0.1): - Flutter - DKImagePickerController/Core (4.3.4): @@ -44,11 +47,13 @@ PODS: - file_selector_ios (0.0.1): - Flutter - Flutter (1.0.0) - - flutter_inappwebview (0.0.1): + - flutter_broadcasts (0.0.1): - Flutter - - flutter_inappwebview/Core (= 0.0.1) + - flutter_inappwebview_ios (0.0.1): + - Flutter + - flutter_inappwebview_ios/Core (= 0.0.1) - OrderedSet (~> 5.0) - - flutter_inappwebview/Core (0.0.1): + - flutter_inappwebview_ios/Core (0.0.1): - Flutter - OrderedSet (~> 5.0) - flutter_keyboard_visibility (0.0.1): @@ -102,11 +107,13 @@ DEPENDENCIES: - app_links (from `.symlinks/plugins/app_links/ios`) - audio_service (from `.symlinks/plugins/audio_service/ios`) - audio_session (from `.symlinks/plugins/audio_session/ios`) + - bonsoir_darwin (from `.symlinks/plugins/bonsoir_darwin/darwin`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - file_selector_ios (from `.symlinks/plugins/file_selector_ios/ios`) - Flutter (from `Flutter`) - - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) + - flutter_broadcasts (from `.symlinks/plugins/flutter_broadcasts/ios`) + - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - flutter_mailer (from `.symlinks/plugins/flutter_mailer/ios`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) @@ -142,6 +149,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/audio_service/ios" audio_session: :path: ".symlinks/plugins/audio_session/ios" + bonsoir_darwin: + :path: ".symlinks/plugins/bonsoir_darwin/darwin" device_info_plus: :path: ".symlinks/plugins/device_info_plus/ios" file_picker: @@ -150,8 +159,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/file_selector_ios/ios" Flutter: :path: Flutter - flutter_inappwebview: - :path: ".symlinks/plugins/flutter_inappwebview/ios" + flutter_broadcasts: + :path: ".symlinks/plugins/flutter_broadcasts/ios" + flutter_inappwebview_ios: + :path: ".symlinks/plugins/flutter_inappwebview_ios/ios" flutter_keyboard_visibility: :path: ".symlinks/plugins/flutter_keyboard_visibility/ios" flutter_mailer: @@ -191,13 +202,15 @@ SPEC CHECKSUMS: app_links: 5ef33d0d295a89d9d16bb81b0e3b0d5f70d6c875 audio_service: f509d65da41b9521a61f1c404dd58651f265a567 audio_session: 4f3e461722055d21515cf3261b64c973c062f345 - device_info_plus: 7545d84d8d1b896cb16a4ff98c19f07ec4b298ea + bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842 + device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de file_selector_ios: 8c25d700d625e1dcdd6599f2d927072f2254647b Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_inappwebview: acd4fc0f012cefd09015000c241137d82f01ba62 + flutter_broadcasts: 3ece15b27d8ccbe2132c3df303e7c3401feab882 + flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83 flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef @@ -221,6 +234,6 @@ SPEC CHECKSUMS: Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 -PODFILE CHECKSUM: 5129d2e80ab0dfc533f262cedf032011b1dfe4fd +PODFILE CHECKSUM: 0659b64ac6e9e96b61d8550decffa8bff51a957e COCOAPODS: 1.15.2 diff --git a/lib/components/connect/connect_device.dart b/lib/components/connect/connect_device.dart new file mode 100644 index 00000000..511db3b9 --- /dev/null +++ b/lib/components/connect/connect_device.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/extensions/context.dart'; +import 'package:spotube/provider/connect/clients.dart'; +import 'package:spotube/utils/service_utils.dart'; + +class ConnectDeviceButton extends HookConsumerWidget { + const ConnectDeviceButton({super.key}); + + @override + Widget build(BuildContext context, ref) { + final ThemeData(:colorScheme) = Theme.of(context); + final connectClients = ref.watch(connectClientsProvider); + + return SizedBox( + height: 40, + child: Stack( + children: [ + Center( + child: InkWell( + onTap: () { + ServiceUtils.push(context, "/connect"); + }, + borderRadius: BorderRadius.circular(50), + child: Ink( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(50), + color: colorScheme.primaryContainer, + ), + padding: + const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (connectClients.asData?.value.resolvedService != + null) ...[ + Container( + width: 7, + height: 7, + decoration: BoxDecoration( + color: Colors.greenAccent, + borderRadius: BorderRadius.circular(50), + ), + ), + const Gap(5), + ], + Text(context.l10n.devices), + if (connectClients.asData?.value.services.isNotEmpty == + true) + Text( + " (${connectClients.asData?.value.services.length})", + style: TextStyle( + color: + colorScheme.onPrimaryContainer.withOpacity(0.5), + ), + ), + const Gap(35), + ], + ), + ), + ), + ), + Positioned( + right: 0, + child: IconButton.filled( + icon: const Icon(SpotubeIcons.speaker), + style: + IconButton.styleFrom(foregroundColor: colorScheme.onPrimary), + onPressed: () { + ServiceUtils.push(context, "/connect"); + }, + ), + ), + ], + ), + ); + } +} diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9fdcbc1b..28c4ced4 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -315,5 +315,6 @@ "donate_on_open_collective": "Donate on Open Collective", "browse_anonymously": "Browse Anonymously", "enable_connect": "Enable Connect", - "enable_connect_description": "Control Spotube from other devices" + "enable_connect_description": "Control Spotube from other devices", + "devices": "Devices" } \ No newline at end of file diff --git a/lib/pages/connect/connect.dart b/lib/pages/connect/connect.dart index 3ddb94d0..6847b2c0 100644 --- a/lib/pages/connect/connect.dart +++ b/lib/pages/connect/connect.dart @@ -3,6 +3,7 @@ import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; +import 'package:spotube/extensions/context.dart'; import 'package:spotube/provider/connect/clients.dart'; import 'package:spotube/utils/service_utils.dart'; @@ -18,9 +19,9 @@ class ConnectPage extends HookConsumerWidget { final discoveredDevices = connectClients.asData?.value.services; return Scaffold( - appBar: const PageWindowTitleBar( + appBar: PageWindowTitleBar( automaticallyImplyLeading: true, - title: Text("Devices"), + title: Text(context.l10n.devices), ), body: ListView.separated( padding: const EdgeInsets.all(10), diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart index a3590378..1e7e3389 100644 --- a/lib/pages/home/home.dart +++ b/lib/pages/home/home.dart @@ -3,22 +3,19 @@ import 'package:flutter_desktop_tools/flutter_desktop_tools.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/collections/spotube_icons.dart'; +import 'package:spotube/components/connect/connect_device.dart'; import 'package:spotube/components/home/sections/featured.dart'; import 'package:spotube/components/home/sections/friends.dart'; import 'package:spotube/components/home/sections/genres.dart'; import 'package:spotube/components/home/sections/made_for_user.dart'; import 'package:spotube/components/home/sections/new_releases.dart'; import 'package:spotube/components/shared/page_window_title_bar.dart'; -import 'package:spotube/provider/connect/clients.dart'; -import 'package:spotube/utils/service_utils.dart'; class HomePage extends HookConsumerWidget { const HomePage({super.key}); @override Widget build(BuildContext context, ref) { - final ThemeData(:colorScheme) = Theme.of(context); final controller = useScrollController(); return SafeArea( @@ -26,37 +23,26 @@ class HomePage extends HookConsumerWidget { child: Scaffold( appBar: DesktopTools.platform.isLinux || DesktopTools.platform.isWindows - ? const PageWindowTitleBar() + ? const PageWindowTitleBar( + actions: [ + ConnectDeviceButton(), + Gap(10), + ], + ) : null, body: CustomScrollView( controller: controller, slivers: [ if (DesktopTools.platform.isMacOS || DesktopTools.platform.isWeb) const SliverGap(20), - SliverAppBar( - actions: [ - Consumer( - builder: (context, ref, _) { - final connectClients = ref.watch(connectClientsProvider); - - return IconButton( - icon: const Icon(SpotubeIcons.speaker), - style: connectClients.asData?.value.resolvedService != - null - ? IconButton.styleFrom( - backgroundColor: colorScheme.primaryContainer, - foregroundColor: colorScheme.primary, - ) - : null, - onPressed: () { - ServiceUtils.push(context, "/connect"); - }, - ); - }, - ), - const Gap(10), - ], - ), + if (!DesktopTools.platform.isLinux && + !DesktopTools.platform.isWindows) + const SliverAppBar( + actions: [ + ConnectDeviceButton(), + Gap(10), + ], + ), const HomeGenresSection(), const SliverToBoxAdapter(child: HomeFeaturedSection()), const HomePageFriendsSection(), diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 68a46ae4..317de385 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -12,6 +12,9 @@ PODS: - FlutterMacOS - file_selector_macos (0.0.1): - FlutterMacOS + - flutter_inappwebview_macos (0.0.1): + - FlutterMacOS + - OrderedSet (~> 5.0) - flutter_secure_storage_macos (6.1.1): - FlutterMacOS - FlutterMacOS (1.0.0) @@ -25,6 +28,7 @@ PODS: - media_kit_native_event_loop (1.0.0): - FlutterMacOS - metadata_god (0.0.1) + - OrderedSet (5.0.0) - package_info_plus (0.0.1): - FlutterMacOS - path_provider_foundation (0.0.1): @@ -56,6 +60,7 @@ DEPENDENCIES: - bonsoir_darwin (from `Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`) + - flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`) - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - local_notifier (from `Flutter/ephemeral/.symlinks/plugins/local_notifier/macos`) @@ -76,6 +81,7 @@ DEPENDENCIES: SPEC REPOS: trunk: - FMDB + - OrderedSet EXTERNAL SOURCES: app_links: @@ -90,6 +96,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos file_selector_macos: :path: Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos + flutter_inappwebview_macos: + :path: Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos flutter_secure_storage_macos: :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos FlutterMacOS: @@ -130,6 +138,7 @@ SPEC CHECKSUMS: bonsoir_darwin: e3b8526c42ca46a885142df84229131dfabea842 device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f file_selector_macos: 468fb6b81fac7c0e88d71317f3eec34c3b008ff9 + flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a @@ -137,6 +146,7 @@ SPEC CHECKSUMS: media_kit_libs_macos_audio: 3871782a4f3f84c77f04d7666c87800a781c24da media_kit_native_event_loop: 7321675377cb9ae8596a29bddf3a3d2b5e8792c5 metadata_god: eceae399d0020475069a5cebc35943ce8562b5d7 + OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 diff --git a/untranslated_messages.json b/untranslated_messages.json index 26eb5d26..efaf3fed 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1,103 +1,123 @@ { "ar": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "bn": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "ca": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "de": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "es": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "fa": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "fr": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "hi": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "it": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "ja": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "ko": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "ne": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "nl": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "pl": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "pt": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "ru": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "tr": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "uk": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "vi": [ "friends", "no_lyrics_available", "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ], "zh": [ "enable_connect", - "enable_connect_description" + "enable_connect_description", + "devices" ] }