Skip to content

Commit 2fe6ba6

Browse files
committed
update audio ui
1 parent 8147caa commit 2fe6ba6

3 files changed

Lines changed: 175 additions & 58 deletions

File tree

lib/pages/player/audio.dart

Lines changed: 159 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,37 @@ import 'package:iris/models/file.dart';
66
import 'package:iris/models/storages/storage.dart';
77
import 'package:iris/store/use_storage_store.dart';
88

9+
class _CoverImage extends StatelessWidget {
10+
final FileItem cover;
11+
final String? auth;
12+
final BoxFit fit;
13+
14+
const _CoverImage({
15+
required this.cover,
16+
required this.auth,
17+
required this.fit,
18+
});
19+
20+
@override
21+
Widget build(BuildContext context) {
22+
final isLocal = cover.storageId == localStorageId;
23+
if (isLocal) {
24+
return Image.file(
25+
File(cover.uri),
26+
fit: fit,
27+
gaplessPlayback: true,
28+
);
29+
} else {
30+
return Image.network(
31+
cover.uri,
32+
headers: auth != null ? {'authorization': auth!} : null,
33+
fit: fit,
34+
gaplessPlayback: true,
35+
);
36+
}
37+
}
38+
}
39+
940
class Audio extends HookWidget {
1041
const Audio({
1142
super.key,
@@ -22,60 +53,145 @@ class Audio extends HookWidget {
2253
: useStorageStore().findById(cover!.storageId),
2354
[cover?.storageId]);
2455
final auth = useMemoized(() => storage?.getAuth(), [storage]);
56+
2557
return IgnorePointer(
2658
child: Stack(
59+
fit: StackFit.expand,
2760
children: [
28-
SizedBox(
29-
width: MediaQuery.of(context).size.width,
30-
height: MediaQuery.of(context).size.height,
31-
child: cover != null
32-
? cover?.storageId == localStorageId
33-
? Image.file(
34-
File(cover!.uri),
35-
fit: BoxFit.cover,
36-
)
37-
: Image.network(
38-
cover!.uri,
39-
headers: auth != null ? {'authorization': auth} : null,
40-
fit: BoxFit.cover,
41-
)
42-
: null,
43-
),
61+
if (cover != null)
62+
_CoverImage(cover: cover!, auth: auth, fit: BoxFit.cover),
4463
BackdropFilter(
45-
filter: ImageFilter.blur(sigmaX: 16.0, sigmaY: 16.0),
46-
child: Container(color: Colors.transparent),
64+
filter: ImageFilter.blur(sigmaX: 24.0, sigmaY: 24.0),
65+
child: DecoratedBox(
66+
decoration: BoxDecoration(
67+
gradient: LinearGradient(
68+
begin: Alignment.topCenter,
69+
end: Alignment.bottomCenter,
70+
colors: [
71+
Theme.of(context)
72+
.colorScheme
73+
.surface
74+
.withValues(alpha: 0.6),
75+
Theme.of(context)
76+
.colorScheme
77+
.surface
78+
.withValues(alpha: 0.2),
79+
],
80+
),
81+
),
82+
),
4783
),
48-
Positioned(
49-
left: 0,
50-
top: 0,
51-
right: MediaQuery.of(context).size.width > 800
52-
? MediaQuery.of(context).size.width / 2
53-
: 0,
54-
bottom: 0,
55-
child: Center(
56-
child: SizedBox(
57-
height: MediaQuery.of(context).size.height / 2,
58-
child: ClipRRect(
59-
borderRadius: BorderRadius.circular(8),
60-
child: cover != null
61-
? cover!.storageId == localStorageId
62-
? Image.file(
63-
File(cover!.uri),
64-
fit: BoxFit.contain,
65-
)
66-
: Image.network(
67-
cover!.uri,
68-
headers:
69-
auth != null ? {'authorization': auth} : null,
70-
fit: BoxFit.contain,
71-
)
72-
: null,
84+
LayoutBuilder(
85+
builder: (context, constraints) {
86+
const double wideLayoutThreshold = 600;
87+
final isWideScreen = constraints.maxWidth >= wideLayoutThreshold;
88+
89+
if (isWideScreen) {
90+
return _buildWideLayout(context, constraints, cover, auth);
91+
} else {
92+
return _buildNarrowLayout(context, constraints, cover, auth);
93+
}
94+
},
95+
),
96+
],
97+
),
98+
);
99+
}
100+
101+
Widget _buildNarrowLayout(BuildContext context, BoxConstraints constraints,
102+
FileItem? cover, String? auth) {
103+
return Align(
104+
alignment: const Alignment(0.0, -0.2),
105+
child: Padding(
106+
padding: const EdgeInsets.symmetric(horizontal: 48.0, vertical: 24.0),
107+
child: ConstrainedBox(
108+
constraints: const BoxConstraints(
109+
maxWidth: 400.0,
110+
maxHeight: 400.0,
111+
),
112+
child: AspectRatio(
113+
aspectRatio: 1.0,
114+
child: _buildCoverCard(
115+
cover: cover,
116+
auth: auth,
117+
shadowColor: Theme.of(context)
118+
.colorScheme
119+
.onSurface
120+
.withValues(alpha: 0.15),
121+
),
122+
),
123+
),
124+
),
125+
);
126+
}
127+
128+
Widget _buildWideLayout(BuildContext context, BoxConstraints constraints,
129+
FileItem? cover, String? auth) {
130+
return Row(
131+
children: [
132+
Expanded(
133+
flex: 5,
134+
child: Align(
135+
alignment: const Alignment(0.0, -0.2),
136+
child: Padding(
137+
padding: const EdgeInsets.fromLTRB(48, 24, 24, 24),
138+
child: ConstrainedBox(
139+
constraints: const BoxConstraints(
140+
maxWidth: 400.0,
141+
maxHeight: 400.0,
142+
),
143+
child: AspectRatio(
144+
aspectRatio: 1.0,
145+
child: _buildCoverCard(
146+
cover: cover,
147+
auth: auth,
148+
shadowColor: Theme.of(context)
149+
.colorScheme
150+
.onSurface
151+
.withValues(alpha: 0.15),
152+
),
73153
),
74154
),
75155
),
76156
),
157+
),
158+
Expanded(
159+
flex: 5,
160+
child: Container(
161+
padding:
162+
const EdgeInsets.symmetric(horizontal: 48.0, vertical: 24.0),
163+
),
164+
),
165+
],
166+
);
167+
}
168+
169+
Widget _buildCoverCard(
170+
{required FileItem? cover,
171+
required String? auth,
172+
required Color shadowColor}) {
173+
return Container(
174+
decoration: BoxDecoration(
175+
borderRadius: BorderRadius.circular(16),
176+
boxShadow: [
177+
BoxShadow(
178+
color: shadowColor,
179+
blurRadius: 32,
180+
spreadRadius: 2,
181+
offset: const Offset(0, 8),
182+
),
77183
],
78184
),
185+
child: ClipRRect(
186+
borderRadius: BorderRadius.circular(16),
187+
child: cover != null
188+
? _CoverImage(
189+
cover: cover,
190+
auth: auth,
191+
fit: BoxFit.cover,
192+
)
193+
: Container(),
194+
),
79195
);
80196
}
81197
}

lib/pages/player/control_bar/control_bar.dart

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ class ControlBar extends HookWidget {
8686
begin: Alignment.topCenter,
8787
end: Alignment.bottomCenter,
8888
colors: [
89-
Colors.black87.withValues(alpha: 0),
90-
Colors.black87.withValues(alpha: 0.3),
91-
Colors.black87.withValues(alpha: 0.8),
89+
Colors.black.withValues(alpha: 0),
90+
Colors.black.withValues(alpha: 0.25),
91+
Colors.black.withValues(alpha: 0.65),
9292
],
9393
),
9494
),
@@ -105,7 +105,7 @@ class ControlBar extends HookWidget {
105105
mainAxisAlignment: MainAxisAlignment.center,
106106
crossAxisAlignment: CrossAxisAlignment.center,
107107
children: [
108-
const SizedBox(width: 4),
108+
const SizedBox(width: 2),
109109
Stack(
110110
alignment: Alignment.center,
111111
children: [
@@ -116,7 +116,7 @@ class ControlBar extends HookWidget {
116116
displayIsPlaying.value
117117
? Icons.pause_rounded
118118
: Icons.play_arrow_rounded,
119-
size: 36,
119+
size: 32,
120120
color: color,
121121
),
122122
onPressed: () {
@@ -133,8 +133,8 @@ class ControlBar extends HookWidget {
133133
),
134134
if (isInitializing)
135135
SizedBox(
136-
width: 36,
137-
height: 36,
136+
width: 32,
137+
height: 32,
138138
child: CircularProgressIndicator(
139139
strokeWidth: 4,
140140
color: Theme.of(context).colorScheme.surface,
@@ -146,7 +146,7 @@ class ControlBar extends HookWidget {
146146
tooltip: '${t.stop} ( Ctrl + C )',
147147
icon: Icon(
148148
Icons.stop_rounded,
149-
size: 28,
149+
size: 26,
150150
color: color,
151151
),
152152
onPressed: () {
@@ -162,7 +162,7 @@ class ControlBar extends HookWidget {
162162
tooltip: '${t.previous} ( Ctrl + ← )',
163163
icon: Icon(
164164
Icons.skip_previous_rounded,
165-
size: 28,
165+
size: 26,
166166
color: color,
167167
),
168168
onPressed: () {
@@ -176,7 +176,7 @@ class ControlBar extends HookWidget {
176176
tooltip: '${t.next} ( Ctrl + → )',
177177
icon: Icon(
178178
Icons.skip_next_rounded,
179-
size: 28,
179+
size: 26,
180180
color: color,
181181
),
182182
onPressed: () {
@@ -263,6 +263,7 @@ class ControlBar extends HookWidget {
263263
fontWeight: item == rate
264264
? FontWeight.bold
265265
: FontWeight.w100,
266+
height: 1,
266267
),
267268
),
268269
onTap: () async {
@@ -288,7 +289,7 @@ class ControlBar extends HookWidget {
288289
),
289290
),
290291
),
291-
if (MediaQuery.of(context).size.width < 600)
292+
if (MediaQuery.of(context).size.width < 640)
292293
Builder(
293294
builder: (context) => IconButton(
294295
tooltip: '${t.volume}: $volume',
@@ -307,7 +308,7 @@ class ControlBar extends HookWidget {
307308
style: ButtonStyle(overlayColor: overlayColor),
308309
),
309310
),
310-
if (MediaQuery.of(context).size.width >= 600)
311+
if (MediaQuery.of(context).size.width >= 640)
311312
SizedBox(
312313
width: 160,
313314
child: VolumeControl(
@@ -670,7 +671,7 @@ class ControlBar extends HookWidget {
670671
),
671672
],
672673
),
673-
const SizedBox(width: 4),
674+
const SizedBox(width: 2),
674675
],
675676
),
676677
],

lib/widgets/title_bar.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class TitleBar extends HookWidget {
4040
begin: Alignment.topCenter,
4141
end: Alignment.bottomCenter,
4242
colors: [
43-
Colors.black87.withValues(alpha: 0.8),
44-
Colors.black87.withValues(alpha: 0.3),
43+
Colors.black87.withValues(alpha: 0.6),
44+
Colors.black87.withValues(alpha: 0.25),
4545
Colors.black87.withValues(alpha: 0),
4646
],
4747
),

0 commit comments

Comments
 (0)