Skip to content

Commit a0044ce

Browse files
committed
文章渲染设置,将 progressbar 设置为 private
1 parent d9d7ec9 commit a0044ce

File tree

9 files changed

+283
-165
lines changed

9 files changed

+283
-165
lines changed

lib/storages/settings_storage.dart

+14-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'package:shared_preferences/shared_preferences.dart';
33
class SettingsStorage {
44
final _instance = SharedPreferences.getInstance();
55

6+
// 主题配置
67
/// 主题模式
78
/// [value] [0..2] => System,Light,Dark
89
void setThemeMode(int value) async {
@@ -12,24 +13,27 @@ class SettingsStorage {
1213
case 2:
1314
(await _instance).setInt(_MAP.THEME_MODE, value);
1415
default:
15-
throw UnsupportedError(
16-
'Invalid input! Expected [0..2], but got $value!');
16+
throw UnsupportedError('Invalid input! Expected [0..2], but got $value!');
1717
}
1818
}
19-
20-
Future<int?> getThemeMode() async =>
21-
(await _instance).getInt(_MAP.THEME_MODE);
19+
Future<int?> getThemeMode() async => (await _instance).getInt(_MAP.THEME_MODE);
2220

2321
/// Monet 取色开关
24-
void setThemeMonet(bool value) async {
25-
(await _instance).setBool(_MAP.THEME_MONET, value);
26-
}
22+
void setThemeMonet(bool value) async => (await _instance).setBool(_MAP.THEME_MONET, value);
23+
Future<bool?> getThemeMonet() async => (await _instance).getBool(_MAP.THEME_MONET);
2724

28-
Future<bool?> getThemeMonet() async =>
29-
(await _instance).getBool(_MAP.THEME_MONET);
25+
// 渲染配置
26+
/// 限制最大渲染宽度
27+
void setRenderLimitWidth(bool value) async => (await _instance).setBool(_MAP.RENDER_LIMIT_WIDTH, value);
28+
Future<bool?> getRenderLimitWidth() async => (await _instance).getBool(_MAP.RENDER_LIMIT_WIDTH);
29+
void setRenderLimitWidthValue(double value) async => (await _instance).setDouble(_MAP.RENDER_LIMIT_WIDTH_VALUE, value);
30+
Future<double?> getRenderLimitWidthValue() async => (await _instance).getDouble(_MAP.RENDER_LIMIT_WIDTH_VALUE);
3031
}
3132

3233
class _MAP {
3334
static const THEME_MODE = 'settings@theme.mode';
3435
static const THEME_MONET = 'settings@theme.monet';
36+
37+
static const RENDER_LIMIT_WIDTH = 'settings@render.limit-width';
38+
static const RENDER_LIMIT_WIDTH_VALUE = 'settings@render.limit-width.value';
3539
}

