1
+ import 'package:material_symbols_icons/symbols.dart' ;
1
2
import 'package:provider/provider.dart' ;
2
3
import 'package:fluent_ui/fluent_ui.dart' ;
4
+ import 'package:rune/providers/playback_controller.dart' ;
5
+ import 'package:rune/providers/volume.dart' ;
6
+ import 'package:rune/widgets/playback_controller/constants/controller_items.dart' ;
3
7
4
8
import '../../../utils/ax_shadow.dart' ;
5
9
import '../../../utils/format_time.dart' ;
@@ -27,14 +31,17 @@ class SmallScreenPlayingTrack extends StatelessWidget {
27
31
28
32
final width = MediaQuery .of (context).size.width;
29
33
34
+ Provider .of <VolumeProvider >(context);
35
+
30
36
return Selector <PlaybackStatusProvider ,
31
- (String ?, String ?, String ?, String ?, double ?)>(
37
+ (String ?, String ?, String ?, String ?, double ?, String ? )>(
32
38
selector: (context, playbackStatusProvider) => (
33
39
playbackStatusProvider.playbackStatus? .coverArtPath,
34
40
playbackStatusProvider.playbackStatus? .artist,
35
41
playbackStatusProvider.playbackStatus? .album,
36
42
playbackStatusProvider.playbackStatus? .title,
37
43
playbackStatusProvider.playbackStatus? .duration,
44
+ playbackStatusProvider.playbackStatus? .state,
38
45
),
39
46
builder: (context, p, child) {
40
47
if (p.$1 == null ) return Container ();
@@ -50,68 +57,142 @@ class SmallScreenPlayingTrack extends StatelessWidget {
50
57
playbackControllerHeight + 12 ,
51
58
),
52
59
constraints: const BoxConstraints (maxWidth: 240 ),
53
- child: Column (
54
- crossAxisAlignment: CrossAxisAlignment .center,
55
- mainAxisAlignment: MainAxisAlignment .center,
56
- children: [
57
- SmallerOrEqualTo (
58
- breakpoint: DeviceType .zune,
59
- builder: (context, isSmaller) {
60
- if (isSmaller) return Container ();
61
- return Container (
62
- padding: const EdgeInsets .symmetric (horizontal: 10 ),
63
- child: Container (
64
- decoration: BoxDecoration (
65
- border: Border .all (color: Colors .white, width: 4 ),
66
- boxShadow: axShadow (9 ),
67
- ),
68
- child: AspectRatio (
69
- aspectRatio: 1 ,
70
- child: CoverArt (
71
- hint: (
72
- p.$3 ?? "" ,
73
- p.$2 ?? "" ,
74
- 'Total Time ${formatTime (p .$5 ?? 0 )}'
60
+ child: SmallerOrEqualTo (
61
+ breakpoint: DeviceType .zune,
62
+ builder: (context, isZune) {
63
+ return Column (
64
+ crossAxisAlignment: CrossAxisAlignment .center,
65
+ mainAxisAlignment: MainAxisAlignment .center,
66
+ children: [
67
+ if (! isZune)
68
+ Container (
69
+ padding: const EdgeInsets .symmetric (horizontal: 10 ),
70
+ child: Container (
71
+ decoration: BoxDecoration (
72
+ border: Border .all (color: Colors .white, width: 4 ),
73
+ boxShadow: axShadow (9 ),
74
+ ),
75
+ child: AspectRatio (
76
+ aspectRatio: 1 ,
77
+ child: CoverArt (
78
+ hint: (
79
+ p.$3 ?? "" ,
80
+ p.$2 ?? "" ,
81
+ 'Total Time ${formatTime (p .$5 ?? 0 )}'
82
+ ),
83
+ key: p.$1 != null ? Key (p.$1.toString ()) : null ,
84
+ path: p.$1,
85
+ size: (width - 20 ).clamp (0 , 240 ),
75
86
),
76
- key: p.$1 != null ? Key (p.$1.toString ()) : null ,
77
- path: p.$1,
78
- size: (width - 20 ).clamp (0 , 240 ),
79
87
),
80
88
),
81
89
),
82
- );
83
- },
84
- ),
85
- SmallerOrEqualTo (
86
- breakpoint: DeviceType .zune,
87
- builder: (context, isSmaller) {
88
- if (isSmaller) return Container ();
89
-
90
- return Transform .translate (
90
+ if (! isZune)
91
+ Transform .translate (
91
92
offset: const Offset (0 , - 16 ),
92
93
child: SizedBox (
93
94
height: 80 ,
94
95
child: CoverArtPageProgressBar (shadows: shadows),
95
96
),
96
- );
97
- }),
98
- const SizedBox (height: 8 ),
99
- Text (
100
- p.$4 ?? "Unknown Track" ,
101
- style: typography.subtitle? .apply (shadows: shadows),
102
- textAlign: TextAlign .center,
103
- ),
104
- const SizedBox (height: 12 ),
105
- Text (
106
- '$artist · $album ' ,
107
- style:
108
- typography.body? .apply (shadows: shadows, heightFactor: 2 ),
109
- textAlign: TextAlign .center,
110
- ),
111
- ],
97
+ ),
98
+ const SizedBox (height: 8 ),
99
+ Text (
100
+ p.$4 ?? "Unknown Track" ,
101
+ style: typography.subtitle? .apply (shadows: shadows),
102
+ textAlign: TextAlign .center,
103
+ ),
104
+ const SizedBox (height: 12 ),
105
+ Text (
106
+ '$artist · $album ' ,
107
+ style: typography.body
108
+ ? .apply (shadows: shadows, heightFactor: 2 ),
109
+ textAlign: TextAlign .center,
110
+ ),
111
+ if (isZune) const SizedBox (height: 12 ),
112
+ if (isZune)
113
+ Selector <PlaybackControllerProvider ,
114
+ (List <ControllerEntry >, List <ControllerEntry >)>(
115
+ selector: (context, controllerProvider) {
116
+ final entries = controllerProvider.entries;
117
+ final hiddenIndex =
118
+ entries.indexWhere ((entry) => entry.id == 'hidden' );
119
+ final List <ControllerEntry > visibleEntries =
120
+ hiddenIndex != - 1
121
+ ? entries.sublist (0 , hiddenIndex)
122
+ : entries;
123
+ final List <ControllerEntry > hiddenEntries =
124
+ hiddenIndex != - 1
125
+ ? entries.sublist (hiddenIndex + 1 )
126
+ : [];
127
+
128
+ return (visibleEntries, hiddenEntries);
129
+ },
130
+ builder: (context, entries, child) {
131
+ return CommandBar (
132
+ isCompact: true ,
133
+ overflowMenuItemBuilder: (context, entry) {
134
+ if (entry is PrimaryCommandBarItem ) {
135
+ return entry.entry.flyoutEntryBuilder (context);
136
+ }
137
+
138
+ throw "Unacceptable entry type" ;
139
+ },
140
+ overflowItemBuilder: (onPressed) {
141
+ return OverflowCommandBarItem (
142
+ key: const ValueKey ("Overflow Item" ),
143
+ onPressed: onPressed,
144
+ );
145
+ },
146
+ primaryItems: entries.$1
147
+ .map (
148
+ (x) => PrimaryCommandBarItem (
149
+ key: ValueKey (x.id),
150
+ entry: x,
151
+ ),
152
+ )
153
+ .toList (),
154
+ secondaryItems: entries.$2
155
+ .map (
156
+ (x) => PrimaryCommandBarItem (
157
+ key: ValueKey (x.id),
158
+ entry: x,
159
+ ),
160
+ )
161
+ .toList (),
162
+ );
163
+ },
164
+ )
165
+ ],
166
+ );
167
+ },
112
168
),
113
169
);
114
170
},
115
171
);
116
172
}
117
173
}
174
+
175
+ class PrimaryCommandBarItem extends CommandBarItem {
176
+ PrimaryCommandBarItem ({required super .key, required this .entry});
177
+
178
+ final ControllerEntry entry;
179
+
180
+ @override
181
+ Widget build (BuildContext context, CommandBarItemDisplayMode displayMode) {
182
+ return entry.controllerButtonBuilder (context);
183
+ }
184
+ }
185
+
186
+ class OverflowCommandBarItem extends CommandBarItem {
187
+ OverflowCommandBarItem ({required super .key, required this .onPressed});
188
+
189
+ final VoidCallback onPressed;
190
+
191
+ @override
192
+ Widget build (BuildContext context, CommandBarItemDisplayMode displayMode) {
193
+ return IconButton (
194
+ icon: const Icon (Symbols .more_vert),
195
+ onPressed: onPressed,
196
+ );
197
+ }
198
+ }
0 commit comments