Skip to content

Commit b79a79b

Browse files
committed
feat: 平板布局
1 parent dea59c8 commit b79a79b

File tree

5 files changed

+272
-171
lines changed

5 files changed

+272
-171
lines changed

lib/pages/detail/view.dart

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:miru_app/pages/detail/widgets/detail_extension_tile.dart';
1414
import 'package:miru_app/pages/detail/widgets/detail_favorite_button.dart';
1515
import 'package:miru_app/pages/detail/widgets/detail_overview.dart';
1616
import 'package:miru_app/utils/i18n.dart';
17+
import 'package:miru_app/utils/layout.dart';
1718
import 'package:miru_app/widgets/cache_network_image.dart';
1819
import 'package:miru_app/widgets/card_tile.dart';
1920
import 'package:miru_app/widgets/platform_widget.dart';
@@ -71,8 +72,14 @@ class _DetailPageState extends State<DetailPage> {
7172
child: Text(c.error.value),
7273
);
7374
}
74-
return DefaultTabController(
75-
length: 3,
75+
final tabs = [
76+
if (!LayoutUtils.isTablet) Tab(text: episodesString),
77+
Tab(text: 'detail.overview'.i18n),
78+
if (c.type == ExtensionType.bangumi) Tab(text: 'detail.cast'.i18n),
79+
];
80+
81+
final content = DefaultTabController(
82+
length: tabs.length,
7683
child: NestedScrollView(
7784
controller: c.scrollController,
7885
headerSliverBuilder:
@@ -89,12 +96,7 @@ class _DetailPageState extends State<DetailPage> {
8996
),
9097
flexibleSpace: const DetailAppbarflexibleSpace(),
9198
bottom: TabBar(
92-
tabs: [
93-
Tab(text: episodesString),
94-
Tab(text: 'detail.overview'.i18n),
95-
if (c.type == ExtensionType.bangumi)
96-
Tab(text: 'detail.cast'.i18n),
97-
],
99+
tabs: tabs,
98100
),
99101
actions: [
100102
IconButton(
@@ -117,52 +119,64 @@ class _DetailPageState extends State<DetailPage> {
117119
padding: const EdgeInsets.all(8),
118120
child: TabBarView(
119121
children: [
120-
const DetailEpisodes(),
122+
if (!LayoutUtils.isTablet) const DetailEpisodes(),
121123
const DetailOverView(),
122-
Obx(() {
123-
if (c.tmdbDetail == null || c.tmdbDetail!.casts.isEmpty) {
124-
return const SizedBox();
125-
}
126-
return ListView.builder(
127-
padding: const EdgeInsets.all(0),
128-
itemBuilder: (context, index) {
129-
final cast = c.tmdbDetail!.casts[index];
130-
late String url = '';
131-
if (cast.profilePath != null) {
132-
url = TmdbApi.getImageUrl(cast.profilePath!) ?? '';
133-
}
124+
if (c.type == ExtensionType.bangumi)
125+
Obx(() {
126+
if (c.tmdbDetail == null || c.tmdbDetail!.casts.isEmpty) {
127+
return const SizedBox();
128+
}
129+
return ListView.builder(
130+
padding: const EdgeInsets.all(0),
131+
itemBuilder: (context, index) {
132+
final cast = c.tmdbDetail!.casts[index];
133+
late String url = '';
134+
if (cast.profilePath != null) {
135+
url = TmdbApi.getImageUrl(cast.profilePath!) ?? '';
136+
}
134137

135-
return ListTile(
136-
leading: Container(
137-
decoration: const BoxDecoration(
138-
shape: BoxShape.circle,
139-
),
140-
clipBehavior: Clip.antiAlias,
141-
child: CacheNetWorkImage(
142-
url,
143-
width: 50,
144-
height: 50,
145-
),
146-
),
147-
title: Text(cast.name),
148-
subtitle: Text(cast.character),
149-
onTap: () {
150-
launchUrl(
151-
Uri.parse(
152-
"https://www.themoviedb.org/person/${cast.id}",
138+
return ListTile(
139+
leading: Container(
140+
decoration: const BoxDecoration(
141+
shape: BoxShape.circle,
153142
),
154-
);
155-
},
156-
);
157-
},
158-
itemCount: c.tmdbDetail!.casts.length,
159-
);
160-
}),
143+
clipBehavior: Clip.antiAlias,
144+
child: CacheNetWorkImage(
145+
url,
146+
width: 50,
147+
height: 50,
148+
),
149+
),
150+
title: Text(cast.name),
151+
subtitle: Text(cast.character),
152+
onTap: () {
153+
launchUrl(
154+
Uri.parse(
155+
"https://www.themoviedb.org/person/${cast.id}",
156+
),
157+
);
158+
},
159+
);
160+
},
161+
itemCount: c.tmdbDetail!.casts.length,
162+
);
163+
}),
161164
],
162165
),
163166
),
164167
),
165168
);
169+
if (LayoutUtils.isTablet) {
170+
return Row(
171+
children: [
172+
Expanded(child: content),
173+
const Expanded(
174+
child: SafeArea(child: DetailEpisodes()),
175+
),
176+
],
177+
);
178+
}
179+
return content;
166180
}),
167181
);
168182
}

