feat: build v1 Mews client: reader UI, gestures, Drift store, fetch actor
This commit is contained in:
parent
d5a0fcbf48
commit
01a36e8aee
56 changed files with 7287 additions and 2 deletions
80
app/lib/presentation/reader/address_bar.dart
Normal file
80
app/lib/presentation/reader/address_bar.dart
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:signals/signals_flutter.dart' show SignalBuilder;
|
||||
|
||||
import '../app.dart';
|
||||
|
||||
/// The single-field address bar at the top of the reader. Submitting navigates;
|
||||
/// the field shows the current page's URL whenever the reader is not typing.
|
||||
class AddressBar extends StatefulWidget {
|
||||
const AddressBar({super.key});
|
||||
|
||||
@override
|
||||
State<AddressBar> createState() => _AddressBarState();
|
||||
}
|
||||
|
||||
class _AddressBarState extends State<AddressBar> {
|
||||
final _controller = TextEditingController();
|
||||
final _focus = FocusNode();
|
||||
bool _focused = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_focus.addListener(() {
|
||||
if (_focus.hasFocus != _focused) {
|
||||
setState(() => _focused = _focus.hasFocus);
|
||||
if (_focused) {
|
||||
_controller.selection =
|
||||
TextSelection(baseOffset: 0, extentOffset: _controller.text.length);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focus.dispose();
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final deps = AppScope.of(context).deps;
|
||||
final strings = AppScope.of(context).strings;
|
||||
|
||||
return SignalBuilder(builder: (context) {
|
||||
final url = deps.browser.currentPage.value?.url;
|
||||
if (url != null && !_focused) {
|
||||
_controller.text = url;
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 8, 8, 4),
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
focusNode: _focus,
|
||||
autofocus: false,
|
||||
keyboardType: TextInputType.url,
|
||||
textInputAction: TextInputAction.go,
|
||||
autocorrect: false,
|
||||
enableSuggestions: false,
|
||||
onSubmitted: (value) {
|
||||
_focus.unfocus();
|
||||
deps.browser.open(value);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: strings.t('reader-address-placeholder'),
|
||||
labelText: strings.t('reader-address-label'),
|
||||
prefixIcon: IconButton(
|
||||
icon: const Icon(Icons.refresh),
|
||||
tooltip: strings.t('reader-reload'),
|
||||
onPressed: () => deps.browser.reload(),
|
||||
),
|
||||
isDense: true,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue