mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
rog-supported crate
This commit is contained in:
@@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
+ Support 8bit RGB, RGBA, 16bit Greyscalw, RGB, RGBA
|
+ Support 8bit RGB, RGBA, 16bit Greyscalw, RGB, RGBA
|
||||||
+ add `AsusImage` type for slanted-template pixel-perfect images
|
+ add `AsusImage` type for slanted-template pixel-perfect images
|
||||||
+ `BREAKING:` plain `Image` with time period is changed and old anime configs break as a result (sorry)
|
+ `BREAKING:` plain `Image` with time period is changed and old anime configs break as a result (sorry)
|
||||||
|
### Changed
|
||||||
|
- Graphics control:
|
||||||
|
+ BREAKING: graphics control is pulled out of asusd and moved to new crate; supergfxctl
|
||||||
|
|
||||||
# [3.7.2] - 2021-08-02
|
# [3.7.2] - 2021-08-02
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
14
Cargo.lock
generated
14
Cargo.lock
generated
@@ -37,7 +37,7 @@ dependencies = [
|
|||||||
"rog_aura",
|
"rog_aura",
|
||||||
"rog_dbus",
|
"rog_dbus",
|
||||||
"rog_profiles",
|
"rog_profiles",
|
||||||
"rog_types",
|
"rog_supported",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"supergfxctl",
|
"supergfxctl",
|
||||||
"zbus",
|
"zbus",
|
||||||
@@ -55,7 +55,7 @@ dependencies = [
|
|||||||
"rog_aura",
|
"rog_aura",
|
||||||
"rog_dbus",
|
"rog_dbus",
|
||||||
"rog_profiles",
|
"rog_profiles",
|
||||||
"rog_types",
|
"rog_supported",
|
||||||
"supergfxctl",
|
"supergfxctl",
|
||||||
"tinybmp",
|
"tinybmp",
|
||||||
"zbus",
|
"zbus",
|
||||||
@@ -217,7 +217,7 @@ dependencies = [
|
|||||||
"rog_aura",
|
"rog_aura",
|
||||||
"rog_dbus",
|
"rog_dbus",
|
||||||
"rog_profiles",
|
"rog_profiles",
|
||||||
"rog_types",
|
"rog_supported",
|
||||||
"rusb",
|
"rusb",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
@@ -237,7 +237,7 @@ dependencies = [
|
|||||||
"dirs 3.0.2",
|
"dirs 3.0.2",
|
||||||
"rog_anime",
|
"rog_anime",
|
||||||
"rog_dbus",
|
"rog_dbus",
|
||||||
"rog_types",
|
"rog_supported",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -924,7 +924,7 @@ dependencies = [
|
|||||||
"rog_anime",
|
"rog_anime",
|
||||||
"rog_aura",
|
"rog_aura",
|
||||||
"rog_profiles",
|
"rog_profiles",
|
||||||
"rog_types",
|
"rog_supported",
|
||||||
"supergfxctl",
|
"supergfxctl",
|
||||||
"zbus",
|
"zbus",
|
||||||
"zbus_macros",
|
"zbus_macros",
|
||||||
@@ -942,7 +942,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rog_types"
|
name = "rog_supported"
|
||||||
version = "3.2.0"
|
version = "3.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rog_aura",
|
"rog_aura",
|
||||||
@@ -1068,7 +1068,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "supergfxctl"
|
name = "supergfxctl"
|
||||||
version = "1.1.0"
|
version = "2.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"gumdrop",
|
"gumdrop",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["asusctl", "asus-notify", "daemon", "daemon-user", "rog-types", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "supergfx"]
|
members = ["asusctl", "asus-notify", "daemon", "daemon-user", "rog-supported", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "supergfx"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ zbus = "^1.9"
|
|||||||
serde_json = "^1.0"
|
serde_json = "^1.0"
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_types = { path = "../rog-types" }
|
rog_supported = { path = "../rog-supported" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
supergfxctl = { path = "../supergfx" }
|
supergfxctl = { path = "../supergfx" }
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ macro_rules! base_notification {
|
|||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("asus-notify version {}", env!("CARGO_PKG_VERSION"));
|
println!("asus-notify version {}", env!("CARGO_PKG_VERSION"));
|
||||||
println!(" rog-dbus version {}", rog_dbus::VERSION);
|
println!(" rog-dbus version {}", rog_dbus::VERSION);
|
||||||
|
println!("supergfxctl version {}", supergfxctl::VERSION);
|
||||||
|
|
||||||
let (proxies, conn) = DbusProxies::new()?;
|
let (proxies, conn) = DbusProxies::new()?;
|
||||||
let signals = Signals::new(&proxies)?;
|
let signals = Signals::new(&proxies)?;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ rog_anime = { path = "../rog-anime" }
|
|||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_types = { path = "../rog-types" }
|
rog_supported = { path = "../rog-supported" }
|
||||||
daemon = { path = "../daemon" }
|
daemon = { path = "../daemon" }
|
||||||
gumdrop = "^0.8"
|
gumdrop = "^0.8"
|
||||||
supergfxctl = { path = "../supergfx" }
|
supergfxctl = { path = "../supergfx" }
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use profiles_cli::ProfileCommand;
|
|||||||
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2, ANIME_DATA_LEN};
|
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2, ANIME_DATA_LEN};
|
||||||
use rog_aura::{self, AuraEffect};
|
use rog_aura::{self, AuraEffect};
|
||||||
use rog_dbus::RogDbusClient;
|
use rog_dbus::RogDbusClient;
|
||||||
use rog_types::supported::{
|
use rog_supported::{
|
||||||
AnimeSupportedFunctions, LedSupportedFunctions, PlatformProfileFunctions,
|
AnimeSupportedFunctions, LedSupportedFunctions, PlatformProfileFunctions,
|
||||||
RogBiosSupportedFunctions,
|
RogBiosSupportedFunctions,
|
||||||
};
|
};
|
||||||
@@ -139,14 +139,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
if parsed.version {
|
if parsed.version {
|
||||||
println!("\nApp and daemon versions:");
|
println!("\nApp and daemon versions:");
|
||||||
println!(" asusctl v{}", env!("CARGO_PKG_VERSION"));
|
println!(" asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||||
println!(" asusd v{}", daemon::VERSION);
|
println!(" asusd v{}", daemon::VERSION);
|
||||||
println!("\nComponent crate versions:");
|
println!("\nComponent crate versions:");
|
||||||
println!(" rog-anime v{}", rog_anime::VERSION);
|
println!(" rog-anime v{}", rog_anime::VERSION);
|
||||||
println!(" rog-aura v{}", rog_aura::VERSION);
|
println!(" rog-aura v{}", rog_aura::VERSION);
|
||||||
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||||
println!("rog-profiles v{}", rog_profiles::VERSION);
|
println!(" rog-profiles v{}", rog_profiles::VERSION);
|
||||||
println!(" rog-types v{}", rog_types::VERSION);
|
println!("rog-supported v{}", rog_supported::VERSION);
|
||||||
|
println!(" supergfxctl v{}", supergfxctl::VERSION);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ serde_derive = "^1.0"
|
|||||||
|
|
||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
rog_types = { path = "../rog-types" }
|
rog_supported = { path = "../rog-supported" }
|
||||||
|
|
||||||
dirs = "3.0.1"
|
dirs = "3.0.1"
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ use zbus::{fdo, Connection};
|
|||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!(" user daemon v{}", rog_user::VERSION);
|
println!(" user daemon v{}", rog_user::VERSION);
|
||||||
println!(" rog-anime v{}", rog_anime::VERSION);
|
println!(" rog-anime v{}", rog_anime::VERSION);
|
||||||
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
println!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||||
println!(" rog-types v{}", rog_types::VERSION);
|
println!("rog-supported v{}", rog_supported::VERSION);
|
||||||
|
|
||||||
let (client, _) = RogDbusClient::new().unwrap();
|
let (client, _) = RogDbusClient::new().unwrap();
|
||||||
let supported = client.proxies().supported().get_supported_functions()?;
|
let supported = client.proxies().supported().get_supported_functions()?;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ path = "src/daemon.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_types = { path = "../rog-types" }
|
rog_supported = { path = "../rog-supported" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
rusb = "^0.8"
|
rusb = "^0.8"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use rog_anime::{
|
|||||||
},
|
},
|
||||||
ActionData, AnimeDataBuffer, AnimePacketType, ANIME_DATA_LEN,
|
ActionData, AnimeDataBuffer, AnimePacketType, ANIME_DATA_LEN,
|
||||||
};
|
};
|
||||||
use rog_types::supported::AnimeSupportedFunctions;
|
use rog_supported::AnimeSupportedFunctions;
|
||||||
use rusb::{Device, DeviceHandle};
|
use rusb::{Device, DeviceHandle};
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use rog_aura::{
|
|||||||
},
|
},
|
||||||
AuraEffect, LedBrightness, LED_MSG_LEN,
|
AuraEffect, LedBrightness, LED_MSG_LEN,
|
||||||
};
|
};
|
||||||
use rog_types::supported::LedSupportedFunctions;
|
use rog_supported::LedSupportedFunctions;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{config::Config, error::RogError, GetSupported};
|
use crate::{config::Config, error::RogError, GetSupported};
|
||||||
//use crate::dbus::DbusEvents;
|
//use crate::dbus::DbusEvents;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rog_types::supported::ChargeSupportedFunctions;
|
use rog_supported::ChargeSupportedFunctions;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use crate::GetSupported;
|
|||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
use rog_profiles::{FanCurves, Profile};
|
use rog_profiles::{FanCurves, Profile};
|
||||||
use rog_types::supported::PlatformProfileFunctions;
|
use rog_supported::PlatformProfileFunctions;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{config::Config, error::RogError, GetSupported};
|
use crate::{config::Config, error::RogError, GetSupported};
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use rog_types::supported::RogBiosSupportedFunctions;
|
use rog_supported::RogBiosSupportedFunctions;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::{
|
|||||||
ctrl_profiles::controller::CtrlPlatformProfile, ctrl_rog_bios::CtrlRogBios, GetSupported,
|
ctrl_profiles::controller::CtrlPlatformProfile, ctrl_rog_bios::CtrlRogBios, GetSupported,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rog_types::supported::{
|
use rog_supported::{
|
||||||
AnimeSupportedFunctions, ChargeSupportedFunctions, LedSupportedFunctions,
|
AnimeSupportedFunctions, ChargeSupportedFunctions, LedSupportedFunctions,
|
||||||
PlatformProfileFunctions, RogBiosSupportedFunctions,
|
PlatformProfileFunctions, RogBiosSupportedFunctions,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,12 +54,12 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(" daemon v{}", daemon::VERSION);
|
info!(" daemon v{}", daemon::VERSION);
|
||||||
info!(" rog-anime v{}", rog_anime::VERSION);
|
info!(" rog-anime v{}", rog_anime::VERSION);
|
||||||
info!(" rog-aura v{}", rog_aura::VERSION);
|
info!(" rog-aura v{}", rog_aura::VERSION);
|
||||||
info!(" rog-dbus v{}", rog_dbus::VERSION);
|
info!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||||
info!("rog-profiles v{}", rog_profiles::VERSION);
|
info!(" rog-profiles v{}", rog_profiles::VERSION);
|
||||||
info!(" rog-types v{}", rog_types::VERSION);
|
info!("rog-supported v{}", rog_supported::VERSION);
|
||||||
|
|
||||||
start_daemon()?;
|
start_daemon()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ edition = "2018"
|
|||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_types = { path = "../rog-types" }
|
rog_supported = { path = "../rog-supported" }
|
||||||
supergfxctl = { path = "../supergfx" }
|
supergfxctl = { path = "../supergfx" }
|
||||||
zbus = "^1.9"
|
zbus = "^1.9"
|
||||||
zbus_macros = "^1.9"
|
zbus_macros = "^1.9"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
//!
|
//!
|
||||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||||
|
|
||||||
use rog_types::supported::SupportedFunctions;
|
use rog_supported::SupportedFunctions;
|
||||||
use zbus::{dbus_proxy, Connection, Result};
|
use zbus::{dbus_proxy, Connection, Result};
|
||||||
|
|
||||||
#[dbus_proxy(
|
#[dbus_proxy(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rog_types"
|
name = "rog_supported"
|
||||||
version = "3.2.0"
|
version = "3.2.0"
|
||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = ["Luke <luke@ljones.dev>"]
|
authors = ["Luke <luke@ljones.dev>"]
|
||||||
repository = "https://gitlab.com/asus-linux/asus-nb-ctrl"
|
repository = "https://gitlab.com/asus-linux/asus-nb-ctrl"
|
||||||
homepage = "https://gitlab.com/asus-linux/asus-nb-ctrl"
|
homepage = "https://gitlab.com/asus-linux/asus-nb-ctrl"
|
||||||
description = "A small library of effect types and conversions for ROG Aura"
|
description = "Helper to determine what is supported by asus laptops"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
use rog_aura::AuraModeNum;
|
use rog_aura::AuraModeNum;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
//! This crate is intended for shared types (eg, between daemon and CLI), or
|
|
||||||
//! for types that might be useful in third-party crates perhaps for
|
|
||||||
//! sending messages over dbus wire
|
|
||||||
|
|
||||||
pub static DBUS_NAME: &str = "org.asuslinux.Daemon";
|
|
||||||
pub static DBUS_PATH: &str = "/org/asuslinux/Daemon";
|
|
||||||
pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";
|
|
||||||
|
|
||||||
pub mod supported;
|
|
||||||
|
|
||||||
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "supergfxctl"
|
name = "supergfxctl"
|
||||||
version = "1.1.0"
|
version = "2.0.0"
|
||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = ["Luke <luke@ljones.dev>"]
|
authors = ["Luke <luke@ljones.dev>"]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use supergfxctl::{
|
|||||||
error::GfxError,
|
error::GfxError,
|
||||||
gfx_vendors::GfxVendors,
|
gfx_vendors::GfxVendors,
|
||||||
special::{get_asus_gsync_gfx_mode, has_asus_gsync_gfx_mode},
|
special::{get_asus_gsync_gfx_mode, has_asus_gsync_gfx_mode},
|
||||||
DBUS_DEST_NAME, GFX_CONFIG_PATH,
|
CONFIG_PATH, DBUS_DEST_NAME,
|
||||||
};
|
};
|
||||||
use zbus::{fdo, Connection, ObjectServer};
|
use zbus::{fdo, Connection, ObjectServer};
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let mut object_server = ObjectServer::new(&connection);
|
let mut object_server = ObjectServer::new(&connection);
|
||||||
|
|
||||||
let config = GfxConfig::load(GFX_CONFIG_PATH.into());
|
let config = GfxConfig::load(CONFIG_PATH.into());
|
||||||
let enable_gfx_switching = config.gfx_managed;
|
let enable_gfx_switching = config.gfx_managed;
|
||||||
let config = Arc::new(Mutex::new(config));
|
let config = Arc::new(Mutex::new(config));
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ pub mod system;
|
|||||||
pub mod zbus_iface;
|
pub mod zbus_iface;
|
||||||
pub mod zbus_proxy;
|
pub mod zbus_proxy;
|
||||||
|
|
||||||
pub const GFX_CONFIG_PATH: &str = "/etc/supergfxd.conf";
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
pub const CONFIG_PATH: &str = "/etc/supergfxd.conf";
|
||||||
pub const DBUS_DEST_NAME: &str = "org.supergfxctl.Daemon";
|
pub const DBUS_DEST_NAME: &str = "org.supergfxctl.Daemon";
|
||||||
pub const DBUS_IFACE_PATH: &str = "/org/supergfxctl/Gfx";
|
pub const DBUS_IFACE_PATH: &str = "/org/supergfxctl/Gfx";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user