From 92b409455008b75575641bcff84389cbd52731ed Mon Sep 17 00:00:00 2001 From: ReinerRego Date: Wed, 4 Oct 2023 14:10:17 +0200 Subject: [PATCH] started fixing desktop ui --- .../src/main/res/layout/widget_timetable.xml | 2 +- .../login/school_input/school_input.dart | 122 ++++++++++++++++++ .../login/school_input/school_input_tile.dart | 65 ++++++++++ 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 filcnaplo_desktop_ui/lib/screens/login/school_input/school_input.dart create mode 100644 filcnaplo_desktop_ui/lib/screens/login/school_input/school_input_tile.dart diff --git a/filcnaplo/android/app/src/main/res/layout/widget_timetable.xml b/filcnaplo/android/app/src/main/res/layout/widget_timetable.xml index 69b80b0..75496ef 100644 --- a/filcnaplo/android/app/src/main/res/layout/widget_timetable.xml +++ b/filcnaplo/android/app/src/main/res/layout/widget_timetable.xml @@ -136,7 +136,7 @@ android:layout_below="@id/iv_1" android:layout_marginHorizontal="15dp" android:fontFamily="@font/montserrat_medium" - android:text="A widget használatához, bejelentkezés szükséges." + android:text="A widget használatához bejelentkezés szükséges." android:textColor="@color/black" android:paddingTop="10dp" android:textSize="17sp" diff --git a/filcnaplo_desktop_ui/lib/screens/login/school_input/school_input.dart b/filcnaplo_desktop_ui/lib/screens/login/school_input/school_input.dart new file mode 100644 index 0000000..dfaa1d3 --- /dev/null +++ b/filcnaplo_desktop_ui/lib/screens/login/school_input/school_input.dart @@ -0,0 +1,122 @@ +import 'package:filcnaplo_mobile_ui/screens/login/login_input.dart'; +import 'package:filcnaplo_mobile_ui/screens/login/school_input/school_input_overlay.dart'; +import 'package:filcnaplo_desktop_ui/screens/login/school_input/school_input_tile.dart'; +import 'package:filcnaplo_mobile_ui/screens/login/school_input/school_search.dart'; +import 'package:flutter/material.dart'; +import 'package:filcnaplo_kreta_api/models/school.dart'; + +class SchoolInput extends StatefulWidget { + const SchoolInput({Key? key, required this.controller, required this.scroll}) + : super(key: key); + + final SchoolInputController controller; + final ScrollController scroll; + + @override + _SchoolInputState createState() => _SchoolInputState(); +} + +class _SchoolInputState extends State { + final _focusNode = FocusNode(); + final _layerLink = LayerLink(); + late SchoolInputOverlay overlay; + + @override + void initState() { + super.initState(); + + widget.controller.update = (fn) { + if (mounted) setState(fn); + }; + + overlay = SchoolInputOverlay(layerLink: _layerLink); + + // Show school list when focused + _focusNode.addListener(() { + if (_focusNode.hasFocus) { + WidgetsBinding.instance + .addPostFrameCallback((_) => overlay.createOverlayEntry(context)); + Future.delayed(const Duration(milliseconds: 100)).then((value) { + if (mounted && widget.scroll.hasClients) { + widget.scroll.animateTo(widget.scroll.offset + 500, + duration: const Duration(milliseconds: 500), + curve: Curves.ease); + } + }); + } else { + overlay.entry?.remove(); + } + }); + + // LoginInput TextField listener + widget.controller.textController.addListener(() { + String text = widget.controller.textController.text; + if (text.isEmpty) { + overlay.children = null; + return; + } + + List results = + searchSchools(widget.controller.schools ?? [], text); + setState(() { + overlay.children = results + .map((School e) => SchoolInputTile( + school: e, + onTap: () => _selectSchool(e), + )) + .toList(); + }); + Overlay.of(context).setState(() {}); + }); + } + + void _selectSchool(School school) { + FocusScope.of(context).requestFocus(FocusNode()); + + setState(() { + widget.controller.selectedSchool = school; + widget.controller.textController.text = school.name; + }); + } + + @override + Widget build(BuildContext context) { + return CompositedTransformTarget( + link: _layerLink, + child: widget.controller.schools == null + ? Container( + width: double.infinity, + padding: const EdgeInsets.symmetric(vertical: 10.0), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.15), + borderRadius: BorderRadius.circular(12.0), + ), + child: const Center( + child: SizedBox( + height: 28.0, + width: 28.0, + child: CircularProgressIndicator( + color: Colors.white, + ), + ), + ), + ) + : LoginInput( + style: LoginInputStyle.school, + focusNode: _focusNode, + onClear: () { + widget.controller.selectedSchool = null; + FocusScope.of(context).requestFocus(_focusNode); + }, + controller: widget.controller.textController, + ), + ); + } +} + +class SchoolInputController { + final textController = TextEditingController(); + School? selectedSchool; + List? schools; + late void Function(void Function()) update; +} diff --git a/filcnaplo_desktop_ui/lib/screens/login/school_input/school_input_tile.dart b/filcnaplo_desktop_ui/lib/screens/login/school_input/school_input_tile.dart new file mode 100644 index 0000000..81455f1 --- /dev/null +++ b/filcnaplo_desktop_ui/lib/screens/login/school_input/school_input_tile.dart @@ -0,0 +1,65 @@ +import 'package:filcnaplo_kreta_api/models/school.dart'; +import 'package:flutter/material.dart'; + +class SchoolInputTile extends StatelessWidget { + const SchoolInputTile({Key? key, required this.school, this.onTap}) + : super(key: key); + + final School school; + final Function()? onTap; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(4.0), + child: GestureDetector( + onPanDown: (e) { + onTap!(); + }, + child: InkWell( + onTapDown: (e) {}, + borderRadius: BorderRadius.circular(6.0), + child: Padding( + padding: const EdgeInsets.all(6.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // School name + Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: Text( + school.name, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontWeight: FontWeight.w600), + ), + ), + Row( + children: [ + // School id + Expanded( + child: Text( + school.instituteCode, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + // School city + Expanded( + child: Text( + school.city, + textAlign: TextAlign.right, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ], + ), + ), + ), + ), + ); + } +}