Move search provider stuff into own file; A bit code cleanup
This commit is contained in:
parent
75156a1b41
commit
dc3bd094b2
@ -87,6 +87,7 @@ mod headerbar;
|
||||
mod window;
|
||||
|
||||
mod manager;
|
||||
mod search_provider;
|
||||
mod settings;
|
||||
mod static_resource;
|
||||
mod utils;
|
||||
|
||||
@ -53,6 +53,7 @@ podcasts_sources = files(
|
||||
'i18n.rs',
|
||||
'main.rs',
|
||||
'manager.rs',
|
||||
'search_provider.rs',
|
||||
'settings.rs',
|
||||
'utils.rs'
|
||||
)
|
||||
|
||||
122
podcasts-gtk/src/search_provider.rs
Normal file
122
podcasts-gtk/src/search_provider.rs
Normal file
@ -0,0 +1,122 @@
|
||||
// search_provider.rs
|
||||
//
|
||||
// Copyright 2019 Felix Häcker <haeckerfelix@gnome.org>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use crossbeam_channel::Sender;
|
||||
use gtk::prelude::*;
|
||||
use podcasts_data::dbqueries;
|
||||
use search_provider::{ResultMetadata, SearchProvider as SP};
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::app::Action;
|
||||
use crate::config::APP_ID;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct SearchProvider {
|
||||
search_provider: Arc<SP>,
|
||||
window: gtk::ApplicationWindow,
|
||||
sender: Sender<Action>,
|
||||
}
|
||||
|
||||
impl SearchProvider {
|
||||
pub(crate) fn new(window: gtk::ApplicationWindow, sender: Sender<Action>) -> SearchProvider {
|
||||
let search_provider = SP::new(
|
||||
APP_ID.to_string(),
|
||||
"/org/gnome/Podcasts/SearchProvider".to_string(),
|
||||
);
|
||||
|
||||
let sp = SearchProvider {
|
||||
search_provider,
|
||||
window,
|
||||
sender,
|
||||
};
|
||||
|
||||
sp.setup_callbacks();
|
||||
sp
|
||||
}
|
||||
|
||||
fn setup_callbacks(&self) {
|
||||
let window = self.window.clone();
|
||||
let sender = self.sender.clone();
|
||||
self.search_provider
|
||||
.connect_activate_result(move |sp_id, _, timestamp| {
|
||||
// Show window
|
||||
window.present_with_time(timestamp);
|
||||
window.show_all();
|
||||
window.present();
|
||||
|
||||
// Get episode
|
||||
let mut id = sp_id.clone().split("_").collect::<Vec<&str>>();
|
||||
let title: &str = id.pop().unwrap();
|
||||
let show_id: i32 = std::str::FromStr::from_str(id.pop().unwrap()).unwrap();
|
||||
let episode = dbqueries::get_episode_from_pk(title, show_id).unwrap();
|
||||
|
||||
// Play episode
|
||||
sender
|
||||
.send(Action::InitEpisode(episode.rowid()))
|
||||
.expect("Action channel blew up somehow");
|
||||
// TODO: Sometimes it's necessary to download the episode first. Otherwise it cannot be played.
|
||||
// TODO: Greyout title state doesn't get applied.
|
||||
});
|
||||
|
||||
self.search_provider
|
||||
.connect_get_initial_result_set(|terms| {
|
||||
let term = terms.join("");
|
||||
Self::search(term)
|
||||
});
|
||||
|
||||
self.search_provider
|
||||
.connect_get_subsearch_result_set(|_, terms| {
|
||||
let term = terms.join("");
|
||||
Self::search(term)
|
||||
});
|
||||
|
||||
self.search_provider.connect_get_result_metas(|sp_ids| {
|
||||
let mut metas = Vec::new();
|
||||
for sp_id in sp_ids {
|
||||
let id = sp_id.clone().split("_").collect::<Vec<&str>>();
|
||||
let show_id: i32 = FromStr::from_str(id[0]).unwrap();
|
||||
|
||||
let episode = dbqueries::get_episode_from_pk(id[1], show_id).unwrap();
|
||||
|
||||
let meta = ResultMetadata::new(
|
||||
sp_id,
|
||||
episode.title(),
|
||||
"folder-documents-symbolic",
|
||||
episode.description().unwrap_or(""),
|
||||
);
|
||||
metas.insert(0, meta);
|
||||
}
|
||||
metas
|
||||
});
|
||||
}
|
||||
|
||||
fn search(term: String) -> Vec<String> {
|
||||
let episodes = dbqueries::search_episodes(&term)
|
||||
.expect("Could not search for episodes (search provider)");
|
||||
|
||||
let mut sp_ids = Vec::new();
|
||||
for episode in episodes {
|
||||
let sp_id = format!("{}_{}", episode.show_id(), episode.title());
|
||||
sp_ids.insert(0, sp_id);
|
||||
}
|
||||
sp_ids
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,7 @@ use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
|
||||
use crate::app::{Action, PdApplication};
|
||||
use crate::headerbar::Header;
|
||||
use crate::search_provider::SearchProvider;
|
||||
use crate::settings::{self, WindowGeometry};
|
||||
use crate::stacks::Content;
|
||||
use crate::utils;
|
||||
@ -149,6 +150,9 @@ impl MainWindow {
|
||||
glib::Continue(true)
|
||||
});
|
||||
|
||||
// Setup GNOME Shell search provider integration
|
||||
let search_provider = SearchProvider::new(window.clone(), sender.clone());
|
||||
|
||||
Self {
|
||||
app: app.clone(),
|
||||
window,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user