Skip to content

Commit

Permalink
search
Browse files Browse the repository at this point in the history
  • Loading branch information
niuhuan committed Jan 5, 2022
1 parent 00da4ed commit b757b51
Show file tree
Hide file tree
Showing 7 changed files with 439 additions and 72 deletions.
9 changes: 9 additions & 0 deletions lib/basic/methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ class Methods {
return ComicsResponse.fromJson(jsonDecode(rsp));
}

Future<ComicsResponse> comicSearch(String searchQuery, SortBy sortBy, int page) async {
final rsp = await _invoke("comic_search", {
"search_query": searchQuery,
"sort_by": sortBy.value,
"page": page,
});
return ComicsResponse.fromJson(jsonDecode(rsp));
}

Future<CategoriesResponse> categories() async {
return CategoriesResponse.fromJson(
jsonDecode(await _invoke("categories", "")));
Expand Down
98 changes: 56 additions & 42 deletions lib/screens/app_screen.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
import 'package:flutter/material.dart';
import 'package:jasmine/screens/browser_screen.dart';
import 'package:jasmine/screens/comic_search_screen.dart';
import 'package:jasmine/screens/components/badge.dart';
import 'package:jasmine/screens/components/floating_search_bar.dart';
import 'package:jasmine/screens/user_screen.dart';

import 'components/comic_floating_search_bar.dart';

class AppScreen extends StatefulWidget {
const AppScreen({Key? key}) : super(key: key);

@override
State<StatefulWidget> createState() => _AppScreenState();
}

class _AppScreenState extends State<AppScreen> {
class _AppScreenState extends State<AppScreen> {
final _searchBarController = FloatingSearchBarController();

late final List<AppScreenData> _screens = [
AppScreenData(
BrowserScreen(searchBarController: _searchBarController),
'浏览',
const Icon(Icons.menu_book_outlined),
const Icon(Icons.menu_book),
),
const AppScreenData(
UserScreen(),
'书架',
VersionBadged(child: Icon(Icons.image_outlined)),
VersionBadged(child: Icon(Icons.image)),
),
];

@override
void dispose() {
_pageController.dispose();
Expand All @@ -31,52 +52,45 @@ class _AppScreenState extends State<AppScreen> {

@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
allowImplicitScrolling: false,
controller: _pageController,
onPageChanged: (index) {
setState(() {
_selectedIndex = index;
});
},
children: _screens.map((e) => e.screen).toList(),
),
bottomNavigationBar: BottomNavigationBar(
items: _screens
.map((e) => BottomNavigationBarItem(
label: e.title,
icon: e.icon,
activeIcon: e.activeIcon,
))
.toList(),
currentIndex: _selectedIndex,
iconSize: 20,
selectedFontSize: 12,
unselectedFontSize: 12,
onTap: _onItemTapped,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.black.withAlpha(120),
return ComicFloatingSearchBarScreen(
onQuery: (value) {
Navigator.of(context).push(MaterialPageRoute(builder: (_) {
return ComicSearchScreen(initKeywords: value);
}));
},
controller: _searchBarController,
child: Scaffold(
body: PageView(
allowImplicitScrolling: false,
controller: _pageController,
onPageChanged: (index) {
setState(() {
_selectedIndex = index;
});
},
children: _screens.map((e) => e.screen).toList(),
),
bottomNavigationBar: BottomNavigationBar(
items: _screens
.map((e) => BottomNavigationBarItem(
label: e.title,
icon: e.icon,
activeIcon: e.activeIcon,
))
.toList(),
currentIndex: _selectedIndex,
iconSize: 20,
selectedFontSize: 12,
unselectedFontSize: 12,
onTap: _onItemTapped,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.black.withAlpha(120),
),
),
);
}
}

const List<AppScreenData> _screens = [
AppScreenData(
BrowserScreen(),
'浏览',
Icon(Icons.menu_book_outlined),
Icon(Icons.menu_book),
),
AppScreenData(
UserScreen(),
'书架',
VersionBadged(child: Icon(Icons.image_outlined)),
VersionBadged(child: Icon(Icons.image)),
),
];

class AppScreenData {
final Widget screen;
final String title;
Expand Down
51 changes: 21 additions & 30 deletions lib/screens/browser_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import 'package:jasmine/basic/commons.dart';
import 'package:jasmine/basic/methods.dart';
import 'package:jasmine/screens/components/comic_pager.dart';
import 'package:jasmine/screens/components/content_builder.dart';
import 'package:jasmine/screens/components/floating_search_bar.dart';

import 'components/browser_bottom_sheet.dart';
import 'components/actions.dart';

class BrowserScreen extends StatefulWidget {
const BrowserScreen({Key? key}) : super(key: key);
final FloatingSearchBarController searchBarController;

const BrowserScreen({Key? key, required this.searchBarController})
: super(key: key);

@override
State<StatefulWidget> createState() => _BrowserScreenState();
Expand Down Expand Up @@ -41,14 +46,21 @@ class _BrowserScreenState extends State<BrowserScreen>
_future = methods.categories();
});
},
successBuilder:
(BuildContext context, AsyncSnapshot<CategoriesResponse> snapshot) {
successBuilder: (
BuildContext context,
AsyncSnapshot<CategoriesResponse> snapshot,
) {
final categories = snapshot.requireData.categories;
return Scaffold(
appBar: AppBar(
title: const Text("浏览"),
actions: [
IconButton(onPressed: () {}, icon: const Icon(Icons.search)),
IconButton(
onPressed: () {
widget.searchBarController.display(modifyInput: "");
},
icon: const Icon(Icons.search),
),
const BrowserBottomSheetAction(),
],
),
Expand All @@ -74,7 +86,11 @@ class _BrowserScreenState extends State<BrowserScreen>
},
),
),
_buildOrderSwitch(),
buildOrderSwitch(context,_sortBy,(value){
setState(() {
_sortBy = value;
});
}),
],
),
),
Expand All @@ -95,31 +111,6 @@ class _BrowserScreenState extends State<BrowserScreen>
);
}