lib/ui/home.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class HomeUI extends StatelessWidget {
1919
final String title;
2020

2121
final NavigatorController nctr = Get.put(NavigatorController());
22-
final ProgressbarController progressbar = Get.find();
22+
final ProgressbarController _progressbar = Get.find();
2323

2424
@override
2525
Widget build(BuildContext context) {
@@ -31,9 +31,9 @@ class HomeUI extends StatelessWidget {
3131
actions: [
3232
IconButton(
3333
onPressed: () async {
34-
progressbar.start();
34+
_progressbar.start();
3535
await SubscribeUpdateTask.run();
36-
progressbar.finish();
36+
_progressbar.finish();
3737
},
3838
icon: const Icon(Icons.refresh),
3939
),
@@ -50,7 +50,7 @@ class HomeUI extends StatelessWidget {
5050
child: SizedBox(
5151
width: MediaQuery.of(context).size.width,
5252
height: 3,
53-
child: Obx(() => progressbar.widget.value),
53+
child: Obx(() => _progressbar.widget.value),
5454
),
5555
),
5656
),

lib/ui/paragraph.dart

+159-124
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import 'package:miofeed/controllers/progressbar_controller.dart';
55
import 'package:miofeed/main.dart';
66
import 'package:miofeed/models/universal_feed.dart';
77
import 'package:miofeed/models/universal_item.dart';
8+
import 'package:miofeed/storages/settings_storage.dart';
89
import 'package:miofeed/ui/models/navigation_bar.dart';
910
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
11+
import 'package:miofeed/utils/after_layout.dart';
1012
import 'package:share_plus/share_plus.dart';
1113
import 'package:url_launcher/url_launcher.dart';
1214

@@ -24,145 +26,161 @@ class ParagraphUI extends StatelessWidget {
2426
final UniversalItem data;
2527
final UniversalFeed parent;
2628

27-
final ProgressbarController progressbar = Get.find();
29+
final ProgressbarController _progressbar = Get.find();
30+
final _ParagraphUIController _ctr = Get.put(_ParagraphUIController());
2831

2932
@override
3033
Widget build(BuildContext context) {
3134
final dateFormatter = DateFormat('yyyy-MM-dd HH:mm:ss');
32-
return Scaffold(
33-
appBar: AppBar(
34-
title: Text(
35-
'$title - ${data.title.length < 7 ? data.title : '${data.title.substring(0, 7)}...'}'),
36-
bottom: PreferredSize(
37-
preferredSize: Size(MediaQuery.of(context).size.width, 3),
38-
child: SizedBox(
39-
width: MediaQuery.of(context).size.width,
40-
height: 3,
41-
child: Obx(() => progressbar.widget.value),
35+
return AfterLayout(
36+
callback: (RenderAfterLayout ral) {
37+
_ctr.load();
38+
},
39+
child: Scaffold(
40+
appBar: AppBar(
41+
title: Text(
42+
'$title - ${data.title.length < 7 ? data.title : '${data.title.substring(0, 7)}...'}'),
43+
bottom: PreferredSize(
44+
preferredSize: Size(MediaQuery.of(context).size.width, 3),
45+
child: SizedBox(
46+
width: MediaQuery.of(context).size.width,
47+
height: 3,
48+
child: Obx(() => _progressbar.widget.value),
49+
),
4250
),
4351
),
44-
),
45-
body: ListView(
46-
children: [
47-
Container(
48-
margin: const EdgeInsets.all(20),
49-
child: Column(
50-
crossAxisAlignment: CrossAxisAlignment.start,
51-
children: [
52-
Text(
53-
data.title,
54-
style: const TextStyle(fontSize: 30),
55-
),
56-
Row(
57-
children: [
58-
Container(
59-
margin: const EdgeInsets.only(right: 5),
60-
child: ClipRRect(
61-
borderRadius: BorderRadius.circular(5),
62-
child: SizedBox(
63-
width: 20,
64-
height: 20,
65-
child: parent.icon.isNotEmpty
66-
? Image.network(
67-
parent.icon,
68-
errorBuilder: (
69-
context,
70-
error,
71-
stackTrace,
72-
) {
73-
return ParagraphUtils.buildColorIcon(
74-
parent.title);
75-
},
76-
)
77-
: ParagraphUtils.buildColorIcon(parent.title)),
52+
body: ListView(
53+
children: [
54+
Container(
55+
margin: const EdgeInsets.all(20),
56+
child: Column(
57+
crossAxisAlignment: CrossAxisAlignment.start,
58+
children: [
59+
Text(
60+
data.title,
61+
style: const TextStyle(fontSize: 30),
62+
),
63+
Row(
64+
children: [
65+
Container(
66+
margin: const EdgeInsets.only(right: 5),
67+
child: ClipRRect(
68+
borderRadius: BorderRadius.circular(5),
69+
child: SizedBox(
70+
width: 20,
71+
height: 20,
72+
child: parent.icon.isNotEmpty
73+
? Image.network(
74+
parent.icon,
75+
errorBuilder: (
76+
context,
77+
error,
78+
stackTrace,
79+
) {
80+
return ParagraphUtils.buildColorIcon(
81+
parent.title);
82+
},
83+
)
84+
: ParagraphUtils.buildColorIcon(
85+
parent.title)),
86+
),
7887
),
79-
),
80-
Text(
81-
'${parent.title} | ${data.publishTime != null ? dateFormatter.format(data.publishTime!) : '未知'}'),
82-
],
83-
),
84-
Container(
85-
margin: const EdgeInsets.only(bottom: 5),
86-
),
87-
Row(
88-
children: [
89-
const Icon(
90-
Icons.supervised_user_circle,
91-
size: 18,
92-
),
93-
Container(
94-
margin: const EdgeInsets.only(left: 5),
95-
child: Text(_buildAuthorText()),
96-
),
97-
],
98-
),
99-
_buildLabels(data.categories ?? []),
100-
],
88+
Expanded(
89+
child: Text(
90+
'${parent.title} | ${data.publishTime != null ? dateFormatter.format(data.publishTime!) : '未知'}',
91+
),
92+
),
93+
],
94+
),
95+
Container(
96+
margin: const EdgeInsets.only(bottom: 5),
97+
),
98+
Row(
99+
children: [
100+
const Icon(
101+
Icons.supervised_user_circle,
102+
size: 18,
103+
),
104+
Container(
105+
margin: const EdgeInsets.only(left: 5),
106+
child: Text(_buildAuthorText()),
107+
),
108+
],
109+
),
110+
_buildLabels(data.categories ?? []),
111+
],
112+
),
101113
),
102-
),
103-
const Divider(),
104-
Container(
105-
margin: const EdgeInsets.all(25),
106-
child: Column(
107-
children: [
108-
SelectionArea(
109-
child: HtmlWidget(
110-
data.content,
111-
onTapUrl: (url) => launchUrl(Uri.parse(url)),
114+
const Divider(),
115+
Container(
116+
margin: const EdgeInsets.all(25),
117+
child: Column(
118+
children: [
119+
SelectionArea(
120+
child: Obx(() => SizedBox(
121+
width: _ctr.renderLimitWidth.value
122+
? MediaQuery.of(context).size.width -
123+
_ctr.renderLimitWidthValue.value
124+
: null,
125+
child: HtmlWidget(
126+
data.content,
127+
onTapUrl: (url) => launchUrl(Uri.parse(url)),
128+
),
129+
)),
112130
),
113-
),
114-
],
131+
],
132+
),
115133
),
116-
),
117-
const Divider(),
118-
Container(
119-
margin: const EdgeInsets.all(25),
120-
child: Column(
121-
crossAxisAlignment: CrossAxisAlignment.start,
122-
children: [
123-
Container(
124-
margin: const EdgeInsets.only(bottom: 20),
125-
child: Column(
134+
const Divider(),
135+
Container(
136+
margin: const EdgeInsets.all(25),
137+
child: Column(
138+
crossAxisAlignment: CrossAxisAlignment.start,
139+
children: [
140+
Container(
141+
margin: const EdgeInsets.only(bottom: 20),
142+
child: Column(
143+
children: [
144+
Text(
145+
'发布时间: ${data.publishTime != null ? dateFormatter.format(data.publishTime!) : '未知'}'),
146+
Text(
147+
'更新时间: ${data.updateTime != null ? dateFormatter.format(data.publishTime!) : '未知'}'),
148+
if (data.generator != null)
149+
Text('Generated by ${data.generator}')
150+
],
151+
),
152+
),
153+
Row(
126154
children: [
127-
Text(
128-
'发布时间: ${data.publishTime != null ? dateFormatter.format(data.publishTime!) : '未知'}'),
129-
Text(
130-
'更新时间: ${data.updateTime != null ? dateFormatter.format(data.publishTime!) : '未知'}'),
131-
if (data.generator != null)
132-
Text('Generated by ${data.generator}')
155+
IconButton(
156+
iconSize: 30,
157+
icon: const Icon(Icons.link),
158+
onPressed: data.link != null
159+
? () {
160+
launchUrl(Uri.parse(data.link!));
161+
}
162+
: null,
163+
tooltip: '访问网站',
164+
),
165+
IconButton(
166+
iconSize: 30,
167+
icon: const Icon(Icons.share),
168+
onPressed: data.link != null
169+
? () {
170+
Share.share('${data.title} - ${data.link!}');
171+
}
172+
: null,
173+
tooltip: '分享',
174+
),
133175
],
134176
),
135-
),
136-
Row(
137-
children: [
138-
IconButton(
139-
iconSize: 30,
140-
icon: const Icon(Icons.link),
141-
onPressed: data.link != null
142-
? () {
143-
launchUrl(Uri.parse(data.link!));
144-
}
145-
: null,
146-
tooltip: '访问网站',
147-
),
148-
IconButton(
149-
iconSize: 30,
150-
icon: const Icon(Icons.share),
151-
onPressed: data.link != null
152-
? () {
153-
Share.share('${data.title} - ${data.link!}');
154-
}
155-
: null,
156-
tooltip: '分享',
157-
),
158-
],
159-
),
160-
],
177+
],
178+
),
161179
),
162-
),
163-
],
180+
],
181+
),
182+
bottomNavigationBar: navigationBar(),
164183
),
165-
bottomNavigationBar: navigationBar(),
166184
);
167185
}
168186

@@ -205,3 +223,20 @@ class ParagraphUI extends StatelessWidget {
205223
);
206224
}
207225
}
226+
227+
class _ParagraphUIController extends GetxController {
228+
final _settings = SettingsStorage();
229+
230+
var renderLimitWidth = false.obs;
231+
RxDouble renderLimitWidthValue = 0.0.obs;
232+
233+
load() async {
234+
await _initValues();
235+
}
236+
237+
_initValues() async {
238+
renderLimitWidth.value = await _settings.getRenderLimitWidth() ?? false;
239+
renderLimitWidthValue.value =
240+
await _settings.getRenderLimitWidthValue() ?? 0.0;
241+
}
242+
}

0 commit comments

Comments
 (0)