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:flutter/material.dart' hide Page;
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
@ -122,6 +123,27 @@ class _HomeState extends State<Home> {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
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(
|
||||
child: Row(
|
||||
children: [
|
||||
@ -165,21 +187,25 @@ class _HomeState extends State<Home> {
|
||||
builder: (context, snapshot) {
|
||||
var avatarImg = snapshot.data?.images?.last.url;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if (avatarImg != null)
|
||||
CircleAvatar(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: avatarImg,
|
||||
Row(
|
||||
children: [
|
||||
if (avatarImg != null)
|
||||
CircleAvatar(
|
||||
backgroundImage:
|
||||
CachedNetworkImageProvider(avatarImg),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
snapshot.data?.displayName ?? "User's name",
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
snapshot.data?.displayName ?? "User's name",
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings_outlined),
|
||||
@ -202,12 +228,15 @@ class _HomeState extends State<Home> {
|
||||
if (_selectedIndex == 0)
|
||||
Expanded(
|
||||
child: Scrollbar(
|
||||
child: PagedListView(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<Category>(
|
||||
itemBuilder: (context, item, index) {
|
||||
return CategoryCard(item);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: PagedListView(
|
||||
pagingController: _pagingController,
|
||||
builderDelegate: PagedChildBuilderDelegate<Category>(
|
||||
itemBuilder: (context, item, index) {
|
||||
return CategoryCard(item);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
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:provider/provider.dart';
|
||||
import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/PageWindowTitleBar.dart';
|
||||
import 'package:spotube/components/PlaylistCard.dart';
|
||||
import 'package:spotube/provider/SpotifyDI.dart';
|
||||
|
||||
@ -24,19 +25,13 @@ class _PlaylistGenreViewState extends State<PlaylistGenreView> {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const BackButton(),
|
||||
// genre name
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.genreName,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
const PageWindowTitleBar(
|
||||
leading: BackButton(),
|
||||
),
|
||||
Text(
|
||||
widget.genreName,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
Consumer<SpotifyDI>(
|
||||
builder: (context, data, child) => Expanded(
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'dart:ui';
|
||||
|
||||
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/provider/Playback.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -98,42 +97,49 @@ class _PlaylistViewState extends State<PlaylistView> {
|
||||
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
// nav back
|
||||
const BackButton(),
|
||||
// heart playlist
|
||||
IconButton(
|
||||
icon: const Icon(Icons.favorite_outline_rounded),
|
||||
onPressed: () {},
|
||||
),
|
||||
// play playlist
|
||||
Consumer<Playback>(builder: (context, playback, widget) {
|
||||
var isPlaylistPlaying = playback.currentPlaylist?.id ==
|
||||
this.widget.playlist.id;
|
||||
return IconButton(
|
||||
icon: Icon(
|
||||
isPlaylistPlaying
|
||||
? Icons.stop_rounded
|
||||
: Icons.play_arrow_rounded,
|
||||
),
|
||||
onPressed: snapshot.hasData
|
||||
? () {
|
||||
if (!isPlaylistPlaying) {
|
||||
playback.setCurrentPlaylist =
|
||||
CurrentPlaylist(
|
||||
tracks: tracks,
|
||||
id: this.widget.playlist.id!,
|
||||
name: this.widget.playlist.name!,
|
||||
thumbnail:
|
||||
this.widget.playlist.images![0].url!,
|
||||
);
|
||||
PageWindowTitleBar(
|
||||
leading: Row(
|
||||
children: [
|
||||
// nav back
|
||||
const BackButton(),
|
||||
// heart playlist
|
||||
IconButton(
|
||||
icon: const Icon(Icons.favorite_outline_rounded),
|
||||
onPressed: () {},
|
||||
),
|
||||
// play playlist
|
||||
Consumer<Playback>(
|
||||
builder: (context, playback, widget) {
|
||||
var isPlaylistPlaying =
|
||||
playback.currentPlaylist?.id ==
|
||||
this.widget.playlist.id;
|
||||
return IconButton(
|
||||
icon: Icon(
|
||||
isPlaylistPlaying
|
||||
? Icons.stop_rounded
|
||||
: Icons.play_arrow_rounded,
|
||||
),
|
||||
onPressed: snapshot.hasData
|
||||
? () {
|
||||
if (!isPlaylistPlaying) {
|
||||
playback.setCurrentPlaylist =
|
||||
CurrentPlaylist(
|
||||
tracks: tracks,
|
||||
id: this.widget.playlist.id!,
|
||||
name: this.widget.playlist.name!,
|
||||
thumbnail: this
|
||||
.widget
|
||||
.playlist
|
||||
.images![0]
|
||||
.url!,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
: null,
|
||||
);
|
||||
}),
|
||||
],
|
||||
: null,
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Text(widget.playlist.name!,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:spotube/components/PageWindowTitleBar.dart';
|
||||
import 'package:spotube/provider/Auth.dart';
|
||||
|
||||
class Settings extends StatefulWidget {
|
||||
@ -14,18 +15,16 @@ class _SettingsState extends State<Settings> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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(
|
||||
children: [
|
||||
PageWindowTitleBar(
|
||||
leading: const BackButton(),
|
||||
center: Text(
|
||||
"Settings",
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Builder(builder: (context) {
|
||||
var auth = context.read<Auth>();
|
||||
return ElevatedButton(
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@ -10,6 +11,12 @@ import 'package:spotube/provider/SpotifyDI.dart';
|
||||
|
||||
void main() {
|
||||
runApp(MyApp());
|
||||
doWhenWindowReady(() {
|
||||
appWindow.minSize = const Size(900, 700);
|
||||
appWindow.alignment = Alignment.center;
|
||||
appWindow.maximize();
|
||||
appWindow.show();
|
||||
});
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@ -57,40 +64,46 @@ class MyApp extends StatelessWidget {
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Spotube',
|
||||
theme: ThemeData(
|
||||
primaryColor: Colors.greenAccent[400],
|
||||
primarySwatch: Colors.green,
|
||||
buttonTheme: const ButtonThemeData(
|
||||
buttonColor: Colors.green,
|
||||
),
|
||||
textTheme: TextTheme(
|
||||
bodyText1: TextStyle(color: Colors.grey[850]),
|
||||
headline1: TextStyle(color: Colors.grey[850]),
|
||||
headline2: TextStyle(color: Colors.grey[850]),
|
||||
headline3: TextStyle(color: Colors.grey[850]),
|
||||
headline4: TextStyle(color: Colors.grey[850]),
|
||||
headline5: TextStyle(color: Colors.grey[850]),
|
||||
headline6: TextStyle(color: Colors.grey[850]),
|
||||
),
|
||||
listTileTheme: ListTileThemeData(
|
||||
iconColor: Colors.grey[850],
|
||||
horizontalTitleGap: 0,
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.green[400]!,
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey[800]!,
|
||||
),
|
||||
primaryColor: Colors.greenAccent[400],
|
||||
primarySwatch: Colors.green,
|
||||
buttonTheme: const ButtonThemeData(
|
||||
buttonColor: Colors.green,
|
||||
),
|
||||
textTheme: TextTheme(
|
||||
bodyText1: TextStyle(color: Colors.grey[850]),
|
||||
headline1: TextStyle(color: Colors.grey[850]),
|
||||
headline2: TextStyle(color: Colors.grey[850]),
|
||||
headline3: TextStyle(color: Colors.grey[850]),
|
||||
headline4: TextStyle(color: Colors.grey[850]),
|
||||
headline5: TextStyle(color: Colors.grey[850]),
|
||||
headline6: TextStyle(color: Colors.grey[850]),
|
||||
),
|
||||
listTileTheme: ListTileThemeData(
|
||||
iconColor: Colors.grey[850],
|
||||
horizontalTitleGap: 0,
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.green[400]!,
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
navigationRailTheme: NavigationRailThemeData(
|
||||
backgroundColor: Colors.blueGrey[50],
|
||||
)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey[800]!,
|
||||
),
|
||||
),
|
||||
),
|
||||
navigationRailTheme: NavigationRailThemeData(
|
||||
backgroundColor: Colors.blueGrey[50],
|
||||
unselectedIconTheme:
|
||||
IconThemeData(color: Colors.grey[850], opacity: 1),
|
||||
unselectedLabelTextStyle: TextStyle(
|
||||
color: Colors.grey[850],
|
||||
),
|
||||
),
|
||||
),
|
||||
home: const Home(),
|
||||
),
|
||||
);
|
||||
|
@ -6,9 +6,13 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
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 =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
bitsdojo_window_linux
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
|
||||
#include "my_application.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_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));
|
||||
|
||||
g_autoptr(FlDartProject) project = fl_dart_project_new();
|
||||
|
35
pubspec.lock
35
pubspec.lock
@ -8,6 +8,41 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -44,6 +44,7 @@ dependencies:
|
||||
youtube_explode_dart: ^1.10.8
|
||||
mpv_dart: ^0.0.1
|
||||
infinite_scroll_pagination: ^3.1.0
|
||||
bitsdojo_window: ^0.1.1+1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Loading…
Reference in New Issue
Block a user