Skip to content

Commit

Permalink
Merge pull request #95 from lamarios/fix/player_as_an_overlay
Browse files Browse the repository at this point in the history
Fix/player as an overlay
  • Loading branch information
lamarios authored Apr 5, 2023
2 parents 9601c89 + d5870f9 commit 0414e9d
Show file tree
Hide file tree
Showing 28 changed files with 720 additions and 730 deletions.
22 changes: 5 additions & 17 deletions lib/controllers/miniPayerController.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:invidious/utils.dart';
import 'package:logging/logging.dart';

import 'package:back_button_interceptor/back_button_interceptor.dart';
import '../main.dart';
import '../models/baseVideo.dart';
import '../models/video.dart';
import '../views/video.dart';
Expand Down Expand Up @@ -53,7 +54,7 @@ class MiniPlayerController extends GetxController {
@override
onReady() {
super.onReady();
BackButtonInterceptor.add(handleBackButton, name: 'miniPlayer');
BackButtonInterceptor.add(handleBackButton, name: 'miniPlayer', zIndex: 2);
// show();
}

Expand All @@ -67,7 +68,8 @@ class MiniPlayerController extends GetxController {
if (isFullScreen) {
isFullScreen = false;
update();
return false;
globalNavigator.currentState?.pop();
return true;
} else if (!isMini) {
// we block the backbutton behavior and we make the player small
showMiniPlayer();
Expand Down Expand Up @@ -214,7 +216,7 @@ class MiniPlayerController extends GetxController {
}

playVideo(List<BaseVideo> videos, {bool? goBack}) {
if (goBack ?? false) Get.back();
if (goBack ?? false) navigatorKey.currentState?.pop();
log.info('Playing ${videos.length} videos');
if (videos.isNotEmpty) {
this.videos = List.from(videos, growable: true);
Expand Down Expand Up @@ -303,15 +305,6 @@ class MiniPlayerController extends GetxController {
return videos.indexWhere((element) => element.videoId == video.videoId) >= 0;
}

void handleOverflowOpening(bool opened) {
log.info('overflow opened $opened');
if (!isFullScreen) {
isShowingOverflow = opened;
}

update();
}

void handleVideoEvent(BetterPlayerEvent event) {
switch (event.betterPlayerEventType) {
case BetterPlayerEventType.progress:
Expand Down Expand Up @@ -340,12 +333,7 @@ class MiniPlayerController extends GetxController {
isFullScreen = false;
update();
break;
case BetterPlayerEventType.overflowOpened:
case BetterPlayerEventType.overflowClosed:
handleOverflowOpening(event.betterPlayerEventType == BetterPlayerEventType.overflowOpened);
break;
default:
handleOverflowOpening(false);
break;
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/controllers/miniPlayerAwareController.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import 'package:get/get.dart';
import 'package:invidious/controllers/miniPayerController.dart';
import 'package:invidious/utils.dart';
import 'package:logging/logging.dart';

class MiniPlayerAwareController extends GetxController {
Logger log = Logger('MiniPlayerAwareController');
static MiniPlayerAwareController? to() => safeGet();
bool applyPadding = false;

setPadding(bool apply) {
log.info('setting mini player padding $applyPadding');
applyPadding = apply;
update();
}
Expand Down
9 changes: 3 additions & 6 deletions lib/controllers/playlistController.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:invidious/controllers/miniPayerController.dart';
import 'package:invidious/controllers/playlistListController.dart';
import 'package:invidious/views/miniPlayer.dart';
import 'package:logging/logging.dart';

import '../globals.dart';
import '../models/playlist.dart';
import '../models/video.dart';
import '../models/videoInList.dart';

class PlaylistController extends GetxController {
Expand All @@ -33,14 +30,14 @@ class PlaylistController extends GetxController {
Future<bool> removeVideoFromPlayList(VideoInList v) async {
await service.deleteUserPlaylistVideo(playlist.playlistId, v.indexId ?? '');
PlaylistListController.to(tag: PlaylistListController.getTag(userPlayListTag))?.refreshPlaylists();

playlist.videos.remove(v);
update();

return false;
}

play(){
MiniPlayerController.to()?.playVideo(playlist.videos, goBack: false);
play() {
MiniPlayerController.to()?.playVideo(playlist.videos, goBack: false);
}

getAllVideos() async {
Expand Down
2 changes: 2 additions & 0 deletions lib/controllers/serverListSettingsController.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,10 @@ class ServerListSettingsController extends GetxController {
publicServersError = PublicServerErrors.none;
update();
} catch (err) {
err.printError();
publicServersError = PublicServerErrors.couldNotGetList;
update();
rethrow;
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/globals.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const BROADCAST_SERVER_CHANGED = 'server-changed';
const BROADCAST_STOP_PLAYING = 'stop-playing';
const BROADCAST_STOP_MINI_PLAYER = 'stop-mini-player';
const BROADCAST_MOVE_MINI_PLAYER = 'move-mini-player';

const NAVIGATOR_KEY =1;
const YOUTUBE_HOSTS = ['youtube.com', 'www.youtube.com', 'm.youtube.com', 'youtu.be'];

const animationDuration = Duration(milliseconds: 250);
Expand Down
171 changes: 99 additions & 72 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import 'dart:async';

import 'package:after_layout/after_layout.dart';
import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:get/get.dart';
import 'package:invidious/controllers/homeController.dart';
import 'package:invidious/controllers/miniPayerController.dart';
import 'package:invidious/globals.dart';
import 'package:invidious/views/components/miniPlayerAware.dart';
import 'package:invidious/views/miniPlayer.dart';
Expand All @@ -27,6 +27,7 @@ const brandColor = Color(0xFF4f0096);

final scaffoldKey = GlobalKey<ScaffoldMessengerState>();
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> globalNavigator = GlobalKey<NavigatorState>();
final RouteObserver<ModalRoute> routeObserver = MyRouteObserver();

Future<void> main() async {
Expand All @@ -35,7 +36,7 @@ Future<void> main() async {
debugPrint('[${record.level.name}] [${record.loggerName}] ${record.message}');
});

WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
WidgetsFlutterBinding.ensureInitialized();

db = await DbClient.create();
runApp(const MyApp());
Expand Down Expand Up @@ -89,15 +90,29 @@ class MyApp extends StatelessWidget {
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
scaffoldMessengerKey: scaffoldKey,
navigatorKey: globalNavigator,
title: 'Clipious',
navigatorObservers: [routeObserver],
navigatorKey: navigatorKey,
theme: ThemeData(
useMaterial3: true,
colorScheme: lightColorScheme,
),
darkTheme: ThemeData(useMaterial3: true, colorScheme: darkColorScheme),
home: showWizard ? const WelcomeWizard() : const Home());
home: Stack(
children: [
MiniPlayerAware(
child: Navigator(
observers: [MyRouteObserver()],
key: navigatorKey,
initialRoute: '/',
onGenerateRoute: (settings) {
if (settings.name == '/') {
return GetPageRoute(page: () => showWizard ? const WelcomeWizard() : const Home());
}
}),
),
const MiniPlayer()
],
));
});
}
}
Expand All @@ -111,7 +126,26 @@ class Home extends StatefulWidget {

class _HomeState extends State<Home> with AfterLayoutMixin {
openSettings(BuildContext context) {
Navigator.push(context, MaterialPageRoute(settings: ROUTE_SETTINGS, builder: (context) => const Settings()));
navigatorKey.currentState?.push(MaterialPageRoute(settings: ROUTE_SETTINGS, builder: (context) => const Settings()));
}

@override
void initState() {
super.initState();
BackButtonInterceptor.add((stopDefaultButtonEvent, RouteInfo routeInfo) {
if (routeInfo.currentRoute(context)?.settings.name != null) {
navigatorKey.currentState?.pop();
return true;
} else {
return false;
}
}, name: 'mainNavigator', zIndex: 0, ifNotYetIntercepted: true);
}

@override
void dispose() {
BackButtonInterceptor.removeByName('mainNavigator');
super.dispose();
}

// This widget is the root of your application.
Expand All @@ -133,77 +167,70 @@ class _HomeState extends State<Home> with AfterLayoutMixin {
navigationWidgets.add(NavigationDestination(icon: const Icon(Icons.playlist_play), label: navigationLabels[3]));
}

return MiniPlayerAware(
child: Scaffold(
return Scaffold(
backgroundColor: colorScheme.background,
bottomNavigationBar: NavigationBar(
labelBehavior: NavigationDestinationLabelBehavior.onlyShowSelected,
elevation: 0,
onDestinationSelected: _.selectIndex,
selectedIndex: _.selectedIndex,
destinations: navigationWidgets,
),
floatingActionButton: _.selectedIndex == 3 ? AddPlayListButton() : null,
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: colorScheme.background,
systemNavigationBarIconBrightness: colorScheme.brightness == Brightness.dark ? Brightness.light : Brightness.dark,
statusBarColor: colorScheme.background,
statusBarIconBrightness: colorScheme.brightness == Brightness.dark ? Brightness.light : Brightness.dark),
title: Text(navigationLabels[_.selectedIndex]),
scrolledUnderElevation: 0,
// backgroundColor: Colors.pink,
backgroundColor: colorScheme.background,
bottomNavigationBar: NavigationBar(
labelBehavior: NavigationDestinationLabelBehavior.onlyShowSelected,
elevation: 0,
onDestinationSelected: _.selectIndex,
selectedIndex: _.selectedIndex,
destinations: navigationWidgets,
),
floatingActionButton: _.selectedIndex == 3 ? AddPlayListButton() : null,
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: colorScheme.background,
systemNavigationBarIconBrightness: colorScheme.brightness == Brightness.dark ? Brightness.light : Brightness.dark,
statusBarColor: colorScheme.background,
statusBarIconBrightness: colorScheme.brightness == Brightness.dark ? Brightness.light : Brightness.dark),
title: Text(navigationLabels[_.selectedIndex]),
scrolledUnderElevation: 0,
// backgroundColor: Colors.pink,
backgroundColor: colorScheme.background,
actions: [
IconButton(
onPressed: () {
showSearch(context: context, delegate: MySearchDelegate());
actions: [
IconButton(
onPressed: () {
showSearch(context: context, delegate: MySearchDelegate());
},
icon: const Icon(Icons.search),
),
IconButton(
onPressed: () => openSettings(context),
icon: const Icon(Icons.settings),
),
],
),
body: SafeArea(
bottom: false,
child: Stack(children: [
AnimatedSwitcher(
switchInCurve: Curves.easeInOutQuad,
switchOutCurve: Curves.easeInOutQuad,
transitionBuilder: (Widget child, Animation<double> animation) {
return FadeTransition(opacity: animation, child: child);
},
icon: const Icon(Icons.search),
),
IconButton(
onPressed: () => openSettings(context),
icon: const Icon(Icons.settings),
color: colorScheme.secondary,
),
],
),
body: SafeArea(
bottom: false,
child: Stack(children: [
AnimatedSwitcher(
switchInCurve: Curves.easeInOutQuad,
switchOutCurve: Curves.easeInOutQuad,
transitionBuilder: (Widget child, Animation<double> animation) {
return FadeTransition(opacity: animation, child: child);
},
duration: animationDuration,
child: <Widget>[
const Popular(
key: ValueKey(0),
),
const Trending(
key: ValueKey(1),
),
const Subscriptions(
key: ValueKey(2),
),
const Playlists(
key: ValueKey(3),
canDeleteVideos: true,
)
][_.selectedIndex],
)
]))),
);
duration: animationDuration,
child: <Widget>[
const Popular(
key: ValueKey(0),
),
const Trending(
key: ValueKey(1),
),
const Subscriptions(
key: ValueKey(2),
),
const Playlists(
key: ValueKey(3),
canDeleteVideos: true,
)
][_.selectedIndex],
)
])));
},
);
}

@override
FutureOr<void> afterFirstLayout(BuildContext context) {
Overlay.of(context).insert(OverlayEntry(
builder: (context) => MiniPlayer(),
));
}
FutureOr<void> afterFirstLayout(BuildContext context) {}
}
2 changes: 1 addition & 1 deletion lib/models/invidiousServerStats.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ part 'invidiousServerStats.g.dart';
@JsonSerializable()
class InvidiousServerStats {
InvidiousServerSoftware software;
bool openRegistrations;
bool? openRegistrations;

InvidiousServerStats(this.software, this.openRegistrations);

Expand Down
2 changes: 1 addition & 1 deletion lib/models/invidiousServerStats.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0414e9d

Please sign in to comment.