Skip to content

Commit b6c1c9e

Browse files
committed
没有任何软用的搜索
1 parent 4f51556 commit b6c1c9e

12 files changed

+194
-23
lines changed

lib/models/search_data.dart

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class SearchData {
2+
SearchData({
3+
required this.matchTitle,
4+
required this.matchContent,
5+
this.title,
6+
this.contentMatched,
7+
});
8+
9+
final bool matchTitle;
10+
final bool matchContent;
11+
12+
final String? title;
13+
final List<String>? contentMatched;
14+
}

lib/ui/home.dart

+3-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:miofeed/controllers/navigator_controller.dart';
44
import 'package:miofeed/models/universal_feed.dart';
55
import 'package:miofeed/models/universal_item.dart';
66
import 'package:miofeed/tasks/subscribe_update.dart';
7+
import 'package:miofeed/ui/models/search_dialog.dart';
78
import 'package:miofeed/ui/paragraph.dart';
89
import 'package:miofeed/utils/after_layout.dart';
910
import 'package:miofeed/utils/paragraph_utils.dart';
@@ -38,15 +39,7 @@ class HomeUI extends StatelessWidget {
3839
),
3940
IconButton(
4041
onPressed: () async {
41-
Get.dialog(
42-
const SimpleDialog(
43-
children: [
44-
Center(
45-
child: Text('Comming soon'),
46-
)
47-
],
48-
),
49-
);
42+
Get.dialog(searchDialog(context));
5043
},
5144
icon: const Icon(Icons.search),
5245
)
@@ -161,7 +154,7 @@ class HomeUI extends StatelessWidget {
161154
),
162155
),
163156
),
164-
bottomNavigationBar: NavigationBarX().build(),
157+
bottomNavigationBar: navigationBar(),
165158
);
166159
}
167160

lib/ui/models/navigation_bar.dart

+5-7
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ import 'package:get/get.dart';
33

44
import '../../controllers/navigator_controller.dart';
55

6-
class NavigationBarX {
7-
final NavigatorController nctr = Get.put(NavigatorController());
6+
final NavigatorController _nCtr = Get.put(NavigatorController());
87

9-
build() => NavigationBar(
10-
selectedIndex: nctr.currentPage.value,
8+
navigationBar() => NavigationBar(
9+
selectedIndex: _nCtr.currentPage.value,
1110
onDestinationSelected: (index) async {
12-
nctr.currentPage.value = index;
13-
nctr.subCurrentPage.value = 0;
11+
_nCtr.currentPage.value = index;
12+
_nCtr.subCurrentPage.value = 0;
1413
switch (index) {
1514
case 0:
1615
// 首页
@@ -26,4 +25,3 @@ class NavigationBarX {
2625
NavigationDestination(icon: Icon(Icons.settings), label: "设置"),
2726
],
2827
);
29-
}

lib/ui/models/search_dialog.dart

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_markdown/flutter_markdown.dart';
3+
import 'package:get/get.dart';
4+
import 'package:miofeed/models/search_data.dart';
5+
import 'package:miofeed/models/universal_item.dart';
6+
import 'package:miofeed/utils/rss/rss_utils.dart';
7+
8+
searchDialog(BuildContext context) {
9+
final controller = Get.put(_SearchController());
10+
final dataParagraph = RssUtils.allRssParagraph;
11+
controller.searchData.clear();
12+
return SimpleDialog(
13+
children: [
14+
Container(
15+
margin: const EdgeInsets.symmetric(horizontal: 10),
16+
child: Column(
17+
children: [
18+
SearchBar(
19+
onChanged: (value) async {
20+
controller.hasSearch.value = true;
21+
controller.searchData.clear();
22+
if (value != '') {
23+
for (var paraData in dataParagraph) {
24+
final UniversalItem item = paraData['item'];
25+
final String title = item.title;
26+
final String description = item.content
27+
.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ' ')
28+
.replaceAll(RegExp(r'\n{2,}'), ' ')
29+
.replaceAll(RegExp(r'\r{2,}'), ' ')
30+
.replaceAll(RegExp(r' {2,}'), ' ')
31+
.trim();
32+
bool matchTitle = false;
33+
String? outputTitle;
34+
bool matchContent = false;
35+
List<String>? outputContent;
36+
if (title.contains(value)) {
37+
matchTitle = true;
38+
outputTitle = title.replaceAll(value, " **$value** ");
39+
print(outputTitle);
40+
}
41+
42+
if (description.contains(value)) {
43+
matchContent = true;
44+
// 使用正则表达式匹配 value
45+
RegExp regExp = RegExp(
46+
'(.{0,17}$value.{0,17})',
47+
unicode: true, // 确保处理中文字符
48+
);
49+
description.replaceAll(value, " **$value** ");
50+
Iterable<RegExpMatch> matches =
51+
regExp.allMatches(description);
52+
outputContent = [];
53+
for (var match in matches) {
54+
if (match.group(0) != null) {
55+
outputContent.add(match.group(0)!);
56+
}
57+
}
58+
print(outputContent);
59+
controller.searchData.add(
60+
SearchData(
61+
matchTitle: matchTitle,
62+
matchContent: matchContent,
63+
title: outputTitle,
64+
contentMatched: outputContent,
65+
),
66+
);
67+
}
68+
}
69+
print(controller.searchData.length);
70+
} else {
71+
controller.hasSearch.value = false;
72+
controller.searchData.clear();
73+
}
74+
},
75+
),
76+
SizedBox(
77+
width: MediaQuery.of(context).size.width - 20,
78+
height: MediaQuery.of(context).size.height - 20,
79+
child: Obx(
80+
() => controller.hasSearch.value
81+
? ListView.builder(
82+
itemCount: controller.searchData.length,
83+
itemBuilder: (BuildContext context, int i) {
84+
final item = controller.searchData[i];
85+
List<Widget> contents = [];
86+
87+
if (item.matchContent) {
88+
for (var c in item.contentMatched!) {
89+
contents.add(MarkdownBody(data: c));
90+
}
91+
}
92+
93+
return controller.searchData.isNotEmpty
94+
? item.matchTitle
95+
? ListTile(
96+
title: MarkdownBody(data: item.title!),
97+
subtitle: contents.isNotEmpty
98+
? Column(
99+
crossAxisAlignment:
100+
CrossAxisAlignment.start,
101+
children: contents,
102+
)
103+
: null,
104+
)
105+
: ListTile(
106+
title: contents.isNotEmpty
107+
? Column(
108+
crossAxisAlignment:
109+
CrossAxisAlignment.start,
110+
children: contents,
111+
)
112+
: null,
113+
)
114+
: Center(
115+
child: Container(
116+
margin: const EdgeInsets.only(top: 40),
117+
child: const Text('什么也没搜到...'),
118+
),
119+
);
120+
})
121+
: Center(
122+
child: Container(
123+
margin: const EdgeInsets.only(top: 40),
124+
child: const Text('来搜点什么吧...'),
125+
),
126+
),
127+
// child: ListView(
128+
// children: [
129+
// Center(
130+
// child: Container(
131+
// margin: const EdgeInsets.only(top: 40),
132+
// child: const Text('来搜点什么吧...'),
133+
// ),
134+
// )
135+
// ],
136+
// ),
137+
),
138+
),
139+
],
140+
),
141+
),
142+
],
143+
);
144+
}
145+
146+
class _SearchController extends GetxController {
147+
var hasSearch = false.obs;
148+
var searchData = <SearchData>[].obs;
149+
}

lib/ui/paragraph.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class ParagraphUI extends StatelessWidget {
162162
),
163163
],
164164
),
165-
bottomNavigationBar: NavigationBarX().build(),
165+
bottomNavigationBar: navigationBar(),
166166
);
167167
}
168168

