ORN676K73ZYSHZYPQL7UHA5JLIXZTI6C7QWD6T2NHC5UY5XRLKLQC
44QFWIGSLPDS3ZMNKUM7BOYM56YKXENMBIPC7NCUCWU5S2XV76QQC
DV7FTWQFELGDZ3EOWITAODFV4LTR2T67UM543Z7DQ64OBFSHOCNAC
J7PC7UGJE64XZIJXE5YETSHYZUUHSH2B52OA5E5JVQUIF6P72JAQC
K772IAVA7N3R2TAC7SAXK4FVUOOROWMKFMUN3HX7A276H6JA6Y7QC
VO4UOVTJKRL5LOOMKGMQ5DGN5SAZGCEUAUZTKGRE6N3KSCCXHWFAC
CEXASC5XWUEA4SWUKX6HSAXV7DSZTIIBXIQEFZAHAFZ7NUIWQLXAC
MVB4BCD4FIJBLC5ISSG2ZKPYDSEV6IBB3YL75LXVEVZ3BEJDZ52QC
7DWCVQ7NSWW52VKMR7DM27CMOVDXECTXNHYNLDF4NVAI6YH3HHVQC
C6ZDDCL46FXQ7W2UEDZ62YJWI5LUEI4ONHQWU3CHWRVTYSLWRDWAC
XUDXYHQJFNZKP7UHEXWII6J4RJATWTKMWMMW643GRTP7JRASIFVAC
let pkgs = import nixpkgs { inherit system; };
let
mozPkgs = import "${sources.nixpkgsMoz}/package-set.nix" {
pkgs = import nixpkgs { inherit system; };
};
rustChannel = mozPkgs.latest.rustChannels.stable;
pkgs = import nixpkgs {
inherit system;
overlays = [
(self: super: {
rustc = rustChannel.rust;
inherit (rustChannel)
;
})
];
};
"ruma 0.0.1 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-api 0.17.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-api-macros 0.17.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-client 0.4.0 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-client-api 0.10.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-common 0.2.0 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-common-macros 0.2.0 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-events 0.22.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-events-macros 0.22.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-identifiers 0.17.4 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-identifiers-macros 0.17.4 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-identifiers-validation 0.1.1 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l",
"ruma-serde 0.2.3 (git+https://github.com/ruma/ruma/?branch=main#6c4bd7c72cef22b240a6babad38ecdbfd9f569da)": "0hz5aanaw92ah2wcd2ppq4pp0yqa1j9qclladbckbpqarwff4s1l"
"ruma 0.0.1 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-api 0.17.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-api-macros 0.17.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-client 0.4.0 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-client-api 0.10.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-common 0.2.0 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-common-macros 0.2.0 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-events 0.22.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-events-macros 0.22.0-alpha.1 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-identifiers 0.17.4 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-identifiers-macros 0.17.4 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-identifiers-validation 0.1.1 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz",
"ruma-serde 0.2.3 (git+https://github.com/ruma/ruma/?branch=main#8ccf0f128b66192e46eee020b0e59da3c81397ae)": "1mxlx5jkv3js0vv80aniw1xaanj3kqlhj5p5dsya1mib3bqk7pmz"
let server_media_dir = format!(
"{}content/{}",
crate::data_dir!(),
content_url
.authority()
.map(|a| a.as_str().replace('.', "_"))?
);
Some(PathBuf::from(server_media_dir))
content_url.authority().map(|authority| {
PathBuf::from(format!(
"{}content/{}",
crate::data_dir!(),
authority.as_str().replace('.', "_")
))
})
}
}
#[derive(Debug)]
pub enum ClientError {
/// Error occurred during an IO operation.
IOError(std::io::Error),
/// Error occurred while parsing a string as URL.
URLParse(String, http::uri::InvalidUri),
/// Error occurred in the Matrix client library.
Internal(ruma_client::Error<ruma::api::client::Error>),
/// The user is already logged in.
AlreadyLoggedIn,
/// Not all required login information was provided.
MissingLoginInfo,
/// Custom error
Custom(String),
}
impl Clone for ClientError {
fn clone(&self) -> Self {
use ClientError::*;
match self {
AlreadyLoggedIn => AlreadyLoggedIn,
MissingLoginInfo => MissingLoginInfo,
Custom(err) => Custom(err.clone()),
_ => Custom(self.to_string()),
}
impl From<ruma_client::Error<ruma::api::client::Error>> for ClientError {
fn from(other: ruma_client::Error<ruma::api::client::Error>) -> Self {
Self::Internal(other)
}
}
impl From<std::io::Error> for ClientError {
fn from(other: std::io::Error) -> Self {
Self::IOError(other)
}
}
impl Display for ClientError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use ruma::{api::client::error::ErrorKind as ClientAPIErrorKind, api::error::*};
use ruma_client::Error as InnerClientError;
match self {
ClientError::URLParse(string, err) => {
write!(fmt, "Could not parse URL '{}': {}", string, err)
}
ClientError::Internal(err) => {
match err {
InnerClientError::FromHttpResponse(FromHttpResponseError::Http(
ServerError::Known(err),
)) => match err.kind {
ClientAPIErrorKind::Forbidden => {
return write!(
fmt,
"The server rejected your login information: {}",
err.message
);
}
ClientAPIErrorKind::Unauthorized => {
return write!(
fmt,
"You are unauthorized to perform an operation: {}",
err.message
);
}
ClientAPIErrorKind::UnknownToken { soft_logout: _ } => {
return write!(
fmt,
"Your session has expired, please login again: {}",
err.message
);
}
_ => {}
},
InnerClientError::Response(_) => {
return write!(
fmt,
"Please check if you can connect to the internet and try again: {}",
err,
);
}
InnerClientError::AuthenticationRequired => {
return write!(
fmt,
"Authentication is required for an operation, please login (again)",
);
}
_ => {}
}
write!(fmt, "An internal error occurred: {}", err.to_string())
}
ClientError::IOError(err) => write!(fmt, "An IO error occurred: {}", err),
ClientError::AlreadyLoggedIn => write!(fmt, "Already logged in with another user."),
ClientError::MissingLoginInfo => {
write!(fmt, "Missing required login information, can't login.")
}
ClientError::Custom(msg) => write!(fmt, "{}", msg),
}
}
}
pub type Members = AHashMap<UserId, Member>;
pub struct Member {
avatar_url: Option<Uri>,
display_name: Option<String>,
display_user: bool,
typing_received: Option<Duration>,
}
impl Default for Member {
fn default() -> Self {
Self {
avatar_url: None,
display_name: None,
display_user: true,
typing_received: None,
}
}
}
impl Member {
pub fn new() -> Self {
Self::default()
}
pub fn avatar_url(&self) -> Option<&Uri> {
self.avatar_url.as_ref()
}
pub fn display_name(&self) -> Option<&str> {
self.display_name.as_deref()
}
pub fn display(&self) -> bool {
self.display_user
}
pub fn is_typing(&self) -> bool {
self.typing_received.is_some()
}
pub fn set_avatar_url(&mut self, new_avatar_url: Option<Uri>) {
self.avatar_url = new_avatar_url;
}
pub fn set_display_name(&mut self, new_display_name: Option<String>) {
self.display_name = new_display_name;
}
pub fn set_display(&mut self, new_display: bool) {
self.display_user = new_display;
}
pub fn set_typing(&mut self, new_typing_recieved: Option<Duration>) {
self.typing_received = new_typing_recieved;
}
}
Container::new(
Column::with_children(message_group.drain(..).collect())
.align_items(Align::Start)
.padding(16)
.spacing(4),
)
.style(crate::ui::style::RoundContainer),
Container::new(super::column(message_group.drain(..).collect()))
.style(crate::ui::style::RoundContainer),
Container::new(
Column::with_children(message_group.drain(..).collect())
.align_items(Align::Start)
.padding(16)
.spacing(4),
)
.style(crate::ui::style::RoundContainer),
Container::new(super::column(message_group.drain(..).collect()))
.style(crate::ui::style::RoundContainer),
Container::new(
Column::with_children(message_group.drain(..).collect())
.align_items(Align::Start)
.padding(16)
.spacing(4),
)
.style(crate::ui::style::RoundContainer),
Container::new(super::column(message_group.drain(..).collect()))
.style(crate::ui::style::RoundContainer),
use super::style::{PADDING, SPACING};
use iced::{Align, Column, Element, Row};
pub fn column<'a, M>(children: Vec<Element<'a, M>>) -> Column<'a, M> {
Column::with_children(children)
.align_items(Align::Start)
.padding(PADDING)
.spacing(SPACING)
}
pub fn row<'a, M>(children: Vec<Element<'a, M>>) -> Row<'a, M> {
Row::with_children(children)
.align_items(Align::Start)
.padding(PADDING)
.spacing(SPACING)
}
let send_file_button =
Button::new(&mut self.send_file_but_state, Text::new("↑").size(28))
.style(DarkButton)
.on_press(Message::SendFile(room_id.clone()));
let send_file_button = Button::new(
&mut self.send_file_but_state,
Text::new("↑").size((PADDING / 4) * 3 + MESSAGE_SIZE),
)
.style(DarkButton)
.on_press(Message::SendFile(room_id.clone()));
pub const ALL: [Theme; 2] = [Theme::Light, Theme::Dark];
const SENDER_COLORS_DARK: [Color; 8] = [
Color::from_rgb(
0x6d as f32 / 255.0,
0xdd as f32 / 255.0,
0x18 as f32 / 255.0,
),
Color::from_rgb(
0xfc as f32 / 255.0,
0xd2 as f32 / 255.0,
0x00 as f32 / 255.0,
),
Color::from_rgb(
0xcc as f32 / 255.0,
0xf9 as f32 / 255.0,
0xff as f32 / 255.0,
),
Color::from_rgb(
0x3d as f32 / 255.0,
0xdb as f32 / 255.0,
0x8c as f32 / 255.0,
),
Color::from_rgb(
0xdd as f32 / 255.0,
0x6a as f32 / 255.0,
0x35 as f32 / 255.0,
),
const SENDER_COLORS: [Color; 8] = [
0xe2 as f32 / 255.0,
0x22 as f32 / 255.0,
0x45 as f32 / 255.0,
),
Color::from_rgb(
0x09 as f32 / 255.0,
0xe5 as f32 / 255.0,
0x38 as f32 / 255.0,
),
Color::from_rgb(
0xd1 as f32 / 255.0,
0x32 as f32 / 255.0,
0x71 as f32 / 255.0,
),
];
const SENDER_COLORS_LIGHT: [Color; 8] = [
Color::from_rgb(