blob: 34d05fae0eb6efb23099a12199e419b826e00c5d [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file is hand-formatted.
import 'package:flutter/widgets.dart';
import '../dart/model.dart';
import 'content.dart';
import 'runtime.dart';
export '../dart/model.dart' show DynamicMap, LibraryName;
/// Injection point for a remote widget.
///
/// This widget combines an RFW [Runtime] and [DynamicData], inserting a
/// specified [widget] into the tree.
class RemoteWidget extends StatefulWidget {
/// Inserts the specified [widget] into the tree.
///
/// The [onEvent] argument is optional. When omitted, events are discarded.
const RemoteWidget({ Key? key, required this.runtime, required this.widget, required this.data, this.onEvent }) : super(key: key);
/// The [Runtime] to use to render the widget specified by [library] and [name].
///
/// This should update rarely (doing so is relatively expensive), but it is
/// fine to update it. For example, a client could update this on the fly when
/// the server deploys a new version of the widget library.
///
/// Frequent updates (e.g. animations) should be done by updating [data] instead.
final Runtime runtime;
/// The name of the widget to display, and the library from which to obtain
/// in.
///
/// The widget must be either declared in the specified library or one of its
/// dependencies.
///
/// The data to show in the widget is specified using [data].
final FullyQualifiedWidgetName widget;
/// The data to which the widget specified by [name] will be bound.
///
/// This includes data that comes from the application, e.g. a description of
/// the user's device, the current time, or an animation controller's value,
/// and data that comes from the server, e.g. the contents of the user's
/// shopping cart.
///
/// This can be updated frequently (once per frame) using
/// [DynamicContent.update].
final DynamicContent data;
/// Called when there's an event triggered by a remote widget.
///
/// If this is null, events are discarded.
final RemoteEventHandler? onEvent;
@override
_RemoteWidgetState createState() => _RemoteWidgetState();
}
class _RemoteWidgetState extends State<RemoteWidget> {
@override
void initState() {
super.initState();
widget.runtime.addListener(_runtimeChanged);
}
@override
void didUpdateWidget(RemoteWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.runtime != widget.runtime) {
oldWidget.runtime.removeListener(_runtimeChanged);
widget.runtime.addListener(_runtimeChanged);
}
}
@override
void dispose() {
widget.runtime.removeListener(_runtimeChanged);
super.dispose();
}
void _runtimeChanged() {
setState(() { /* widget probably changed */ });
}
void _eventHandler(String eventName, DynamicMap eventArguments) {
if (widget.onEvent != null) {
widget.onEvent!(eventName, eventArguments);
}
}
@override
Widget build(BuildContext context) {
return widget.runtime.build(context, widget.widget, widget.data, _eventHandler);
}
}