Skip to content

Commit

Permalink
feat(mini_player): show/hide UI on hover toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingkor Roy Tirtho committed Apr 25, 2023
1 parent bd3b7f9 commit 2e8b647
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 128 deletions.
2 changes: 2 additions & 0 deletions lib/collections/spotube_icons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,6 @@ abstract class SpotubeIcons {
static const maximize = FeatherIcons.maximize2;
static const pinOn = Icons.push_pin_rounded;
static const pinOff = Icons.push_pin_outlined;
static const hoverOn = Icons.back_hand_rounded;
static const hoverOff = Icons.back_hand_outlined;
}
306 changes: 178 additions & 128 deletions lib/pages/lyrics/mini_lyrics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class MiniLyricsPage extends HookConsumerWidget {

final playlistQueue = ref.watch(PlaylistQueueNotifier.provider);

final areaActive = useState(false);
final hoverMode = useState(true);

useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
prevSize.value = await DesktopTools.window.getSize();
Expand All @@ -46,140 +49,187 @@ class MiniLyricsPage extends HookConsumerWidget {
);
}

return DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: theme.colorScheme.surface.withOpacity(0.4),
appBar: PreferredSize(
preferredSize: const Size.fromHeight(60),
child: DragToMoveArea(
child: Row(
children: [
const SizedBox(width: 10),
SizedBox(
height: 30,
width: 30,
child: Sidebar.brandLogo(),
),
const Spacer(),
const SizedBox(
height: 30,
child: TabBar(
tabs: [Tab(text: 'Synced'), Tab(text: 'Plain')],
isScrollable: true,
),
),
const Spacer(),
FutureBuilder(
future: DesktopTools.window.isAlwaysOnTop(),
builder: (context, snapshot) {
return IconButton(
tooltip: 'Always on top',
icon: Icon(
snapshot.data == true
? SpotubeIcons.pinOn
: SpotubeIcons.pinOff,
),
style: ButtonStyle(
foregroundColor: snapshot.data == true
? MaterialStateProperty.all(
theme.colorScheme.primary)
: null,
),
onPressed: snapshot.data == null
? null
: () async {
await DesktopTools.window.setAlwaysOnTop(
snapshot.data == true ? false : true,
);
update();
},
);
}),
IconButton(
tooltip: 'Exit Mini Player',
icon: const Icon(SpotubeIcons.maximize),
onPressed: () async {
try {
await DesktopTools.window
.setMinimumSize(const Size(300, 700));
await DesktopTools.window.setAlwaysOnTop(false);
if (wasMaximized.value) {
await DesktopTools.window.maximize();
} else {
await DesktopTools.window.setSize(prevSize.value!);
}
await DesktopTools.window.setAlignment(Alignment.center);
if (!kIsLinux) {
await DesktopTools.window.setHasShadow(true);
}
await Future.delayed(const Duration(milliseconds: 200));
} finally {
if (context.mounted) {
GoRouter.of(context).go('/lyrics');
}
}
},
return MouseRegion(
onEnter: !hoverMode.value
? null
: (event) {
areaActive.value = true;
},
onExit: !hoverMode.value
? null
: (event) {
areaActive.value = false;
},
child: DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: theme.colorScheme.surface.withOpacity(0.4),
appBar: PreferredSize(
preferredSize: const Size.fromHeight(60),
child: AnimatedCrossFade(
duration: const Duration(milliseconds: 200),
crossFadeState: areaActive.value
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
secondChild: const SizedBox(),
firstChild: DragToMoveArea(
child: Row(
children: [
const SizedBox(width: 10),
SizedBox(
height: 30,
width: 30,
child: Sidebar.brandLogo(),
),
const Spacer(),
const SizedBox(
height: 30,
child: TabBar(
tabs: [Tab(text: 'Synced'), Tab(text: 'Plain')],
isScrollable: true,
),
),
const Spacer(),
IconButton(
tooltip: 'Show/Hide UI on hover',
icon: hoverMode.value
? const Icon(SpotubeIcons.hoverOn)
: const Icon(SpotubeIcons.hoverOff),
style: ButtonStyle(
foregroundColor: hoverMode.value
? MaterialStateProperty.all(
theme.colorScheme.primary)
: null,
),
onPressed: () async {
if (!hoverMode.value == true) {
areaActive.value = true;
}
hoverMode.value = !hoverMode.value;
},
),
FutureBuilder(
future: DesktopTools.window.isAlwaysOnTop(),
builder: (context, snapshot) {
return IconButton(
tooltip: 'Always on top',
icon: Icon(
snapshot.data == true
? SpotubeIcons.pinOn
: SpotubeIcons.pinOff,
),
style: ButtonStyle(
foregroundColor: snapshot.data == true
? MaterialStateProperty.all(
theme.colorScheme.primary)
: null,
),
onPressed: snapshot.data == null
? null
: () async {
await DesktopTools.window.setAlwaysOnTop(
snapshot.data == true ? false : true,
);
update();
},
);
},
),
],
),
],
),
),
),
),
body: Column(
children: [
if (playlistQueue != null)
Text(
playlistQueue.activeTrack.name!,
style: theme.textTheme.titleMedium,
),
Expanded(
child: TabBarView(
children: [
SyncedLyrics(
palette: PaletteColor(theme.colorScheme.background, 0),
isModal: true,
defaultTextZoom: 65,
),
PlainLyrics(
palette: PaletteColor(theme.colorScheme.background, 0),
isModal: true,
defaultTextZoom: 65,
),
],
body: Column(
children: [
if (playlistQueue != null)
Text(
playlistQueue.activeTrack.name!,
style: theme.textTheme.titleMedium,
),
Expanded(
child: TabBarView(
children: [
SyncedLyrics(
palette: PaletteColor(theme.colorScheme.background, 0),
isModal: true,
defaultTextZoom: 65,
),
PlainLyrics(
palette: PaletteColor(theme.colorScheme.background, 0),
isModal: true,
defaultTextZoom: 65,
),
],
),
),
),
Row(
children: [
IconButton(
icon: const Icon(SpotubeIcons.queue),
tooltip: 'Queue',
onPressed: playlistQueue != null
? () {
showModalBottomSheet(
context: context,
isDismissible: true,
enableDrag: true,
isScrollControlled: true,
backgroundColor: Colors.black12,
barrierColor: Colors.black12,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
constraints: BoxConstraints(
maxHeight:
MediaQuery.of(context).size.height * .7,
),
builder: (context) {
return const PlayerQueue(floating: true);
},
);
AnimatedCrossFade(
crossFadeState: areaActive.value
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 200),
secondChild: const SizedBox(),
firstChild: Row(
children: [
IconButton(
icon: const Icon(SpotubeIcons.queue),
tooltip: 'Queue',
onPressed: playlistQueue != null
? () {
showModalBottomSheet(
context: context,
isDismissible: true,
enableDrag: true,
isScrollControlled: true,
backgroundColor: Colors.black12,
barrierColor: Colors.black12,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
constraints: BoxConstraints(
maxHeight:
MediaQuery.of(context).size.height * .7,
),
builder: (context) {
return const PlayerQueue(floating: true);
},
);
}
: null,
),
Flexible(child: PlayerControls(compact: true)),
IconButton(
tooltip: 'Exit Mini Player',
icon: const Icon(SpotubeIcons.maximize),
onPressed: () async {
try {
await DesktopTools.window
.setMinimumSize(const Size(300, 700));
await DesktopTools.window.setAlwaysOnTop(false);
if (wasMaximized.value) {
await DesktopTools.window.maximize();
} else {
await DesktopTools.window.setSize(prevSize.value!);
}
await DesktopTools.window
.setAlignment(Alignment.center);
if (!kIsLinux) {
await DesktopTools.window.setHasShadow(true);
}
await Future.delayed(
const Duration(milliseconds: 200));
} finally {
if (context.mounted) {
GoRouter.of(context).go('/lyrics');
}
}
: null,
},
),
],
),
Flexible(child: PlayerControls(compact: true))
],
)
],
)
],
),
),
),
);
Expand Down

0 comments on commit 2e8b647

Please sign in to comment.