aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/connection.rs77
-rw-r--r--src/client/context.rs32
2 files changed, 103 insertions, 6 deletions
diff --git a/src/client/connection.rs b/src/client/connection.rs
index 8937710..02075d6 100644
--- a/src/client/connection.rs
+++ b/src/client/connection.rs
@@ -70,6 +70,8 @@ impl Display for ConnectionError {
}
}
+type CurrentPresence = (Option<Game>, OnlineStatus, bool);
+
/// A connection is a handler for a websocket connection to Discord's gateway.
/// The connection allows for sending and receiving messages over the websocket,
/// such as setting the active game, reconnecting, syncing guilds, and more.
@@ -134,6 +136,7 @@ impl Display for ConnectionError {
/// [`receive`]: #method.receive
/// [docs]: https://discordapp.com/developers/docs/topics/gateway#sharding
pub struct Connection {
+ current_presence: CurrentPresence,
keepalive_channel: MpscSender<Status>,
last_sequence: u64,
login_type: LoginType,
@@ -212,6 +215,7 @@ impl Connection {
Ok((feature_voice! {{
Connection {
+ current_presence: (None, OnlineStatus::Online, false),
keepalive_channel: tx.clone(),
last_sequence: sequence,
login_type: login_type,
@@ -223,6 +227,7 @@ impl Connection {
}
} else {
Connection {
+ current_presence: (None, OnlineStatus::Online, false),
keepalive_channel: tx.clone(),
last_sequence: sequence,
login_type: login_type,
@@ -238,11 +243,62 @@ impl Connection {
self.shard_info
}
- pub fn set_game(&self, game: Option<Game>) {
- self.set_presence(game, OnlineStatus::Online, false)
+ /// Sets whether the current user is afk. This helps Discord determine where
+ /// to send notifications.
+ ///
+ /// Other presence settings are maintained.
+ pub fn set_afk(&mut self, afk: bool) {
+ self.current_presence.2 = afk;
+
+ self.update_presence();
+ }
+
+ /// Sets the user's current game, if any.
+ ///
+ /// Other presence settings are maintained.
+ pub fn set_game(&mut self, game: Option<Game>) {
+ self.current_presence.0 = game;
+
+ self.update_presence();
+ }
+
+ /// Sets the user's current online status.
+ ///
+ /// Note that [`Offline`] is not a valid presence, so it is automatically
+ /// converted to [`Invisible`].
+ ///
+ /// Other presence settings are maintained.
+ pub fn set_status(&mut self, online_status: OnlineStatus) {
+ self.current_presence.1 = match online_status {
+ OnlineStatus::Offline => OnlineStatus::Invisible,
+ other => other,
+ };
+
+ self.update_presence();
}
- pub fn set_presence(&self,
+ /// Sets the user's full presence information.
+ ///
+ /// Consider using the individual setters if you only need to modify one of
+ /// these.
+ ///
+ /// # Examples
+ ///
+ /// Set the current user as playing `"Heroes of the Storm"`, being online,
+ /// and not being afk:
+ ///
+ /// ```rust,no_run
+ /// use serenity::model::{Game, OnlineStatus};
+ ///
+ /// // assuming you are in a context
+ ///
+ /// context.connection.lock()
+ /// .unwrap()
+ /// .set_presence(Game::playing("Heroes of the Storm"),
+ /// OnlineStatus::Online,
+ /// false);
+ /// ```
+ pub fn set_presence(&mut self,
game: Option<Game>,
status: OnlineStatus,
afk: bool) {
@@ -250,6 +306,15 @@ impl Connection {
OnlineStatus::Offline => OnlineStatus::Invisible,
other => other,
};
+
+ self.current_presence = (game, status, afk);
+
+ self.update_presence();
+ }
+
+ fn update_presence(&self) {
+ let (ref game, status, afk) = self.current_presence;
+
let msg = ObjectBuilder::new()
.insert("op", OpCode::StatusUpdate.num())
.insert_object("d", move |mut object| {
@@ -257,10 +322,10 @@ impl Connection {
.insert("afk", afk)
.insert("status", status.name());
- match game {
- Some(game) => {
+ match game.as_ref() {
+ Some(ref game) => {
object.insert_object("game", move |o| o
- .insert("name", game.name))
+ .insert("name", &game.name))
},
None => object.insert("game", Value::Null),
}
diff --git a/src/client/context.rs b/src/client/context.rs
index d262096..e2d9fe2 100644
--- a/src/client/context.rs
+++ b/src/client/context.rs
@@ -1218,6 +1218,38 @@ impl Context {
http::send_message(channel_id.into().0, Value::Object(map))
}
+ /// Sets the current user as being [`Online`]. This maintains the current
+ /// game and `afk` setting.
+ ///
+ /// [`Online`]: ../model/enum.OnlineStatus.html#variant.Online
+ pub fn online(&self) {
+ self.connection.lock().unwrap().set_status(OnlineStatus::Online);
+ }
+
+ /// Sets the current user as being [`Idle`]. This maintains the current
+ /// game and `afk` setting.
+ ///
+ /// [`Idle`]: ../model/enum.OnlineStatus.html#variant.Idle
+ pub fn idle(&self) {
+ self.connection.lock().unwrap().set_status(OnlineStatus::Idle);
+ }
+
+ /// Sets the current user as being [`DoNotDisturb`]. This maintains the
+ /// current game and `afk` setting.
+ ///
+ /// [`DoNotDisturb`]: ../model/enum.OnlineStatus.html#variant.DoNotDisturb
+ pub fn dnd(&self) {
+ self.connection.lock().unwrap().set_status(OnlineStatus::DoNotDisturb);
+ }
+
+ /// Sets the current user as being [`Invisible`]. This maintains the current
+ /// game and `afk` setting.
+ ///
+ /// [`Invisible`]: ../model/enum.OnlineStatus.html#variant.Invisible
+ pub fn invisible(&self) {
+ self.connection.lock().unwrap().set_status(OnlineStatus::Invisible);
+ }
+
/// "Resets" the current user's presence, by setting the game to `None`,
/// the online status to [`Online`], and `afk` to `false`.
///