🐛 Bug fixes
This commit is contained in:
		
							
								
								
									
										17
									
								
								.github/workflows/nightly.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/nightly.yml
									
									
									
									
										vendored
									
									
								
							@@ -5,23 +5,6 @@ on:
 | 
				
			|||||||
    branches: [master]
 | 
					    branches: [master]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  build-web:
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Clone repository
 | 
					 | 
				
			||||||
        uses: actions/checkout@v4
 | 
					 | 
				
			||||||
      - name: Set up Flutter
 | 
					 | 
				
			||||||
        uses: subosito/flutter-action@v2
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          channel: stable
 | 
					 | 
				
			||||||
          cache: true
 | 
					 | 
				
			||||||
      - run: flutter pub get
 | 
					 | 
				
			||||||
      - run: flutter build web --release --base-href=/
 | 
					 | 
				
			||||||
      - name: Archive production artifacts
 | 
					 | 
				
			||||||
        uses: actions/upload-artifact@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          name: build-output-web
 | 
					 | 
				
			||||||
          path: build/web
 | 
					 | 
				
			||||||
  build-exe:
 | 
					  build-exe:
 | 
				
			||||||
    runs-on: windows-latest
 | 
					    runs-on: windows-latest
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,11 @@ Future<void> main(List<String> rawArgs) async {
 | 
				
			|||||||
  if (PlatformInfo.isDesktop) {
 | 
					  if (PlatformInfo.isDesktop) {
 | 
				
			||||||
    await windowManager.ensureInitialized();
 | 
					    await windowManager.ensureInitialized();
 | 
				
			||||||
    await windowManager.setPreventClose(true);
 | 
					    await windowManager.setPreventClose(true);
 | 
				
			||||||
 | 
					    if (PlatformInfo.isMacOS) {
 | 
				
			||||||
 | 
					      await windowManager.setTitleBarStyle(TitleBarStyle.hidden);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      await windowManager.setTitleBarStyle(TitleBarStyle.normal);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (PlatformInfo.isWindows) {
 | 
					  if (PlatformInfo.isWindows) {
 | 
				
			||||||
    await SMTCWindows.initialize();
 | 
					    await SMTCWindows.initialize();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,9 +11,12 @@ class AboutScreen extends StatelessWidget {
 | 
				
			|||||||
    const denseButtonStyle =
 | 
					    const denseButtonStyle =
 | 
				
			||||||
        ButtonStyle(visualDensity: VisualDensity(vertical: -4));
 | 
					        ButtonStyle(visualDensity: VisualDensity(vertical: -4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Material(
 | 
					    return Scaffold(
 | 
				
			||||||
      color: Theme.of(context).colorScheme.surface,
 | 
					      backgroundColor: Theme.of(context).colorScheme.surface,
 | 
				
			||||||
      child: SizedBox(
 | 
					      appBar: AppBar(
 | 
				
			||||||
 | 
					        title: const Text('About'),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      body: SizedBox(
 | 
				
			||||||
        width: double.infinity,
 | 
					        width: double.infinity,
 | 
				
			||||||
        child: Column(
 | 
					        child: Column(
 | 
				
			||||||
          mainAxisAlignment: MainAxisAlignment.center,
 | 
					          mainAxisAlignment: MainAxisAlignment.center,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -132,12 +132,13 @@ class _MiniPlayerScreenState extends State<MiniPlayerScreen> {
 | 
				
			|||||||
                                    await windowManager.setAlwaysOnTop(
 | 
					                                    await windowManager.setAlwaysOnTop(
 | 
				
			||||||
                                      snapshot.data == true ? false : true,
 | 
					                                      snapshot.data == true ? false : true,
 | 
				
			||||||
                                    );
 | 
					                                    );
 | 
				
			||||||
 | 
					                                    setState(() {});
 | 
				
			||||||
                                  },
 | 
					                                  },
 | 
				
			||||||
                          );
 | 
					                          );
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                      ),
 | 
					                      ),
 | 
				
			||||||
                  ],
 | 
					                  ],
 | 
				
			||||||
                ).paddingSymmetric(horizontal: 24),
 | 
					                ).paddingSymmetric(horizontal: 14),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ class SystemShell extends StatelessWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    if (PlatformInfo.isDesktop) {
 | 
					    if (PlatformInfo.isMacOS) {
 | 
				
			||||||
      return DragToMoveArea(
 | 
					      return DragToMoveArea(
 | 
				
			||||||
        child: Column(
 | 
					        child: Column(
 | 
				
			||||||
          children: [
 | 
					          children: [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ import 'package:rhythm_box/providers/audio_player.dart';
 | 
				
			|||||||
import 'package:rhythm_box/services/audio_services/image.dart';
 | 
					import 'package:rhythm_box/services/audio_services/image.dart';
 | 
				
			||||||
import 'package:rhythm_box/widgets/auto_cache_image.dart';
 | 
					import 'package:rhythm_box/widgets/auto_cache_image.dart';
 | 
				
			||||||
import 'package:rhythm_box/widgets/player/controls.dart';
 | 
					import 'package:rhythm_box/widgets/player/controls.dart';
 | 
				
			||||||
 | 
					import 'package:rhythm_box/widgets/player/devices.dart';
 | 
				
			||||||
import 'package:rhythm_box/widgets/player/track_details.dart';
 | 
					import 'package:rhythm_box/widgets/player/track_details.dart';
 | 
				
			||||||
import 'package:rhythm_box/widgets/tracks/querying_track_info.dart';
 | 
					import 'package:rhythm_box/widgets/tracks/querying_track_info.dart';
 | 
				
			||||||
import 'package:rhythm_box/widgets/volume_slider.dart';
 | 
					import 'package:rhythm_box/widgets/volume_slider.dart';
 | 
				
			||||||
@@ -163,6 +164,16 @@ class _BottomPlayerState extends State<BottomPlayer>
 | 
				
			|||||||
                      child: Row(
 | 
					                      child: Row(
 | 
				
			||||||
                        mainAxisAlignment: MainAxisAlignment.end,
 | 
					                        mainAxisAlignment: MainAxisAlignment.end,
 | 
				
			||||||
                        children: [
 | 
					                        children: [
 | 
				
			||||||
 | 
					                          IconButton(
 | 
				
			||||||
 | 
					                            icon: const Icon(Icons.speaker, size: 18),
 | 
				
			||||||
 | 
					                            onPressed: () {
 | 
				
			||||||
 | 
					                              showModalBottomSheet(
 | 
				
			||||||
 | 
					                                useRootNavigator: true,
 | 
				
			||||||
 | 
					                                context: context,
 | 
				
			||||||
 | 
					                                builder: (context) => const PlayerDevicePopup(),
 | 
				
			||||||
 | 
					                              );
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
                          if (!widget.isMiniPlayer && PlatformInfo.isDesktop)
 | 
					                          if (!widget.isMiniPlayer && PlatformInfo.isDesktop)
 | 
				
			||||||
                            IconButton(
 | 
					                            IconButton(
 | 
				
			||||||
                              icon: const Icon(
 | 
					                              icon: const Icon(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										85
									
								
								lib/widgets/player/devices.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								lib/widgets/player/devices.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:get/get.dart';
 | 
				
			||||||
 | 
					import 'package:media_kit/media_kit.dart';
 | 
				
			||||||
 | 
					import 'package:rhythm_box/services/audio_player/audio_player.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PlayerDevicePopup extends StatefulWidget {
 | 
				
			||||||
 | 
					  const PlayerDevicePopup({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  State<PlayerDevicePopup> createState() => _PlayerDevicePopupState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _PlayerDevicePopupState extends State<PlayerDevicePopup> {
 | 
				
			||||||
 | 
					  late Future<List<AudioDevice>> devicesFuture;
 | 
				
			||||||
 | 
					  late Stream<List<AudioDevice>> devicesStream;
 | 
				
			||||||
 | 
					  late Future<AudioDevice> selectedDeviceFuture;
 | 
				
			||||||
 | 
					  late Stream<AudioDevice> selectedDeviceStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void initState() {
 | 
				
			||||||
 | 
					    super.initState();
 | 
				
			||||||
 | 
					    devicesFuture = audioPlayer.devices;
 | 
				
			||||||
 | 
					    devicesStream = audioPlayer.devicesStream;
 | 
				
			||||||
 | 
					    selectedDeviceFuture = audioPlayer.selectedDevice;
 | 
				
			||||||
 | 
					    selectedDeviceStream = audioPlayer.selectedDeviceStream;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Column(
 | 
				
			||||||
 | 
					      crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					      children: [
 | 
				
			||||||
 | 
					        Text(
 | 
				
			||||||
 | 
					          'Devices',
 | 
				
			||||||
 | 
					          style: Theme.of(context).textTheme.headlineSmall,
 | 
				
			||||||
 | 
					        ).paddingOnly(left: 24, right: 24, top: 32, bottom: 16),
 | 
				
			||||||
 | 
					        Expanded(
 | 
				
			||||||
 | 
					          child: StreamBuilder<List<AudioDevice>>(
 | 
				
			||||||
 | 
					            stream: devicesStream,
 | 
				
			||||||
 | 
					            builder: (context, devicesSnapshot) {
 | 
				
			||||||
 | 
					              return FutureBuilder<List<AudioDevice>>(
 | 
				
			||||||
 | 
					                future: devicesFuture,
 | 
				
			||||||
 | 
					                builder: (context, devicesFutureSnapshot) {
 | 
				
			||||||
 | 
					                  final devices =
 | 
				
			||||||
 | 
					                      devicesSnapshot.data ?? devicesFutureSnapshot.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  return StreamBuilder<AudioDevice>(
 | 
				
			||||||
 | 
					                    stream: selectedDeviceStream,
 | 
				
			||||||
 | 
					                    builder: (context, selectedDeviceSnapshot) {
 | 
				
			||||||
 | 
					                      return FutureBuilder<AudioDevice>(
 | 
				
			||||||
 | 
					                        future: selectedDeviceFuture,
 | 
				
			||||||
 | 
					                        builder: (context, selectedDeviceFutureSnapshot) {
 | 
				
			||||||
 | 
					                          final selectedDevice = selectedDeviceSnapshot.data ??
 | 
				
			||||||
 | 
					                              selectedDeviceFutureSnapshot.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                          if (devices == null || selectedDevice == null) {
 | 
				
			||||||
 | 
					                            return const CircularProgressIndicator();
 | 
				
			||||||
 | 
					                          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                          return ListView.builder(
 | 
				
			||||||
 | 
					                            itemCount: devices.length,
 | 
				
			||||||
 | 
					                            itemBuilder: (context, idx) {
 | 
				
			||||||
 | 
					                              final device = devices[idx];
 | 
				
			||||||
 | 
					                              return ListTile(
 | 
				
			||||||
 | 
					                                leading: const Icon(Icons.speaker),
 | 
				
			||||||
 | 
					                                title: Text(device.description),
 | 
				
			||||||
 | 
					                                subtitle: Text(device.name),
 | 
				
			||||||
 | 
					                                selected: selectedDevice == device,
 | 
				
			||||||
 | 
					                                onTap: () => audioPlayer.setAudioDevice(device),
 | 
				
			||||||
 | 
					                              );
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                          );
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                      );
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                  );
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -67,7 +67,7 @@ class VolumeSlider extends StatelessWidget {
 | 
				
			|||||||
              }
 | 
					              }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          slider,
 | 
					          SizedBox(width: 100, child: slider),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -1228,10 +1228,10 @@ packages:
 | 
				
			|||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
      name: shelf_web_socket
 | 
					      name: shelf_web_socket
 | 
				
			||||||
      sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
 | 
					      sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
 | 
				
			||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "1.0.4"
 | 
					    version: "2.0.0"
 | 
				
			||||||
  skeletonizer:
 | 
					  skeletonizer:
 | 
				
			||||||
    dependency: "direct main"
 | 
					    dependency: "direct main"
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
@@ -1522,10 +1522,10 @@ packages:
 | 
				
			|||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
      name: vm_service
 | 
					      name: vm_service
 | 
				
			||||||
      sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
 | 
					      sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
 | 
				
			||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "14.2.4"
 | 
					    version: "14.2.5"
 | 
				
			||||||
  watcher:
 | 
					  watcher:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
@@ -1542,14 +1542,22 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "0.5.1"
 | 
					    version: "0.5.1"
 | 
				
			||||||
 | 
					  web_socket:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: web_socket
 | 
				
			||||||
 | 
					      sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "0.1.6"
 | 
				
			||||||
  web_socket_channel:
 | 
					  web_socket_channel:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
      name: web_socket_channel
 | 
					      name: web_socket_channel
 | 
				
			||||||
      sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
 | 
					      sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
 | 
				
			||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "2.4.0"
 | 
					    version: "3.0.1"
 | 
				
			||||||
  win32:
 | 
					  win32:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user