Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package netease-cloud-music-gtk for
openSUSE:Factory checked in at 2021-01-18 11:27:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/netease-cloud-music-gtk (Old)
and /work/SRC/openSUSE:Factory/.netease-cloud-music-gtk.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "netease-cloud-music-gtk"
Mon Jan 18 11:27:56 2021 rev:5 rq:862795 version:1.2.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/netease-cloud-music-gtk/netease-cloud-music-gtk.changes
2020-11-17 21:22:01.361152699 +0100
+++
/work/SRC/openSUSE:Factory/.netease-cloud-music-gtk.new.28504/netease-cloud-music-gtk.changes
2021-01-18 11:31:04.340608811 +0100
@@ -1,0 +2,8 @@
+Wed Jan 13 05:09:51 UTC 2021 - gmg 137 <[email protected]>
+
+- Updata to version 1.2.0:
+ + Add a playlist.
+ + Search page automatically loads more.
+ + Fix bug.
+
+-------------------------------------------------------------------
Old:
----
netease-cloud-music-gtk-1.1.3.tar.xz
New:
----
netease-cloud-music-gtk-1.2.0.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ netease-cloud-music-gtk.spec ++++++
--- /var/tmp/diff_new_pack.inQF30/_old 2021-01-18 11:31:29.848633940 +0100
+++ /var/tmp/diff_new_pack.inQF30/_new 2021-01-18 11:31:29.852633945 +0100
@@ -1,7 +1,7 @@
#
# spec file for package netease-cloud-music-gtk
#
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
# Copyright (c) specCURRENT_YEAR SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
@@ -18,7 +18,7 @@
Name: netease-cloud-music-gtk
-Version: 1.1.3
+Version: 1.2.0
Release: 0
Summary: Linux ??????????????? Rust + GTK
?????????????????????????????????
License: GPL-3.0-or-later
++++++ netease-cloud-music-gtk-1.1.3.tar.xz ->
netease-cloud-music-gtk-1.2.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/Cargo.toml
new/netease-cloud-music-gtk-1.2.0/Cargo.toml
--- old/netease-cloud-music-gtk-1.1.3/Cargo.toml 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/Cargo.toml 2021-01-13
05:37:02.000000000 +0100
@@ -1,7 +1,7 @@
[package]
name = "netease-cloud-music-gtk"
description = "Linux ??????????????? Rust + GTK
?????????????????????????????????"
-version = "1.1.3"
+version = "1.2.0"
authors = ["gmg137 <[email protected]>"]
license = "GPL-v3"
edition = "2018"
@@ -36,7 +36,7 @@
xdg = "*"
futures = "^0.3"
async-std = "^1.6.1"
-isahc = { version = "*", features = ["cookies"] }
+isahc = { version = "^1.0.1", features = ["cookies"] }
custom_error = "*"
log = "*"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/README.md
new/netease-cloud-music-gtk-1.2.0/README.md
--- old/netease-cloud-music-gtk-1.1.3/README.md 2020-11-06 03:47:40.000000000
+0100
+++ new/netease-cloud-music-gtk-1.2.0/README.md 2021-01-13 05:37:02.000000000
+0100
@@ -21,6 +21,7 @@
- ????????????(????????? [OSDLyrics](https://github.com/osdlyrics/osdlyrics))
- ????????????
- ????????????
+- Mpris ??????
## ????????????
> openssl, gstreamer, gstreamer-plugins-base, gstreamer-plugins-good,
> gstreamer-plugins-bad, gstreamer-plugins-ugly
@@ -30,6 +31,13 @@
```bash
sudo zypper in netease-cloud-music-gtk
```
+### openSUSE Leap
+```bash
+// ?????????
+sudo zypper ar -f obs://multimedia:apps multimedia
+// ??????
+sudo zypper in netease-cloud-music-gtk
+```
### Arch Linux
[????????????](https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/)??????
/etc/pacman.conf
?????????????????????????????????[????????????????????????](https://github.com/archlinuxcn/mirrorlist-repo)??????
```
@@ -55,7 +63,7 @@
sudo apt install netease-cloud-music-gtk
```
-### openSUSE Leap / Ubuntu
+### Fedora / Ubuntu
- ??????
[RPM/DEB](https://gitee.com/gmg137/netease-cloud-music-gtk/releases)????????????
### ???????????????
@@ -95,12 +103,32 @@
cargo install cargo-deb
cargo deb
```
+### FAQ
+1. ???????????????????????????????????????????
+> ?????? GTK3
??????????????????????????????????????????????????????????????????<br>
+> **????????????:**
+> - Mpris ??????: GNOME ?????? [Mpris Indicator
Button](https://extensions.gnome.org/extension/1379/mpris-indicator-button/)??????????????????????????????
Mpris ?????????
+> - ????????????????????????????????????????????????
+2. ???????????????????????????????????????????
+> ???????????????????????????????????????????????????????????? glib
???????????????????????????????????????(ubuntu18.04,
leap15)????????????????????????
+3. ?????????????????????????????????????????????????
+>
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????
+4. ?????????????????????????????????????
+> ???????????????????????? ```--debug```
?????????????????????????????????????????????????????????????????????
+5. ??????????????????????????????????
+> ???????????????????????? ```--debug``` ?????????????????????,
?????????????????????
+6. ?????? [OSDLyrics](https://github.com/osdlyrics/osdlyrics)
?????????????????????????????????
+> ?????? [OSDLyrics](https://github.com/osdlyrics/osdlyrics)
???????????????????????????????????????????????????????????????????????????????????????????????????????????????
+> ?????????????????????????????????????????????????????????
## ??????



+## License
+This project's source code and documentation is licensed under the [GNU
General Public License](LICENSE) (GPL v3).
+
## ??????
- [podcasts](https://gitlab.gnome.org/World/podcasts)
- [gnome-music](https://gitlab.gnome.org/GNOME/gnome-music)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/app.rs
new/netease-cloud-music-gtk-1.2.0/src/app.rs
--- old/netease-cloud-music-gtk-1.1.3/src/app.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/app.rs 2021-01-13
05:37:02.000000000 +0100
@@ -64,12 +64,17 @@
RefreshMineFmPlayerList,
RefreshMineFmPlay,
RefreshMineFmPause,
+ RefreshMineFmImage(String),
CancelCollection,
Search(String),
+ AppendSearch,
+ AppendSubLowView(Vec<SongInfo>),
PlayerInit(SongInfo, PlayerTypes),
PlayerTypes(PlayerTypes),
ReadyPlayer(SongInfo),
RefreshLyricsText(String),
+ RefreshPlaylist(PlayerListData),
+ PlaylistSong(i32),
Player(SongInfo),
PlayerOne,
RefreshPlayerImage(String),
@@ -255,6 +260,7 @@
}
Action::RefreshMineFmPlay => self.view.switch_fm_play(),
Action::RefreshMineFmPause => self.view.switch_fm_pause(),
+ Action::RefreshMineFmImage(path) => self.view.set_fm_image(path),
Action::PlayerFm => self.view.play_fm(),
Action::PauseFm => self.player.pause(),
Action::FmLike => self.view.like_fm(),
@@ -264,14 +270,22 @@
}
Action::CancelCollection => self.view.cancel_collection(),
Action::Search(text) => self.view.switch_stack_search(text),
+ Action::AppendSearch => {
+ if let Some((text, num)) = self.view.get_sub_page_data() {
+ self.view.append_search(text, num);
+ }
+ }
+ Action::AppendSubLowView(song_list) =>
self.view.append_sub_low_view(song_list),
Action::Login(name, pass) => self.header.login(name, pass),
Action::Logout => self.header.logout(),
Action::DailyTask => self.header.daily_task(),
Action::PlayerInit(info, pt) =>
self.player.initialize_player(info, pt, self.configs.borrow().lyrics),
Action::PlayerTypes(pt) => self.player.set_player_typers(pt),
+ Action::PlaylistSong(index) => self.player.playlist_song(index),
Action::Player(info) => self.player.player(info),
Action::ReadyPlayer(info) => self.player.ready_player(info,
self.configs.borrow().lyrics),
Action::RefreshLyricsText(lrc) =>
self.player.update_lyrics_text(lrc),
+ Action::RefreshPlaylist(pl) => self.player.update_playlist(pl),
Action::ShowNotice(text) => {
let notif = mark_all_notif(text);
let old = self.notice.replace(Some(notif));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/musicapi/mod.rs
new/netease-cloud-music-gtk-1.2.0/src/musicapi/mod.rs
--- old/netease-cloud-music-gtk-1.1.3/src/musicapi/mod.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/musicapi/mod.rs 2021-01-13
05:37:02.000000000 +0100
@@ -7,7 +7,7 @@
pub(crate) mod model;
use crate::model::{Errors, NCMResult};
use encrypt::Crypto;
-use isahc::prelude::*;
+use isahc::{prelude::*, *};
use lazy_static::lazy_static;
use model::*;
use regex::Regex;
@@ -128,14 +128,14 @@
}
}
}
- response.text_async().await.map_err(|_| Errors::NoneError)
+ response.text().await.map_err(|_| Errors::NoneError)
}
Method::GET => self
.client
.get_async(&url)
.await
.map_err(|_| Errors::NoneError)?
- .text_async()
+ .text()
.await
.map_err(|_| Errors::NoneError),
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/task.rs
new/netease-cloud-music-gtk-1.2.0/src/task.rs
--- old/netease-cloud-music-gtk-1.1.3/src/task.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/task.rs 2021-01-13
05:37:02.000000000 +0100
@@ -18,6 +18,7 @@
width: u32,
high: u32,
timeout: u64,
+ fm: bool,
},
DownloadMusic {
url: String,
@@ -42,8 +43,12 @@
width,
high,
timeout,
+ fm,
} => {
download_img(&url, &path, width, high, timeout).await.ok();
+ if fm {
+
sender.send(Action::RefreshMineFmImage(path.clone())).unwrap();
+ }
sender.send(Action::RefreshPlayerImage(path)).unwrap();
}
Task::DownloadMineRecommendImage(rr) => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/utils.rs
new/netease-cloud-music-gtk-1.2.0/src/utils.rs
--- old/netease-cloud-music-gtk-1.1.3/src/utils.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/utils.rs 2021-01-13
05:37:02.000000000 +0100
@@ -12,12 +12,15 @@
musicapi::model::SongInfo,
widgets::player::LoopsState,
};
-use async_std::fs;
+use async_std::{
+ fs,
+ sync::{Arc, Mutex},
+};
use cairo::{Context, ImageSurface};
use gdk::{pixbuf_get_from_surface, prelude::GdkContextExt};
use gdk_pixbuf::Pixbuf;
use glib::Sender;
-use isahc::{prelude::*, ResponseExt};
+use isahc::{prelude::*, *};
use rand::{seq::SliceRandom, thread_rng};
use serde::{Deserialize, Serialize};
use std::{io, io::Error, time::Duration};
@@ -40,7 +43,9 @@
let mut response = client.get_async(music_url).await?;
if response.status().is_success() {
let tmp_path = format!("{}.tmp", path);
- response.copy_to_file(&tmp_path)?;
+ let mut buf = vec![];
+ response.copy_to(&mut buf).await?;
+ fs::write(&tmp_path, buf).await?;
fs::rename(&tmp_path, path).await?;
}
}
@@ -66,7 +71,9 @@
let client =
HttpClient::builder().timeout(Duration::from_millis(timeout)).build()?;
let mut response = client.get_async(image_url).await?;
if response.status().is_success() {
- response.copy_to_file(path)?;
+ let mut buf = vec![];
+ response.copy_to(&mut buf).await?;
+ fs::write(&path, buf).await?;
}
}
Ok(())
@@ -74,13 +81,13 @@
// ??????????????????
#[derive(Debug, Deserialize, Serialize)]
-struct PlayerListData {
+pub(crate) struct PlayerListData {
// ????????????: (????????????,????????????)
- player_list: Vec<(SongInfo, bool)>,
+ pub player_list: Vec<(SongInfo, bool)>,
// ??????????????????????????????
shuffle_list: Vec<i32>,
// ???????????????????????????
- index: i32,
+ pub index: i32,
}
// ??????????????????
@@ -253,7 +260,7 @@
// ??????????????????
#[allow(unused)]
-pub(crate) async fn update_player_list(sender: Sender<Action>) ->
NCMResult<()> {
+pub(crate) async fn update_player_list(sender: Sender<Action>, music_data:
Arc<Mutex<MusicData>>) -> NCMResult<()> {
let path = format!("{}player_list.db", NCM_DATA.to_string_lossy());
let buffer = fs::read(&path).await?;
// ????????????????????????
@@ -264,7 +271,7 @@
} = bincode::deserialize(&buffer).map_err(|_| Errors::NoneError)?;
// ???????????? id ??????
let song_id_list = player_list.iter().map(|(si, _)|
si.id).collect::<Vec<u64>>();
- let mut api = MusicData::new().await;
+ let mut api = music_data.lock().await;
// ?????????????????? URL
if let Ok(v) = api.songs_url(&song_id_list, 320).await {
// ?????????????????????
@@ -483,3 +490,34 @@
let lrc = fs::read_to_string(&path).await?;
Ok(lrc)
}
+
+// ??????????????????
+#[allow(unused)]
+pub(crate) async fn get_playlist() -> NCMResult<PlayerListData> {
+ // ??????????????????
+ let path = format!("{}player_list.db", NCM_DATA.to_string_lossy());
+ let buffer = fs::read(&path).await?;
+ // ????????????????????????
+ Ok(bincode::deserialize(&buffer).map_err(|_| Errors::NoneError)?)
+}
+
+// ?????????????????????????????????
+// index: ????????????
+#[allow(unused)]
+pub(crate) async fn get_playlist_song_by_index(index_new: i32, sender:
Sender<Action>) -> NCMResult<()> {
+ // ??????????????????
+ let path = format!("{}player_list.db", NCM_DATA.to_string_lossy());
+ let buffer = fs::read(&path).await?;
+ // ????????????????????????
+ let mut pld: PlayerListData = bincode::deserialize(&buffer).map_err(|_|
Errors::NoneError)?;
+ // ???????????????????????????
+ if !pld.player_list.is_empty() {
+ pld.index = index_new;
+ fs::write(&path, bincode::serialize(&pld).map_err(|_|
Errors::NoneError)?).await?;
+ if let Some((si, _)) = pld.player_list.get(index_new as usize) {
+ sender.send(Action::ReadyPlayer(si.to_owned())).unwrap();
+ return Ok(());
+ }
+ }
+ Err(Errors::NoneError)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/view/mine/fm.rs
new/netease-cloud-music-gtk-1.2.0/src/view/mine/fm.rs
--- old/netease-cloud-music-gtk-1.1.3/src/view/mine/fm.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/view/mine/fm.rs 2021-01-13
05:37:02.000000000 +0100
@@ -242,4 +242,11 @@
self.play.hide();
self.pause.show();
}
+
+ pub(crate) fn set_fm_image(&self, image_path: String) {
+ if let Ok(image) = Pixbuf::from_file(&image_path) {
+ let image = image.scale_simple(140, 140, InterpType::Bilinear);
+ self.image.set_from_pixbuf(image.as_ref());
+ };
+ }
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/view/mod.rs
new/netease-cloud-music-gtk-1.2.0/src/view/mod.rs
--- old/netease-cloud-music-gtk-1.1.3/src/view/mod.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/view/mod.rs 2021-01-13
05:37:02.000000000 +0100
@@ -224,11 +224,12 @@
let text_clone = text.clone();
task::spawn(async move {
let mut data = MusicData::new().await;
- if let Ok(json) = data.search(text_clone, 1, 0, 50).await {
+ if let Ok(json) = data.search(text_clone.to_owned(), 1, 0,
50).await {
if let Ok(song_list) =
serde_json::from_str::<Vec<SongInfo>>(&json) {
+ let search_text = format!("search:{}", text_clone);
// ????????????????????????, ??????????????????????????????
if sender
- .send(Action::RefreshSubUpView(0, String::new(),
String::new()))
+ .send(Action::RefreshSubUpView(0, search_text,
String::new()))
.is_ok()
{
// ??????????????????
@@ -243,6 +244,26 @@
self.sender.send(Action::SwitchHeaderBar(text)).unwrap_or(());
}
+ // ????????????
+ pub(crate) fn append_search(&self, text: String, num: usize) {
+ let sender = self.sender.clone();
+ task::spawn(async move {
+ let mut data = MusicData::new().await;
+ if let Ok(json) = data.search(text.to_owned(), 1, num as u16,
50).await {
+ if let Ok(song_list) =
serde_json::from_str::<Vec<SongInfo>>(&json) {
+ // ??????????????????
+
sender.send(Action::AppendSubLowView(song_list)).unwrap_or(());
+ }
+ } else {
+
sender.send(Action::ShowNotice("????????????????????????!".to_owned())).unwrap();
+ }
+ });
+ }
+
+ pub(crate) fn append_sub_low_view(&self, song_list: Vec<SongInfo>) {
+ self.subpages.borrow_mut().append_low_view(song_list);
+ }
+
pub(crate) fn update_home_view(&self, tsl: Arc<Vec<SongList>>, rr:
Arc<Vec<SongList>>) {
self.home.borrow_mut().update(tsl, rr);
}
@@ -294,6 +315,10 @@
self.subpages.borrow_mut().update_low_view(song_list);
}
+ pub(crate) fn get_sub_page_data(&self) -> Option<(String, usize)> {
+ self.subpages.borrow_mut().get_search_data()
+ }
+
pub(crate) fn update_home(&self) {
let sender = self.sender.clone();
let mut sender_task = self.sender_task.clone();
@@ -627,6 +652,10 @@
self.mine.borrow_mut().fmview.switch_pause();
}
+ pub(crate) fn set_fm_image(&self, path: String) {
+ self.mine.borrow_mut().fmview.set_fm_image(path);
+ }
+
pub(crate) fn cancel_collection(&self) {
if let Some(id) = self.mine.borrow_mut().listview.get_song_id() {
let sender = self.sender.clone();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/view/subpages.rs
new/netease-cloud-music-gtk-1.2.0/src/view/subpages.rs
--- old/netease-cloud-music-gtk-1.1.3/src/view/subpages.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/view/subpages.rs 2021-01-13
06:58:06.000000000 +0100
@@ -12,12 +12,16 @@
use async_std::task;
use gdk_pixbuf::{InterpType, Pixbuf};
use glib::Sender;
-use gtk::{prelude::*, Builder, Button, CellRendererText, Grid, Image, Label,
ListStore, TreeView, TreeViewColumn};
+use gtk::{
+ prelude::*, Builder, Button, CellRendererText, Grid, Image, Label,
ListStore, ScrolledWindow, TreeView,
+ TreeViewColumn,
+};
use pango::EllipsizeMode;
#[derive(Clone)]
pub(crate) struct Subpages {
overview: Overview,
+ scrolled: ScrolledWindow,
tree: TreeView,
store: ListStore,
song_list: Vec<SongInfo>,
@@ -53,6 +57,9 @@
let play: Button = builder
.get_object("subpages_play_button")
.expect("???????????? subpages_play_button .");
+ let scrolled: ScrolledWindow = builder
+ .get_object("subpages_scrolled_window")
+ .expect("???????????? subpages_scrolled_window.");
let overview = Overview {
grid,
pic,
@@ -74,6 +81,7 @@
]);
let s = Subpages {
overview,
+ scrolled,
tree,
store,
song_list: vec![],
@@ -144,6 +152,14 @@
s.overview.like.connect_clicked(move |_| {
sender.send(Action::LikeSongList).unwrap_or(());
});
+
+ // ?????????????????????????????????
+ let sender = s.sender.clone();
+ s.scrolled.connect_edge_overshot(move |_, position| {
+ if position == gtk::PositionType::Bottom {
+ sender.send(Action::AppendSearch).unwrap_or(());
+ }
+ });
}
pub(crate) fn update_up_view(&mut self, id: u64, name: String, image_path:
String) {
@@ -158,12 +174,19 @@
self.overview.grid.hide();
return;
}
+ if name.starts_with("search:") {
+ self.overview.grid.hide();
+ }
if let Ok(image) = Pixbuf::from_file(&image_path) {
let image = image.scale_simple(140, 140, InterpType::Bilinear);
self.overview.pic.set_from_pixbuf(image.as_ref());
};
self.overview.album.set_label(&name);
self.overview.num.set_label("0 ???");
+ // ?????????????????????????????????, ?????????????????????????????????
+ //if let Some(adj) = self.scrolled.get_vadjustment() {
+ //adj.set_value(0.0);
+ //}
}
pub(crate) fn update_low_view(&mut self, song_list: Vec<SongInfo>) {
@@ -234,6 +257,27 @@
});
}
+ pub(crate) fn append_low_view(&mut self, song_list: Vec<SongInfo>) {
+ let mut song_list_old = self.song_list.to_owned();
+ let mut song_list_new = song_list.to_owned();
+ song_list_old.append(&mut song_list_new);
+ self.song_list = song_list_old;
+ song_list.iter().for_each(|song| {
+ self.store.insert_with_values(
+ None,
+ &[0, 1, 2, 3, 4, 5],
+ &[
+ &song.id,
+ &song.name,
+ &song.duration,
+ &song.singer,
+ &song.album,
+ &song.pic_url,
+ ],
+ );
+ });
+ }
+
pub(crate) fn play_all(&self) {
let song_list = self.song_list.clone();
let sender = self.sender.clone();
@@ -258,4 +302,16 @@
pub(crate) fn get_song_list_id(&self) -> u64 {
self.song_list_id
}
+
+ // ??????????????????
+ // return: (???????????????,??????????????????)
+ pub(crate) fn get_search_data(&self) -> Option<(String, usize)> {
+ let text = self.overview.album.get_text().to_string();
+ let num = self.song_list.len();
+ if text.starts_with("search:") {
+ Some((text.replace("search:", ""), num))
+ } else {
+ None
+ }
+ }
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/src/widgets/player.rs
new/netease-cloud-music-gtk-1.2.0/src/widgets/player.rs
--- old/netease-cloud-music-gtk-1.1.3/src/widgets/player.rs 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/src/widgets/player.rs 2021-01-13
05:37:02.000000000 +0100
@@ -12,10 +12,11 @@
use glib::{clone, Sender, SignalHandlerId, WeakRef};
use gst::ClockTime;
use gtk::{
- prelude::*, AccelGroup, ActionBar, Builder, Button, Image, Label,
MenuButton, RadioButton, Scale, TextView,
- VolumeButton,
+ prelude::*, AccelGroup, ActionBar, Builder, Button, CellRendererText,
Image, Label, ListStore, MenuButton, Popover,
+ RadioButton, Scale, TextView, TreeView, TreeViewColumn, VolumeButton,
};
use mpris_player::{LoopStatus, Metadata, MprisPlayer,
OrgMprisMediaPlayer2Player, PlaybackStatus};
+use pango::EllipsizeMode;
use serde::{Deserialize, Serialize};
use std::{cell::RefCell, ops::Deref, path::Path, rc::Rc, sync::Arc};
@@ -27,7 +28,10 @@
forward: Button,
like: Button,
volume: VolumeButton,
- lyrics: MenuButton,
+ more: MenuButton,
+ more_popover: Popover,
+ tree: TreeView,
+ store: ListStore,
lyrics_text: TextView,
}
@@ -201,8 +205,19 @@
volume.set_value(volume_value);
player.set_volume(volume_value);
mpris.set_volume(volume_value).ok();
- let lyrics: MenuButton = builder.get_object("lyrics_button").unwrap();
+ let more: MenuButton = builder.get_object("more_button").unwrap();
+ let more_popover: Popover =
builder.get_object("more_popover").unwrap();
let lyrics_text: TextView =
builder.get_object("lyrics_text_view").unwrap();
+ let tree: TreeView = builder
+ .get_object("playlist_tree_view")
+ .expect("???????????? playlist_tree_view .");
+ let store: ListStore = ListStore::new(&[
+ glib::Type::U64,
+ String::static_type(),
+ String::static_type(),
+ String::static_type(),
+ String::static_type(),
+ ]);
let controls = PlayerControls {
play,
@@ -211,7 +226,10 @@
backward,
like,
volume,
- lyrics,
+ more,
+ more_popover,
+ tree,
+ store,
lyrics_text,
};
@@ -337,6 +355,7 @@
width: 34,
high: 34,
timeout: 1000,
+ fm: false,
})
.await
.ok();
@@ -365,6 +384,15 @@
pub(crate) fn ready_player(&self, song_info: SongInfo, lyrics: bool) {
let sender = self.sender.clone();
let mut sender_task = self.sender_task.clone();
+ // ???????????? FM ????????????
+ let mut fm = false;
+ let mut width = 34;
+ let mut high = 34;
+ if let PlayerTypes::Fm = *self.player_types.borrow() {
+ fm = true;
+ width = 140;
+ high = 140;
+ }
task::spawn(async move {
// ????????????
if lyrics {
@@ -380,9 +408,10 @@
.send(Task::DownloadPlayerImg {
url: song_info.pic_url.to_owned(),
path: image_path.to_owned(),
- width: 34,
- high: 34,
+ width,
+ high,
timeout: 1000,
+ fm,
})
.await
.ok();
@@ -414,6 +443,11 @@
self.player.set_uri(&music_url);
}
self.play();
+ // ????????????????????????????????????????????????
+ if self.controls.more_popover.is_visible() {
+ self.get_lyrics_text();
+ self.get_playlist();
+ }
}
fn connect_update_slider(slider: &Scale, player:
WeakRef<gst_player::Player>) -> SignalHandlerId {
@@ -560,6 +594,16 @@
});
}
+ fn get_playlist(&self) {
+ let sender = self.sender.clone();
+ task::spawn(async move {
+ // ??????????????????
+ if let Ok(playlist) = get_playlist().await {
+ sender.send(Action::RefreshPlaylist(playlist)).unwrap();
+ }
+ });
+ }
+
// ??? Mpris2 ??????????????????
fn set_loops(&self, loops_status: LoopStatus) {
match loops_status {
@@ -599,10 +643,76 @@
}
}
+ pub(crate) fn update_playlist(&self, pl: PlayerListData) {
+ self.controls.store.clear();
+ for c in self.controls.tree.get_columns().iter() {
+ self.controls.tree.remove_column(c);
+ }
+ self.controls.tree.set_model(Some(&self.controls.store));
+
+ let column = TreeViewColumn::new();
+ column.set_visible(false);
+ column.set_sizing(gtk::TreeViewColumnSizing::Fixed);
+ let id = CellRendererText::new();
+ column.pack_start(&id, true);
+ column.add_attribute(&id, "text", 0);
+ self.controls.tree.append_column(&column);
+
+ let column = TreeViewColumn::new();
+ column.set_sizing(gtk::TreeViewColumnSizing::Fixed);
+ let play = CellRendererText::new();
+ play.set_property_xpad(18);
+ play.set_property_xalign(0.0);
+ play.set_property_yalign(0.5);
+ play.set_property_height(37);
+ column.pack_start(&play, true);
+ column.add_attribute(&play, "text", 1);
+ self.controls.tree.append_column(&column);
+
+ let column = TreeViewColumn::new();
+ column.set_sizing(gtk::TreeViewColumnSizing::Fixed);
+ let title = CellRendererText::new();
+ play.set_property_xpad(18);
+ play.set_property_xalign(0.0);
+ title.set_property_ellipsize(EllipsizeMode::End);
+ column.pack_start(&title, true);
+ column.add_attribute(&title, "text", 2);
+
+ let duration = CellRendererText::new();
+ duration.set_property_xpad(32);
+ duration.set_property_xalign(0.0);
+ column.pack_start(&duration, true);
+ column.add_attribute(&duration, "text", 3);
+
+ let singer = CellRendererText::new();
+ singer.set_property_xpad(22);
+ singer.set_property_xalign(0.0);
+ singer.set_property_ellipsize(EllipsizeMode::End);
+ column.pack_start(&singer, true);
+ column.add_attribute(&singer, "text", 4);
+ self.controls.tree.append_column(&column);
+
+ let song_id = *self.info.song_id.borrow();
+ pl.player_list.iter().for_each(|(song, _)| {
+ let play_icon = if Some(song.id).eq(&song_id) { "???" } else { ""
};
+ self.controls.store.insert_with_values(
+ None,
+ &[0, 1, 2, 3, 4],
+ &[&song.id, &play_icon, &song.name, &song.duration,
&song.singer],
+ );
+ });
+ }
+
pub(crate) fn set_player_typers(&self, player_types: PlayerTypes) {
*self.player_types.borrow_mut() = player_types;
}
+ pub(crate) fn playlist_song(&self, index: i32) {
+ if task::block_on(get_playlist_song_by_index(index,
self.sender.clone())).is_err() {
+
self.sender.send(Action::ShowNotice("????????????!".to_owned())).unwrap();
+ }
+ }
+
pub(crate) fn set_cover_image(&self, image_path: String) {
if let Ok(image) = Pixbuf::from_file(&image_path) {
let image = image.scale_simple(38, 38, InterpType::Bilinear);
@@ -659,12 +769,26 @@
}
fn init(&self, sender: &Sender<Action>) {
+ self.connect_control_tree();
self.connect_control_buttons();
self.connect_loops_buttons();
self.connect_mpris_buttons();
self.connect_gst_signals(sender);
}
+ fn connect_control_tree(&self) {
+ let sender = self.sender.clone();
+ self.controls.tree.connect_button_press_event(move |tree, event| {
+ if event.get_event_type() == gdk::EventType::DoubleButtonPress {
+ if let Some(path) =
tree.get_selection().get_selected_rows().0.get(0) {
+ let index = path.get_indices()[0];
+ sender.send(Action::PlaylistSong(index)).unwrap_or(());
+ }
+ }
+ Inhibit(false)
+ });
+ }
+
/// Connect the `PlayerControls` buttons to the `PlayerExt` methods.
fn connect_control_buttons(&self) {
let weak = Rc::clone(self);
@@ -697,8 +821,9 @@
weak.set_volume(value,false);
}));
- self.controls.lyrics.connect_clicked(clone!(@weak weak => move |_| {
+ self.controls.more.connect_clicked(clone!(@weak weak => move |_| {
weak.get_lyrics_text();
+ weak.get_playlist();
}));
}
@@ -708,15 +833,17 @@
.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
let sender_clone = sender.clone();
+ let data = self.music_data.clone();
// Log gst errors.
self.player.connect_error(move |_, _| {
sender_clone
.send(Action::ShowNotice("??????????????????!".to_owned()))
.unwrap();
let sender_clone = sender_clone.clone();
+ let data = data.clone();
// ??????????????????
task::spawn(async move {
- update_player_list(sender_clone).await.ok();
+ update_player_list(sender_clone, data).await.ok();
});
});
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/ui/subpages.ui
new/netease-cloud-music-gtk-1.2.0/ui/subpages.ui
--- old/netease-cloud-music-gtk-1.1.3/ui/subpages.ui 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/ui/subpages.ui 2021-01-13
05:37:02.000000000 +0100
@@ -139,7 +139,7 @@
</packing>
</child>
<child>
- <object class="GtkScrolledWindow">
+ <object class="GtkScrolledWindow" id="subpages_scrolled_window">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/netease-cloud-music-gtk-1.1.3/ui/window.ui
new/netease-cloud-music-gtk-1.2.0/ui/window.ui
--- old/netease-cloud-music-gtk-1.1.3/ui/window.ui 2020-11-06
03:47:40.000000000 +0100
+++ new/netease-cloud-music-gtk-1.2.0/ui/window.ui 2021-01-13
05:37:02.000000000 +0100
@@ -639,7 +639,7 @@
</packing>
</child>
<child>
- <object class="GtkMenuButton" id="lyrics_button">
+ <object class="GtkMenuButton" id="more_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -647,18 +647,12 @@
<property name="valign">center</property>
<property name="relief">none</property>
<property name="direction">up</property>
- <property name="popover">lyrics_popover</property>
+ <property name="popover">more_popover</property>
<child>
- <object class="GtkLabel">
+ <object class="GtkImage" id="more_image">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="label" translatable="yes">???</property>
- <property name="justify">center</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
+ <property name="can-focus">False</property>
+ <property name="icon-name">view-more-symbolic</property>
</object>
</child>
</object>
@@ -941,34 +935,128 @@
</object>
</child>
</object>
- <object class="GtkPopover" id="lyrics_popover">
- <property name="can_focus">False</property>
- <property name="relative_to">lyrics_button</property>
+ <object class="GtkPopover" id="more_popover">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="relative-to">more_button</property>
<child>
- <object class="GtkScrolledWindow">
- <property name="width_request">350</property>
- <property name="height_request">220</property>
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="margin_top">8</property>
- <property name="margin_bottom">8</property>
- <property name="shadow_type">in</property>
+ <property name="can-focus">False</property>
<child>
- <object class="GtkTextView" id="lyrics_text_view">
+ <object class="GtkBox">
+ <property name="width-request">550</property>
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscroll_policy">natural</property>
- <property name="vscroll_policy">natural</property>
- <property name="pixels_below_lines">1</property>
- <property name="editable">False</property>
- <property name="justification">center</property>
- <property name="left_margin">8</property>
- <property name="right_margin">8</property>
- <property name="top_margin">18</property>
- <property name="bottom_margin">18</property>
- <property name="cursor_visible">False</property>
- <property name="accepts_tab">False</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label"
translatable="yes">????????????</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <property name="margin-top">8</property>
+ <property name="margin-bottom">8</property>
+ <child>
+ <object class="GtkTreeView" id="playlist_tree_view">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">start</property>
+ <property name="headers_visible">False</property>
+ <property name="enable_search">False</property>
+ <property name="fixed_height_mode">True</property>
+ <property name="show_expanders">False</property>
+ <property name="enable_grid_lines">horizontal</property>
+ <property name="activate_on_single_click">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes">??????</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="width-request">350</property>
+ <property name="height-request">220</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="halign">end</property>
+ <property name="margin-top">8</property>
+ <property name="margin-bottom">8</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTextView" id="lyrics_text_view">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hscroll-policy">natural</property>
+ <property name="vscroll-policy">natural</property>
+ <property name="pixels-below-lines">1</property>
+ <property name="editable">False</property>
+ <property name="justification">center</property>
+ <property name="left-margin">8</property>
+ <property name="right-margin">8</property>
+ <property name="top-margin">18</property>
+ <property name="bottom_margin">18</property>
+ <property name="cursor-visible">False</property>
+ <property name="accepts-tab">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
</child>
++++++ vendor.tar.xz ++++++
/work/SRC/openSUSE:Factory/netease-cloud-music-gtk/vendor.tar.xz
/work/SRC/openSUSE:Factory/.netease-cloud-music-gtk.new.28504/vendor.tar.xz
differ: char 25, line 1