List federated instances in instance selector (#8)
Co-authored-by: Bnyro <bnyro@tutanota.com>
This commit is contained in:
parent
38c0c4fd27
commit
daa539031f
|
@ -0,0 +1,29 @@
|
||||||
|
use crate::settings;
|
||||||
|
use lemmy_api_common::{
|
||||||
|
lemmy_db_schema::source::instance::Instance,
|
||||||
|
site::{GetFederatedInstances, GetFederatedInstancesResponse},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn fetch_instances() -> std::result::Result<Vec<Instance>, reqwest::Error> {
|
||||||
|
// TODO: Update code to use the Instance views from lemmy 0.18.0
|
||||||
|
let params = GetFederatedInstances {
|
||||||
|
auth: settings::get_current_account().jwt,
|
||||||
|
};
|
||||||
|
|
||||||
|
// we fetch the instances from the official instance because the instance is likely unset on first startup
|
||||||
|
let instances = super::CLIENT
|
||||||
|
.get("https://lemmy.ml/api/v3/federated_instances".to_owned())
|
||||||
|
.query(¶ms)
|
||||||
|
.send()?
|
||||||
|
.json::<GetFederatedInstancesResponse>()?;
|
||||||
|
|
||||||
|
match instances.federated_instances {
|
||||||
|
Some(instances) => Ok(instances
|
||||||
|
.linked
|
||||||
|
.iter()
|
||||||
|
.filter(|instance| instance.software == Some("lemmy".to_owned()))
|
||||||
|
.map(|instance| instance.clone())
|
||||||
|
.collect::<Vec<Instance>>()),
|
||||||
|
None => Ok(vec![]),
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,13 +6,14 @@ pub mod auth;
|
||||||
pub mod comment;
|
pub mod comment;
|
||||||
pub mod communities;
|
pub mod communities;
|
||||||
pub mod community;
|
pub mod community;
|
||||||
pub mod image;
|
|
||||||
pub mod moderation;
|
pub mod moderation;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod posts;
|
pub mod posts;
|
||||||
pub mod private_message;
|
pub mod private_message;
|
||||||
pub mod search;
|
pub mod search;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
|
pub mod image;
|
||||||
|
pub mod instances;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
||||||
static API_VERSION: &str = "v3";
|
static API_VERSION: &str = "v3";
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
use gtk::prelude::*;
|
||||||
|
use lemmy_api_common::lemmy_db_schema::source::instance::Instance;
|
||||||
|
use relm4::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InstanceRow {
|
||||||
|
instance: Instance,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum InstanceRowMsg {
|
||||||
|
OpenInstance,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::factory(pub)]
|
||||||
|
impl FactoryComponent for InstanceRow {
|
||||||
|
type Init = Instance;
|
||||||
|
type Input = InstanceRowMsg;
|
||||||
|
type Output = crate::AppMsg;
|
||||||
|
type CommandOutput = ();
|
||||||
|
type Widgets = PostViewWidgets;
|
||||||
|
type ParentInput = crate::AppMsg;
|
||||||
|
type ParentWidget = gtk::Box;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
root = gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 10,
|
||||||
|
set_margin_end: 10,
|
||||||
|
set_margin_start: 10,
|
||||||
|
set_vexpand: false,
|
||||||
|
|
||||||
|
add_controller = gtk::GestureClick {
|
||||||
|
connect_pressed[sender] => move |_, _, _, _| {
|
||||||
|
sender.input(InstanceRowMsg::OpenInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
|
set_spacing: 10,
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_label: &self.instance.domain
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_hexpand: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
gtk::Separator {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn forward_to_parent(output: Self::Output) -> Option<Self::ParentInput> {
|
||||||
|
Some(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender<Self>) -> Self {
|
||||||
|
Self { instance: value }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_widgets(
|
||||||
|
&mut self,
|
||||||
|
_index: &Self::Index,
|
||||||
|
root: &Self::Root,
|
||||||
|
_returned_widget: &<Self::ParentWidget as relm4::factory::FactoryView>::ReturnedWidget,
|
||||||
|
sender: FactorySender<Self>,
|
||||||
|
) -> Self::Widgets {
|
||||||
|
let widgets = view_output!();
|
||||||
|
widgets
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Self::Input, sender: FactorySender<Self>) {
|
||||||
|
match message {
|
||||||
|
InstanceRowMsg::OpenInstance => {
|
||||||
|
let instance_address = format!("https://{}", self.instance.domain);
|
||||||
|
sender.output(crate::AppMsg::DoneChoosingInstance(
|
||||||
|
instance_address.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ pub mod comment_row;
|
||||||
pub mod community_page;
|
pub mod community_page;
|
||||||
pub mod community_row;
|
pub mod community_row;
|
||||||
pub mod inbox_page;
|
pub mod inbox_page;
|
||||||
|
pub mod instance_row;
|
||||||
|
pub mod instances_page;
|
||||||
pub mod mention_row;
|
pub mod mention_row;
|
||||||
pub mod post_page;
|
pub mod post_page;
|
||||||
pub mod post_row;
|
pub mod post_row;
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -10,6 +10,7 @@ use components::{
|
||||||
community_page::{self, CommunityPage},
|
community_page::{self, CommunityPage},
|
||||||
community_row::CommunityRow,
|
community_row::CommunityRow,
|
||||||
inbox_page::{InboxInput, InboxPage},
|
inbox_page::{InboxInput, InboxPage},
|
||||||
|
instances_page::{InstancePageInput, InstancesPage},
|
||||||
post_page::{self, PostPage},
|
post_page::{self, PostPage},
|
||||||
post_row::PostRow,
|
post_row::PostRow,
|
||||||
profile_page::{self, ProfilePage},
|
profile_page::{self, ProfilePage},
|
||||||
|
@ -55,6 +56,7 @@ struct App {
|
||||||
back_queue: Vec<AppMsg>,
|
back_queue: Vec<AppMsg>,
|
||||||
posts: FactoryVecDeque<PostRow>,
|
posts: FactoryVecDeque<PostRow>,
|
||||||
communities: FactoryVecDeque<CommunityRow>,
|
communities: FactoryVecDeque<CommunityRow>,
|
||||||
|
instances_page: Controller<InstancesPage>,
|
||||||
profile_page: Controller<ProfilePage>,
|
profile_page: Controller<ProfilePage>,
|
||||||
community_page: Controller<CommunityPage>,
|
community_page: Controller<CommunityPage>,
|
||||||
post_page: Controller<PostPage>,
|
post_page: Controller<PostPage>,
|
||||||
|
@ -179,27 +181,8 @@ impl SimpleComponent for App {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AppState::ChooseInstance => gtk::Box {
|
AppState::ChooseInstance => gtk::Box {
|
||||||
set_hexpand: true,
|
#[local_ref]
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
instances_page -> gtk::Box {}
|
||||||
set_spacing: 12,
|
|
||||||
set_margin_all: 20,
|
|
||||||
set_valign: gtk::Align::Center,
|
|
||||||
set_halign: gtk::Align::Center,
|
|
||||||
gtk::Label {
|
|
||||||
set_text: "Please enter the URL of a valid lemmy instance",
|
|
||||||
},
|
|
||||||
#[name(instance_url)]
|
|
||||||
gtk::Entry {
|
|
||||||
set_tooltip_text: Some("Instance"),
|
|
||||||
},
|
|
||||||
gtk::Button {
|
|
||||||
set_label: "Done",
|
|
||||||
connect_clicked[sender, instance_url] => move |_| {
|
|
||||||
let text = instance_url.text().as_str().to_string();
|
|
||||||
instance_url.set_text("");
|
|
||||||
sender.input(AppMsg::DoneChoosingInstance(text));
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
AppState::Login => gtk::Box {
|
AppState::Login => gtk::Box {
|
||||||
set_hexpand: true,
|
set_hexpand: true,
|
||||||
|
@ -287,6 +270,7 @@ impl SimpleComponent for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppState::Person => {
|
AppState::Person => {
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
#[local_ref]
|
#[local_ref]
|
||||||
|
@ -357,6 +341,9 @@ impl SimpleComponent for App {
|
||||||
// initialize all controllers and factories
|
// initialize all controllers and factories
|
||||||
let posts = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
let posts = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||||
let communities = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
let communities = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
|
||||||
|
let instances_page = InstancesPage::builder()
|
||||||
|
.launch(())
|
||||||
|
.forward(sender.input_sender(), |msg| msg);
|
||||||
let profile_page = ProfilePage::builder()
|
let profile_page = ProfilePage::builder()
|
||||||
.launch(default_person())
|
.launch(default_person())
|
||||||
.forward(sender.input_sender(), |msg| msg);
|
.forward(sender.input_sender(), |msg| msg);
|
||||||
|
@ -380,6 +367,7 @@ impl SimpleComponent for App {
|
||||||
logged_in,
|
logged_in,
|
||||||
posts,
|
posts,
|
||||||
communities,
|
communities,
|
||||||
|
instances_page,
|
||||||
profile_page,
|
profile_page,
|
||||||
community_page,
|
community_page,
|
||||||
post_page,
|
post_page,
|
||||||
|
@ -401,6 +389,7 @@ impl SimpleComponent for App {
|
||||||
// setup all widgets and different stack pages
|
// setup all widgets and different stack pages
|
||||||
let posts_box = model.posts.widget();
|
let posts_box = model.posts.widget();
|
||||||
let communities_box = model.communities.widget();
|
let communities_box = model.communities.widget();
|
||||||
|
let instances_page = model.instances_page.widget();
|
||||||
let profile_page = model.profile_page.widget();
|
let profile_page = model.profile_page.widget();
|
||||||
let community_page = model.community_page.widget();
|
let community_page = model.community_page.widget();
|
||||||
let post_page = model.post_page.widget();
|
let post_page = model.post_page.widget();
|
||||||
|
@ -486,6 +475,9 @@ impl SimpleComponent for App {
|
||||||
}
|
}
|
||||||
AppMsg::ChooseInstance => {
|
AppMsg::ChooseInstance => {
|
||||||
self.state = AppState::ChooseInstance;
|
self.state = AppState::ChooseInstance;
|
||||||
|
self.instances_page
|
||||||
|
.sender()
|
||||||
|
.emit(InstancePageInput::FetchInstances);
|
||||||
}
|
}
|
||||||
AppMsg::StartFetchPosts(type_, remove_previous) => {
|
AppMsg::StartFetchPosts(type_, remove_previous) => {
|
||||||
self.current_posts_type = type_;
|
self.current_posts_type = type_;
|
||||||
|
@ -536,6 +528,7 @@ impl SimpleComponent for App {
|
||||||
sender.input(message);
|
sender.input(message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
AppMsg::DoneFetchCommunities(communities) => {
|
AppMsg::DoneFetchCommunities(communities) => {
|
||||||
self.state = AppState::Communities;
|
self.state = AppState::Communities;
|
||||||
if self.current_communities_page == 1 {
|
if self.current_communities_page == 1 {
|
||||||
|
|
Loading…
Reference in New Issue