lib/pages/extension_settings/view.dart

Lines changed: 129 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:miru_app/router/router.dart';
1111
import 'package:miru_app/utils/database.dart';
1212
import 'package:miru_app/utils/extension.dart';
1313
import 'package:miru_app/utils/i18n.dart';
14+
import 'package:miru_app/utils/layout.dart';
1415
import 'package:miru_app/widgets/cache_network_image.dart';
1516
import 'package:miru_app/widgets/card_tile.dart';
1617
import 'package:miru_app/widgets/messenger.dart';
@@ -138,103 +139,101 @@ class _ExtensionSettingsPageState extends State<ExtensionSettingsPage> {
138139
);
139140
}
140141
final extension = c.runtime.value!.extension;
141-
return Scaffold(
142-
appBar: AppBar(
143-
title: Text('extension-info.title'.i18n),
144-
),
145-
body: SingleChildScrollView(
146-
child: Column(
147-
children: [
148-
const SizedBox(height: 30),
149-
Center(
150-
child: Container(
151-
height: 100,
152-
width: 100,
153-
decoration: BoxDecoration(
154-
borderRadius: BorderRadius.circular(10),
155-
),
156-
clipBehavior: Clip.antiAlias,
157-
child: CacheNetWorkImage(
158-
extension.icon ?? '',
159-
fit: BoxFit.contain,
160-
),
142+
143+
final content = SingleChildScrollView(
144+
child: Column(
145+
children: [
146+
const SizedBox(height: 30),
147+
Center(
148+
child: Container(
149+
height: 100,
150+
width: 100,
151+
decoration: BoxDecoration(
152+
borderRadius: BorderRadius.circular(10),
153+
),
154+
clipBehavior: Clip.antiAlias,
155+
child: CacheNetWorkImage(
156+
extension.icon ?? '',
157+
fit: BoxFit.contain,
161158
),
162159
),
163-
const SizedBox(height: 16),
164-
Text(
165-
extension.name,
166-
style: Theme.of(context).textTheme.titleLarge,
167-
),
168-
Text(
169-
extension.package,
170-
style: Theme.of(context).textTheme.bodySmall,
171-
),
172-
const SizedBox(height: 30),
173-
Padding(
174-
padding: const EdgeInsets.symmetric(horizontal: 16),
175-
child: GridView(
176-
shrinkWrap: true,
177-
physics: const NeverScrollableScrollPhysics(),
178-
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
179-
crossAxisCount: 2,
180-
childAspectRatio: 3,
181-
crossAxisSpacing: 2,
182-
mainAxisSpacing: 8,
183-
),
184-
children: [
185-
InfoCard(
186-
icon: Icons.person,
187-
title: 'extension-info.author'.i18n,
188-
content: extension.author,
189-
),
190-
InfoCard(
191-
icon: Icons.info,
192-
title: 'extension-info.version'.i18n,
193-
content: extension.version,
194-
),
195-
InfoCard(
196-
icon: Icons.language,
197-
title: 'extension-info.language'.i18n,
198-
content: extension.lang,
199-
),
200-
InfoCard(
201-
icon: Icons.description,
202-
title: 'extension-info.license'.i18n,
203-
content: extension.license,
204-
),
205-
InfoCard(
206-
icon: Icons.link,
207-
title: 'extension-info.original-site'.i18n,
208-
content: extension.webSite,
209-
),
210-
],
160+
),
161+
const SizedBox(height: 16),
162+
Text(
163+
extension.name,
164+
style: Theme.of(context).textTheme.titleLarge,
165+
),
166+
Text(
167+
extension.package,
168+
style: Theme.of(context).textTheme.bodySmall,
169+
),
170+
const SizedBox(height: 30),
171+
Padding(
172+
padding: const EdgeInsets.symmetric(horizontal: 16),
173+
child: GridView(
174+
shrinkWrap: true,
175+
physics: const NeverScrollableScrollPhysics(),
176+
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
177+
crossAxisCount: 2,
178+
childAspectRatio: 3,
179+
crossAxisSpacing: 2,
180+
mainAxisSpacing: 8,
211181
),
182+
children: [
183+
InfoCard(
184+
icon: Icons.person,
185+
title: 'extension-info.author'.i18n,
186+
content: extension.author,
187+
),
188+
InfoCard(
189+
icon: Icons.info,
190+
title: 'extension-info.version'.i18n,
191+
content: extension.version,
192+
),
193+
InfoCard(
194+
icon: Icons.language,
195+
title: 'extension-info.language'.i18n,
196+
content: extension.lang,
197+
),
198+
InfoCard(
199+
icon: Icons.description,
200+
title: 'extension-info.license'.i18n,
201+
content: extension.license,
202+
),
203+
InfoCard(
204+
icon: Icons.link,
205+
title: 'extension-info.original-site'.i18n,
206+
content: extension.webSite,
207+
),
208+
],
212209
),
213-
Padding(
214-
padding: const EdgeInsets.all(16),
215-
child: Row(
216-
children: [
217-
Expanded(
218-
child: OutlinedButton(
219-
onPressed: () async {
220-
await ExtensionUtils.uninstall(extension.package);
221-
Get.back();
222-
},
223-
child: Text('common.uninstall'.i18n),
224-
),
210+
),
211+
Padding(
212+
padding: const EdgeInsets.all(16),
213+
child: Row(
214+
children: [
215+
Expanded(
216+
child: OutlinedButton(
217+
onPressed: () async {
218+
await ExtensionUtils.uninstall(extension.package);
219+
Get.back();
220+
},
221+
child: Text('common.uninstall'.i18n),
225222
),
226-
const SizedBox(width: 16),
227-
Expanded(
228-
child: FilledButton(
229-
onPressed: () {
230-
Get.to(CodeEditPage(extension: extension));
231-
},
232-
child: Text('extension.edit-code'.i18n),
233-
),
234-
)
235-
],
236-
),
223+
),
224+
const SizedBox(width: 16),
225+
Expanded(
226+
child: FilledButton(
227+
onPressed: () {
228+
Get.to(CodeEditPage(extension: extension));
229+
},
230+
child: Text('extension.edit-code'.i18n),
231+
),
232+
)
233+
],
237234
),
235+
),
236+
if (!LayoutUtils.isTablet) ...[
238237
const Divider(),
239238
SettingsTile(
240239
title: 'cookie-clean.title'.i18n,
@@ -251,10 +250,47 @@ class _ExtensionSettingsPageState extends State<ExtensionSettingsPage> {
251250
),
252251
),
253252
...settingsContent(),
254-
],
255-
),
253+
]
254+
],
256255
),
257256
);
257+
258+
return Scaffold(
259+
appBar: AppBar(
260+
title: Text('extension-info.title'.i18n),
261+
),
262+
body: LayoutUtils.isTablet
263+
? Row(
264+
crossAxisAlignment: CrossAxisAlignment.start,
265+
children: [
266+
Expanded(child: content),
267+
Expanded(
268+
child: SingleChildScrollView(
269+
child: Column(
270+
children: [
271+
SettingsTile(
272+
title: 'cookie-clean.title'.i18n,
273+
buildSubtitle: () => 'cookie-clean.subtitle'.i18n,
274+
trailing: TextButton(
275+
child: Text('cookie-clean.clean'.i18n),
276+
onPressed: () {
277+
c.runtime.value!.cleanCookie();
278+
showPlatformSnackbar(
279+
context: context,
280+
content: 'cookie-clean.success'.i18n,
281+
);
282+
},
283+
),
284+
),
285+
...settingsContent(),
286+
],
287+
),
288+
),
289+
),
290+
],
291+
)
292+
: content,
293+
);
258294
});
259295
}
260296

0 commit comments

Comments
 (0)