Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show grey song #211

Merged
merged 2 commits into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions data/com.gitee.gmg137.NeteaseCloudMusicGtk4.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,9 @@
<default>1.0</default>
<summary>Volume</summary>
</key>
<key name="not-ignore-grey" type="b">
<default>false</default>
<summary>Always try to play grey song</summary>
</key>
</schema>
</schemalist>
14 changes: 14 additions & 0 deletions data/gtk/preferences.ui
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Not ignore grey song</property>
<property name="subtitle" translatable="yes">Always try to play grey song</property>
<property name="use_underline">True</property>
<property name="activatable-widget">not_ignore_grey_switch</property>
<child>
<object class="GtkSwitch" id="not_ignore_grey_switch">
<property name="valign">center</property>
<property name="state">False</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Network Proxy</property>
Expand Down
8 changes: 8 additions & 0 deletions data/gtk/songlist-page.ui
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="time_label">
<property name="label"></property>
<property name="halign">start</property>
<property name="valign">end</property>
<property name="visible">False</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="halign">fill</property>
Expand Down
3 changes: 3 additions & 0 deletions data/gtk/songlist-row.ui
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<property name="focusable">False</property>
<property name="selectable">False</property>
<property name="height-request">59</property>
<style>
<class name="song_row" />
</style>
<child>
<object class="GtkBox">
<property name="focusable">False</property>
Expand Down
8 changes: 8 additions & 0 deletions data/themes/discover.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,11 @@ flowboxchild:active {
margin-right: 24px;
padding: 6px;
}

.song_row label {
opacity: 0.5;
}

