mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
Custom Window Titlebar support
This commit is contained in:
parent
619aa4af1a
commit
4d41b037e4
Binary file not shown.
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 76 KiB |
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart' hide Page;
|
import 'package:flutter/material.dart' hide Page;
|
||||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||||
@ -122,6 +123,27 @@ class _HomeState extends State<Home> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
|
WindowTitleBarBox(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 256),
|
||||||
|
color:
|
||||||
|
Theme.of(context).navigationRailTheme.backgroundColor,
|
||||||
|
child: MoveWindow(),
|
||||||
|
),
|
||||||
|
Expanded(child: MoveWindow())
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
MinimizeWindowButton(animate: true),
|
||||||
|
MaximizeWindowButton(animate: true),
|
||||||
|
CloseWindowButton(animate: true),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -165,22 +187,26 @@ class _HomeState extends State<Home> {
|
|||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
var avatarImg = snapshot.data?.images?.last.url;
|
var avatarImg = snapshot.data?.images?.last.url;
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(16),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
children: [
|
children: [
|
||||||
if (avatarImg != null)
|
if (avatarImg != null)
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
child: CachedNetworkImage(
|
backgroundImage:
|
||||||
imageUrl: avatarImg,
|
CachedNetworkImageProvider(avatarImg),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
snapshot.data?.displayName ?? "User's name",
|
snapshot.data?.displayName ?? "User's name",
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.settings_outlined),
|
icon: const Icon(Icons.settings_outlined),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -202,6 +228,8 @@ class _HomeState extends State<Home> {
|
|||||||
if (_selectedIndex == 0)
|
if (_selectedIndex == 0)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Scrollbar(
|
child: Scrollbar(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: PagedListView(
|
child: PagedListView(
|
||||||
pagingController: _pagingController,
|
pagingController: _pagingController,
|
||||||
builderDelegate: PagedChildBuilderDelegate<Category>(
|
builderDelegate: PagedChildBuilderDelegate<Category>(
|
||||||
@ -212,6 +240,7 @@ class _HomeState extends State<Home> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
if (_selectedIndex == 2) const UserLibrary(),
|
if (_selectedIndex == 2) const UserLibrary(),
|
||||||
// player itself
|
// player itself
|
||||||
],
|
],
|
||||||
|
23
lib/components/PageWindowTitleBar.dart
Normal file
23
lib/components/PageWindowTitleBar.dart
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class PageWindowTitleBar extends StatelessWidget {
|
||||||
|
final Widget? leading;
|
||||||
|
final Widget? center;
|
||||||
|
const PageWindowTitleBar({Key? key, this.leading, this.center})
|
||||||
|
: super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return WindowTitleBarBox(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
if (leading != null) leading!,
|
||||||
|
Expanded(child: MoveWindow(child: Center(child: center))),
|
||||||
|
MinimizeWindowButton(animate: true),
|
||||||
|
MaximizeWindowButton(animate: true),
|
||||||
|
CloseWindowButton(animate: true),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
|
import 'package:spotube/components/PageWindowTitleBar.dart';
|
||||||
import 'package:spotube/components/PlaylistCard.dart';
|
import 'package:spotube/components/PlaylistCard.dart';
|
||||||
import 'package:spotube/provider/SpotifyDI.dart';
|
import 'package:spotube/provider/SpotifyDI.dart';
|
||||||
|
|
||||||
@ -24,20 +25,14 @@ class _PlaylistGenreViewState extends State<PlaylistGenreView> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
const PageWindowTitleBar(
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
leading: BackButton(),
|
||||||
children: [
|
),
|
||||||
const BackButton(),
|
Text(
|
||||||
// genre name
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
widget.genreName,
|
widget.genreName,
|
||||||
style: Theme.of(context).textTheme.headline4,
|
style: Theme.of(context).textTheme.headline4,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Consumer<SpotifyDI>(
|
Consumer<SpotifyDI>(
|
||||||
builder: (context, data, child) => Expanded(
|
builder: (context, data, child) => Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:spotube/components/PageWindowTitleBar.dart';
|
||||||
import 'package:spotube/helpers/zero-pad-num-str.dart';
|
import 'package:spotube/helpers/zero-pad-num-str.dart';
|
||||||
import 'package:spotube/provider/Playback.dart';
|
import 'package:spotube/provider/Playback.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -98,7 +97,8 @@ class _PlaylistViewState extends State<PlaylistView> {
|
|||||||
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
PageWindowTitleBar(
|
||||||
|
leading: Row(
|
||||||
children: [
|
children: [
|
||||||
// nav back
|
// nav back
|
||||||
const BackButton(),
|
const BackButton(),
|
||||||
@ -108,8 +108,10 @@ class _PlaylistViewState extends State<PlaylistView> {
|
|||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
),
|
),
|
||||||
// play playlist
|
// play playlist
|
||||||
Consumer<Playback>(builder: (context, playback, widget) {
|
Consumer<Playback>(
|
||||||
var isPlaylistPlaying = playback.currentPlaylist?.id ==
|
builder: (context, playback, widget) {
|
||||||
|
var isPlaylistPlaying =
|
||||||
|
playback.currentPlaylist?.id ==
|
||||||
this.widget.playlist.id;
|
this.widget.playlist.id;
|
||||||
return IconButton(
|
return IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
@ -125,8 +127,11 @@ class _PlaylistViewState extends State<PlaylistView> {
|
|||||||
tracks: tracks,
|
tracks: tracks,
|
||||||
id: this.widget.playlist.id!,
|
id: this.widget.playlist.id!,
|
||||||
name: this.widget.playlist.name!,
|
name: this.widget.playlist.name!,
|
||||||
thumbnail:
|
thumbnail: this
|
||||||
this.widget.playlist.images![0].url!,
|
.widget
|
||||||
|
.playlist
|
||||||
|
.images![0]
|
||||||
|
.url!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,6 +140,7 @@ class _PlaylistViewState extends State<PlaylistView> {
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
Center(
|
Center(
|
||||||
child: Text(widget.playlist.name!,
|
child: Text(widget.playlist.name!,
|
||||||
style: Theme.of(context).textTheme.headline4),
|
style: Theme.of(context).textTheme.headline4),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:spotube/components/PageWindowTitleBar.dart';
|
||||||
import 'package:spotube/provider/Auth.dart';
|
import 'package:spotube/provider/Auth.dart';
|
||||||
|
|
||||||
class Settings extends StatefulWidget {
|
class Settings extends StatefulWidget {
|
||||||
@ -14,18 +15,16 @@ class _SettingsState extends State<Settings> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
elevation: 0,
|
|
||||||
iconTheme: Theme.of(context).iconTheme,
|
|
||||||
title: const Text(
|
|
||||||
"Settings",
|
|
||||||
),
|
|
||||||
centerTitle: true,
|
|
||||||
titleTextStyle: Theme.of(context).textTheme.headline4,
|
|
||||||
),
|
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
|
PageWindowTitleBar(
|
||||||
|
leading: const BackButton(),
|
||||||
|
center: Text(
|
||||||
|
"Settings",
|
||||||
|
style: Theme.of(context).textTheme.headline5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
Builder(builder: (context) {
|
Builder(builder: (context) {
|
||||||
var auth = context.read<Auth>();
|
var auth = context.read<Auth>();
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
@ -10,6 +11,12 @@ import 'package:spotube/provider/SpotifyDI.dart';
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
|
doWhenWindowReady(() {
|
||||||
|
appWindow.minSize = const Size(900, 700);
|
||||||
|
appWindow.alignment = Alignment.center;
|
||||||
|
appWindow.maximize();
|
||||||
|
appWindow.show();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
@ -90,7 +97,13 @@ class MyApp extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
navigationRailTheme: NavigationRailThemeData(
|
navigationRailTheme: NavigationRailThemeData(
|
||||||
backgroundColor: Colors.blueGrey[50],
|
backgroundColor: Colors.blueGrey[50],
|
||||||
)),
|
unselectedIconTheme:
|
||||||
|
IconThemeData(color: Colors.grey[850], opacity: 1),
|
||||||
|
unselectedLabelTextStyle: TextStyle(
|
||||||
|
color: Colors.grey[850],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
home: const Home(),
|
home: const Home(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -6,9 +6,13 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
|
||||||
|
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
bitsdojo_window_linux
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
|
||||||
#include "my_application.h"
|
#include "my_application.h"
|
||||||
|
|
||||||
#include <flutter_linux/flutter_linux.h>
|
#include <flutter_linux/flutter_linux.h>
|
||||||
@ -47,7 +48,9 @@ static void my_application_activate(GApplication* application) {
|
|||||||
gtk_window_set_title(window, "spotube");
|
gtk_window_set_title(window, "spotube");
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_window_set_default_size(window, 1280, 720);
|
auto bdw = bitsdojo_window_from(window);
|
||||||
|
bdw->setCustomFrame(true);
|
||||||
|
// gtk_window_set_default_size(window, 1280, 720);
|
||||||
gtk_widget_show(GTK_WIDGET(window));
|
gtk_widget_show(GTK_WIDGET(window));
|
||||||
|
|
||||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||||
|
35
pubspec.lock
35
pubspec.lock
@ -8,6 +8,41 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.8.2"
|
version: "2.8.2"
|
||||||
|
bitsdojo_window:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: bitsdojo_window
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1+1"
|
||||||
|
bitsdojo_window_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bitsdojo_window_linux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
|
bitsdojo_window_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bitsdojo_window_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
|
bitsdojo_window_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bitsdojo_window_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
|
bitsdojo_window_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bitsdojo_window_windows
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -44,6 +44,7 @@ dependencies:
|
|||||||
youtube_explode_dart: ^1.10.8
|
youtube_explode_dart: ^1.10.8
|
||||||
mpv_dart: ^0.0.1
|
mpv_dart: ^0.0.1
|
||||||
infinite_scroll_pagination: ^3.1.0
|
infinite_scroll_pagination: ^3.1.0
|
||||||
|
bitsdojo_window: ^0.1.1+1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user