mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
feat: ability to toggle system title bar & custom title bar (#185)
This commit is contained in:
parent
a14fb9ec38
commit
8d4602962b
@ -93,4 +93,5 @@ abstract class SpotubeIcons {
|
|||||||
static const skip = FeatherIcons.fastForward;
|
static const skip = FeatherIcons.fastForward;
|
||||||
static const noWifi = FeatherIcons.wifiOff;
|
static const noWifi = FeatherIcons.wifiOff;
|
||||||
static const wifi = FeatherIcons.wifi;
|
static const wifi = FeatherIcons.wifi;
|
||||||
|
static const window = Icons.window_rounded;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ final closeNotification = DesktopTools.createNotification(
|
|||||||
windowManager.close();
|
windowManager.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
class PageWindowTitleBar extends StatefulHookWidget
|
class PageWindowTitleBar extends StatefulHookConsumerWidget
|
||||||
implements PreferredSizeWidget {
|
implements PreferredSizeWidget {
|
||||||
final Widget? leading;
|
final Widget? leading;
|
||||||
final bool automaticallyImplyLeading;
|
final bool automaticallyImplyLeading;
|
||||||
@ -60,23 +60,23 @@ class PageWindowTitleBar extends StatefulHookWidget
|
|||||||
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PageWindowTitleBar> createState() => _PageWindowTitleBarState();
|
ConsumerState<PageWindowTitleBar> createState() => _PageWindowTitleBarState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PageWindowTitleBarState extends ConsumerState<PageWindowTitleBar> {
|
||||||
|
void onDrag(details) {
|
||||||
|
final systemTitleBar =
|
||||||
|
ref.read(userPreferencesProvider.select((s) => s.systemTitleBar));
|
||||||
|
if (kIsDesktop && !systemTitleBar) {
|
||||||
|
DesktopTools.window.startDragging();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PageWindowTitleBarState extends State<PageWindowTitleBar> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onHorizontalDragStart: (details) {
|
onHorizontalDragStart: onDrag,
|
||||||
if (kIsDesktop) {
|
onVerticalDragStart: onDrag,
|
||||||
windowManager.startDragging();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onVerticalDragStart: (details) {
|
|
||||||
if (kIsDesktop) {
|
|
||||||
windowManager.startDragging();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: AppBar(
|
child: AppBar(
|
||||||
leading: widget.leading,
|
leading: widget.leading,
|
||||||
automaticallyImplyLeading: widget.automaticallyImplyLeading,
|
automaticallyImplyLeading: widget.automaticallyImplyLeading,
|
||||||
@ -108,13 +108,12 @@ class WindowTitleBarButtons extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final closeBehavior =
|
final preferences = ref.watch(userPreferencesProvider);
|
||||||
ref.watch(userPreferencesProvider.select((s) => s.closeBehavior));
|
|
||||||
final isMaximized = useState<bool?>(null);
|
final isMaximized = useState<bool?>(null);
|
||||||
const type = ThemeType.auto;
|
const type = ThemeType.auto;
|
||||||
|
|
||||||
Future<void> onClose() async {
|
Future<void> onClose() async {
|
||||||
if (closeBehavior == CloseBehavior.close) {
|
if (preferences.closeBehavior == CloseBehavior.close) {
|
||||||
await windowManager.close();
|
await windowManager.close();
|
||||||
} else {
|
} else {
|
||||||
await windowManager.hide();
|
await windowManager.hide();
|
||||||
@ -131,7 +130,7 @@ class WindowTitleBarButtons extends HookConsumerWidget {
|
|||||||
return null;
|
return null;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!kIsDesktop || kIsMacOS) {
|
if (!kIsDesktop || kIsMacOS || preferences.systemTitleBar) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,5 +258,6 @@
|
|||||||
"piped_api_down": "Piped API is down",
|
"piped_api_down": "Piped API is down",
|
||||||
"piped_down_error_instructions": "The Piped instance {pipedInstance} is currently down\n\nEither change the instance or change the 'API type' to official YouTube API\n\nMake sure to restart the app after change",
|
"piped_down_error_instructions": "The Piped instance {pipedInstance} is currently down\n\nEither change the instance or change the 'API type' to official YouTube API\n\nMake sure to restart the app after change",
|
||||||
"you_are_offline": "You are currently offline",
|
"you_are_offline": "You are currently offline",
|
||||||
"connection_restored": "Your internet connection was restored"
|
"connection_restored": "Your internet connection was restored",
|
||||||
|
"use_system_title_bar": "Use system title bar"
|
||||||
}
|
}
|
@ -496,6 +496,12 @@ class SettingsPage extends HookConsumerWidget {
|
|||||||
value: preferences.showSystemTrayIcon,
|
value: preferences.showSystemTrayIcon,
|
||||||
onChanged: preferences.setShowSystemTrayIcon,
|
onChanged: preferences.setShowSystemTrayIcon,
|
||||||
),
|
),
|
||||||
|
SwitchListTile(
|
||||||
|
secondary: const Icon(SpotubeIcons.window),
|
||||||
|
title: Text(context.l10n.use_system_title_bar),
|
||||||
|
value: preferences.systemTitleBar,
|
||||||
|
onChanged: preferences.setSystemTitleBar,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (!kIsWeb)
|
if (!kIsWeb)
|
||||||
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:spotube/components/settings/color_scheme_picker_dialog.dart';
|
import 'package:spotube/components/settings/color_scheme_picker_dialog.dart';
|
||||||
@ -65,6 +66,8 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
|
|
||||||
YoutubeApiType youtubeApiType;
|
YoutubeApiType youtubeApiType;
|
||||||
|
|
||||||
|
bool systemTitleBar;
|
||||||
|
|
||||||
final Ref ref;
|
final Ref ref;
|
||||||
|
|
||||||
UserPreferences(
|
UserPreferences(
|
||||||
@ -85,6 +88,7 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
this.searchMode = SearchMode.youtube,
|
this.searchMode = SearchMode.youtube,
|
||||||
this.skipNonMusic = true,
|
this.skipNonMusic = true,
|
||||||
this.youtubeApiType = YoutubeApiType.youtube,
|
this.youtubeApiType = YoutubeApiType.youtube,
|
||||||
|
this.systemTitleBar = false,
|
||||||
}) : super() {
|
}) : super() {
|
||||||
if (downloadLocation.isEmpty && !kIsWeb) {
|
if (downloadLocation.isEmpty && !kIsWeb) {
|
||||||
_getDefaultDownloadDirectory().then(
|
_getDefaultDownloadDirectory().then(
|
||||||
@ -197,6 +201,15 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
updatePersistence();
|
updatePersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSystemTitleBar(bool isSystemTitleBar) {
|
||||||
|
systemTitleBar = isSystemTitleBar;
|
||||||
|
DesktopTools.window.setTitleBarStyle(
|
||||||
|
systemTitleBar ? TitleBarStyle.normal : TitleBarStyle.hidden,
|
||||||
|
);
|
||||||
|
notifyListeners();
|
||||||
|
updatePersistence();
|
||||||
|
}
|
||||||
|
|
||||||
Future<String> _getDefaultDownloadDirectory() async {
|
Future<String> _getDefaultDownloadDirectory() async {
|
||||||
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
if (kIsAndroid) return "/storage/emulated/0/Download/Spotube";
|
||||||
|
|
||||||
@ -257,6 +270,10 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
(type) => type.name == map["youtubeApiType"],
|
(type) => type.name == map["youtubeApiType"],
|
||||||
orElse: () => YoutubeApiType.youtube,
|
orElse: () => YoutubeApiType.youtube,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
systemTitleBar = map["systemTitleBar"] ?? systemTitleBar;
|
||||||
|
// updates the title bar
|
||||||
|
setSystemTitleBar(systemTitleBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -279,6 +296,7 @@ class UserPreferences extends PersistedChangeNotifier {
|
|||||||
"searchMode": searchMode.name,
|
"searchMode": searchMode.name,
|
||||||
"skipNonMusic": skipNonMusic,
|
"skipNonMusic": skipNonMusic,
|
||||||
"youtubeApiType": youtubeApiType.name,
|
"youtubeApiType": youtubeApiType.name,
|
||||||
|
'systemTitleBar': systemTitleBar,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ca": [
|
"ca": [
|
||||||
@ -11,58 +12,67 @@
|
|||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"de": [
|
"de": [
|
||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"es": [
|
"es": [
|
||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fr": [
|
"fr": [
|
||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"hi": [
|
"hi": [
|
||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pl": [
|
"pl": [
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
"piped_api_down",
|
"piped_api_down",
|
||||||
"piped_down_error_instructions",
|
"piped_down_error_instructions",
|
||||||
"you_are_offline",
|
"you_are_offline",
|
||||||
"connection_restored"
|
"connection_restored",
|
||||||
|
"use_system_title_bar"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user