.song_row.activatable label {
opacity: 1;
}
70 changes: 36 additions & 34 deletions src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use glib::{clone, timeout_future, timeout_future_seconds, MainContext, Receiver,
use gtk::{gio, glib, prelude::*};
use log::*;
use ncm_api::{
AlbumDetailDynamic, BannersInfo, CookieJar, DetailDynamic, LoginInfo, SingerInfo, SongInfo,
SongList, SongListDetailDynamic, TopList,
AlbumDetailDynamic, BannersInfo, CookieJar, LoginInfo, PlayListDetailDynamic, SingerInfo,
SongInfo, SongList, TopList,
};
use once_cell::sync::OnceCell;
use std::fs;
Expand Down Expand Up @@ -693,7 +693,7 @@ impl NeteaseCloudMusicGtk4Application {
window.play(song_info);
}
Action::ToSongListPage(songlist) => {
let page = window.init_songlist_page(&songlist);
let page = window.init_songlist_page(&songlist, false);
window.page_new(&page, &songlist.name);
let page = page.downgrade();

Expand All @@ -702,16 +702,15 @@ impl NeteaseCloudMusicGtk4Application {
ctx.spawn_local(async move {
let detal_dynamic_as = ncmapi.client.songlist_detail_dynamic(songlist.id);
match ncmapi.client.song_list_detail(songlist.id).await {
Ok(sis) => {
debug!("获取歌单详情: {:?}", sis);
let dy = DetailDynamic::SongList(
detal_dynamic_as.await.unwrap_or_else(|err| {
error!("{:?}", err);
SongListDetailDynamic::default()
}),
);
Ok(detail) => {
debug!("获取歌单详情: {:?}", detail);
let dy = detal_dynamic_as.await.unwrap_or_else(|err| {
error!("{:?}", err);
PlayListDetailDynamic::default()
});
let detail = SongListDetail::PlayList(detail, dy);
if let Some(page) = page.upgrade() {
window.update_songlist_page(page, sis, dy);
window.update_songlist_page(page, &detail);
}
}
Err(err) => {
Expand All @@ -726,7 +725,7 @@ impl NeteaseCloudMusicGtk4Application {
});
}
Action::ToAlbumPage(songlist) => {
let page = window.init_songlist_page(&songlist);
let page = window.init_songlist_page(&songlist, true);
window.page_new(&page, &songlist.name);
let page = page.downgrade();

Expand All @@ -735,16 +734,15 @@ impl NeteaseCloudMusicGtk4Application {
ctx.spawn_local(async move {
let detal_dynamic_as = ncmapi.client.album_detail_dynamic(songlist.id);
match ncmapi.client.album(songlist.id).await {
Ok(sis) => {
debug!("获取专辑详情: {:?}", sis);
let dy = DetailDynamic::Album(detal_dynamic_as.await.unwrap_or_else(
|err| {
error!("{:?}", err);
AlbumDetailDynamic::default()
},
));
Ok(detail) => {
debug!("获取专辑详情: {:?}", detail);
let dy = detal_dynamic_as.await.unwrap_or_else(|err| {
error!("{:?}", err);
AlbumDetailDynamic::default()
});
let detail = SongListDetail::Album(detail, dy);
if let Some(page) = page.upgrade() {
window.update_songlist_page(page, sis, dy);
window.update_songlist_page(page, &detail);
}
}
Err(err) => {
Expand Down Expand Up @@ -871,9 +869,9 @@ impl NeteaseCloudMusicGtk4Application {
let ctx = glib::MainContext::default();
ctx.spawn_local(async move {
match ncmapi.client.song_list_detail(id).await {
Ok(sis) => {
debug!("获取榜单 {} 详情:{:?}", id, sis);
sender.send(Action::UpdateTopList(sis)).unwrap();
Ok(detail) => {
debug!("获取榜单 {} 详情:{:?}", id, detail);
sender.send(Action::UpdateTopList(detail.songs)).unwrap();
}
Err(err) => {
error!("获取榜单 {} 失败! {:?}", id, err);
Expand Down Expand Up @@ -973,16 +971,20 @@ impl NeteaseCloudMusicGtk4Application {
Ok(sls) => {
debug!("获取心动歌单:{:?}", sls);
if !sls.is_empty() {
if let Ok(sis) = ncmapi.client.song_list_detail(sls[0].id).await {
if let Some(page) = page.upgrade() {
window.update_search_song_page(page, sis);
match ncmapi.client.song_list_detail(sls[0].id).await {
Ok(detail) => {
if let Some(page) = page.upgrade() {
window.update_search_song_page(page, detail.songs);
}
}
Err(err) => {
error!("{:?}", err);
sender
.send(Action::AddToast(gettext(
"Failed to get song list details!",
)))
.unwrap();
}
} else {
sender
.send(Action::AddToast(gettext(
"Failed to get song list details!",
)))
.unwrap();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/gui/discover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ mod imp {
pic_url: banner.pic_url.to_owned(),
duration: banner.duration.to_owned(),
song_url: "".to_owned(),
copyright: ncm_api::SongCopyright::Unknown,
};
let sender = self.sender.get().unwrap();
sender.send(Action::AddPlay(song_info)).unwrap();
Expand Down
13 changes: 12 additions & 1 deletion src/gui/player_controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,16 @@ impl PlayerControls {
}

pub fn add_list(&self, list: Vec<SongInfo>) {
let settings = self.settings();
let not_ignore_grey = settings.get("not-ignore-grey");
let list: Vec<SongInfo> = if not_ignore_grey {
list
} else {
list.into_iter()
.filter(|si| si.copyright.playable())
.collect()
};

if let Ok(mut playlist) = self.imp().playlist.lock() {
playlist.add_list(list);
}
Expand Down Expand Up @@ -718,8 +728,9 @@ mod imp {
album: String::new(),
album_id: 0,
pic_url: String::new(),
duration: String::new(),
duration: 0,
song_url: String::new(),
copyright: ncm_api::SongCopyright::Unknown,
})
.to_owned();
let sender = self.sender.get().unwrap().clone();
Expand Down
13 changes: 12 additions & 1 deletion src/gui/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ impl NeteaseCloudMusicGtk4Preferences {
.flags(SettingsBindFlags::DEFAULT)
.build();

let not_ignore_grey_switch = self.imp().not_ignore_grey_switch.get();
self.settings()
.bind("not-ignore-grey", &not_ignore_grey_switch, "state")
.flags(SettingsBindFlags::DEFAULT)
.build();

let entry = self.imp().proxy_entry.get();
self.settings()
.bind("proxy-address", &entry, "text")
Expand All @@ -66,7 +72,10 @@ impl NeteaseCloudMusicGtk4Preferences {
}

pub fn set_cache_size_label(&self, size: f64, unit: String) {
self.imp().cache_clear.get().set_property("subtitle", format!("{:.1} {}", size, unit));
self.imp()
.cache_clear
.get()
.set_property("subtitle", format!("{:.1} {}", size, unit));
}
}

Expand All @@ -91,6 +100,8 @@ mod imp {
#[template_child]
pub mute_start_switch: TemplateChild<Switch>,
#[template_child]
pub not_ignore_grey_switch: TemplateChild<Switch>,
#[template_child]
pub proxy_entry: TemplateChild<Entry>,
#[template_child]
pub switch_rate: TemplateChild<adw::ComboRow>,
Expand Down
63 changes: 43 additions & 20 deletions src/gui/songlist_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
use gettextrs::gettext;
use glib::{ParamSpec, ParamSpecBoolean, SendWeakRef, Sender, Value};
pub(crate) use gtk::{glib, prelude::*, subclass::prelude::*, CompositeTemplate, *};
use ncm_api::{DetailDynamic, SongInfo, SongList};
use ncm_api::{SongList};
use once_cell::sync::{Lazy, OnceCell};

use crate::{
application::Action, gui::songlist_view::SongListView, model::DiscoverSubPage, path::CACHE,
application::Action,
gui::songlist_view::SongListView,
model::{DiscoverSubPage, SongListDetail},
path::CACHE,
};
use std::{
cell::{Cell, RefCell},
Expand All @@ -34,11 +37,15 @@ impl SonglistPage {
self.imp().sender.set(sender).unwrap();
}

pub fn init_songlist_info(&self, songlist: &SongList, is_logined: bool) {
pub fn init_songlist_info(&self, songlist: &SongList, is_album: bool, is_logined: bool) {
let imp = self.imp();
let sender = imp.sender.get().unwrap();
imp.songlist.replace(Some(songlist.to_owned()));

if is_album {
imp.time_label.set_visible(true);
}

// 判断是否显示收藏按钮
let like_button = imp.like_button.get();
if is_logined {
Expand Down Expand Up @@ -81,33 +88,48 @@ impl SonglistPage {
imp.songs_list.clear_list();
}

pub fn init_songlist(&self, sis: &[SongInfo], dy: DetailDynamic, likes: &[bool]) {
pub fn init_songlist(&self, detail: &SongListDetail, likes: &[bool]) {
let imp = self.imp();
let songs_list = imp.songs_list.get();
match dy {
DetailDynamic::Album(dy) => {

let sis = detail.sis();

match detail {
SongListDetail::Album(detail, dy) => {
self.set_property("like", dy.is_sub);
imp.songs_list.set_property("no-act-album", true);
imp.page_type.replace(Some(DiscoverSubPage::Album));
imp.num_label.get().set_label(&gettext!(
"{} songs, {} favs",
sis.len(),
dy.sub_count
{
let year = detail.publish_time as f64 / (1000.0 * 60.0 * 60.0 * 24.0 * 365.25)
+ 1970.0;
let duration_min = sis
.iter()
.fold(0u64, |v, next| v + next.duration / (1000 * 60));

imp.time_label.set_label(&format!(
"{}, {}",
year as u64,
gettext!("{} min", duration_min),
));
}
imp.num_label.set_label(&format!(
"{}, {}",
gettext!("{} songs", sis.len()),
gettext!("{} favs", dy.sub_count)
));
}
DetailDynamic::SongList(dy) => {
SongListDetail::PlayList(_detail, dy) => {
self.set_property("like", dy.subscribed);
imp.songs_list.set_property("no-act-album", false);
imp.page_type.replace(Some(DiscoverSubPage::SongList));
imp.num_label.get().set_label(&gettext!(
"{} songs, {} favs",
sis.len(),
dy.booked_count
imp.num_label.set_label(&format!(
"{}, {}",
gettext!("{} songs", sis.len()),
gettext!("{} favs", dy.booked_count)
));
}
}

imp.playlist.replace(Clone::clone(&sis).to_vec());
let sender = imp.sender.get().unwrap();
songs_list.set_sender(sender.clone());
songs_list.init_new_list(sis, likes);
Expand All @@ -131,6 +153,8 @@ mod imp {
pub cover_image: TemplateChild<Image>,
#[template_child(id = "title_label")]
pub title_label: TemplateChild<Label>,
#[template_child(id = "time_label")]
pub time_label: TemplateChild<Label>,
#[template_child(id = "num_label")]
pub num_label: TemplateChild<Label>,
#[template_child(id = "play_button")]
Expand All @@ -141,7 +165,6 @@ mod imp {
#[template_child(id = "songs_list")]
pub songs_list: TemplateChild<SongListView>,

pub playlist: Rc<RefCell<Vec<SongInfo>>>,
pub songlist: Rc<RefCell<Option<SongList>>>,
pub page_type: Rc<RefCell<Option<DiscoverSubPage>>>,

Expand Down Expand Up @@ -171,9 +194,9 @@ mod imp {
#[template_callback]
fn play_button_clicked_cb(&self) {
let sender = self.sender.get().unwrap();
if !self.playlist.borrow().is_empty() {
let playlist = &*self.playlist.borrow();
sender.send(Action::AddPlayList(playlist.clone())).unwrap();
let playlist = self.songs_list.get_songinfo_list();
if !playlist.is_empty() {
sender.send(Action::AddPlayList(playlist)).unwrap();
} else {
sender
.send(Action::AddToast(gettext("This is an empty song list!")))
Expand Down
Loading