lib/ui/settings.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class SettingsUI extends StatelessWidget {
6868
),
6969
],
7070
),
71-
bottomNavigationBar: NavigationBarX().build(),
71+
bottomNavigationBar: navigationBar(),
7272
);
7373
}
7474
}

lib/ui/settings/about.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class AboutUI extends StatelessWidget {
7272
),
7373
],
7474
),
75-
bottomNavigationBar: NavigationBarX().build(),
75+
bottomNavigationBar: navigationBar(),
7676
);
7777
}
7878
}

lib/ui/settings/render.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class RenderSettingUI extends StatelessWidget {
2727
body: const Center(
2828
child: Text('Coming soon'),
2929
),
30-
bottomNavigationBar: NavigationBarX().build(),
30+
bottomNavigationBar: navigationBar(),
3131
);
3232
}
3333
}

lib/ui/settings/rss_subscribe.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class _RssSubSettingState extends State<RssSubSettingUI> {
7474
),
7575
],
7676
),
77-
bottomNavigationBar: NavigationBarX().build(),
77+
bottomNavigationBar: navigationBar(),
7878
);
7979
}
8080
}

lib/ui/settings/theme.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class ThemeSettingUI extends StatelessWidget {
120120
],
121121
),
122122
),
123-
bottomNavigationBar: NavigationBarX().build(),
123+
bottomNavigationBar: navigationBar(),
124124
);
125125
}
126126

pubspec.lock

+16
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,14 @@ packages:
254254
url: "https://pub.dev"
255255
source: hosted
256256
version: "4.0.0"
257+
flutter_markdown:
258+
dependency: "direct main"
259+
description:
260+
name: flutter_markdown
261+
sha256: a23c41ee57573e62fc2190a1f36a0480c4d90bde3a8a8d7126e5d5992fb53fb7
262+
url: "https://pub.dev"
263+
source: hosted
264+
version: "0.7.3+1"
257265
flutter_svg:
258266
dependency: transitive
259267
description:
@@ -456,6 +464,14 @@ packages:
456464
url: "https://pub.dev"
457465
source: hosted
458466
version: "1.2.0"
467+
markdown:
468+
dependency: transitive
469+
description:
470+
name: markdown
471+
sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
472+
url: "https://pub.dev"
473+
source: hosted
474+
version: "7.2.2"
459475
matcher:
460476
dependency: transitive
461477
description:

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ dependencies:
4848
dynamic_color: ^1.7.0
4949
background_fetch: ^1.3.5
5050
package_info_plus: ^8.0.2
51+
flutter_markdown: ^0.7.3+1
5152

5253
dev_dependencies:
5354
flutter_test:

0 commit comments

Comments
 (0)