blob: d0ac5cf034f39eb1043227ecc12f49c9c166cd4b [file] [log] [blame]
// Copyright 2019 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 'dart:async';
import 'package:fidl_fuchsia_intl/fidl_async.dart';
import 'package:flutter/material.dart';
import 'package:fuchsia_internationalization_flutter/internationalization.dart';
import 'package:fuchsia_scenic/views.dart';
import 'package:fuchsia_services/services.dart';
import 'package:keyboard_shortcuts/keyboard_shortcuts.dart';
import '../blocs/tabs_bloc.dart';
import '../models/tabs_action.dart';
import '../models/webpage_action.dart';
import '../utils/browser_shortcuts.dart';
/// Model that handles the browser's tab and webpage states.
///
/// tabsBloc: A listener for the tab and web page states.
/// localeStream: A getter for the current localization value.
/// initialLocale: A getter for the initial localization value.
/// keyboardShortcuts: A getter for the browser's [KeyboardShortcuts].
class AppModel {
final TabsBloc tabsBloc;
Stream<Locale> _localeStream;
late final FocusNode fieldFocus;
late final KeyboardShortcuts? _keyboardShortcuts;
AppModel({
required this.tabsBloc,
required Stream<Locale> localeStream,
}) : _localeStream = localeStream {
fieldFocus = FocusNode();
_keyboardShortcuts =
// TODO(https://fxbug.dev/71711): Figure out why `dart analyze`
// complains about this.
// ignore: argument_type_not_assignable
BrowserShortcuts(tabsBloc: tabsBloc, actions: _shortcutActions())
.activateShortcuts(ScenicContext.hostViewRef());
}
factory AppModel.fromStartupContext({required TabsBloc tabsBloc}) {
final _intl = PropertyProviderProxy();
Incoming.fromSvcPath()
..connectToService(_intl)
..close();
final localStream = LocaleSource(_intl).stream().asBroadcastStream();
return AppModel(
tabsBloc: tabsBloc,
localeStream: localStream,
);
}
Stream<Locale> get localeStream => _localeStream;
KeyboardShortcuts? get keyboardShortcuts => _keyboardShortcuts;
void newTab() => tabsBloc.request.add(NewTabAction());
Map<String, VoidCallback> _shortcutActions() {
return {
'newTab': newTab,
'closeTab': _closeTab,
'goBack': _goBack,
'goForward': _goForward,
'refresh': _refresh,
'previousTab': _previousTab,
'nextTab': _nextTab,
'focusField': _focusField,
};
}
void _closeTab() {
if (tabsBloc.isOnlyTab) {
return;
}
tabsBloc.request.add(RemoveTabAction(tab: tabsBloc.currentTab!));
}
void _goBack() {
if (tabsBloc.currentTab!.backState) {
tabsBloc.currentTab!.request.add(GoBackAction());
return;
}
return;
}
void _goForward() {
if (tabsBloc.currentTab!.forwardState) {
tabsBloc.currentTab!.request.add(GoForwardAction());
return;
}
return;
}
void _refresh() => tabsBloc.currentTab!.request.add(RefreshAction());
void _previousTab() {
if (tabsBloc.isOnlyTab || tabsBloc.previousTab == null) {
return;
}
tabsBloc.request.add(FocusTabAction(tab: tabsBloc.previousTab!));
}
void _nextTab() {
if (tabsBloc.isOnlyTab || tabsBloc.nextTab == null) {
return;
}
tabsBloc.request.add(FocusTabAction(tab: tabsBloc.nextTab!));
}
void _focusField() => fieldFocus.requestFocus();
// ignore: avoid_positional_boolean_parameters
void onFocus(bool focused) {
if (focused && tabsBloc.currentTab!.webService.isLoaded) {
tabsBloc.currentTab!.request.add(SetFocusAction());
}
}
// TODO: Activate/Deactivate the keyboardShortcuts depending on the browser's
// focus state when its relevant support is ready (fxb/42185)
}