Widget _buildOrderSwitch() {
final iconColor = Theme.of(context).appBarTheme.iconTheme?.color;
return MaterialButton(
onPressed: () async {
final target = await chooseSortBy(context);
if (target != null) {
setState(() {
_sortBy = target;
});
}
},
child: Column(
children: [
Expanded(child: Container()),
Icon(
Icons.sort,
color: iconColor,
),
Expanded(child: Container()),
Text(_sortBy.toString(), style: TextStyle(color: iconColor)),
Expanded(child: Container()),
],
),
);
}
}

class _MTabBar extends StatefulWidget {
Expand Down
66 changes: 66 additions & 0 deletions lib/screens/comic_search_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import 'package:jasmine/basic/methods.dart';
import 'package:jasmine/screens/components/floating_search_bar.dart';

import 'components/browser_bottom_sheet.dart';
import 'components/comic_floating_search_bar.dart';
import 'components/comic_pager.dart';
import 'components/actions.dart';

class ComicSearchScreen extends StatefulWidget {
final String initKeywords;

const ComicSearchScreen({required this.initKeywords, Key? key})
: super(key: key);

@override
State<StatefulWidget> createState() => _ComicSearchScreenState();
}

class _ComicSearchScreenState extends State<ComicSearchScreen> {
final _controller = FloatingSearchBarController();
late var _keywords = widget.initKeywords;
SortBy _sortBy = sortByDefault;

@override
Widget build(BuildContext context) {
return ComicFloatingSearchBarScreen(
controller: _controller,
onQuery: (value) {
setState(() {
_keywords = value;
});
},
child: Scaffold(
appBar: AppBar(
title: Text(_keywords),
actions: [
IconButton(
onPressed: () {
_controller.display(modifyInput: _keywords);
},
icon: const Icon(Icons.search),
),
const BrowserBottomSheetAction(),
buildOrderSwitch(context, _sortBy, (value) {
setState(() {
_sortBy = value;
});
}),
],
),
body: ComicPager(
key: Key("$_keywords:$_sortBy"),
onPage: (int page) async {
final response = await methods.comicSearch(
_keywords,
_sortBy,
page,
);
return response;
},
),
),
);
}
}
31 changes: 31 additions & 0 deletions lib/screens/components/actions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:jasmine/basic/commons.dart';
import 'package:jasmine/basic/entities.dart';

Widget buildOrderSwitch(
BuildContext context,
SortBy value,
ValueChanged<SortBy> valueChanged,
) {
final iconColor = Theme.of(context).appBarTheme.iconTheme?.color;
return MaterialButton(
onPressed: () async {
final target = await chooseSortBy(context);
if (target != null) {
valueChanged(target);
}
},
child: Column(
children: [
Expanded(child: Container()),
Icon(
Icons.sort,
color: iconColor,
),
Expanded(child: Container()),
Text(value.toString(), style: TextStyle(color: iconColor)),
Expanded(child: Container()),
],
),
);
}
39 changes: 39 additions & 0 deletions lib/screens/components/comic_floating_search_bar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:flutter/material.dart';

import '../comic_search_screen.dart';
import 'floating_search_bar.dart';

class ComicFloatingSearchBarScreen extends StatefulWidget {
final FloatingSearchBarController controller;
final Widget child;
final ValueChanged<String>? onQuery;

const ComicFloatingSearchBarScreen({
Key? key,
required this.controller,
required this.child,
this.onQuery,
}) : super(key: key);

@override
State<StatefulWidget> createState() => _ComicFloatingSearchBarScreenState();
}

class _ComicFloatingSearchBarScreenState
extends State<ComicFloatingSearchBarScreen> {
@override
Widget build(BuildContext context) {
return FloatingSearchBarScreen(
controller: widget.controller,
child: widget.child,
onSubmitted: _onSubmitted,
);
}

void _onSubmitted(String value) {
widget.controller.hide();
if (value.isNotEmpty && widget.onQuery != null) {
widget.onQuery!(value);
}
}
}
Loading

0 comments on commit b757b51

Please sign in to comment.