blob: 0f86b836d44d3e4a79bdedc0b3bae51b9af8b99d [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:fidl_fuchsia_ui_remotewidgets/fidl_async.dart';
import 'package:fidl_fuchsia_update_channelcontrol/fidl_async.dart';
import 'package:flutter/material.dart';
import 'package:fuchsia_services/services.dart' show Incoming;
import 'package:internationalization/strings.dart';
import 'package:quickui/quickui.dart';
/// Defines a [UiSpec] for displaying channel.
class Channel extends UiSpec {
// Localized strings.
static String get _title => Strings.channel;
// Icon for channel title.
static IconValue get _icon =>
IconValue(codePoint: Icons.cloud_outlined.codePoint);
// Action to change channel.
static int changeAction = QuickAction.details.$value;
late _ChannelModel model;
Channel(ChannelControlProxy control) {
model = _ChannelModel(control: control, onChange: _onChange);
}
factory Channel.withSvcPath() {
final control = ChannelControlProxy();
Incoming.fromSvcPath().connectToService(control);
return Channel(control);
}
void _onChange() async {
spec = await _specForChannel(model);
}
@override
void update(Value value) async {
if (value.$tag == ValueTag.button &&
value.button!.action == QuickAction.cancel.$value) {
spec = await _specForChannel(model);
} else if (value.$tag == ValueTag.text && value.text!.action > 0) {
if (value.text!.action == changeAction) {
spec = await _specForChannel(model, changeAction);
} else {
final index = value.text!.action ^ QuickAction.submit.$value;
model.channel = model.channels[index];
spec = await _specForChannel(model);
}
}
}
@override
void dispose() {
model.dispose();
}
Future<Spec> _specForChannel(_ChannelModel model, [int action = 0]) async {
if (action == 0 || action & QuickAction.cancel.$value > 0) {
return Spec(title: _title, groups: [
Group(title: _title, icon: _icon, values: [
Value.withText(TextValue(
text: model.channel,
action: changeAction,
)),
Value.withIcon(IconValue(
codePoint: Icons.arrow_right.codePoint,
action: changeAction,
)),
]),
]);
} else if (action == changeAction) {
var channels = model.channels;
final values = List<TextValue>.generate(
channels.length,
(index) => TextValue(
text: channels[index],
action: QuickAction.submit.$value | index,
));
return Spec(title: _title, groups: [
Group(title: 'Select Channel', values: [
Value.withGrid(GridValue(
columns: 1,
values: values,
)),
Value.withButton(ButtonValue(
label: 'close',
action: QuickAction.cancel.$value,
)),
]),
]);
} else {
return Spec(title: _title, groups: [
Group(title: _title, values: [
Value.withText(TextValue(text: 'loading...')),
]),
]);
}
}
}
class _ChannelModel {
final ChannelControlProxy control;
final VoidCallback onChange;
late String _channel;
late List<String> _channels;
_ChannelModel({required this.control, required this.onChange}) {
loadCurrentChannel();
loadTargetChannels();
}
void dispose() {
control.ctrl.close();
}
String get channel => _channel;
set channel(String name) {
_channel = name;
control.setTarget(name);
onChange();
}
List<String> get channels => _channels;
void loadCurrentChannel() {
control.getTarget().then((name) {
_channel = name;
onChange();
});
}
void loadTargetChannels() {
control.getTargetList().then((channels) {
_channels = channels;
});
}
}