Skip to content

Commit

Permalink
Merge pull request #4 from TheAppgineer/3-implement-zone-transfer
Browse files Browse the repository at this point in the history
3 implement zone transfer
  • Loading branch information
JanKoudijs authored Jun 8, 2024
2 parents 0a92e4a + f8da202 commit 3c6e12a
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 26 deletions.
62 changes: 38 additions & 24 deletions lib/src/frontend/zones.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class _ZonesState extends State<Zones> {
Widget? trailing;
Widget? playState;
Text? metaData;
TextStyle? style = zones[index].zoneId == appState.zone!.zoneId
? TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary)
: const TextStyle(fontWeight: FontWeight.normal);

switch (zones[index].state) {
case PlayState.playing:
Expand All @@ -59,21 +62,11 @@ class _ZonesState extends State<Zones> {
break;
}

if (appState.zone != null && appState.zone!.zoneId == zones[index].zoneId) {
trailing = MenuAnchor(
builder: (context, controller, child) {
return IconButton(
onPressed: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
icon: const Icon(Icons.more_vert),
);
},
menuChildren: List<MenuItemButton>.generate(
if (appState.zone != null) {
List<MenuItemButton>? menuChildren;

if (appState.zone!.zoneId == zones[index].zoneId) {
menuChildren = List<MenuItemButton>.generate(
(zones[index].outputIds.length == 1 ? 1 : 2),
(index) => MenuItemButton(
child: Text(index > 0 ? 'Ungroup' : 'Group...'),
Expand All @@ -90,30 +83,51 @@ class _ZonesState extends State<Zones> {
}
},
),
),
);
} else {
menuChildren = List<MenuItemButton>.generate(
1,
(index) => MenuItemButton(
child: Text('Transfer Queue to ${appState.zone!.displayName}'),
onPressed: () {
transferFromZone(zoneId: zones[index].zoneId);
},
),
);
}

trailing = MenuAnchor(
builder: (context, controller, child) {
return IconButton(
onPressed: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
icon: const Icon(Icons.more_vert),
);
},
menuChildren: menuChildren,
onClose: () {
// Delay the onClose handling to make sure onPressed can be handled first
Future.delayed(const Duration(milliseconds: 100), () {
});
},
);
} else {
var imageKey = zones[index].imageKey;

if (imageKey != null) {
trailing = _imageCache[imageKey] ?? appState.requestImage(imageKey, addToImageCache);
}
}

if (zones[index].nowPlaying != null) {
metaData = Text(zones[index].nowPlaying!);
metaData = Text(zones[index].nowPlaying!, style: style);
}

return ListTile(
leading: playState,
trailing: trailing,
title: Text(zones[index].displayName),
title: Text(zones[index].displayName, style: style),
subtitle: metaData,
focusColor: Colors.transparent,
onTap: () {
var zoneId = zones[index].zoneId;

Expand Down
3 changes: 3 additions & 0 deletions lib/src/rust/api/simple.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ Future<void> setServerProperties({required String ip, String? port}) =>
Future<void> selectZone({required String zoneId}) =>
RustLib.instance.api.crateApiSimpleSelectZone(zoneId: zoneId);

Future<void> transferFromZone({required String zoneId}) =>
RustLib.instance.api.crateApiSimpleTransferFromZone(zoneId: zoneId);

Future<void> getImage({required String imageKey}) =>
RustLib.instance.api.crateApiSimpleGetImage(imageKey: imageKey);

Expand Down
29 changes: 28 additions & 1 deletion lib/src/rust/frb_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
String get codegenVersion => '2.0.0-dev.37';

@override
int get rustContentHash => 852261618;
int get rustContentHash => -2102101347;

static const kDefaultExternalLibraryLoaderConfig =
ExternalLibraryLoaderConfig(
Expand Down Expand Up @@ -132,6 +132,8 @@ abstract class RustLibApi extends BaseApi {
Future<String> crateApiSimpleStartRoon(
{required String supportPath,
required FutureOr<void> Function(RoonEvent) cb});

Future<void> crateApiSimpleTransferFromZone({required String zoneId});
}

class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
Expand Down Expand Up @@ -794,6 +796,31 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["supportPath", "cb"],
);

@override
Future<void> crateApiSimpleTransferFromZone({required String zoneId}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_String(zoneId, serializer);
pdeCallFfi(generalizedFrbRustBinding, serializer,
funcId: 27, port: port_);
},
codec: SseCodec(
decodeSuccessData: sse_decode_unit,
decodeErrorData: null,
),
constMeta: kCrateApiSimpleTransferFromZoneConstMeta,
argValues: [zoneId],
apiImpl: this,
));
}

TaskConstMeta get kCrateApiSimpleTransferFromZoneConstMeta =>
const TaskConstMeta(
debugName: "transfer_from_zone",
argNames: ["zoneId"],
);

Future<void> Function(int, dynamic)
encode_DartFn_Inputs_roon_event_Output_unit_AnyhowException(
FutureOr<void> Function(RoonEvent) raw) {
Expand Down
8 changes: 8 additions & 0 deletions rust/src/api/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ pub async fn select_zone(zone_id: String) {
}
}

pub async fn transfer_from_zone(zone_id: String) {
let api = API.lock().await;

if let Some(roon) = api.roon.as_ref() {
roon.transfer_from_zone(&zone_id).await;
}
}

pub async fn get_image(image_key: String) {
let api = API.lock().await;

Expand Down
12 changes: 12 additions & 0 deletions rust/src/backend/roon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,18 @@ impl Roon {
Some(())
}

pub async fn transfer_from_zone(&self, zone_id: &str) -> Option<()> {
let handler = self.handler.lock().await;

handler
.transport
.as_ref()?
.transfer_zone(zone_id, handler.zone_id.as_deref()?)
.await;

Some(())
}

pub async fn browse_category(
&self,
category: i32,
Expand Down
40 changes: 39 additions & 1 deletion rust/src/frb_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
default_rust_auto_opaque = RustAutoOpaqueMoi,
);
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0-dev.37";
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 852261618;
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -2102101347;

// Section: executor

Expand Down Expand Up @@ -980,6 +980,43 @@ fn wire__crate__api__simple__start_roon_impl(
},
)
}
fn wire__crate__api__simple__transfer_from_zone_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "transfer_from_zone",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_zone_id = <String>::sse_decode(&mut deserializer);
deserializer.end();
move |context| async move {
transform_result_sse(
(move || async move {
Result::<_, ()>::Ok(
crate::api::simple::transfer_from_zone(api_zone_id).await,
)
})()
.await,
)
}
},
)
}

// Section: static_checks

Expand Down Expand Up @@ -2082,6 +2119,7 @@ fn pde_ffi_dispatcher_primary_impl(
}
25 => wire__crate__api__simple__standby_impl(port, ptr, rust_vec_len, data_len),
26 => wire__crate__api__simple__start_roon_impl(port, ptr, rust_vec_len, data_len),
27 => wire__crate__api__simple__transfer_from_zone_impl(port, ptr, rust_vec_len, data_len),
_ => unreachable!(),
}
}
Expand Down

0 comments on commit 3c6e12a

Please sign in to comment.