import playlist feat wip

This commit is contained in:
liyaowhen
2024-08-13 21:19:26 -07:00
parent 60cfb31919
commit 7dee91725f
24 changed files with 1013 additions and 136 deletions
@@ -0,0 +1 @@
disable = true
+4
View File
@@ -0,0 +1,4 @@
{
"C_Cpp.default.compileCommands": "/home/liyaowhen/Documents/YoutubeCollector/youtubecollector/builddir/compile_commands.json",
"C_Cpp.default.configurationProvider": "mesonbuild.mesonbuild"
}
+41 -4
View File
@@ -1,7 +1,7 @@
{ {
"id" : "com.liyaowhen.YoutubeCollector", "id" : "com.liyaowhen.YoutubeCollector",
"runtime" : "org.gnome.Platform", "runtime" : "org.gnome.Platform",
"runtime-version" : "master", "runtime-version" : "46",
"sdk" : "org.gnome.Sdk", "sdk" : "org.gnome.Sdk",
"sdk-extensions" : [ "sdk-extensions" : [
"org.freedesktop.Sdk.Extension.vala" "org.freedesktop.Sdk.Extension.vala"
@@ -12,7 +12,21 @@
"--share=ipc", "--share=ipc",
"--socket=fallback-x11", "--socket=fallback-x11",
"--device=dri", "--device=dri",
"--socket=wayland" "--socket=wayland",
"--socket=x11",
"--socket=wayland",
"--talk-name=org.freedesktop.DBus",
"--talk-name=org.freedesktop.portal.Desktop",
"--system-talk-name=org.freedesktop.UDisks2",
"--system-talk-name=org.freedesktop.UPower",
"--filesystem=host",
"--filesystem=home",
"--filesystem=xdg-download",
"--filesystem=host-os",
"--talk-name=org.freedesktop.DBus",
"--own-name=org.freedesktop.DBus",
"--session-bus=yes",
"--system-bus=yes"
], ],
"build-options" : { "build-options" : {
"append-path" : "/usr/lib/sdk/vala/bin", "append-path" : "/usr/lib/sdk/vala/bin",
@@ -31,14 +45,37 @@
"*.a" "*.a"
], ],
"modules" : [ "modules" : [
{ {
"name": "vte",
"buildsystem": "meson",
"config-opts": ["-Dgtk4=true", "-Dgtk3=false", "-Dsixel=true"],
"sources": [
{
"type": "archive",
"url": "https://gitlab.gnome.org/GNOME/vte/-/archive/3c8f66be867aca6656e4109ce880b6ea7431b895/vte-3c8f66be867aca6656e4109ce880b6ea7431b895.tar.gz",
"sha256": "320618260a29c99ab68d1e8674f6d4926bbf1e7e6541e8e04898fad85bb6e1b9"
}
]
},
{
"name": "json-glib",
"buildsystem": "meson",
"sources": [
{
"type": "archive",
"url": "https://gitlab.gnome.org/GNOME/json-glib/-/archive/23ae2f59bea7405d95218e82edb7f3c4c7c80a87/json-glib-23ae2f59bea7405d95218e82edb7f3c4c7c80a87.tar.gz",
"sha256": "9fa88f1b8fc926bfd7c4115354a06f79b7b30fa367450a3e7a36932e3b7022ba"
}
]
},
{
"name" : "youtubecollector", "name" : "youtubecollector",
"builddir" : true, "builddir" : true,
"buildsystem" : "meson", "buildsystem" : "meson",
"sources" : [ "sources" : [
{ {
"type" : "git", "type" : "git",
"url" : "file:///home/liyaowhen/Documents/YoutubeCollector/youtubecollector" "url" : "https://gitlab.com/liyaowhen/song"
} }
] ]
} }
@@ -0,0 +1,15 @@
id: com.liyaowhen.YoutubeCollector
runtime: org.freedesktop.Platform
runtime-version: '23.08'
sdk: org.freedesktop.Sdk
command: hello
modules:
- name: hello
buildsystem: simple
build-commands:
- install -Dm755 hello.sh /app/bin/hello
sources:
- type: script
dest-filename: hello.sh
commands:
- echo "Hello world, from a sandbox"
+550
View File
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -18,10 +18,10 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
namespace Song { namespace YoutubeCollector {
public class Application : Adw.Application { public class Application : Adw.Application {
public Application () { public Application () {
Object (application_id: "com.liyaowhen.Song", flags: ApplicationFlags.DEFAULT_FLAGS); Object (application_id: "com.liyaowhen.YoutubeCollector", flags: ApplicationFlags.DEFAULT_FLAGS);
} }
construct { construct {
@@ -41,7 +41,7 @@ namespace Song {
base.activate (); base.activate ();
var win = this.active_window; var win = this.active_window;
if (win == null) { if (win == null) {
win = new Song.Window (this); win = new YoutubeCollector.Window (this);
} }
win.present (); win.present ();
@@ -52,7 +52,7 @@ namespace Song {
var about = new Adw.AboutWindow () { var about = new Adw.AboutWindow () {
transient_for = this.active_window, transient_for = this.active_window,
application_name = "song", application_name = "song",
application_icon = "com.liyaowhen.Song", application_icon = "com.liyaowhen.YoutubeCollector",
developer_name = "Leo Wen", developer_name = "Leo Wen",
version = "0.1.0", version = "0.1.0",
developers = developers, developers = developers,
+1 -1
View File
@@ -1,4 +1,4 @@
namespace Song { namespace YoutubeCollector {
class BackgroundContainer : Gtk.DrawingArea { class BackgroundContainer : Gtk.DrawingArea {
// WIP entirely // WIP entirely
// TODO: make this able to // TODO: make this able to
+108
View File
@@ -0,0 +1,108 @@
using Gtk;
namespace YoutubeCollector {
/* to ensure that doing things on the main_view_content or sidebar_content
in this SongController allows for those objects to exist, instead of
doing functions related to this controller in the bare construct {},
put it in a signal that will be released when the SongController is ready to use */
public class AppController : Object {
public static MainViewContent main_view_content; // main view content should avoid using this controller during instanciation
public static SideBarContent sidebar_content;
public static SideBar side_bar;
public static Adw.OverlaySplitView split_view;
public static MainView main_view;
public static SongControls song_controls;
public static YoutubeCollector.Window window;
public static Adw.ToastOverlay toast_overlay = new Adw.ToastOverlay();
public static string app_data_dir = Path.build_filename (Environment.get_user_data_dir (), "com.liyaowhen.YoutubeCollector");
public static async void append_yt_playlist(PlaylistObject playlist, string source) {
try {
GLib.Dir dir = GLib.Dir.open(Path.build_filename(Environment.get_user_data_dir(), "com.liyaowhen.YoutubeCollector", playlist.name));
Gee.HashSet<string> files = new Gee.HashSet<string>();
string? filename;
while ((filename = dir.read_name()) != null) {
files.add(filename);
}
playlist.items.foreach((i) => {
if (files.contains(i.file)) {
files.remove(i.file);
}
});
files.foreach((i) => {
PlaylistItem item = new PlaylistItem();
item.source = source;
item.file = i;
item.name = i;
playlist.add_item(item);
return true;
});
var config = Config.get_instance();
config.save.begin();
} catch (GLib.FileError e) {
print(e.message);
}
}
}
public class SignalHub : Object {
private static SignalHub? instance = null;
public signal void mouse_clicked();
public signal void enter_yt_search_mode();
public signal void exit_yt_search_mode();
public signal void request_search(string query);
public YtSearchBar yt_search_bar;
public signal void start_drag();
public signal void end_drag();
public bool isDragging = false;
public static SignalHub get_instance () {
if (instance == null) {
instance = new SignalHub();
}
return instance;
}
}
public class ActiveProcesses : Object {
public Gee.HashSet<string> active_subprocesses = new Gee.HashSet<string>();
public signal void add_process(string id) {
active_subprocesses.add(id);
}
public signal void process_completed(string process) {
active_subprocesses.remove(process);
}
public static ActiveProcesses? instance = null;
public static ActiveProcesses get_instance() {
if (instance == null) {
instance = new ActiveProcesses();
}
return instance;
}
}
}
-49
View File
@@ -1,49 +0,0 @@
using Gtk;
namespace Song {
/* to ensure that doing things on the main_view_content or sidebar_content
in this SongController allows for those objects to exist, instead of
doing functions related to this controller in the bare construct {},
put it in a signal that will be released when the SongController is ready to use */
public class SongController : Object {
public static MainViewContent main_view_content; // main view content should avoid using this controller during instanciation
public static SideBarContent sidebar_content;
public static SideBar side_bar;
public static Adw.OverlaySplitView split_view;
public static MainView main_view;
public static SongControls song_controls;
public static Song.Window window;
public static Adw.ToastOverlay toast_overlay = new Adw.ToastOverlay();
}
public class SignalHub : Object {
private static SignalHub? instance = null;
public signal void mouse_clicked();
public signal void enter_yt_search_mode();
public signal void exit_yt_search_mode();
public signal void request_search(string query);
public YtSearchBar yt_search_bar;
public signal void start_drag();
public signal void end_drag();
public bool isDragging = false;
public static SignalHub get_instance () {
if (instance == null) {
instance = new SignalHub();
}
return instance;
}
}
}
+51 -10
View File
@@ -25,7 +25,7 @@
*/ */
namespace Song { namespace YoutubeCollector {
public enum PlaylistType { public enum PlaylistType {
VIDEO_ONLY = 0, VIDEO_ONLY = 0,
@@ -101,15 +101,30 @@ namespace Song {
_playList.name = member_name; _playList.name = member_name;
// TODO: ADD PROPERTIES _playList.properties = whatever // TODO: ADD PROPERTIES _playList.properties = whatever
// TODO: fix item iterator, it is invalid as it calls on each member, not each "object" // TODO: fix item iterator, it is invalid as it calls on each member, not each "object"
Json.Object? items_object = null; Json.Array? items_object = null;
if (object.has_member("items")) { if (object.has_member("items")) {
items_object = object.get_object_member("items"); items_object = object.get_array_member("items");
} }
if (items_object != null) { if (items_object != null) {
var items_list = items_object.get_members(); var item_iterator = items_object.get_length();
items_list.foreach((item) => {
for (int i = 0; i < item_iterator; i++) {
PlaylistItem _item = new PlaylistItem(); PlaylistItem _item = new PlaylistItem();
var _item_object = items_object.get_object_member(item); var _item_object = items_object.get_object_element(i);
_item.item_type = _item_object.get_int_member("item_type");
_item.name = _item_object.get_string_member("name");
_item.file = _item_object.get_string_member("file");
if (_item_object.has_member("picture")) {
_item.picture = _item_object.get_string_member("picture");
}
if (_item_object.has_member("source")) {
_item.picture = _item_object.get_string_member("source");
}
_playList.items.append(_item);
}
/*items_list.foreach((item) => {
PlaylistItem _item = new PlaylistItem();
var _item_object = items_object.get_(item);
_item.item_type = _item_object.get_int_member("item_type"); _item.item_type = _item_object.get_int_member("item_type");
_item.name = item; _item.name = item;
_item.file = _item_object.get_string_member("file"); _item.file = _item_object.get_string_member("file");
@@ -120,7 +135,7 @@ namespace Song {
_item.picture = _item_object.get_string_member("source"); _item.picture = _item_object.get_string_member("source");
} }
_playList.items.append(_item); _playList.items.append(_item);
}); });*/
} }
} }
@@ -142,6 +157,22 @@ namespace Song {
return playlists.; return playlists.;
}*/ }*/
public bool allocate_playlist_space(PlaylistObject playlist) {
string app_data_dir = Path.build_filename(Environment.get_user_data_dir(), "com.liyaowhen.YoutubeCollector");
var playlist_folder = Path.build_filename(app_data_dir, playlist.name);
var playlist_folder_item = File.new_for_path(playlist_folder);
if (!playlist_folder_item.query_exists(null)) {
try {
playlist_folder_item.make_directory_with_parents(null);
} catch (Error e) {
print(e.message);
}
return true;
} else {
return false;
}
}
// Save configuration to file // Save configuration to file
public async void save() { public async void save() {
@@ -171,7 +202,7 @@ namespace Song {
// items // items
builder.set_member_name("items"); builder.set_member_name("items");
builder.begin_object(); builder.begin_array();
// foreach item // foreach item
item.items.foreach((e) => { item.items.foreach((e) => {
@@ -179,7 +210,7 @@ namespace Song {
builder.begin_object(); builder.begin_object();
builder.set_member_name("name"); builder.set_member_name("name");
builder.add_string_value("name"); builder.add_string_value(e.name);
builder.set_member_name("item_type"); builder.set_member_name("item_type");
builder.add_int_value(e.item_type); builder.add_int_value(e.item_type);
@@ -201,7 +232,7 @@ namespace Song {
}); });
// items end // items end
builder.end_object(); builder.end_array();
builder.end_object(); builder.end_object();
} }
@@ -244,6 +275,16 @@ namespace Song {
Config.get_instance().save.begin(); // Create the file with default values Config.get_instance().save.begin(); // Create the file with default values
} }
string data_dir = Environment.get_user_data_dir();
File data = File.new_for_path(data_dir);
if (!data.query_exists(null)) {
try {
data.make_directory_with_parents(null);
} catch (Error e) {
print("Error creating directory: %s\n", e.message);
}
}
} }
} }
} }
+4 -4
View File
@@ -1,14 +1,14 @@
int main (string[] args) { int main (string[] args) {
Gst.init(ref args); Gst.init(ref args);
Song.Config.init("com.liyaowhen.Song"); YoutubeCollector.Config.init("com.liyaowhen.YoutubeCollector");
var config = Song.Config.get_instance (); var config = YoutubeCollector.Config.get_instance ();
Song.PlaylistObject playlist = new Song.PlaylistObject(); YoutubeCollector.PlaylistObject playlist = new YoutubeCollector.PlaylistObject();
playlist.name = "QQ"; playlist.name = "QQ";
var app = new Song.Application (); var app = new YoutubeCollector.Application ();
return app.run (args); return app.run (args);
} }
+2 -1
View File
@@ -7,13 +7,14 @@ youtubecollector_sources = [
'json_config.vala', 'json_config.vala',
'widgets/main_view.vala', 'widgets/main_view.vala',
'widgets/playlist.vala', 'widgets/playlist.vala',
'controllers/song_controller.vala', 'controllers/app_controller.vala',
'widgets/music_list_row.vala', 'widgets/music_list_row.vala',
'widgets/song_controls.vala', 'widgets/song_controls.vala',
'playlist_object.vala', 'playlist_object.vala',
'widgets/new_playlist_popover.vala', 'widgets/new_playlist_popover.vala',
'widgets/yt_search.vala', 'widgets/yt_search.vala',
'background.vala', 'background.vala',
'widgets/import_playlist_popover.vala',
] ]
youtubecollector_deps = [ youtubecollector_deps = [
+16 -5
View File
@@ -1,9 +1,9 @@
using GLib; using GLib;
namespace Song { namespace YoutubeCollector {
public class NewMusicPopover : Adw.Dialog { public class NewMusicPopover : Adw.Dialog {
private Settings settings = new Settings ("com.liyaowhen.Song"); private Settings settings = new Settings ("com.liyaowhen.YoutubeCollector");
public signal void download(); public signal void download();
@@ -13,7 +13,9 @@ namespace Song {
private Gtk.Button next_button; private Gtk.Button next_button;
private bool isPlaylistFolder; private bool isPlaylistFolder;
private string item_directory = Path.build_path("/", Environment.get_user_data_dir(), "com.liyaowhen.Song"); private PlaylistObject playlist;
private string item_directory = Path.build_path("/", Environment.get_user_data_dir(), "com.liyaowhen.YoutubeCollector");
public string song_title = ""; public string song_title = "";
public string song_url = ""; public string song_url = "";
@@ -89,6 +91,8 @@ namespace Song {
private void provide_ui() { private void provide_ui() {
playlist = AppController.main_view_content.current_playlist;
navigation_view_steps = new Adw.NavigationView(); navigation_view_steps = new Adw.NavigationView();
// starting page (choose what kind of app should be) // starting page (choose what kind of app should be)
@@ -224,6 +228,9 @@ namespace Song {
next_button.sensitive = false; next_button.sensitive = false;
steps_state = "online"; steps_state = "online";
item_directory = Path.build_path("/", item_directory, playlist.name);
print(item_directory);
var path = File.new_for_path(item_directory); var path = File.new_for_path(item_directory);
if (!path.query_exists(null)) { if (!path.query_exists(null)) {
try { try {
@@ -285,13 +292,17 @@ namespace Song {
PlaylistItem item = new PlaylistItem(); PlaylistItem item = new PlaylistItem();
item.name = song_title; item.name = song_title;
item.file = "%s.%s".printf(Path.build_filename(item_directory, song_title), "mp3"); item.file = "%s.%s".printf(song_title, "mp3");
item.source = song_url; item.source = song_url;
var main_content = SongController.main_view_content; var main_content = AppController.main_view_content;
main_content.current_playlist.add_item(item); main_content.current_playlist.add_item(item);
Config.get_instance().save.begin(); Config.get_instance().save.begin();
next_button.label = "Finish";
next_button.clicked.connect(() => {
close();
});
//TODO: implement //TODO: implement
} }
+1 -1
View File
@@ -1,4 +1,4 @@
namespace Song { namespace YoutubeCollector {
public class PlaylistObject : Object { public class PlaylistObject : Object {
Symlink
+1
View File
@@ -0,0 +1 @@
/home/liyaowhen/Documents/YoutubeCollector/youtubecollector/song
+77
View File
@@ -0,0 +1,77 @@
namespace YoutubeCollector {
public class ImportPlaylistPopover : Adw.AlertDialog {
private Adw.ToolbarView toolbar_view = new Adw.ToolbarView ();
private Gtk.Entry entry = new Gtk.Entry ();
construct {
var cancel_button = new Gtk.Button.with_label ("Cancel");
cancel_button.clicked.connect(() => {
close();
});
var import_button = new Gtk.Button.with_label ("Import");
import_button.clicked.connect(() => {
close();
Subprocess import_process;
SubprocessLauncher import_process_launcher = new SubprocessLauncher(GLib.SubprocessFlags.STDIN_PIPE | GLib.SubprocessFlags.STDOUT_PIPE | GLib.SubprocessFlags.STDERR_PIPE);
import_process_launcher.set_cwd(Path.build_filename (Environment.get_user_data_dir (), "com.liyaowhen.YoutubeCollector", AppController.main_view_content.current_playlist.name));
var active_processes = ActiveProcesses.get_instance ();
try {
import_process = import_process_launcher.spawnv ({ "yt-dlp", entry.get_text ()});
} catch (GLib.Error e) {
print(e.message);
}
string id = import_process.get_identifier ();
active_processes.add_process (id);
import_process.communicate_utf8_async.begin (null, null, (obj, res) => {
string? stdout;
string? stderr;
try {
import_process.communicate_utf8_async.end(res, out stdout, out stderr);
} catch (GLib.Error e) {
print(e.message);
}
if (stdout != null) {
print(stdout + "stdout");
active_processes.process_completed(id);
AppController.append_yt_playlist.begin (AppController.main_view_content.current_playlist, entry.get_text());
}
if (stderr != null) {
print ("STDERR: %s\n", stderr);
}
});
});
var bottom_bar = new Adw.HeaderBar();
bottom_bar.show_end_title_buttons = false;
bottom_bar.show_start_title_buttons = false;
bottom_bar.pack_start (cancel_button);
bottom_bar.pack_end (import_button);
var content = new Adw.Clamp();
content.set_margin_bottom (5);
content.set_margin_end (10);
content.set_margin_start (10);
content.set_margin_top (10);
content.set_child(entry);
entry.placeholder_text = "Add Youtube Playlist Link Here:";
toolbar_view.add_bottom_bar (bottom_bar);
toolbar_view.set_content(content);
set_child(toolbar_view);
}
}
}
+89 -17
View File
@@ -1,13 +1,14 @@
namespace Song { namespace YoutubeCollector {
public class MainView : Adw.NavigationPage { public class MainView : Adw.NavigationPage {
private Window window; private Window window;
public Settings settings = new Settings("com.liyaowhen.Song.playlists"); public Settings settings = new Settings("com.liyaowhen.YoutubeCollector.playlists");
public MainViewContent main_content; public MainViewContent main_content;
public PlaylistObject current_playlist; public PlaylistObject current_playlist;
private Gtk.Revealer add_button_revealer = new Gtk.Revealer(); private Gtk.Revealer add_buttons_revealer = new Gtk.Revealer();
private Gtk.Revealer controls_revealer = new Gtk.Revealer(); private Gtk.Revealer controls_revealer = new Gtk.Revealer();
private Gtk.Revealer exit_yt_search_mode_revealer = new Gtk.Revealer(); private Gtk.Revealer exit_yt_search_mode_revealer = new Gtk.Revealer();
private Gtk.Revealer active_processes_revealer = new Gtk.Revealer();
private Adw.HeaderBar action_bar; private Adw.HeaderBar action_bar;
@@ -17,7 +18,7 @@ namespace Song {
} }
construct { construct {
SongController.main_view = this; AppController.main_view = this;
// make ui // make ui
var toolbar_view = new Adw.ToolbarView (); var toolbar_view = new Adw.ToolbarView ();
@@ -39,15 +40,32 @@ namespace Song {
add_button_content.set_label("Add Item"); add_button_content.set_label("Add Item");
add_button.set_child(add_button_content); add_button.set_child(add_button_content);
add_button.valign = Gtk.Align.CENTER; add_button.valign = Gtk.Align.CENTER;
add_button_revealer.set_child(add_button);
add_button_revealer.set_reveal_child(true); var import_playlist = new Gtk.Button();
add_button_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT; var import_playlist_content = new Adw.ButtonContent();
import_playlist_content.set_icon_name("application-exit-symbolic");
import_playlist_content.set_label("Import Youtube Playlist");
import_playlist.set_child(import_playlist_content);
import_playlist.valign = Gtk.Align.CENTER;
var button_container = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
button_container.append(add_button);
button_container.append(import_playlist);
add_buttons_revealer.set_child(button_container);
add_buttons_revealer.set_reveal_child(true);
add_buttons_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT;
add_button.clicked.connect(() => { add_button.clicked.connect(() => {
var popover = new NewMusicPopover(); var popover = new NewMusicPopover();
popover.present(this); popover.present(this);
}); });
import_playlist.clicked.connect(() => {
var popover = new ImportPlaylistPopover();
popover.present(this);
});
var exit_yt_search_mode = new Gtk.Button.from_icon_name("go-previous-symbolic"); var exit_yt_search_mode = new Gtk.Button.from_icon_name("go-previous-symbolic");
exit_yt_search_mode.valign = Gtk.Align.CENTER; exit_yt_search_mode.valign = Gtk.Align.CENTER;
exit_yt_search_mode_revealer.set_child(exit_yt_search_mode); exit_yt_search_mode_revealer.set_child(exit_yt_search_mode);
@@ -58,31 +76,84 @@ namespace Song {
SignalHub.get_instance().exit_yt_search_mode(); SignalHub.get_instance().exit_yt_search_mode();
}); });
// active processes indicator
var active_processes_container = new Gtk.Box(Gtk.Orientation.VERTICAL, 5);
var active_processes_popover = new Gtk.Popover();
active_processes_popover.set_child(active_processes_container);
Gee.HashSet<Gtk.Box> job_boxes = new Gee.HashSet<Gtk.Box>();
var active_processes_button = new Gtk.MenuButton();
active_processes_button.set_popover(active_processes_popover);
active_processes_button.margin_top = 5;
active_processes_button.margin_bottom = 5;
//active_processes_button.add_css_class("suggested-action");
var active_processes_spinner = new Gtk.Spinner();
active_processes_spinner.spinning = true;
active_processes_button.set_child(active_processes_spinner);
active_processes_revealer.set_child(active_processes_button);
active_processes_revealer.set_reveal_child(false);
active_processes_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_LEFT);
var active_processes_controller = ActiveProcesses.get_instance();
var active_processes = active_processes_controller.active_subprocesses;
active_processes_controller.add_process.connect_after((process) => {
active_processes = active_processes_controller.active_subprocesses;
active_processes_revealer.set_reveal_child(true);
var job_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 5);
var job_title = new Gtk.Label(process);
var job_progress = new Gtk.ProgressBar();
job_box.append(job_title);
job_box.append(job_progress);
job_box.name = process;
job_boxes.add(job_box);
active_processes_container.append(job_box);
});
active_processes_controller.process_completed.connect_after((process) => {
job_boxes.foreach((i) => {
if (i.name == process) {
job_boxes.remove(i);
active_processes_container.remove(i);
if (active_processes.size == 0) {
active_processes_revealer.set_reveal_child(false);
}
print("removed");
}
});
});
action_bar = new Adw.HeaderBar(); action_bar = new Adw.HeaderBar();
action_bar.show_back_button = false; action_bar.show_back_button = false;
action_bar.title_widget = new YtSearchBar(); action_bar.title_widget = new YtSearchBar();
action_bar.pack_start(collapse_button); action_bar.pack_start(collapse_button);
action_bar.pack_start(add_button_revealer); action_bar.pack_start(add_buttons_revealer);
action_bar.pack_start(exit_yt_search_mode_revealer); action_bar.pack_start(exit_yt_search_mode_revealer);
action_bar.pack_end(active_processes_revealer);
action_bar.margin_start = 5; action_bar.margin_start = 5;
collapse_button.clicked.connect(() => { collapse_button.clicked.connect(() => {
if(SongController.split_view.get_collapsed ()){ if(AppController.split_view.get_collapsed ()){
SongController.split_view.show_sidebar = false; AppController.split_view.show_sidebar = false;
collapse_button.visible = true; collapse_button.visible = true;
} else { } else {
SongController.split_view.show_sidebar = true; AppController.split_view.show_sidebar = true;
collapse_button.visible = false; collapse_button.visible = false;
} }
}); });
Timeout.add(1, () => { Timeout.add(1, () => {
if (SongController.side_bar != null && SongController.split_view != null) { if (AppController.side_bar != null && AppController.split_view != null) {
if (SongController.split_view.get_show_sidebar()) { if (AppController.split_view.get_show_sidebar()) {
collapse_button.visible = false; collapse_button.visible = false;
} else collapse_button.visible = true; } else collapse_button.visible = true;
SongController.side_bar.collapsing.connect(() => { AppController.side_bar.collapsing.connect(() => {
collapse_button.visible = true; collapse_button.visible = true;
}); });
@@ -111,7 +182,7 @@ namespace Song {
private void instanciate_signals() { private void instanciate_signals() {
var signal_hub = SignalHub.get_instance(); var signal_hub = SignalHub.get_instance();
signal_hub.enter_yt_search_mode.connect(() => { signal_hub.enter_yt_search_mode.connect(() => {
add_button_revealer.set_reveal_child(false); add_buttons_revealer.set_reveal_child(false);
controls_revealer.set_reveal_child(false); controls_revealer.set_reveal_child(false);
exit_yt_search_mode_revealer.set_reveal_child(true); exit_yt_search_mode_revealer.set_reveal_child(true);
action_bar.set_margin_start(-5); action_bar.set_margin_start(-5);
@@ -119,7 +190,7 @@ namespace Song {
}); });
signal_hub.exit_yt_search_mode.connect(() => { signal_hub.exit_yt_search_mode.connect(() => {
add_button_revealer.set_reveal_child(true); add_buttons_revealer.set_reveal_child(true);
controls_revealer.set_reveal_child(true); controls_revealer.set_reveal_child(true);
exit_yt_search_mode_revealer.set_reveal_child(false); exit_yt_search_mode_revealer.set_reveal_child(false);
action_bar.set_margin_start(0); action_bar.set_margin_start(0);
@@ -175,7 +246,7 @@ namespace Song {
} }
construct { construct {
SongController.main_view_content = this; AppController.main_view_content = this;
var config = Config.get_instance(); var config = Config.get_instance();
config.config_changed.connect(() => { config.config_changed.connect(() => {
@@ -183,6 +254,7 @@ namespace Song {
if (config.playlists.length() == 1) { if (config.playlists.length() == 1) {
config.playlists.foreach((i) => { config.playlists.foreach((i) => {
change_page(i); change_page(i);
print("called");
return; return;
}); });
} }
+10 -10
View File
@@ -1,7 +1,7 @@
namespace Song { namespace YoutubeCollector {
public class MusicListRow : Gtk.Box { public class MusicListRow : Gtk.Box {
private Settings settings = new Settings("com.liyaowhen.Song.playlists"); private Settings settings = new Settings("com.liyaowhen.YoutubeCollector.playlists");
public PlaylistItem item; public PlaylistItem item;
private PlaylistObject playlist; private PlaylistObject playlist;
@@ -37,22 +37,22 @@ namespace Song {
play_button.add_css_class("flat"); play_button.add_css_class("flat");
play_button.clicked.connect(() => { play_button.clicked.connect(() => {
if (SongController.song_controls.current_item != item) { if (AppController.song_controls.current_item != item) {
SongController.song_controls.change_item(item); AppController.song_controls.change_item(item, playlist);
play_button.icon_name = "media-playback-pause-symbolic"; play_button.icon_name = "media-playback-pause-symbolic";
Timeout.add(1, () => { Timeout.add(1, () => {
if (SongController.song_controls.current_item != item) { if (AppController.song_controls.current_item != item) {
// when another song is called to play, reset the button state // when another song is called to play, reset the button state
play_button.icon_name = "media-playback-start-symbolic"; play_button.icon_name = "media-playback-start-symbolic";
return false; return false;
} }
return true; return true;
}); });
} else if (SongController.song_controls.isPlaying) { } else if (AppController.song_controls.isPlaying) {
SongController.song_controls.pause(); AppController.song_controls.pause();
play_button.icon_name = "media-playback-start-symbolic"; play_button.icon_name = "media-playback-start-symbolic";
} else if (!SongController.song_controls.isPlaying) { } else if (!AppController.song_controls.isPlaying) {
SongController.song_controls.play(); AppController.song_controls.play();
play_button.icon_name = "media-playback-pause-symbolic"; play_button.icon_name = "media-playback-pause-symbolic";
} }
}); });
@@ -65,7 +65,7 @@ namespace Song {
var add_playlists_menu = new Menu(); var add_playlists_menu = new Menu();
fill_playlists(add_playlists_menu); fill_playlists.begin(add_playlists_menu);
var menu = new Menu(); var menu = new Menu();
menu.append_section("Add To Other Playlists", add_playlists_menu); menu.append_section("Add To Other Playlists", add_playlists_menu);
+8 -3
View File
@@ -1,4 +1,4 @@
namespace Song { namespace YoutubeCollector {
public class NewPlaylistPopover : Adw.Dialog { public class NewPlaylistPopover : Adw.Dialog {
private bool valid_entry = false; private bool valid_entry = false;
@@ -51,8 +51,13 @@ namespace Song {
var config = Config.get_instance (); var config = Config.get_instance ();
var playlist = new PlaylistObject(); var playlist = new PlaylistObject();
playlist.name = entry.text; playlist.name = entry.text;
config.playlists.append(playlist); if (config.allocate_playlist_space (playlist)) {
config.save(); config.playlists.append(playlist);
config.save.begin();
close();
} else {
//TODO: return error for already existing playlist
}
} }
}); });
+2 -2
View File
@@ -1,4 +1,4 @@
namespace Song { namespace YoutubeCollector {
public class PlaylistButton : Gtk.Box { public class PlaylistButton : Gtk.Box {
@@ -38,7 +38,7 @@ namespace Song {
main_button.clicked.connect(() => { main_button.clicked.connect(() => {
//assumes that main_view is already instanciated //assumes that main_view is already instanciated
SongController.main_view_content.change_page(playlist); AppController.main_view_content.change_page(playlist);
}); });
Timeout.add(1, () => { Timeout.add(1, () => {
+10 -10
View File
@@ -1,8 +1,8 @@
namespace Song { namespace YoutubeCollector {
public class SideBar : Adw.NavigationPage { public class SideBar : Adw.NavigationPage {
private Settings settings = new Settings("com.liyaowhen.Song"); private Settings settings = new Settings("com.liyaowhen.YoutubeCollector");
private Window window; private Window window;
public SideBarContent side_bar_content; public SideBarContent side_bar_content;
@@ -17,17 +17,17 @@ namespace Song {
} }
construct { construct {
SongController.side_bar = this; AppController.side_bar = this;
var toolbar_view = new Adw.ToolbarView(); var toolbar_view = new Adw.ToolbarView();
var collapse_button = new Gtk.Button.from_icon_name ("folder-open-symbolic"); var collapse_button = new Gtk.Button.from_icon_name ("folder-open-symbolic");
collapse_button.clicked.connect(() => { collapse_button.clicked.connect(() => {
if(SongController.split_view.get_show_sidebar()){ if(AppController.split_view.get_show_sidebar()){
SongController.split_view.show_sidebar = false; AppController.split_view.show_sidebar = false;
collapse_button.set_icon_name("folder-open-symbolic"); collapse_button.set_icon_name("folder-open-symbolic");
} else { } else {
SongController.split_view.show_sidebar = true; AppController.split_view.show_sidebar = true;
collapse_button.set_icon_name("folder-symbolic"); collapse_button.set_icon_name("folder-symbolic");
} }
collapsing(); collapsing();
@@ -70,7 +70,7 @@ namespace Song {
public class SideBarContent : Gtk.Box { public class SideBarContent : Gtk.Box {
private Settings settings = new Settings("com.liyaowhen.Song.playlists"); private Settings settings = new Settings("com.liyaowhen.YoutubeCollector.playlists");
public Gee.HashSet<PlaylistButton> playlist_buttons = new Gee.HashSet<PlaylistButton>(); public Gee.HashSet<PlaylistButton> playlist_buttons = new Gee.HashSet<PlaylistButton>();
private MainView main_view; private MainView main_view;
@@ -148,15 +148,15 @@ namespace Song {
//print("sidbar requesting main_view_content switch to playlist of name:\n" + playlists.nth_data(0).name); //print("sidbar requesting main_view_content switch to playlist of name:\n" + playlists.nth_data(0).name);
Timeout.add(1, () => { Timeout.add(1, () => {
if (SongController.main_view_content != null) { if (AppController.main_view_content != null) {
if (initial_playlist != null) { if (initial_playlist != null) {
SongController.main_view_content.change_page(initial_playlist); AppController.main_view_content.change_page(initial_playlist);
return false; return false;
} }
} }
return true; return true;
}, 1); }, 1);
SongController.sidebar_content = this; AppController.sidebar_content = this;
//reconfigure_playlist_button_group(); DOES NOT WORK FOR SOME REASON //reconfigure_playlist_button_group(); DOES NOT WORK FOR SOME REASON
+12 -9
View File
@@ -1,19 +1,23 @@
using Gst; using Gst;
/*
TODO: Work towards removing song controller entirely, instead use external apps to preview the files instead
*/
namespace Song { namespace YoutubeCollector {
public class SongControls : Gtk.Box { public class SongControls : Gtk.Box {
private Settings songs_list = new Settings("com.liyaowhen.Song.playlists"); private Settings songs_list = new Settings("com.liyaowhen.YoutubeCollector.playlists");
private Settings settings = new Settings("com.liyaowhen.Song"); private Settings settings = new Settings("com.liyaowhen.YoutubeCollector");
public Gtk.Scale progress_bar; public Gtk.Scale progress_bar;
public Gtk.Adjustment progress_bar_adjustment; public Gtk.Adjustment progress_bar_adjustment;
public PlaylistObject? playlist = null;
private bool isDragging; private bool isDragging;
private Gtk.Button progress_bar_controller; private Gtk.Button progress_bar_controller;
private uint? seekTimeout = null; private uint? seekTimeout = null;
private string item_directory = Path.build_path("/", Environment.get_user_config_dir(), "com.liyaowhen.Song"); private string item_directory = Path.build_path("/", Environment.get_user_config_dir(), "com.liyaowhen.YoutubeCollector");
public bool isPlaying; public bool isPlaying;
public PlaylistItem current_item; public PlaylistItem current_item;
@@ -102,7 +106,7 @@ namespace Song {
// add controls to control the music // add controls to control the music
music_controls(); music_controls();
SongController.song_controls = this; AppController.song_controls = this;
} }
@@ -160,13 +164,12 @@ namespace Song {
isPlaying = false; isPlaying = false;
} }
public void change_item(PlaylistItem item) { public void change_item(PlaylistItem item, PlaylistObject playlist) {
this.playlist = playlist;
print("song is now " + item.name + "\n"); print("song is now " + item.name + "\n");
current_item = item; current_item = item;
string file_path = item.file;
print("song full path is " + file_path);
playbin.set_state(Gst.State.NULL); playbin.set_state(Gst.State.NULL);
playbin.set_property("uri", File.new_for_path(file_path).get_uri()); playbin.set_property("uri", File.new_build_filename(Environment.get_user_data_dir(), "com.liyaowhen.YoutubeCollector", playlist.name, item.file).get_uri());
playbin.set_start_time(0); playbin.set_start_time(0);
playbin.set_state(Gst.State.PLAYING); playbin.set_state(Gst.State.PLAYING);
isPlaying = true; isPlaying = true;
+2 -2
View File
@@ -1,4 +1,4 @@
namespace Song { namespace YoutubeCollector {
public enum YtSearchBarStates { public enum YtSearchBarStates {
ENLARGING, ENLARGING,
SHRINKING, SHRINKING,
@@ -238,7 +238,7 @@ namespace Song {
} }
try { try {
search_process = new Subprocess(GLib.SubprocessFlags.STDIN_PIPE | GLib.SubprocessFlags.STDOUT_PIPE | GLib.SubprocessFlags.STDERR_PIPE, search_process = new Subprocess(GLib.SubprocessFlags.STDIN_PIPE | GLib.SubprocessFlags.STDOUT_PIPE | GLib.SubprocessFlags.STDERR_PIPE,
Environment.get_user_config_dir() + "/com.liyaowhen.Song/search-utility", query); Environment.get_user_config_dir() + "/com.liyaowhen.YoutubeCollector/search-utility", query);
} catch (GLib.Error e) { } catch (GLib.Error e) {
print(e.message); print(e.message);
} }
+4 -4
View File
@@ -1,8 +1,8 @@
namespace Song { namespace YoutubeCollector {
public class Window : Adw.ApplicationWindow { public class Window : Adw.ApplicationWindow {
private Settings settings = new Settings ("com.liyaowhen.Song"); private Settings settings = new Settings ("com.liyaowhen.YoutubeCollector");
public SideBar sidebar; public SideBar sidebar;
public MainView main_view; public MainView main_view;
public Gtk.ShortcutAction ctrl_z = new Gtk.SignalAction("ctrl_z"); public Gtk.ShortcutAction ctrl_z = new Gtk.SignalAction("ctrl_z");
@@ -13,7 +13,7 @@ namespace Song {
construct { construct {
SongController.window = this; AppController.window = this;
var provider = new Gtk.CssProvider(); var provider = new Gtk.CssProvider();
provider.load_from_path("style.css"); provider.load_from_path("style.css");
@@ -66,7 +66,7 @@ namespace Song {
split_view.set_sidebar (sidebar); split_view.set_sidebar (sidebar);
split_view.set_content(main_view); split_view.set_content(main_view);
split_view.collapsed = false; split_view.collapsed = false;
SongController.split_view = split_view; AppController.split_view = split_view;