XUDXYHQJFNZKP7UHEXWII6J4RJATWTKMWMMW643GRTP7JRASIFVAC
7DWCVQ7NSWW52VKMR7DM27CMOVDXECTXNHYNLDF4NVAI6YH3HHVQC
K772IAVA7N3R2TAC7SAXK4FVUOOROWMKFMUN3HX7A276H6JA6Y7QC
VO4UOVTJKRL5LOOMKGMQ5DGN5SAZGCEUAUZTKGRE6N3KSCCXHWFAC
C6ZDDCL46FXQ7W2UEDZ62YJWI5LUEI4ONHQWU3CHWRVTYSLWRDWAC
CEXASC5XWUEA4SWUKX6HSAXV7DSZTIIBXIQEFZAHAFZ7NUIWQLXAC
J7PC7UGJE64XZIJXE5YETSHYZUUHSH2B52OA5E5JVQUIF6P72JAQC
fuzzy-matcher = "0.3.7"
) -> Element<'a, Message> {
let mut rooms = rooms.iter().collect::<Vec<(&RoomId, &Room)>>();
rooms.sort_unstable_by(|(_, room), (_, other_room)| {
room.get_display_name().cmp(&other_room.get_display_name())
});
) -> (Element<'a, Message>, Option<RoomId>) {
let mut rooms = rooms
.iter()
.map(|(room_id, room)| (room_id, room.get_display_name()))
.collect::<Vec<(&RoomId, String)>>();
if room_filter_text.is_empty() {
rooms.sort_unstable_by(|(_, room_name), (_, other_room_name)| {
room_name.cmp(&other_room_name)
});
} else {
let matcher = SkimMatcherV2::default();
let mut rooms_filtered = rooms
.drain(..)
.flat_map(|(room_id, room_name)| {
Some((
matcher.fuzzy(&room_name, room_filter_text, false)?.0, // extract match score
room_id,
room_name,
))
})
.collect::<Vec<_>>();
rooms_filtered.sort_unstable_by_key(|(score, _, _)| *score);
rooms = rooms_filtered
.into_iter()
.rev()
.map(|(_, room_id, room_name)| (room_id, room_name))
.collect();
}
let first_room_id = rooms.first().map(|(room_id, _)| room_id.clone().clone());
for ((room_id, room), button_state) in rooms.into_iter().zip(buttons_state.iter_mut()) {
let mut but = Button::new(button_state, Text::new(room.get_display_name()))
for ((room_id, room_name), button_state) in rooms.into_iter().zip(buttons_state.iter_mut()) {
let mut but = Button::new(button_state, Text::new(room_name))
pub fn view(&mut self, theme: Theme) -> Element<Message> {
if let Some(confirmation) = self.logging_out {
return if confirmation {
Container::new(Text::new("Logging out...").size(30))
.center_y()
.center_x()
.width(Length::Fill)
.height(Length::Fill)
.style(theme)
.into()
} else {
let logout_confirm_panel = Column::with_children(
pub fn logout_screen(&mut self, theme: Theme, confirmation: bool) -> Element<Message> {
if confirmation {
Container::new(Text::new("Logging out...").size(30))
.center_y()
.center_x()
.width(Length::Fill)
.height(Length::Fill)
.style(theme)
.into()
} else {
#[inline(always)]
fn make_button<'a>(
state: &'a mut button::State,
confirm: bool,
theme: Theme,
) -> Element<'a, Message> {
Button::new(
state,
Container::new(Text::new(if confirm { "Yes" } else { "No" }))
.width(Length::Fill)
.center_x(),
)
.width(Length::FillPortion(1))
.on_press(Message::LogoutConfirmation(confirm))
.style(theme)
.into()
}
#[inline(always)]
fn make_space<'a>(units: u16) -> Element<'a, Message> {
Space::with_width(Length::FillPortion(units)).into()
}
let logout_confirm_panel = Column::with_children(
Space::with_width(Length::FillPortion(2)).into(),
Button::new(&mut self.logout_approve_but_state, Container::new(Text::new("Yes")).width(Length::Fill).center_x())
.width(Length::FillPortion(1))
.on_press(Message::LogoutConfirmation(true))
.style(theme)
.into(),
Space::with_width(Length::FillPortion(1)).into(),
Button::new(&mut self.logout_cancel_but_state, Container::new(Text::new("No")).width(Length::Fill).center_x())
.width(Length::FillPortion(1))
.on_press(Message::LogoutConfirmation(false))
.style(theme)
.into(),
Space::with_width(Length::FillPortion(2)).into(),
make_space(2),
make_button(&mut self.logout_approve_but_state, true, theme),
make_space(1),
make_button(&mut self.logout_cancel_but_state, false, theme),
make_space(2),
let padded_panel = Row::with_children(vec![
Space::with_width(Length::FillPortion(3)).into(),
logout_confirm_panel.width(Length::FillPortion(4)).into(),
Space::with_width(Length::FillPortion(3)).into(),
])
Container::new(padded_panel)
.width(Length::Fill)
for (room_id, index) in self.looking_at_event.drain().collect::<Vec<_>>() {
if self
.client
.rooms()
.keys()
.any(|other_room_id| other_room_id == &room_id)
{
self.looking_at_event.insert(room_id, index);
}
pub fn view(&mut self, theme: Theme, client: &Client) -> Element<Message> {
if let Some(confirmation) = self.logging_out {
return self.logout_screen(theme, confirmation);
for (room_id, room) in self.client.rooms() {
if !self.looking_at_event.keys().any(|id| id == room_id) {
let rooms = client.rooms();
// Add missing looking_at_event values for newly added rooms (if there is any)
for (room_id, room) in rooms {
if !self.looking_at_event.contains_key(room_id) {
let rooms = self.client.rooms();
let username = client.current_user_id().localpart().to_string();
// Build the top menu
let menu = PickList::new(
&mut self.menu_state,
vec![
username.clone(),
"Join Room".to_string(),
"Logout".to_string(),
],
Some(username),
Message::SelectedMenuOption,
)
.width(Length::Fill)
.style(theme);
let username = self.client.current_user_id().localpart().to_string();
let menu = PickList::new(
&mut self.menu_state,
vec![
username.clone(),
"Join Room".to_string(),
"Logout".to_string(),
],
Some(username),
Message::SelectedMenuOption,
let mut room_search = TextInput::new(
&mut self.room_search_box_state,
"Search rooms...",
&self.room_search_text,
Message::RoomSearchTextChanged,
let rooms_area = Column::with_children(vec![room_list, menu.width(Length::Fill).into()]);
if let Some(room_id) = first_room_id {
room_search = room_search.on_submit(Message::RoomChanged(room_id));
} else {
// if first_room_id is None, then that means no room found (either cause of filter, or the user aren't in any room)
// reusing the room_list variable here
room_list = Container::new(Text::new("No room found"))
.center_x()
.center_y()
.height(Length::Fill)
.width(Length::Fill)
.style(theme)
.into();
}
let rooms_area = Column::with_children(vec![
menu.into(),
room_list,
Container::new(room_search)
.width(Length::Fill)
.padding(6)
.into(),
]);
let thumbnail_urls = self.client.process_events_around_response(*response);
return make_thumbnail_commands(&self.client, thumbnail_urls);
let thumbnail_urls = client.process_events_around_response(*response);
return make_thumbnail_commands(&client, thumbnail_urls);
pub fn subscription(&self) -> Subscription<super::Message> {
let rooms_queued_events = self.client.rooms_queued_events();
pub fn subscription(&self, client: &Client) -> Subscription<super::Message> {
let rooms_queued_events = client.rooms_queued_events();
if let Some(flag) = flags {
match flag {
// "Login" with given session, skipping the info fields.
StartupFlag::UseSession(session) => (
Self {
screen: Screen::Login {
screen: LoginScreen::with_logging_in(Some(true)),
},
..Self::default()
match flags {
// "Login" with given session, skipping the info fields.
StartupFlag::UseSession(session) => (
Self {
screen: Screen::Login {
screen: LoginScreen::with_logging_in(Some(true)),
Command::perform(async { session }, |session| {
Message::LoginScreen(login::Message::LoginWithSession(session))
}),
),
}
} else {
(Self::default(), Command::none())
..Self::default()
},
Command::perform(async { session }, |session| {
Message::LoginScreen(login::Message::LoginWithSession(session))
}),
),
StartupFlag::None => (Self::default(), Command::none()),