A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
0

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #40 from tsirysndr/feat/sdk-notifications-shout-gif

Add notifications and GIF support across all SDKs with TypeScript typing

+7172 -138
+3 -3
Cargo.lock
··· 6468 6468 6469 6469 [[package]] 6470 6470 name = "rocksky-nif" 6471 - version = "0.2.0" 6471 + version = "0.3.0" 6472 6472 dependencies = [ 6473 6473 "once_cell", 6474 6474 "rocksky-sdk", ··· 6554 6554 6555 6555 [[package]] 6556 6556 name = "rocksky-sdk" 6557 - version = "0.5.0" 6557 + version = "0.6.0" 6558 6558 dependencies = [ 6559 6559 "chrono", 6560 6560 "cid", ··· 6643 6643 6644 6644 [[package]] 6645 6645 name = "rocksky-uniffi" 6646 - version = "0.2.0" 6646 + version = "0.3.0" 6647 6647 dependencies = [ 6648 6648 "once_cell", 6649 6649 "rocksky-sdk",
+1 -1
crates/rocksky-nif/Cargo.toml
··· 1 1 [package] 2 2 name = "rocksky-nif" 3 - version = "0.2.0" 3 + version = "0.3.0" 4 4 edition = "2021" 5 5 description = "Erlang NIF (Rustler) bindings for rocksky-sdk — powers the Erlang, Elixir & Gleam SDKs" 6 6 authors.workspace = true
+75
crates/rocksky-nif/src/lib.rs
··· 175 175 envelope(RT.block_on(av.get(&nsid, &params))) 176 176 } 177 177 178 + /// Mark notifications as viewed (`app.rocksky.notification.updateSeen`). `token` 179 + /// is required. `ids_json` is a JSON array of notification ids, or `[]` to mark 180 + /// **all** as viewed. Returns the typed `{ "unreadCount": <int> }` result. 181 + #[rustler::nif(schedule = "DirtyIo")] 182 + fn update_seen(base: String, token: String, ids_json: String) -> String { 183 + let mut av = appview(&base); 184 + if !token.is_empty() { 185 + av.set_token(Some(token)); 186 + } 187 + let ids: Vec<String> = serde_json::from_str(&ids_json).unwrap_or_default(); 188 + envelope(RT.block_on(av.update_seen(&ids))) 189 + } 190 + 191 + /// Parse a JSON GIF embed (`app.rocksky.shout.defs#gif`) into a 192 + /// [`rocksky_sdk::ShoutGif`]. Empty or invalid input yields `None`. 193 + fn parse_gif(gif_json: &str) -> Option<rocksky_sdk::ShoutGif> { 194 + if gif_json.is_empty() { 195 + return None; 196 + } 197 + serde_json::from_str::<rocksky_sdk::ShoutGif>(gif_json).ok() 198 + } 199 + 178 200 /// Coerce a JSON object of params into string pairs (numbers/bools stringified). 179 201 fn params_from_json(params_json: &str) -> Vec<(String, String)> { 180 202 serde_json::from_str::<std::collections::HashMap<String, serde_json::Value>>(params_json) ··· 625 647 message: String, 626 648 ) -> String { 627 649 envelope(RT.block_on(agent.0.shout(&subject_uri, &subject_cid, &message))) 650 + } 651 + 652 + /// Post a shout with an optional GIF/sticker/clip. `message` may be empty when a 653 + /// `gif_json` embed is supplied (pass at least one); `gif_json` empty = no gif. 654 + #[rustler::nif(schedule = "DirtyIo")] 655 + fn agent_shout_with_gif( 656 + agent: ResourceArc<AgentRes>, 657 + subject_uri: String, 658 + subject_cid: String, 659 + message: String, 660 + gif_json: String, 661 + ) -> String { 662 + let message = if message.is_empty() { 663 + None 664 + } else { 665 + Some(message) 666 + }; 667 + let gif = parse_gif(&gif_json); 668 + envelope( 669 + RT.block_on( 670 + agent 671 + .0 672 + .shout_with_gif(&subject_uri, &subject_cid, message.as_deref(), gif), 673 + ), 674 + ) 675 + } 676 + 677 + /// Reply to a shout with an optional GIF/sticker/clip. Semantics match 678 + /// [`agent_shout_with_gif`], plus a `parent` strong-ref. 679 + #[rustler::nif(schedule = "DirtyIo")] 680 + fn agent_reply_shout_with_gif( 681 + agent: ResourceArc<AgentRes>, 682 + subject_uri: String, 683 + subject_cid: String, 684 + parent_uri: String, 685 + parent_cid: String, 686 + message: String, 687 + gif_json: String, 688 + ) -> String { 689 + let message = if message.is_empty() { 690 + None 691 + } else { 692 + Some(message) 693 + }; 694 + let gif = parse_gif(&gif_json); 695 + envelope(RT.block_on(agent.0.reply_shout_with_gif( 696 + &subject_uri, 697 + &subject_cid, 698 + &parent_uri, 699 + &parent_cid, 700 + message.as_deref(), 701 + gif, 702 + ))) 628 703 } 629 704 630 705 #[rustler::nif(schedule = "DirtyIo")]
+1 -1
crates/rocksky-sdk/Cargo.toml
··· 1 1 [package] 2 2 name = "rocksky-sdk" 3 - version = "0.5.0" 3 + version = "0.6.0" 4 4 description = "Official Rust SDK for Rocksky — a music scrobbling & discovery platform on the AT Protocol" 5 5 authors.workspace = true 6 6 edition.workspace = true
+81 -3
crates/rocksky-sdk/src/agent.rs
··· 26 26 use crate::app_rocksky::graph::follow::Follow; 27 27 use crate::app_rocksky::like::Like; 28 28 use crate::app_rocksky::scrobble::Scrobble; 29 - use crate::app_rocksky::shout::Shout; 29 + use crate::app_rocksky::shout::{Gif, Shout}; 30 30 use crate::app_rocksky::song::Song; 31 31 use crate::appview::AppView; 32 32 use crate::auth::{fetch_profile, rocksky_scopes, Profile}; ··· 137 137 pub tags: Vec<String>, 138 138 pub picture_url: Option<String>, 139 139 pub bio: Option<String>, 140 + } 141 + 142 + /// A GIF / sticker / clip attachment for a shout 143 + /// (`app.rocksky.shout.defs#gif`). Only `url` is required — it may point at an 144 + /// image (GIF/WebP) or a video (MP4); the client decides how to render it from 145 + /// the file extension. The rest enrich the embed when known. 146 + /// 147 + /// ``` 148 + /// use rocksky_sdk::ShoutGif; 149 + /// let _ = ShoutGif { url: "https://media.klipy.com/x.mp4".into(), ..Default::default() }; 150 + /// ``` 151 + #[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)] 152 + #[serde(rename_all = "camelCase", default)] 153 + pub struct ShoutGif { 154 + /// Direct URL of the animated GIF/MP4. 155 + pub url: String, 156 + /// Smaller still / preview image URL. 157 + pub preview_url: Option<String>, 158 + /// Alternative text describing the media. 159 + pub alt: Option<String>, 160 + /// Intrinsic width of the media in pixels. 161 + pub width: Option<i64>, 162 + /// Intrinsic height of the media in pixels. 163 + pub height: Option<i64>, 140 164 } 141 165 142 166 /// The four records a [`scrobble`](RockskyAgent::scrobble) touches. Each URI is ··· 1003 1027 subject_cid: &str, 1004 1028 message: &str, 1005 1029 ) -> Result<String> { 1030 + self.shout_with_gif(subject_uri, subject_cid, Some(message), None) 1031 + .await 1032 + } 1033 + 1034 + /// Post a shout with an optional GIF/sticker/clip attachment 1035 + /// (`app.rocksky.shout`). `message` may be omitted when a `gif` is attached; 1036 + /// pass at least one of the two. Returns the shout URI. 1037 + pub async fn shout_with_gif( 1038 + &self, 1039 + subject_uri: &str, 1040 + subject_cid: &str, 1041 + message: Option<&str>, 1042 + gif: Option<ShoutGif>, 1043 + ) -> Result<String> { 1006 1044 let record = Shout::new() 1007 1045 .subject(strong_ref(subject_uri, subject_cid)?) 1008 - .message(message.to_string()) 1046 + .maybe_message(message.map(Into::into)) 1047 + .maybe_gif(gif.map(build_gif).transpose()?) 1009 1048 .created_at(Datetime::now()) 1010 1049 .build(); 1011 1050 self.create(record, "create shout").await ··· 1021 1060 parent_cid: &str, 1022 1061 message: &str, 1023 1062 ) -> Result<String> { 1063 + self.reply_shout_with_gif( 1064 + subject_uri, 1065 + subject_cid, 1066 + parent_uri, 1067 + parent_cid, 1068 + Some(message), 1069 + None, 1070 + ) 1071 + .await 1072 + } 1073 + 1074 + /// Reply to a shout with an optional GIF/sticker/clip attachment. Like 1075 + /// [`shout_with_gif`](Self::shout_with_gif) but with a `parent` strong-ref 1076 + /// pointing at the shout being replied to. 1077 + pub async fn reply_shout_with_gif( 1078 + &self, 1079 + subject_uri: &str, 1080 + subject_cid: &str, 1081 + parent_uri: &str, 1082 + parent_cid: &str, 1083 + message: Option<&str>, 1084 + gif: Option<ShoutGif>, 1085 + ) -> Result<String> { 1024 1086 let record = Shout::new() 1025 1087 .subject(strong_ref(subject_uri, subject_cid)?) 1026 1088 .maybe_parent(Some(strong_ref(parent_uri, parent_cid)?)) 1027 - .message(message.to_string()) 1089 + .maybe_message(message.map(Into::into)) 1090 + .maybe_gif(gif.map(build_gif).transpose()?) 1028 1091 .created_at(Datetime::now()) 1029 1092 .build(); 1030 1093 self.create(record, "create shout reply").await 1031 1094 } 1095 + } 1096 + 1097 + /// Convert a user-facing [`ShoutGif`] into the generated 1098 + /// `app.rocksky.shout.defs#gif` record embed. Errors when `url` is not a valid 1099 + /// URI. 1100 + fn build_gif(g: ShoutGif) -> Result<Gif> { 1101 + let url = 1102 + parse_uri(&g.url).ok_or_else(|| SdkError::Other(format!("invalid gif url: {}", g.url)))?; 1103 + Ok(Gif::new() 1104 + .url(url) 1105 + .maybe_preview_url(g.preview_url.as_deref().and_then(parse_uri)) 1106 + .maybe_alt(g.alt.map(Into::into)) 1107 + .maybe_width(g.width) 1108 + .maybe_height(g.height) 1109 + .build()) 1032 1110 } 1033 1111 1034 1112 /// Duplicate-prevention index management (the `dedup` feature).
+1
crates/rocksky-sdk/src/app_rocksky.rs
··· 16 16 pub mod library; 17 17 pub mod like; 18 18 pub mod mirror; 19 + pub mod notification; 19 20 pub mod player; 20 21 pub mod playlist; 21 22 pub mod playlist_item;
+674
crates/rocksky-sdk/src/app_rocksky/notification.rs
··· 1 + // @generated by jacquard-lexicon. DO NOT EDIT. 2 + // 3 + // Lexicon: app.rocksky.notification.defs 4 + // 5 + // This file was automatically generated from Lexicon schemas. 6 + // Any manual changes will be overwritten on the next regeneration. 7 + 8 + //! Generated bindings for the `app.rocksky.notification` Lexicon namespace/module. 9 + pub mod get_unread_count; 10 + pub mod list_notifications; 11 + pub mod update_seen; 12 + 13 + #[allow(unused_imports)] 14 + use alloc::collections::BTreeMap; 15 + 16 + #[allow(unused_imports)] 17 + use core::marker::PhantomData; 18 + use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr}; 19 + 20 + #[allow(unused_imports)] 21 + use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation; 22 + use jacquard_common::deps::smol_str::SmolStr; 23 + use jacquard_common::types::ident::AtIdentifier; 24 + use jacquard_common::types::string::{Datetime, Did, UriValue}; 25 + use jacquard_common::types::value::Data; 26 + use jacquard_derive::IntoStatic; 27 + use jacquard_lexicon::lexicon::LexiconDoc; 28 + use jacquard_lexicon::schema::LexiconSchema; 29 + 30 + use crate::app_rocksky::notification; 31 + #[allow(unused_imports)] 32 + use jacquard_lexicon::validation::{ConstraintError, ValidationPath}; 33 + use serde::{Deserialize, Serialize}; 34 + /// The user who triggered a notification. 35 + 36 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] 37 + #[serde( 38 + rename_all = "camelCase", 39 + bound(deserialize = "S: Deserialize<'de> + BosStr") 40 + )] 41 + pub struct NotificationActor<S: BosStr = DefaultStr> { 42 + ///The URL of the actor's avatar image. 43 + #[serde(skip_serializing_if = "Option::is_none")] 44 + pub avatar: Option<UriValue<S>>, 45 + ///The decentralized identifier of the actor. 46 + #[serde(skip_serializing_if = "Option::is_none")] 47 + pub did: Option<Did<S>>, 48 + ///The display name of the actor. 49 + #[serde(skip_serializing_if = "Option::is_none")] 50 + pub display_name: Option<S>, 51 + ///The handle of the actor. 52 + #[serde(skip_serializing_if = "Option::is_none")] 53 + pub handle: Option<AtIdentifier<S>>, 54 + ///The unique identifier of the actor. 55 + #[serde(skip_serializing_if = "Option::is_none")] 56 + pub id: Option<S>, 57 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 58 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 59 + } 60 + 61 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] 62 + #[serde( 63 + rename_all = "camelCase", 64 + bound(deserialize = "S: Deserialize<'de> + BosStr") 65 + )] 66 + pub struct NotificationView<S: BosStr = DefaultStr> { 67 + #[serde(skip_serializing_if = "Option::is_none")] 68 + pub actor: Option<notification::NotificationActor<S>>, 69 + ///When the notification was created. 70 + pub created_at: Datetime, 71 + ///The unique identifier of the notification. 72 + pub id: S, 73 + ///Whether the notification has been viewed. 74 + pub read: bool, 75 + ///The content of the related shout, if any. 76 + #[serde(skip_serializing_if = "Option::is_none")] 77 + pub shout_content: Option<S>, 78 + ///The id of the related shout, if any. 79 + #[serde(skip_serializing_if = "Option::is_none")] 80 + pub shout_id: Option<S>, 81 + ///The at-uri of the subject the notification relates to. 82 + #[serde(skip_serializing_if = "Option::is_none")] 83 + pub subject_uri: Option<S>, 84 + ///The notification type: like_scrobble, follow, comment_scrobble, comment_profile, reply, or react_comment. 85 + pub r#type: NotificationViewType<S>, 86 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 87 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 88 + } 89 + 90 + /// The notification type: like_scrobble, follow, comment_scrobble, comment_profile, reply, or react_comment. 91 + 92 + #[derive(Debug, Clone, PartialEq, Eq, Hash)] 93 + pub enum NotificationViewType<S: BosStr = DefaultStr> { 94 + LikeScrobble, 95 + Follow, 96 + CommentScrobble, 97 + CommentProfile, 98 + Reply, 99 + ReactComment, 100 + Other(S), 101 + } 102 + 103 + impl<S: BosStr> NotificationViewType<S> { 104 + pub fn as_str(&self) -> &str { 105 + match self { 106 + Self::LikeScrobble => "like_scrobble", 107 + Self::Follow => "follow", 108 + Self::CommentScrobble => "comment_scrobble", 109 + Self::CommentProfile => "comment_profile", 110 + Self::Reply => "reply", 111 + Self::ReactComment => "react_comment", 112 + Self::Other(s) => s.as_ref(), 113 + } 114 + } 115 + /// Construct from a string-like value, matching known values. 116 + pub fn from_value(s: S) -> Self { 117 + match s.as_ref() { 118 + "like_scrobble" => Self::LikeScrobble, 119 + "follow" => Self::Follow, 120 + "comment_scrobble" => Self::CommentScrobble, 121 + "comment_profile" => Self::CommentProfile, 122 + "reply" => Self::Reply, 123 + "react_comment" => Self::ReactComment, 124 + _ => Self::Other(s), 125 + } 126 + } 127 + } 128 + 129 + impl<S: BosStr> core::fmt::Display for NotificationViewType<S> { 130 + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 131 + write!(f, "{}", self.as_str()) 132 + } 133 + } 134 + 135 + impl<S: BosStr> AsRef<str> for NotificationViewType<S> { 136 + fn as_ref(&self) -> &str { 137 + self.as_str() 138 + } 139 + } 140 + 141 + impl<S: BosStr> Serialize for NotificationViewType<S> { 142 + fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error> 143 + where 144 + Ser: serde::Serializer, 145 + { 146 + serializer.serialize_str(self.as_str()) 147 + } 148 + } 149 + 150 + impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for NotificationViewType<S> { 151 + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 152 + where 153 + D: serde::Deserializer<'de>, 154 + { 155 + let s = S::deserialize(deserializer)?; 156 + Ok(Self::from_value(s)) 157 + } 158 + } 159 + 160 + impl<S: BosStr + Default> Default for NotificationViewType<S> { 161 + fn default() -> Self { 162 + Self::Other(Default::default()) 163 + } 164 + } 165 + 166 + impl<S: BosStr> jacquard_common::IntoStatic for NotificationViewType<S> 167 + where 168 + S: BosStr + jacquard_common::IntoStatic, 169 + S::Output: BosStr, 170 + { 171 + type Output = NotificationViewType<S::Output>; 172 + fn into_static(self) -> Self::Output { 173 + match self { 174 + NotificationViewType::LikeScrobble => NotificationViewType::LikeScrobble, 175 + NotificationViewType::Follow => NotificationViewType::Follow, 176 + NotificationViewType::CommentScrobble => NotificationViewType::CommentScrobble, 177 + NotificationViewType::CommentProfile => NotificationViewType::CommentProfile, 178 + NotificationViewType::Reply => NotificationViewType::Reply, 179 + NotificationViewType::ReactComment => NotificationViewType::ReactComment, 180 + NotificationViewType::Other(v) => NotificationViewType::Other(v.into_static()), 181 + } 182 + } 183 + } 184 + 185 + impl<S: BosStr> LexiconSchema for NotificationActor<S> { 186 + fn nsid() -> &'static str { 187 + "app.rocksky.notification.defs" 188 + } 189 + fn def_name() -> &'static str { 190 + "notificationActor" 191 + } 192 + fn lexicon_doc() -> LexiconDoc<'static> { 193 + lexicon_doc_app_rocksky_notification_defs() 194 + } 195 + fn validate(&self) -> Result<(), ConstraintError> { 196 + Ok(()) 197 + } 198 + } 199 + 200 + impl<S: BosStr> LexiconSchema for NotificationView<S> { 201 + fn nsid() -> &'static str { 202 + "app.rocksky.notification.defs" 203 + } 204 + fn def_name() -> &'static str { 205 + "notificationView" 206 + } 207 + fn lexicon_doc() -> LexiconDoc<'static> { 208 + lexicon_doc_app_rocksky_notification_defs() 209 + } 210 + fn validate(&self) -> Result<(), ConstraintError> { 211 + Ok(()) 212 + } 213 + } 214 + 215 + fn lexicon_doc_app_rocksky_notification_defs() -> LexiconDoc<'static> { 216 + use alloc::collections::BTreeMap; 217 + #[allow(unused_imports)] 218 + use jacquard_common::{deps::smol_str::SmolStr, types::blob::MimeType, CowStr}; 219 + use jacquard_lexicon::lexicon::*; 220 + LexiconDoc { 221 + lexicon: Lexicon::Lexicon1, 222 + id: CowStr::new_static("app.rocksky.notification.defs"), 223 + defs: { 224 + let mut map = BTreeMap::new(); 225 + map.insert( 226 + SmolStr::new_static("notificationActor"), 227 + LexUserType::Object(LexObject { 228 + description: Some(CowStr::new_static("The user who triggered a notification.")), 229 + properties: { 230 + #[allow(unused_mut)] 231 + let mut map = BTreeMap::new(); 232 + map.insert( 233 + SmolStr::new_static("avatar"), 234 + LexObjectProperty::String(LexString { 235 + description: Some(CowStr::new_static( 236 + "The URL of the actor's avatar image.", 237 + )), 238 + format: Some(LexStringFormat::Uri), 239 + ..Default::default() 240 + }), 241 + ); 242 + map.insert( 243 + SmolStr::new_static("did"), 244 + LexObjectProperty::String(LexString { 245 + description: Some(CowStr::new_static( 246 + "The decentralized identifier of the actor.", 247 + )), 248 + format: Some(LexStringFormat::Did), 249 + ..Default::default() 250 + }), 251 + ); 252 + map.insert( 253 + SmolStr::new_static("displayName"), 254 + LexObjectProperty::String(LexString { 255 + description: Some(CowStr::new_static( 256 + "The display name of the actor.", 257 + )), 258 + ..Default::default() 259 + }), 260 + ); 261 + map.insert( 262 + SmolStr::new_static("handle"), 263 + LexObjectProperty::String(LexString { 264 + description: Some(CowStr::new_static("The handle of the actor.")), 265 + format: Some(LexStringFormat::AtIdentifier), 266 + ..Default::default() 267 + }), 268 + ); 269 + map.insert( 270 + SmolStr::new_static("id"), 271 + LexObjectProperty::String(LexString { 272 + description: Some(CowStr::new_static( 273 + "The unique identifier of the actor.", 274 + )), 275 + ..Default::default() 276 + }), 277 + ); 278 + map 279 + }, 280 + ..Default::default() 281 + }), 282 + ); 283 + map.insert( 284 + SmolStr::new_static("notificationView"), 285 + LexUserType::Object(LexObject { 286 + required: Some( 287 + vec![ 288 + SmolStr::new_static("id"), SmolStr::new_static("type"), 289 + SmolStr::new_static("read"), SmolStr::new_static("createdAt") 290 + ], 291 + ), 292 + properties: { 293 + #[allow(unused_mut)] 294 + let mut map = BTreeMap::new(); 295 + map.insert( 296 + SmolStr::new_static("actor"), 297 + LexObjectProperty::Ref(LexRef { 298 + r#ref: CowStr::new_static( 299 + "app.rocksky.notification.defs#notificationActor", 300 + ), 301 + ..Default::default() 302 + }), 303 + ); 304 + map.insert( 305 + SmolStr::new_static("createdAt"), 306 + LexObjectProperty::String(LexString { 307 + description: Some( 308 + CowStr::new_static("When the notification was created."), 309 + ), 310 + format: Some(LexStringFormat::Datetime), 311 + ..Default::default() 312 + }), 313 + ); 314 + map.insert( 315 + SmolStr::new_static("id"), 316 + LexObjectProperty::String(LexString { 317 + description: Some( 318 + CowStr::new_static( 319 + "The unique identifier of the notification.", 320 + ), 321 + ), 322 + ..Default::default() 323 + }), 324 + ); 325 + map.insert( 326 + SmolStr::new_static("read"), 327 + LexObjectProperty::Boolean(LexBoolean { 328 + ..Default::default() 329 + }), 330 + ); 331 + map.insert( 332 + SmolStr::new_static("shoutContent"), 333 + LexObjectProperty::String(LexString { 334 + description: Some( 335 + CowStr::new_static( 336 + "The content of the related shout, if any.", 337 + ), 338 + ), 339 + ..Default::default() 340 + }), 341 + ); 342 + map.insert( 343 + SmolStr::new_static("shoutId"), 344 + LexObjectProperty::String(LexString { 345 + description: Some( 346 + CowStr::new_static("The id of the related shout, if any."), 347 + ), 348 + ..Default::default() 349 + }), 350 + ); 351 + map.insert( 352 + SmolStr::new_static("subjectUri"), 353 + LexObjectProperty::String(LexString { 354 + description: Some( 355 + CowStr::new_static( 356 + "The at-uri of the subject the notification relates to.", 357 + ), 358 + ), 359 + ..Default::default() 360 + }), 361 + ); 362 + map.insert( 363 + SmolStr::new_static("type"), 364 + LexObjectProperty::String(LexString { 365 + description: Some( 366 + CowStr::new_static( 367 + "The notification type: like_scrobble, follow, comment_scrobble, comment_profile, reply, or react_comment.", 368 + ), 369 + ), 370 + ..Default::default() 371 + }), 372 + ); 373 + map 374 + }, 375 + ..Default::default() 376 + }), 377 + ); 378 + map 379 + }, 380 + ..Default::default() 381 + } 382 + } 383 + 384 + pub mod notification_view_state { 385 + 386 + pub use crate::builder_types::{IsSet, IsUnset, Set, Unset}; 387 + #[allow(unused)] 388 + use ::core::marker::PhantomData; 389 + mod sealed { 390 + pub trait Sealed {} 391 + } 392 + /// State trait tracking which required fields have been set 393 + pub trait State: sealed::Sealed { 394 + type CreatedAt; 395 + type Id; 396 + type Read; 397 + type Type; 398 + } 399 + /// Empty state - all required fields are unset 400 + pub struct Empty(()); 401 + impl sealed::Sealed for Empty {} 402 + impl State for Empty { 403 + type CreatedAt = Unset; 404 + type Id = Unset; 405 + type Read = Unset; 406 + type Type = Unset; 407 + } 408 + ///State transition - sets the `created_at` field to Set 409 + pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>); 410 + impl<St: State> sealed::Sealed for SetCreatedAt<St> {} 411 + impl<St: State> State for SetCreatedAt<St> { 412 + type CreatedAt = Set<members::created_at>; 413 + type Id = St::Id; 414 + type Read = St::Read; 415 + type Type = St::Type; 416 + } 417 + ///State transition - sets the `id` field to Set 418 + pub struct SetId<St: State = Empty>(PhantomData<fn() -> St>); 419 + impl<St: State> sealed::Sealed for SetId<St> {} 420 + impl<St: State> State for SetId<St> { 421 + type CreatedAt = St::CreatedAt; 422 + type Id = Set<members::id>; 423 + type Read = St::Read; 424 + type Type = St::Type; 425 + } 426 + ///State transition - sets the `read` field to Set 427 + pub struct SetRead<St: State = Empty>(PhantomData<fn() -> St>); 428 + impl<St: State> sealed::Sealed for SetRead<St> {} 429 + impl<St: State> State for SetRead<St> { 430 + type CreatedAt = St::CreatedAt; 431 + type Id = St::Id; 432 + type Read = Set<members::read>; 433 + type Type = St::Type; 434 + } 435 + ///State transition - sets the `type` field to Set 436 + pub struct SetType<St: State = Empty>(PhantomData<fn() -> St>); 437 + impl<St: State> sealed::Sealed for SetType<St> {} 438 + impl<St: State> State for SetType<St> { 439 + type CreatedAt = St::CreatedAt; 440 + type Id = St::Id; 441 + type Read = St::Read; 442 + type Type = Set<members::r#type>; 443 + } 444 + /// Marker types for field names 445 + #[allow(non_camel_case_types)] 446 + pub mod members { 447 + ///Marker type for the `created_at` field 448 + pub struct created_at(()); 449 + ///Marker type for the `id` field 450 + pub struct id(()); 451 + ///Marker type for the `read` field 452 + pub struct read(()); 453 + ///Marker type for the `type` field 454 + pub struct r#type(()); 455 + } 456 + } 457 + 458 + /// Builder for constructing an instance of this type. 459 + pub struct NotificationViewBuilder<St: notification_view_state::State, S: BosStr = DefaultStr> { 460 + _state: PhantomData<fn() -> St>, 461 + _fields: ( 462 + Option<notification::NotificationActor<S>>, 463 + Option<Datetime>, 464 + Option<S>, 465 + Option<bool>, 466 + Option<S>, 467 + Option<S>, 468 + Option<S>, 469 + Option<NotificationViewType<S>>, 470 + ), 471 + _type: PhantomData<fn() -> S>, 472 + } 473 + 474 + impl NotificationView<DefaultStr> { 475 + /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed 476 + pub fn new() -> NotificationViewBuilder<notification_view_state::Empty, DefaultStr> { 477 + NotificationViewBuilder::new() 478 + } 479 + } 480 + 481 + impl<S: BosStr> NotificationView<S> { 482 + /// Create a new builder for this type 483 + pub fn builder() -> NotificationViewBuilder<notification_view_state::Empty, S> { 484 + NotificationViewBuilder::builder() 485 + } 486 + } 487 + 488 + impl NotificationViewBuilder<notification_view_state::Empty, DefaultStr> { 489 + /// Create a new builder with all fields unset, using the default string type, if needed 490 + pub fn new() -> Self { 491 + NotificationViewBuilder { 492 + _state: PhantomData, 493 + _fields: (None, None, None, None, None, None, None, None), 494 + _type: PhantomData, 495 + } 496 + } 497 + } 498 + 499 + impl<S: BosStr> NotificationViewBuilder<notification_view_state::Empty, S> { 500 + /// Create a new builder with all fields unset 501 + pub fn builder() -> Self { 502 + NotificationViewBuilder { 503 + _state: PhantomData, 504 + _fields: (None, None, None, None, None, None, None, None), 505 + _type: PhantomData, 506 + } 507 + } 508 + } 509 + 510 + impl<St: notification_view_state::State, S: BosStr> NotificationViewBuilder<St, S> { 511 + /// Set the `actor` field (optional) 512 + pub fn actor(mut self, value: impl Into<Option<notification::NotificationActor<S>>>) -> Self { 513 + self._fields.0 = value.into(); 514 + self 515 + } 516 + /// Set the `actor` field to an Option value (optional) 517 + pub fn maybe_actor(mut self, value: Option<notification::NotificationActor<S>>) -> Self { 518 + self._fields.0 = value; 519 + self 520 + } 521 + } 522 + 523 + impl<St, S: BosStr> NotificationViewBuilder<St, S> 524 + where 525 + St: notification_view_state::State, 526 + St::CreatedAt: notification_view_state::IsUnset, 527 + { 528 + /// Set the `createdAt` field (required) 529 + pub fn created_at( 530 + mut self, 531 + value: impl Into<Datetime>, 532 + ) -> NotificationViewBuilder<notification_view_state::SetCreatedAt<St>, S> { 533 + self._fields.1 = Option::Some(value.into()); 534 + NotificationViewBuilder { 535 + _state: PhantomData, 536 + _fields: self._fields, 537 + _type: PhantomData, 538 + } 539 + } 540 + } 541 + 542 + impl<St, S: BosStr> NotificationViewBuilder<St, S> 543 + where 544 + St: notification_view_state::State, 545 + St::Id: notification_view_state::IsUnset, 546 + { 547 + /// Set the `id` field (required) 548 + pub fn id( 549 + mut self, 550 + value: impl Into<S>, 551 + ) -> NotificationViewBuilder<notification_view_state::SetId<St>, S> { 552 + self._fields.2 = Option::Some(value.into()); 553 + NotificationViewBuilder { 554 + _state: PhantomData, 555 + _fields: self._fields, 556 + _type: PhantomData, 557 + } 558 + } 559 + } 560 + 561 + impl<St, S: BosStr> NotificationViewBuilder<St, S> 562 + where 563 + St: notification_view_state::State, 564 + St::Read: notification_view_state::IsUnset, 565 + { 566 + /// Set the `read` field (required) 567 + pub fn read( 568 + mut self, 569 + value: impl Into<bool>, 570 + ) -> NotificationViewBuilder<notification_view_state::SetRead<St>, S> { 571 + self._fields.3 = Option::Some(value.into()); 572 + NotificationViewBuilder { 573 + _state: PhantomData, 574 + _fields: self._fields, 575 + _type: PhantomData, 576 + } 577 + } 578 + } 579 + 580 + impl<St: notification_view_state::State, S: BosStr> NotificationViewBuilder<St, S> { 581 + /// Set the `shoutContent` field (optional) 582 + pub fn shout_content(mut self, value: impl Into<Option<S>>) -> Self { 583 + self._fields.4 = value.into(); 584 + self 585 + } 586 + /// Set the `shoutContent` field to an Option value (optional) 587 + pub fn maybe_shout_content(mut self, value: Option<S>) -> Self { 588 + self._fields.4 = value; 589 + self 590 + } 591 + } 592 + 593 + impl<St: notification_view_state::State, S: BosStr> NotificationViewBuilder<St, S> { 594 + /// Set the `shoutId` field (optional) 595 + pub fn shout_id(mut self, value: impl Into<Option<S>>) -> Self { 596 + self._fields.5 = value.into(); 597 + self 598 + } 599 + /// Set the `shoutId` field to an Option value (optional) 600 + pub fn maybe_shout_id(mut self, value: Option<S>) -> Self { 601 + self._fields.5 = value; 602 + self 603 + } 604 + } 605 + 606 + impl<St: notification_view_state::State, S: BosStr> NotificationViewBuilder<St, S> { 607 + /// Set the `subjectUri` field (optional) 608 + pub fn subject_uri(mut self, value: impl Into<Option<S>>) -> Self { 609 + self._fields.6 = value.into(); 610 + self 611 + } 612 + /// Set the `subjectUri` field to an Option value (optional) 613 + pub fn maybe_subject_uri(mut self, value: Option<S>) -> Self { 614 + self._fields.6 = value; 615 + self 616 + } 617 + } 618 + 619 + impl<St, S: BosStr> NotificationViewBuilder<St, S> 620 + where 621 + St: notification_view_state::State, 622 + St::Type: notification_view_state::IsUnset, 623 + { 624 + /// Set the `type` field (required) 625 + pub fn r#type( 626 + mut self, 627 + value: impl Into<NotificationViewType<S>>, 628 + ) -> NotificationViewBuilder<notification_view_state::SetType<St>, S> { 629 + self._fields.7 = Option::Some(value.into()); 630 + NotificationViewBuilder { 631 + _state: PhantomData, 632 + _fields: self._fields, 633 + _type: PhantomData, 634 + } 635 + } 636 + } 637 + 638 + impl<St, S: BosStr> NotificationViewBuilder<St, S> 639 + where 640 + St: notification_view_state::State, 641 + St::CreatedAt: notification_view_state::IsSet, 642 + St::Id: notification_view_state::IsSet, 643 + St::Read: notification_view_state::IsSet, 644 + St::Type: notification_view_state::IsSet, 645 + { 646 + /// Build the final struct. 647 + pub fn build(self) -> NotificationView<S> { 648 + NotificationView { 649 + actor: self._fields.0, 650 + created_at: self._fields.1.unwrap(), 651 + id: self._fields.2.unwrap(), 652 + read: self._fields.3.unwrap(), 653 + shout_content: self._fields.4, 654 + shout_id: self._fields.5, 655 + subject_uri: self._fields.6, 656 + r#type: self._fields.7.unwrap(), 657 + extra_data: Default::default(), 658 + } 659 + } 660 + /// Build the final struct with custom extra_data. 661 + pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> NotificationView<S> { 662 + NotificationView { 663 + actor: self._fields.0, 664 + created_at: self._fields.1.unwrap(), 665 + id: self._fields.2.unwrap(), 666 + read: self._fields.3.unwrap(), 667 + shout_content: self._fields.4, 668 + shout_id: self._fields.5, 669 + subject_uri: self._fields.6, 670 + r#type: self._fields.7.unwrap(), 671 + extra_data: Some(extra_data), 672 + } 673 + } 674 + }
+63
crates/rocksky-sdk/src/app_rocksky/notification/get_unread_count.rs
··· 1 + // @generated by jacquard-lexicon. DO NOT EDIT. 2 + // 3 + // Lexicon: app.rocksky.notification.getUnreadCount 4 + // 5 + // This file was automatically generated from Lexicon schemas. 6 + // Any manual changes will be overwritten on the next regeneration. 7 + 8 + #[allow(unused_imports)] 9 + use alloc::collections::BTreeMap; 10 + 11 + #[allow(unused_imports)] 12 + use core::marker::PhantomData; 13 + use jacquard_common::deps::smol_str::SmolStr; 14 + use jacquard_common::types::value::Data; 15 + use jacquard_common::{BosStr, DefaultStr, FromStaticStr}; 16 + use jacquard_derive::IntoStatic; 17 + use serde::{Deserialize, Serialize}; 18 + 19 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] 20 + #[serde( 21 + rename_all = "camelCase", 22 + bound(deserialize = "S: Deserialize<'de> + BosStr") 23 + )] 24 + pub struct GetUnreadCountOutput<S: BosStr = DefaultStr> { 25 + ///The number of unread notifications. 26 + pub count: i64, 27 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 28 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 29 + } 30 + 31 + /** Request marker for the `app.rocksky.notification.getUnreadCount` query. 32 + 33 + This endpoint has no request parameters or input body; send this marker with `jacquard::Client`.*/ 34 + 35 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Copy)] 36 + pub struct GetUnreadCount; 37 + /** Response marker for the `app.rocksky.notification.getUnreadCount` query. 38 + 39 + Implements `jacquard_common::xrpc::XrpcResp`; successful bodies decode as `Self::Output<S>`, which is `GetUnreadCountOutput<S>` for this endpoint.*/ 40 + pub struct GetUnreadCountResponse; 41 + impl jacquard_common::xrpc::XrpcResp for GetUnreadCountResponse { 42 + const NSID: &'static str = "app.rocksky.notification.getUnreadCount"; 43 + const ENCODING: &'static str = "application/json"; 44 + type Output<S: BosStr> = GetUnreadCountOutput<S>; 45 + type Err = jacquard_common::xrpc::GenericError; 46 + } 47 + 48 + impl jacquard_common::xrpc::XrpcRequest for GetUnreadCount { 49 + const NSID: &'static str = "app.rocksky.notification.getUnreadCount"; 50 + const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query; 51 + type Response = GetUnreadCountResponse; 52 + } 53 + 54 + /** Endpoint marker for the `app.rocksky.notification.getUnreadCount` query. 55 + 56 + Path: `/xrpc/app.rocksky.notification.getUnreadCount`. The request payload type is `GetUnreadCount`; use this marker with lower-level `XrpcEndpoint` APIs when you need endpoint metadata.*/ 57 + pub struct GetUnreadCountRequest; 58 + impl jacquard_common::xrpc::XrpcEndpoint for GetUnreadCountRequest { 59 + const PATH: &'static str = "/xrpc/app.rocksky.notification.getUnreadCount"; 60 + const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query; 61 + type Request<S: BosStr> = GetUnreadCount; 62 + type Response = GetUnreadCountResponse; 63 + }
+181
crates/rocksky-sdk/src/app_rocksky/notification/list_notifications.rs
··· 1 + // @generated by jacquard-lexicon. DO NOT EDIT. 2 + // 3 + // Lexicon: app.rocksky.notification.listNotifications 4 + // 5 + // This file was automatically generated from Lexicon schemas. 6 + // Any manual changes will be overwritten on the next regeneration. 7 + 8 + #[allow(unused_imports)] 9 + use alloc::collections::BTreeMap; 10 + 11 + use crate::app_rocksky::notification::NotificationView; 12 + #[allow(unused_imports)] 13 + use core::marker::PhantomData; 14 + use jacquard_common::deps::smol_str::SmolStr; 15 + use jacquard_common::types::value::Data; 16 + use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr}; 17 + use jacquard_derive::IntoStatic; 18 + use serde::{Deserialize, Serialize}; 19 + 20 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] 21 + #[serde( 22 + rename_all = "camelCase", 23 + bound(deserialize = "S: Deserialize<'de> + BosStr") 24 + )] 25 + pub struct ListNotifications<S: BosStr = DefaultStr> { 26 + #[serde(skip_serializing_if = "Option::is_none")] 27 + pub cursor: Option<S>, 28 + /// Defaults to `30`. Min: 1. Max: 100. 29 + #[serde(default = "_default_limit")] 30 + #[serde(skip_serializing_if = "Option::is_none")] 31 + pub limit: Option<i64>, 32 + } 33 + 34 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] 35 + #[serde( 36 + rename_all = "camelCase", 37 + bound(deserialize = "S: Deserialize<'de> + BosStr") 38 + )] 39 + pub struct ListNotificationsOutput<S: BosStr = DefaultStr> { 40 + ///A cursor value to pass to subsequent calls to get the next page of results. 41 + #[serde(skip_serializing_if = "Option::is_none")] 42 + pub cursor: Option<S>, 43 + pub notifications: Vec<NotificationView<S>>, 44 + ///The number of unread notifications. 45 + pub unread_count: i64, 46 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 47 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 48 + } 49 + 50 + /** Response marker for the `app.rocksky.notification.listNotifications` query. 51 + 52 + Implements `jacquard_common::xrpc::XrpcResp`; successful bodies decode as `Self::Output<S>`, which is `ListNotificationsOutput<S>` for this endpoint.*/ 53 + pub struct ListNotificationsResponse; 54 + impl jacquard_common::xrpc::XrpcResp for ListNotificationsResponse { 55 + const NSID: &'static str = "app.rocksky.notification.listNotifications"; 56 + const ENCODING: &'static str = "application/json"; 57 + type Output<S: BosStr> = ListNotificationsOutput<S>; 58 + type Err = jacquard_common::xrpc::GenericError; 59 + } 60 + 61 + impl<S: BosStr> jacquard_common::xrpc::XrpcRequest for ListNotifications<S> { 62 + const NSID: &'static str = "app.rocksky.notification.listNotifications"; 63 + const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query; 64 + type Response = ListNotificationsResponse; 65 + } 66 + 67 + /** Endpoint marker for the `app.rocksky.notification.listNotifications` query. 68 + 69 + Path: `/xrpc/app.rocksky.notification.listNotifications`. The request payload type is `ListNotifications<S>`; send that request with `jacquard::Client` or use this marker through lower-level `XrpcEndpoint` APIs.*/ 70 + pub struct ListNotificationsRequest; 71 + impl jacquard_common::xrpc::XrpcEndpoint for ListNotificationsRequest { 72 + const PATH: &'static str = "/xrpc/app.rocksky.notification.listNotifications"; 73 + const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query; 74 + type Request<S: BosStr> = ListNotifications<S>; 75 + type Response = ListNotificationsResponse; 76 + } 77 + 78 + fn _default_limit() -> Option<i64> { 79 + Some(30i64) 80 + } 81 + 82 + pub mod list_notifications_state { 83 + 84 + pub use crate::builder_types::{IsSet, IsUnset, Set, Unset}; 85 + #[allow(unused)] 86 + use ::core::marker::PhantomData; 87 + mod sealed { 88 + pub trait Sealed {} 89 + } 90 + /// State trait tracking which required fields have been set 91 + pub trait State: sealed::Sealed {} 92 + /// Empty state - all required fields are unset 93 + pub struct Empty(()); 94 + impl sealed::Sealed for Empty {} 95 + impl State for Empty {} 96 + /// Marker types for field names 97 + #[allow(non_camel_case_types)] 98 + pub mod members {} 99 + } 100 + 101 + /// Builder for constructing an instance of this type. 102 + pub struct ListNotificationsBuilder<St: list_notifications_state::State, S: BosStr = DefaultStr> { 103 + _state: PhantomData<fn() -> St>, 104 + _fields: (Option<S>, Option<i64>), 105 + _type: PhantomData<fn() -> S>, 106 + } 107 + 108 + impl ListNotifications<DefaultStr> { 109 + /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed 110 + pub fn new() -> ListNotificationsBuilder<list_notifications_state::Empty, DefaultStr> { 111 + ListNotificationsBuilder::new() 112 + } 113 + } 114 + 115 + impl<S: BosStr> ListNotifications<S> { 116 + /// Create a new builder for this type 117 + pub fn builder() -> ListNotificationsBuilder<list_notifications_state::Empty, S> { 118 + ListNotificationsBuilder::builder() 119 + } 120 + } 121 + 122 + impl ListNotificationsBuilder<list_notifications_state::Empty, DefaultStr> { 123 + /// Create a new builder with all fields unset, using the default string type, if needed 124 + pub fn new() -> Self { 125 + ListNotificationsBuilder { 126 + _state: PhantomData, 127 + _fields: (None, None), 128 + _type: PhantomData, 129 + } 130 + } 131 + } 132 + 133 + impl<S: BosStr> ListNotificationsBuilder<list_notifications_state::Empty, S> { 134 + /// Create a new builder with all fields unset 135 + pub fn builder() -> Self { 136 + ListNotificationsBuilder { 137 + _state: PhantomData, 138 + _fields: (None, None), 139 + _type: PhantomData, 140 + } 141 + } 142 + } 143 + 144 + impl<St: list_notifications_state::State, S: BosStr> ListNotificationsBuilder<St, S> { 145 + /// Set the `cursor` field (optional) 146 + pub fn cursor(mut self, value: impl Into<Option<S>>) -> Self { 147 + self._fields.0 = value.into(); 148 + self 149 + } 150 + /// Set the `cursor` field to an Option value (optional) 151 + pub fn maybe_cursor(mut self, value: Option<S>) -> Self { 152 + self._fields.0 = value; 153 + self 154 + } 155 + } 156 + 157 + impl<St: list_notifications_state::State, S: BosStr> ListNotificationsBuilder<St, S> { 158 + /// Set the `limit` field (optional) 159 + pub fn limit(mut self, value: impl Into<Option<i64>>) -> Self { 160 + self._fields.1 = value.into(); 161 + self 162 + } 163 + /// Set the `limit` field to an Option value (optional) 164 + pub fn maybe_limit(mut self, value: Option<i64>) -> Self { 165 + self._fields.1 = value; 166 + self 167 + } 168 + } 169 + 170 + impl<St, S: BosStr> ListNotificationsBuilder<St, S> 171 + where 172 + St: list_notifications_state::State, 173 + { 174 + /// Build the final struct. 175 + pub fn build(self) -> ListNotifications<S> { 176 + ListNotifications { 177 + cursor: self._fields.0, 178 + limit: self._fields.1, 179 + } 180 + } 181 + }
+72
crates/rocksky-sdk/src/app_rocksky/notification/update_seen.rs
··· 1 + // @generated by jacquard-lexicon. DO NOT EDIT. 2 + // 3 + // Lexicon: app.rocksky.notification.updateSeen 4 + // 5 + // This file was automatically generated from Lexicon schemas. 6 + // Any manual changes will be overwritten on the next regeneration. 7 + 8 + #[allow(unused_imports)] 9 + use alloc::collections::BTreeMap; 10 + 11 + #[allow(unused_imports)] 12 + use core::marker::PhantomData; 13 + use jacquard_common::deps::smol_str::SmolStr; 14 + use jacquard_common::types::value::Data; 15 + use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr}; 16 + use jacquard_derive::IntoStatic; 17 + use serde::{Deserialize, Serialize}; 18 + 19 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] 20 + #[serde( 21 + rename_all = "camelCase", 22 + bound(deserialize = "S: Deserialize<'de> + BosStr") 23 + )] 24 + pub struct UpdateSeen<S: BosStr = DefaultStr> { 25 + ///The ids of the notifications to mark as viewed. Omit to mark all. 26 + #[serde(skip_serializing_if = "Option::is_none")] 27 + pub ids: Option<Vec<S>>, 28 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 29 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 30 + } 31 + 32 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] 33 + #[serde( 34 + rename_all = "camelCase", 35 + bound(deserialize = "S: Deserialize<'de> + BosStr") 36 + )] 37 + pub struct UpdateSeenOutput<S: BosStr = DefaultStr> { 38 + ///The number of unread notifications remaining. 39 + pub unread_count: i64, 40 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 41 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 42 + } 43 + 44 + /** Response marker for the `app.rocksky.notification.updateSeen` procedure. 45 + 46 + Implements `jacquard_common::xrpc::XrpcResp`; successful bodies decode as `Self::Output<S>`, which is `UpdateSeenOutput<S>` for this endpoint.*/ 47 + pub struct UpdateSeenResponse; 48 + impl jacquard_common::xrpc::XrpcResp for UpdateSeenResponse { 49 + const NSID: &'static str = "app.rocksky.notification.updateSeen"; 50 + const ENCODING: &'static str = "application/json"; 51 + type Output<S: BosStr> = UpdateSeenOutput<S>; 52 + type Err = jacquard_common::xrpc::GenericError; 53 + } 54 + 55 + impl<S: BosStr> jacquard_common::xrpc::XrpcRequest for UpdateSeen<S> { 56 + const NSID: &'static str = "app.rocksky.notification.updateSeen"; 57 + const METHOD: jacquard_common::xrpc::XrpcMethod = 58 + jacquard_common::xrpc::XrpcMethod::Procedure("application/json"); 59 + type Response = UpdateSeenResponse; 60 + } 61 + 62 + /** Endpoint marker for the `app.rocksky.notification.updateSeen` procedure. 63 + 64 + Path: `/xrpc/app.rocksky.notification.updateSeen`. The request payload type is `UpdateSeen<S>`; send that request with `jacquard::Client` or use this marker through lower-level `XrpcEndpoint` APIs.*/ 65 + pub struct UpdateSeenRequest; 66 + impl jacquard_common::xrpc::XrpcEndpoint for UpdateSeenRequest { 67 + const PATH: &'static str = "/xrpc/app.rocksky.notification.updateSeen"; 68 + const METHOD: jacquard_common::xrpc::XrpcMethod = 69 + jacquard_common::xrpc::XrpcMethod::Procedure("application/json"); 70 + type Request<S: BosStr> = UpdateSeen<S>; 71 + type Response = UpdateSeenResponse; 72 + }
+714 -64
crates/rocksky-sdk/src/app_rocksky/shout.rs
··· 28 28 use jacquard_common::deps::smol_str::SmolStr; 29 29 use jacquard_common::types::collection::{Collection, RecordError}; 30 30 use jacquard_common::types::ident::AtIdentifier; 31 - use jacquard_common::types::string::{AtUri, Cid, Datetime, UriValue}; 31 + use jacquard_common::types::string::{AtUri, Cid, Datetime, Did, UriValue}; 32 32 use jacquard_common::types::uri::{RecordUri, UriError}; 33 33 use jacquard_common::types::value::Data; 34 34 use jacquard_common::xrpc::XrpcResp; ··· 53 53 pub struct Shout<S: BosStr = DefaultStr> { 54 54 ///The date when the shout was created. 55 55 pub created_at: Datetime, 56 - ///The message of the shout. 57 - pub message: S, 56 + ///Mentions of other actors within the message, anchored to UTF-8 byte ranges. 57 + #[serde(skip_serializing_if = "Option::is_none")] 58 + pub facets: Option<Vec<shout::Mention<S>>>, 59 + ///An attached GIF, sticker, or clip (e.g. from KLIPY). 60 + #[serde(skip_serializing_if = "Option::is_none")] 61 + pub gif: Option<shout::Gif<S>>, 62 + ///The message of the shout. Optional when a gif/sticker/clip is attached. 63 + #[serde(skip_serializing_if = "Option::is_none")] 64 + pub message: Option<S>, 58 65 #[serde(skip_serializing_if = "Option::is_none")] 59 66 pub parent: Option<StrongRef<S>>, 60 67 pub subject: StrongRef<S>, ··· 98 105 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 99 106 } 100 107 108 + /// A GIF, sticker, or clip embedded in a shout. `url` may point at an image (GIF/WebP) or a video (MP4); the client decides how to render it from the file extension. 109 + 110 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] 111 + #[serde( 112 + rename_all = "camelCase", 113 + bound(deserialize = "S: Deserialize<'de> + BosStr") 114 + )] 115 + pub struct Gif<S: BosStr = DefaultStr> { 116 + ///Alternative text describing the media. 117 + #[serde(skip_serializing_if = "Option::is_none")] 118 + pub alt: Option<S>, 119 + ///The intrinsic height of the media in pixels. 120 + #[serde(skip_serializing_if = "Option::is_none")] 121 + pub height: Option<i64>, 122 + ///Smaller still/preview image URL. 123 + #[serde(skip_serializing_if = "Option::is_none")] 124 + pub preview_url: Option<UriValue<S>>, 125 + ///Direct URL of the animated GIF/MP4. 126 + pub url: UriValue<S>, 127 + ///The intrinsic width of the media in pixels. 128 + #[serde(skip_serializing_if = "Option::is_none")] 129 + pub width: Option<i64>, 130 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 131 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 132 + } 133 + 134 + /// A mention of another actor within the shout message, anchored to a UTF-8 byte range in the message. 135 + 136 + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] 137 + #[serde( 138 + rename_all = "camelCase", 139 + bound(deserialize = "S: Deserialize<'de> + BosStr") 140 + )] 141 + pub struct Mention<S: BosStr = DefaultStr> { 142 + ///Exclusive UTF-8 byte offset of the mention end. 143 + pub byte_end: i64, 144 + ///Inclusive UTF-8 byte offset of the mention start. 145 + pub byte_start: i64, 146 + ///The DID of the mentioned actor. 147 + pub did: Did<S>, 148 + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] 149 + pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>, 150 + } 151 + 101 152 #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] 102 153 #[serde( 103 154 rename_all = "camelCase", ··· 110 161 ///The date and time when the shout was created. 111 162 #[serde(skip_serializing_if = "Option::is_none")] 112 163 pub created_at: Option<Datetime>, 164 + ///Mentions of other actors within the message, anchored to UTF-8 byte ranges. 165 + #[serde(skip_serializing_if = "Option::is_none")] 166 + pub facets: Option<Vec<shout::Mention<S>>>, 167 + ///An attached GIF, sticker, or clip. 168 + #[serde(skip_serializing_if = "Option::is_none")] 169 + pub gif: Option<shout::Gif<S>>, 113 170 ///The unique identifier of the shout. 114 171 #[serde(skip_serializing_if = "Option::is_none")] 115 172 pub id: Option<S>, ··· 167 224 lexicon_doc_app_rocksky_shout() 168 225 } 169 226 fn validate(&self) -> Result<(), ConstraintError> { 170 - { 171 - let value = &self.message; 227 + if let Some(ref value) = self.message { 172 228 #[allow(unused_comparisons)] 173 229 if <str>::len(value.as_ref()) > 1000usize { 174 230 return Err(ConstraintError::MaxLength { ··· 178 234 }); 179 235 } 180 236 } 181 - { 182 - let value = &self.message; 237 + Ok(()) 238 + } 239 + } 240 + 241 + impl<S: BosStr> LexiconSchema for Author<S> { 242 + fn nsid() -> &'static str { 243 + "app.rocksky.shout.defs" 244 + } 245 + fn def_name() -> &'static str { 246 + "author" 247 + } 248 + fn lexicon_doc() -> LexiconDoc<'static> { 249 + lexicon_doc_app_rocksky_shout_defs() 250 + } 251 + fn validate(&self) -> Result<(), ConstraintError> { 252 + Ok(()) 253 + } 254 + } 255 + 256 + impl<S: BosStr> LexiconSchema for Gif<S> { 257 + fn nsid() -> &'static str { 258 + "app.rocksky.shout.defs" 259 + } 260 + fn def_name() -> &'static str { 261 + "gif" 262 + } 263 + fn lexicon_doc() -> LexiconDoc<'static> { 264 + lexicon_doc_app_rocksky_shout_defs() 265 + } 266 + fn validate(&self) -> Result<(), ConstraintError> { 267 + if let Some(ref value) = self.alt { 183 268 #[allow(unused_comparisons)] 184 - if <str>::len(value.as_ref()) < 1usize { 185 - return Err(ConstraintError::MinLength { 186 - path: ValidationPath::from_field("message"), 187 - min: 1usize, 269 + if <str>::len(value.as_ref()) > 512usize { 270 + return Err(ConstraintError::MaxLength { 271 + path: ValidationPath::from_field("alt"), 272 + max: 512usize, 188 273 actual: <str>::len(value.as_ref()), 189 274 }); 190 275 } 191 276 } 277 + if let Some(ref value) = self.height { 278 + if *value < 0i64 { 279 + return Err(ConstraintError::Minimum { 280 + path: ValidationPath::from_field("height"), 281 + min: 0i64, 282 + actual: *value, 283 + }); 284 + } 285 + } 286 + if let Some(ref value) = self.width { 287 + if *value < 0i64 { 288 + return Err(ConstraintError::Minimum { 289 + path: ValidationPath::from_field("width"), 290 + min: 0i64, 291 + actual: *value, 292 + }); 293 + } 294 + } 192 295 Ok(()) 193 296 } 194 297 } 195 298 196 - impl<S: BosStr> LexiconSchema for Author<S> { 299 + impl<S: BosStr> LexiconSchema for Mention<S> { 197 300 fn nsid() -> &'static str { 198 301 "app.rocksky.shout.defs" 199 302 } 200 303 fn def_name() -> &'static str { 201 - "author" 304 + "mention" 202 305 } 203 306 fn lexicon_doc() -> LexiconDoc<'static> { 204 307 lexicon_doc_app_rocksky_shout_defs() 205 308 } 206 309 fn validate(&self) -> Result<(), ConstraintError> { 310 + { 311 + let value = &self.byte_end; 312 + if *value < 0i64 { 313 + return Err(ConstraintError::Minimum { 314 + path: ValidationPath::from_field("byte_end"), 315 + min: 0i64, 316 + actual: *value, 317 + }); 318 + } 319 + } 320 + { 321 + let value = &self.byte_start; 322 + if *value < 0i64 { 323 + return Err(ConstraintError::Minimum { 324 + path: ValidationPath::from_field("byte_start"), 325 + min: 0i64, 326 + actual: *value, 327 + }); 328 + } 329 + } 207 330 Ok(()) 208 331 } 209 332 } ··· 234 357 /// State trait tracking which required fields have been set 235 358 pub trait State: sealed::Sealed { 236 359 type CreatedAt; 237 - type Message; 238 360 type Subject; 239 361 } 240 362 /// Empty state - all required fields are unset ··· 242 364 impl sealed::Sealed for Empty {} 243 365 impl State for Empty { 244 366 type CreatedAt = Unset; 245 - type Message = Unset; 246 367 type Subject = Unset; 247 368 } 248 369 ///State transition - sets the `created_at` field to Set ··· 250 371 impl<St: State> sealed::Sealed for SetCreatedAt<St> {} 251 372 impl<St: State> State for SetCreatedAt<St> { 252 373 type CreatedAt = Set<members::created_at>; 253 - type Message = St::Message; 254 - type Subject = St::Subject; 255 - } 256 - ///State transition - sets the `message` field to Set 257 - pub struct SetMessage<St: State = Empty>(PhantomData<fn() -> St>); 258 - impl<St: State> sealed::Sealed for SetMessage<St> {} 259 - impl<St: State> State for SetMessage<St> { 260 - type CreatedAt = St::CreatedAt; 261 - type Message = Set<members::message>; 262 374 type Subject = St::Subject; 263 375 } 264 376 ///State transition - sets the `subject` field to Set ··· 266 378 impl<St: State> sealed::Sealed for SetSubject<St> {} 267 379 impl<St: State> State for SetSubject<St> { 268 380 type CreatedAt = St::CreatedAt; 269 - type Message = St::Message; 270 381 type Subject = Set<members::subject>; 271 382 } 272 383 /// Marker types for field names ··· 274 385 pub mod members { 275 386 ///Marker type for the `created_at` field 276 387 pub struct created_at(()); 277 - ///Marker type for the `message` field 278 - pub struct message(()); 279 388 ///Marker type for the `subject` field 280 389 pub struct subject(()); 281 390 } ··· 286 395 _state: PhantomData<fn() -> St>, 287 396 _fields: ( 288 397 Option<Datetime>, 398 + Option<Vec<shout::Mention<S>>>, 399 + Option<shout::Gif<S>>, 289 400 Option<S>, 290 401 Option<StrongRef<S>>, 291 402 Option<StrongRef<S>>, ··· 312 423 pub fn new() -> Self { 313 424 ShoutBuilder { 314 425 _state: PhantomData, 315 - _fields: (None, None, None, None), 426 + _fields: (None, None, None, None, None, None), 316 427 _type: PhantomData, 317 428 } 318 429 } ··· 323 434 pub fn builder() -> Self { 324 435 ShoutBuilder { 325 436 _state: PhantomData, 326 - _fields: (None, None, None, None), 437 + _fields: (None, None, None, None, None, None), 327 438 _type: PhantomData, 328 439 } 329 440 } ··· 348 459 } 349 460 } 350 461 351 - impl<St, S: BosStr> ShoutBuilder<St, S> 352 - where 353 - St: shout_state::State, 354 - St::Message: shout_state::IsUnset, 355 - { 356 - /// Set the `message` field (required) 357 - pub fn message(mut self, value: impl Into<S>) -> ShoutBuilder<shout_state::SetMessage<St>, S> { 358 - self._fields.1 = Option::Some(value.into()); 359 - ShoutBuilder { 360 - _state: PhantomData, 361 - _fields: self._fields, 362 - _type: PhantomData, 363 - } 462 + impl<St: shout_state::State, S: BosStr> ShoutBuilder<St, S> { 463 + /// Set the `facets` field (optional) 464 + pub fn facets(mut self, value: impl Into<Option<Vec<shout::Mention<S>>>>) -> Self { 465 + self._fields.1 = value.into(); 466 + self 467 + } 468 + /// Set the `facets` field to an Option value (optional) 469 + pub fn maybe_facets(mut self, value: Option<Vec<shout::Mention<S>>>) -> Self { 470 + self._fields.1 = value; 471 + self 472 + } 473 + } 474 + 475 + impl<St: shout_state::State, S: BosStr> ShoutBuilder<St, S> { 476 + /// Set the `gif` field (optional) 477 + pub fn gif(mut self, value: impl Into<Option<shout::Gif<S>>>) -> Self { 478 + self._fields.2 = value.into(); 479 + self 480 + } 481 + /// Set the `gif` field to an Option value (optional) 482 + pub fn maybe_gif(mut self, value: Option<shout::Gif<S>>) -> Self { 483 + self._fields.2 = value; 484 + self 485 + } 486 + } 487 + 488 + impl<St: shout_state::State, S: BosStr> ShoutBuilder<St, S> { 489 + /// Set the `message` field (optional) 490 + pub fn message(mut self, value: impl Into<Option<S>>) -> Self { 491 + self._fields.3 = value.into(); 492 + self 493 + } 494 + /// Set the `message` field to an Option value (optional) 495 + pub fn maybe_message(mut self, value: Option<S>) -> Self { 496 + self._fields.3 = value; 497 + self 364 498 } 365 499 } 366 500 367 501 impl<St: shout_state::State, S: BosStr> ShoutBuilder<St, S> { 368 502 /// Set the `parent` field (optional) 369 503 pub fn parent(mut self, value: impl Into<Option<StrongRef<S>>>) -> Self { 370 - self._fields.2 = value.into(); 504 + self._fields.4 = value.into(); 371 505 self 372 506 } 373 507 /// Set the `parent` field to an Option value (optional) 374 508 pub fn maybe_parent(mut self, value: Option<StrongRef<S>>) -> Self { 375 - self._fields.2 = value; 509 + self._fields.4 = value; 376 510 self 377 511 } 378 512 } ··· 387 521 mut self, 388 522 value: impl Into<StrongRef<S>>, 389 523 ) -> ShoutBuilder<shout_state::SetSubject<St>, S> { 390 - self._fields.3 = Option::Some(value.into()); 524 + self._fields.5 = Option::Some(value.into()); 391 525 ShoutBuilder { 392 526 _state: PhantomData, 393 527 _fields: self._fields, ··· 400 534 where 401 535 St: shout_state::State, 402 536 St::CreatedAt: shout_state::IsSet, 403 - St::Message: shout_state::IsSet, 404 537 St::Subject: shout_state::IsSet, 405 538 { 406 539 /// Build the final struct. 407 540 pub fn build(self) -> Shout<S> { 408 541 Shout { 409 542 created_at: self._fields.0.unwrap(), 410 - message: self._fields.1.unwrap(), 411 - parent: self._fields.2, 412 - subject: self._fields.3.unwrap(), 543 + facets: self._fields.1, 544 + gif: self._fields.2, 545 + message: self._fields.3, 546 + parent: self._fields.4, 547 + subject: self._fields.5.unwrap(), 413 548 extra_data: Default::default(), 414 549 } 415 550 } ··· 417 552 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Shout<S> { 418 553 Shout { 419 554 created_at: self._fields.0.unwrap(), 420 - message: self._fields.1.unwrap(), 421 - parent: self._fields.2, 422 - subject: self._fields.3.unwrap(), 555 + facets: self._fields.1, 556 + gif: self._fields.2, 557 + message: self._fields.3, 558 + parent: self._fields.4, 559 + subject: self._fields.5.unwrap(), 423 560 extra_data: Some(extra_data), 424 561 } 425 562 } ··· 441 578 description: Some(CowStr::new_static("A declaration of a shout.")), 442 579 key: Some(CowStr::new_static("tid")), 443 580 record: LexRecordRecord::Object(LexObject { 444 - required: Some(vec![ 445 - SmolStr::new_static("message"), 446 - SmolStr::new_static("createdAt"), 447 - SmolStr::new_static("subject"), 448 - ]), 581 + required: Some( 582 + vec![ 583 + SmolStr::new_static("createdAt"), 584 + SmolStr::new_static("subject") 585 + ], 586 + ), 449 587 properties: { 450 588 #[allow(unused_mut)] 451 589 let mut map = BTreeMap::new(); 452 590 map.insert( 453 591 SmolStr::new_static("createdAt"), 454 592 LexObjectProperty::String(LexString { 455 - description: Some(CowStr::new_static( 456 - "The date when the shout was created.", 457 - )), 593 + description: Some( 594 + CowStr::new_static("The date when the shout was created."), 595 + ), 458 596 format: Some(LexStringFormat::Datetime), 459 597 ..Default::default() 460 598 }), 461 599 ); 462 600 map.insert( 601 + SmolStr::new_static("facets"), 602 + LexObjectProperty::Array(LexArray { 603 + description: Some( 604 + CowStr::new_static( 605 + "Mentions of other actors within the message, anchored to UTF-8 byte ranges.", 606 + ), 607 + ), 608 + items: LexArrayItem::Ref(LexRef { 609 + r#ref: CowStr::new_static("app.rocksky.shout.defs#mention"), 610 + ..Default::default() 611 + }), 612 + ..Default::default() 613 + }), 614 + ); 615 + map.insert( 616 + SmolStr::new_static("gif"), 617 + LexObjectProperty::Ref(LexRef { 618 + r#ref: CowStr::new_static("app.rocksky.shout.defs#gif"), 619 + ..Default::default() 620 + }), 621 + ); 622 + map.insert( 463 623 SmolStr::new_static("message"), 464 624 LexObjectProperty::String(LexString { 465 - description: Some(CowStr::new_static( 466 - "The message of the shout.", 467 - )), 468 - min_length: Some(1usize), 625 + description: Some( 626 + CowStr::new_static( 627 + "The message of the shout. Optional when a gif/sticker/clip is attached.", 628 + ), 629 + ), 469 630 max_length: Some(1000usize), 470 631 ..Default::default() 471 632 }), ··· 565 726 }), 566 727 ); 567 728 map.insert( 729 + SmolStr::new_static("gif"), 730 + LexUserType::Object(LexObject { 731 + description: Some( 732 + CowStr::new_static( 733 + "A GIF, sticker, or clip embedded in a shout. `url` may point at an image (GIF/WebP) or a video (MP4); the client decides how to render it from the file extension.", 734 + ), 735 + ), 736 + required: Some(vec![SmolStr::new_static("url")]), 737 + properties: { 738 + #[allow(unused_mut)] 739 + let mut map = BTreeMap::new(); 740 + map.insert( 741 + SmolStr::new_static("alt"), 742 + LexObjectProperty::String(LexString { 743 + description: Some( 744 + CowStr::new_static("Alternative text describing the media."), 745 + ), 746 + max_length: Some(512usize), 747 + ..Default::default() 748 + }), 749 + ); 750 + map.insert( 751 + SmolStr::new_static("height"), 752 + LexObjectProperty::Integer(LexInteger { 753 + minimum: Some(0i64), 754 + ..Default::default() 755 + }), 756 + ); 757 + map.insert( 758 + SmolStr::new_static("previewUrl"), 759 + LexObjectProperty::String(LexString { 760 + description: Some( 761 + CowStr::new_static("Smaller still/preview image URL."), 762 + ), 763 + format: Some(LexStringFormat::Uri), 764 + ..Default::default() 765 + }), 766 + ); 767 + map.insert( 768 + SmolStr::new_static("url"), 769 + LexObjectProperty::String(LexString { 770 + description: Some( 771 + CowStr::new_static("Direct URL of the animated GIF/MP4."), 772 + ), 773 + format: Some(LexStringFormat::Uri), 774 + ..Default::default() 775 + }), 776 + ); 777 + map.insert( 778 + SmolStr::new_static("width"), 779 + LexObjectProperty::Integer(LexInteger { 780 + minimum: Some(0i64), 781 + ..Default::default() 782 + }), 783 + ); 784 + map 785 + }, 786 + ..Default::default() 787 + }), 788 + ); 789 + map.insert( 790 + SmolStr::new_static("mention"), 791 + LexUserType::Object(LexObject { 792 + description: Some( 793 + CowStr::new_static( 794 + "A mention of another actor within the shout message, anchored to a UTF-8 byte range in the message.", 795 + ), 796 + ), 797 + required: Some( 798 + vec![ 799 + SmolStr::new_static("did"), SmolStr::new_static("byteStart"), 800 + SmolStr::new_static("byteEnd") 801 + ], 802 + ), 803 + properties: { 804 + #[allow(unused_mut)] 805 + let mut map = BTreeMap::new(); 806 + map.insert( 807 + SmolStr::new_static("byteEnd"), 808 + LexObjectProperty::Integer(LexInteger { 809 + minimum: Some(0i64), 810 + ..Default::default() 811 + }), 812 + ); 813 + map.insert( 814 + SmolStr::new_static("byteStart"), 815 + LexObjectProperty::Integer(LexInteger { 816 + minimum: Some(0i64), 817 + ..Default::default() 818 + }), 819 + ); 820 + map.insert( 821 + SmolStr::new_static("did"), 822 + LexObjectProperty::String(LexString { 823 + description: Some( 824 + CowStr::new_static("The DID of the mentioned actor."), 825 + ), 826 + format: Some(LexStringFormat::Did), 827 + ..Default::default() 828 + }), 829 + ); 830 + map 831 + }, 832 + ..Default::default() 833 + }), 834 + ); 835 + map.insert( 568 836 SmolStr::new_static("shoutView"), 569 837 LexUserType::Object(LexObject { 570 838 properties: { ··· 590 858 }), 591 859 ); 592 860 map.insert( 861 + SmolStr::new_static("facets"), 862 + LexObjectProperty::Array(LexArray { 863 + description: Some( 864 + CowStr::new_static( 865 + "Mentions of other actors within the message, anchored to UTF-8 byte ranges.", 866 + ), 867 + ), 868 + items: LexArrayItem::Ref(LexRef { 869 + r#ref: CowStr::new_static("app.rocksky.shout.defs#mention"), 870 + ..Default::default() 871 + }), 872 + ..Default::default() 873 + }), 874 + ); 875 + map.insert( 876 + SmolStr::new_static("gif"), 877 + LexObjectProperty::Ref(LexRef { 878 + r#ref: CowStr::new_static("app.rocksky.shout.defs#gif"), 879 + ..Default::default() 880 + }), 881 + ); 882 + map.insert( 593 883 SmolStr::new_static("id"), 594 884 LexObjectProperty::String(LexString { 595 885 description: Some( ··· 628 918 ..Default::default() 629 919 } 630 920 } 921 + 922 + pub mod gif_state { 923 + 924 + pub use crate::builder_types::{IsSet, IsUnset, Set, Unset}; 925 + #[allow(unused)] 926 + use ::core::marker::PhantomData; 927 + mod sealed { 928 + pub trait Sealed {} 929 + } 930 + /// State trait tracking which required fields have been set 931 + pub trait State: sealed::Sealed { 932 + type Url; 933 + } 934 + /// Empty state - all required fields are unset 935 + pub struct Empty(()); 936 + impl sealed::Sealed for Empty {} 937 + impl State for Empty { 938 + type Url = Unset; 939 + } 940 + ///State transition - sets the `url` field to Set 941 + pub struct SetUrl<St: State = Empty>(PhantomData<fn() -> St>); 942 + impl<St: State> sealed::Sealed for SetUrl<St> {} 943 + impl<St: State> State for SetUrl<St> { 944 + type Url = Set<members::url>; 945 + } 946 + /// Marker types for field names 947 + #[allow(non_camel_case_types)] 948 + pub mod members { 949 + ///Marker type for the `url` field 950 + pub struct url(()); 951 + } 952 + } 953 + 954 + /// Builder for constructing an instance of this type. 955 + pub struct GifBuilder<St: gif_state::State, S: BosStr = DefaultStr> { 956 + _state: PhantomData<fn() -> St>, 957 + _fields: ( 958 + Option<S>, 959 + Option<i64>, 960 + Option<UriValue<S>>, 961 + Option<UriValue<S>>, 962 + Option<i64>, 963 + ), 964 + _type: PhantomData<fn() -> S>, 965 + } 966 + 967 + impl Gif<DefaultStr> { 968 + /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed 969 + pub fn new() -> GifBuilder<gif_state::Empty, DefaultStr> { 970 + GifBuilder::new() 971 + } 972 + } 973 + 974 + impl<S: BosStr> Gif<S> { 975 + /// Create a new builder for this type 976 + pub fn builder() -> GifBuilder<gif_state::Empty, S> { 977 + GifBuilder::builder() 978 + } 979 + } 980 + 981 + impl GifBuilder<gif_state::Empty, DefaultStr> { 982 + /// Create a new builder with all fields unset, using the default string type, if needed 983 + pub fn new() -> Self { 984 + GifBuilder { 985 + _state: PhantomData, 986 + _fields: (None, None, None, None, None), 987 + _type: PhantomData, 988 + } 989 + } 990 + } 991 + 992 + impl<S: BosStr> GifBuilder<gif_state::Empty, S> { 993 + /// Create a new builder with all fields unset 994 + pub fn builder() -> Self { 995 + GifBuilder { 996 + _state: PhantomData, 997 + _fields: (None, None, None, None, None), 998 + _type: PhantomData, 999 + } 1000 + } 1001 + } 1002 + 1003 + impl<St: gif_state::State, S: BosStr> GifBuilder<St, S> { 1004 + /// Set the `alt` field (optional) 1005 + pub fn alt(mut self, value: impl Into<Option<S>>) -> Self { 1006 + self._fields.0 = value.into(); 1007 + self 1008 + } 1009 + /// Set the `alt` field to an Option value (optional) 1010 + pub fn maybe_alt(mut self, value: Option<S>) -> Self { 1011 + self._fields.0 = value; 1012 + self 1013 + } 1014 + } 1015 + 1016 + impl<St: gif_state::State, S: BosStr> GifBuilder<St, S> { 1017 + /// Set the `height` field (optional) 1018 + pub fn height(mut self, value: impl Into<Option<i64>>) -> Self { 1019 + self._fields.1 = value.into(); 1020 + self 1021 + } 1022 + /// Set the `height` field to an Option value (optional) 1023 + pub fn maybe_height(mut self, value: Option<i64>) -> Self { 1024 + self._fields.1 = value; 1025 + self 1026 + } 1027 + } 1028 + 1029 + impl<St: gif_state::State, S: BosStr> GifBuilder<St, S> { 1030 + /// Set the `previewUrl` field (optional) 1031 + pub fn preview_url(mut self, value: impl Into<Option<UriValue<S>>>) -> Self { 1032 + self._fields.2 = value.into(); 1033 + self 1034 + } 1035 + /// Set the `previewUrl` field to an Option value (optional) 1036 + pub fn maybe_preview_url(mut self, value: Option<UriValue<S>>) -> Self { 1037 + self._fields.2 = value; 1038 + self 1039 + } 1040 + } 1041 + 1042 + impl<St, S: BosStr> GifBuilder<St, S> 1043 + where 1044 + St: gif_state::State, 1045 + St::Url: gif_state::IsUnset, 1046 + { 1047 + /// Set the `url` field (required) 1048 + pub fn url(mut self, value: impl Into<UriValue<S>>) -> GifBuilder<gif_state::SetUrl<St>, S> { 1049 + self._fields.3 = Option::Some(value.into()); 1050 + GifBuilder { 1051 + _state: PhantomData, 1052 + _fields: self._fields, 1053 + _type: PhantomData, 1054 + } 1055 + } 1056 + } 1057 + 1058 + impl<St: gif_state::State, S: BosStr> GifBuilder<St, S> { 1059 + /// Set the `width` field (optional) 1060 + pub fn width(mut self, value: impl Into<Option<i64>>) -> Self { 1061 + self._fields.4 = value.into(); 1062 + self 1063 + } 1064 + /// Set the `width` field to an Option value (optional) 1065 + pub fn maybe_width(mut self, value: Option<i64>) -> Self { 1066 + self._fields.4 = value; 1067 + self 1068 + } 1069 + } 1070 + 1071 + impl<St, S: BosStr> GifBuilder<St, S> 1072 + where 1073 + St: gif_state::State, 1074 + St::Url: gif_state::IsSet, 1075 + { 1076 + /// Build the final struct. 1077 + pub fn build(self) -> Gif<S> { 1078 + Gif { 1079 + alt: self._fields.0, 1080 + height: self._fields.1, 1081 + preview_url: self._fields.2, 1082 + url: self._fields.3.unwrap(), 1083 + width: self._fields.4, 1084 + extra_data: Default::default(), 1085 + } 1086 + } 1087 + /// Build the final struct with custom extra_data. 1088 + pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Gif<S> { 1089 + Gif { 1090 + alt: self._fields.0, 1091 + height: self._fields.1, 1092 + preview_url: self._fields.2, 1093 + url: self._fields.3.unwrap(), 1094 + width: self._fields.4, 1095 + extra_data: Some(extra_data), 1096 + } 1097 + } 1098 + } 1099 + 1100 + pub mod mention_state { 1101 + 1102 + pub use crate::builder_types::{IsSet, IsUnset, Set, Unset}; 1103 + #[allow(unused)] 1104 + use ::core::marker::PhantomData; 1105 + mod sealed { 1106 + pub trait Sealed {} 1107 + } 1108 + /// State trait tracking which required fields have been set 1109 + pub trait State: sealed::Sealed { 1110 + type ByteEnd; 1111 + type ByteStart; 1112 + type Did; 1113 + } 1114 + /// Empty state - all required fields are unset 1115 + pub struct Empty(()); 1116 + impl sealed::Sealed for Empty {} 1117 + impl State for Empty { 1118 + type ByteEnd = Unset; 1119 + type ByteStart = Unset; 1120 + type Did = Unset; 1121 + } 1122 + ///State transition - sets the `byte_end` field to Set 1123 + pub struct SetByteEnd<St: State = Empty>(PhantomData<fn() -> St>); 1124 + impl<St: State> sealed::Sealed for SetByteEnd<St> {} 1125 + impl<St: State> State for SetByteEnd<St> { 1126 + type ByteEnd = Set<members::byte_end>; 1127 + type ByteStart = St::ByteStart; 1128 + type Did = St::Did; 1129 + } 1130 + ///State transition - sets the `byte_start` field to Set 1131 + pub struct SetByteStart<St: State = Empty>(PhantomData<fn() -> St>); 1132 + impl<St: State> sealed::Sealed for SetByteStart<St> {} 1133 + impl<St: State> State for SetByteStart<St> { 1134 + type ByteEnd = St::ByteEnd; 1135 + type ByteStart = Set<members::byte_start>; 1136 + type Did = St::Did; 1137 + } 1138 + ///State transition - sets the `did` field to Set 1139 + pub struct SetDid<St: State = Empty>(PhantomData<fn() -> St>); 1140 + impl<St: State> sealed::Sealed for SetDid<St> {} 1141 + impl<St: State> State for SetDid<St> { 1142 + type ByteEnd = St::ByteEnd; 1143 + type ByteStart = St::ByteStart; 1144 + type Did = Set<members::did>; 1145 + } 1146 + /// Marker types for field names 1147 + #[allow(non_camel_case_types)] 1148 + pub mod members { 1149 + ///Marker type for the `byte_end` field 1150 + pub struct byte_end(()); 1151 + ///Marker type for the `byte_start` field 1152 + pub struct byte_start(()); 1153 + ///Marker type for the `did` field 1154 + pub struct did(()); 1155 + } 1156 + } 1157 + 1158 + /// Builder for constructing an instance of this type. 1159 + pub struct MentionBuilder<St: mention_state::State, S: BosStr = DefaultStr> { 1160 + _state: PhantomData<fn() -> St>, 1161 + _fields: (Option<i64>, Option<i64>, Option<Did<S>>), 1162 + _type: PhantomData<fn() -> S>, 1163 + } 1164 + 1165 + impl Mention<DefaultStr> { 1166 + /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed 1167 + pub fn new() -> MentionBuilder<mention_state::Empty, DefaultStr> { 1168 + MentionBuilder::new() 1169 + } 1170 + } 1171 + 1172 + impl<S: BosStr> Mention<S> { 1173 + /// Create a new builder for this type 1174 + pub fn builder() -> MentionBuilder<mention_state::Empty, S> { 1175 + MentionBuilder::builder() 1176 + } 1177 + } 1178 + 1179 + impl MentionBuilder<mention_state::Empty, DefaultStr> { 1180 + /// Create a new builder with all fields unset, using the default string type, if needed 1181 + pub fn new() -> Self { 1182 + MentionBuilder { 1183 + _state: PhantomData, 1184 + _fields: (None, None, None), 1185 + _type: PhantomData, 1186 + } 1187 + } 1188 + } 1189 + 1190 + impl<S: BosStr> MentionBuilder<mention_state::Empty, S> { 1191 + /// Create a new builder with all fields unset 1192 + pub fn builder() -> Self { 1193 + MentionBuilder { 1194 + _state: PhantomData, 1195 + _fields: (None, None, None), 1196 + _type: PhantomData, 1197 + } 1198 + } 1199 + } 1200 + 1201 + impl<St, S: BosStr> MentionBuilder<St, S> 1202 + where 1203 + St: mention_state::State, 1204 + St::ByteEnd: mention_state::IsUnset, 1205 + { 1206 + /// Set the `byteEnd` field (required) 1207 + pub fn byte_end( 1208 + mut self, 1209 + value: impl Into<i64>, 1210 + ) -> MentionBuilder<mention_state::SetByteEnd<St>, S> { 1211 + self._fields.0 = Option::Some(value.into()); 1212 + MentionBuilder { 1213 + _state: PhantomData, 1214 + _fields: self._fields, 1215 + _type: PhantomData, 1216 + } 1217 + } 1218 + } 1219 + 1220 + impl<St, S: BosStr> MentionBuilder<St, S> 1221 + where 1222 + St: mention_state::State, 1223 + St::ByteStart: mention_state::IsUnset, 1224 + { 1225 + /// Set the `byteStart` field (required) 1226 + pub fn byte_start( 1227 + mut self, 1228 + value: impl Into<i64>, 1229 + ) -> MentionBuilder<mention_state::SetByteStart<St>, S> { 1230 + self._fields.1 = Option::Some(value.into()); 1231 + MentionBuilder { 1232 + _state: PhantomData, 1233 + _fields: self._fields, 1234 + _type: PhantomData, 1235 + } 1236 + } 1237 + } 1238 + 1239 + impl<St, S: BosStr> MentionBuilder<St, S> 1240 + where 1241 + St: mention_state::State, 1242 + St::Did: mention_state::IsUnset, 1243 + { 1244 + /// Set the `did` field (required) 1245 + pub fn did(mut self, value: impl Into<Did<S>>) -> MentionBuilder<mention_state::SetDid<St>, S> { 1246 + self._fields.2 = Option::Some(value.into()); 1247 + MentionBuilder { 1248 + _state: PhantomData, 1249 + _fields: self._fields, 1250 + _type: PhantomData, 1251 + } 1252 + } 1253 + } 1254 + 1255 + impl<St, S: BosStr> MentionBuilder<St, S> 1256 + where 1257 + St: mention_state::State, 1258 + St::ByteEnd: mention_state::IsSet, 1259 + St::ByteStart: mention_state::IsSet, 1260 + St::Did: mention_state::IsSet, 1261 + { 1262 + /// Build the final struct. 1263 + pub fn build(self) -> Mention<S> { 1264 + Mention { 1265 + byte_end: self._fields.0.unwrap(), 1266 + byte_start: self._fields.1.unwrap(), 1267 + did: self._fields.2.unwrap(), 1268 + extra_data: Default::default(), 1269 + } 1270 + } 1271 + /// Build the final struct with custom extra_data. 1272 + pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Mention<S> { 1273 + Mention { 1274 + byte_end: self._fields.0.unwrap(), 1275 + byte_start: self._fields.1.unwrap(), 1276 + did: self._fields.2.unwrap(), 1277 + extra_data: Some(extra_data), 1278 + } 1279 + } 1280 + }
+138
crates/rocksky-sdk/src/appview.rs
··· 140 140 .map_err(|e| SdkError::Other(format!("decode {nsid}: {e}: {body}"))) 141 141 } 142 142 143 + /// POST an `application/json` body to an XRPC procedure and decode the JSON 144 + /// response. Attaches the bearer token when one is set — most procedures are 145 + /// auth-gated. 146 + async fn mutate<T: DeserializeOwned>(&self, nsid: &str, body: serde_json::Value) -> Result<T> { 147 + let url = format!("{}/xrpc/{}", self.base, nsid); 148 + let mut req = self.http.post(&url).json(&body); 149 + if let Some(token) = &self.token { 150 + req = req.bearer_auth(token); 151 + } 152 + let res = req.send().await?; 153 + let status = res.status(); 154 + let body = res.text().await.unwrap_or_default(); 155 + if !status.is_success() { 156 + return Err(SdkError::AppView { 157 + nsid: nsid.to_string(), 158 + status: status.as_u16(), 159 + body, 160 + }); 161 + } 162 + serde_json::from_str(&body) 163 + .map_err(|e| SdkError::Other(format!("decode {nsid}: {e}: {body}"))) 164 + } 165 + 143 166 /// Escape hatch — call **any** AppView read query by its nsid and get the raw 144 167 /// JSON response back. Every named method on this client is sugar over this, 145 168 /// so `get` reaches queries that have no dedicated wrapper (and any added ··· 974 997 ) 975 998 .await 976 999 } 1000 + 1001 + /// The number of unread notifications for the authenticated viewer 1002 + /// (`app.rocksky.notification.getUnreadCount`, auth-gated). 1003 + pub async fn unread_count(&self) -> Result<UnreadCount> { 1004 + self.query("app.rocksky.notification.getUnreadCount", &[]) 1005 + .await 1006 + } 1007 + 1008 + /// The authenticated viewer's notifications, most recent first 1009 + /// (`app.rocksky.notification.listNotifications`, auth-gated). `limit` 1010 + /// defaults to 30 server-side; `cursor` paginates. 1011 + pub async fn notifications( 1012 + &self, 1013 + limit: Option<u32>, 1014 + cursor: Option<&str>, 1015 + ) -> Result<NotificationList> { 1016 + self.query( 1017 + "app.rocksky.notification.listNotifications", 1018 + &[ 1019 + ("limit", limit.map(|l| l.to_string()).unwrap_or_default()), 1020 + ("cursor", cursor.unwrap_or_default().to_string()), 1021 + ], 1022 + ) 1023 + .await 1024 + } 1025 + 1026 + /// Mark notifications as viewed (`app.rocksky.notification.updateSeen`, 1027 + /// procedure, auth-gated). Pass the notification ids to mark, or an empty 1028 + /// slice to mark **all** of the viewer's notifications. Returns the number 1029 + /// remaining unread. 1030 + pub async fn update_seen(&self, ids: &[String]) -> Result<UpdateSeenResult> { 1031 + // An empty `ids` array would mark nothing; omit the field to mark all. 1032 + let body = if ids.is_empty() { 1033 + serde_json::json!({}) 1034 + } else { 1035 + serde_json::json!({ "ids": ids }) 1036 + }; 1037 + self.mutate("app.rocksky.notification.updateSeen", body) 1038 + .await 1039 + } 977 1040 } 978 1041 979 1042 // ---- wire types ---------------------------------------------------------- ··· 1194 1257 pub albums: u64, 1195 1258 #[serde(default)] 1196 1259 pub tracks: u64, 1260 + } 1261 + 1262 + /// `app.rocksky.notification.defs#notificationActor` — the user who triggered a 1263 + /// notification. 1264 + #[derive(Clone, Debug, Default, Serialize, Deserialize)] 1265 + #[serde(rename_all = "camelCase")] 1266 + pub struct NotificationActor { 1267 + #[serde(default)] 1268 + pub id: Option<String>, 1269 + #[serde(default)] 1270 + pub did: Option<String>, 1271 + #[serde(default)] 1272 + pub handle: Option<String>, 1273 + #[serde(default)] 1274 + pub display_name: Option<String>, 1275 + #[serde(default)] 1276 + pub avatar: Option<String>, 1277 + } 1278 + 1279 + /// `app.rocksky.notification.defs#notificationView`. 1280 + #[derive(Clone, Debug, Default, Serialize, Deserialize)] 1281 + #[serde(rename_all = "camelCase")] 1282 + pub struct NotificationView { 1283 + #[serde(default)] 1284 + pub id: String, 1285 + /// One of `like_scrobble`, `follow`, `comment_scrobble`, `comment_profile`, 1286 + /// `reply`, `react_comment`. 1287 + #[serde(default)] 1288 + pub r#type: String, 1289 + /// Whether the notification has been viewed. 1290 + #[serde(default)] 1291 + pub read: bool, 1292 + #[serde(default)] 1293 + pub created_at: String, 1294 + /// The at-uri of the subject the notification relates to. 1295 + #[serde(default)] 1296 + pub subject_uri: Option<String>, 1297 + #[serde(default)] 1298 + pub shout_id: Option<String>, 1299 + #[serde(default)] 1300 + pub shout_content: Option<String>, 1301 + #[serde(default)] 1302 + pub actor: Option<NotificationActor>, 1303 + } 1304 + 1305 + /// Result of `app.rocksky.notification.listNotifications`. 1306 + #[derive(Clone, Debug, Default, Serialize, Deserialize)] 1307 + #[serde(rename_all = "camelCase")] 1308 + pub struct NotificationList { 1309 + #[serde(default)] 1310 + pub notifications: Vec<NotificationView>, 1311 + /// The number of unread notifications. 1312 + #[serde(default)] 1313 + pub unread_count: i64, 1314 + /// Cursor to pass to the next call for the following page. 1315 + #[serde(default)] 1316 + pub cursor: Option<String>, 1317 + } 1318 + 1319 + /// Result of `app.rocksky.notification.getUnreadCount`. 1320 + #[derive(Clone, Debug, Default, Serialize, Deserialize)] 1321 + #[serde(rename_all = "camelCase")] 1322 + pub struct UnreadCount { 1323 + /// The number of unread notifications. 1324 + #[serde(default)] 1325 + pub count: i64, 1326 + } 1327 + 1328 + /// Result of `app.rocksky.notification.updateSeen`. 1329 + #[derive(Clone, Debug, Default, Serialize, Deserialize)] 1330 + #[serde(rename_all = "camelCase")] 1331 + pub struct UpdateSeenResult { 1332 + /// The number of unread notifications remaining. 1333 + #[serde(default)] 1334 + pub unread_count: i64, 1197 1335 } 1198 1336 1199 1337 // ---- output envelopes ----------------------------------------------------
+4 -3
crates/rocksky-sdk/src/lib.rs
··· 76 76 77 77 pub use agent::{ 78 78 AlbumDraft, ArtistDraft, NowPlaying, RockskyAgent, RockskyAgentBuilder, ScrobbleDraft, 79 - ScrobbleMatch, ScrobbleResult, SongDraft, 79 + ScrobbleMatch, ScrobbleResult, ShoutGif, SongDraft, 80 80 }; 81 81 pub use appview::{ 82 - AlbumView, AppView, ArtistView, DateInterval, FeedItem, FeedView, GlobalStats, ProfileView, 83 - ScrobbleView, SearchResults, SongView, 82 + AlbumView, AppView, ArtistView, DateInterval, FeedItem, FeedView, GlobalStats, 83 + NotificationActor, NotificationList, NotificationView, ProfileView, ScrobbleView, 84 + SearchResults, SongView, UnreadCount, UpdateSeenResult, 84 85 }; 85 86 pub use auth::Profile; 86 87 #[cfg(feature = "dedup")]
+1 -1
crates/rocksky-uniffi/Cargo.toml
··· 1 1 [package] 2 2 name = "rocksky-uniffi" 3 - version = "0.2.0" 3 + version = "0.3.0" 4 4 edition = "2021" 5 5 description = "UniFFI bindings core for rocksky-sdk — one Rust core powering the Python, Ruby & Clojure SDKs" 6 6 authors.workspace = true
+91
crates/rocksky-uniffi/src/capi.rs
··· 191 191 } 192 192 } 193 193 194 + /// Mark notifications as viewed (`app.rocksky.notification.updateSeen`). `token` 195 + /// is required (empty → error at the server). `ids_json` is a JSON array of 196 + /// notification ids, or `[]`/empty to mark **all** as viewed. Returns the typed 197 + /// `{ "unreadCount": <int> }` result as JSON. 198 + #[no_mangle] 199 + pub extern "C" fn rocksky_update_seen( 200 + base: *const c_char, 201 + token: *const c_char, 202 + ids_json: *const c_char, 203 + ) -> *mut c_char { 204 + let mut av = appview(base); 205 + let t = cstr(token); 206 + if !t.is_empty() { 207 + av.set_token(Some(t)); 208 + } 209 + let ids: Vec<String> = serde_json::from_str(&cstr(ids_json)).unwrap_or_default(); 210 + respond(RT.block_on(av.update_seen(&ids)).map_err(|e| e.to_string())) 211 + } 212 + 213 + /// Parse a JSON GIF embed (`app.rocksky.shout.defs#gif`) into a 214 + /// [`rocksky_sdk::ShoutGif`]. Empty or invalid input yields `None`. 215 + fn parse_gif(gif_json: *const c_char) -> Option<rocksky_sdk::ShoutGif> { 216 + let s = cstr(gif_json); 217 + if s.is_empty() { 218 + return None; 219 + } 220 + serde_json::from_str::<rocksky_sdk::ShoutGif>(&s).ok() 221 + } 222 + 194 223 /// Parse a JSON object of params into string pairs, coercing scalar values 195 224 /// (numbers, bools) to their string form so callers can pass `{"limit": 20}`. 196 225 pub(crate) fn json_params(s: &str) -> Vec<(String, String)> { ··· 490 519 respond( 491 520 RT.block_on(a.shout(&cstr(subject_uri), &cstr(subject_cid), &cstr(message))) 492 521 .map_err(|e| e.to_string()), 522 + ) 523 + } 524 + 525 + /// Post a shout with an optional GIF/sticker/clip. `message` may be empty when a 526 + /// `gif_json` embed is supplied (pass at least one). `gif_json` is a JSON GIF 527 + /// embed or empty for none. Returns the shout URI. 528 + /// 529 + /// # Safety 530 + /// `agent` must be a live handle; the string args valid C strings. 531 + #[no_mangle] 532 + pub unsafe extern "C" fn rocksky_agent_shout_with_gif( 533 + agent: *mut Agent, 534 + subject_uri: *const c_char, 535 + subject_cid: *const c_char, 536 + message: *const c_char, 537 + gif_json: *const c_char, 538 + ) -> *mut c_char { 539 + let a = with_agent(agent); 540 + let msg = cstr(message); 541 + let message = if msg.is_empty() { None } else { Some(msg) }; 542 + let gif = parse_gif(gif_json); 543 + respond( 544 + RT.block_on(a.shout_with_gif( 545 + &cstr(subject_uri), 546 + &cstr(subject_cid), 547 + message.as_deref(), 548 + gif, 549 + )) 550 + .map_err(|e| e.to_string()), 551 + ) 552 + } 553 + 554 + /// Reply to a shout with an optional GIF/sticker/clip. Semantics match 555 + /// [`rocksky_agent_shout_with_gif`], plus a `parent` strong-ref. Returns the 556 + /// shout URI. 557 + /// 558 + /// # Safety 559 + /// `agent` must be a live handle; the string args valid C strings. 560 + #[no_mangle] 561 + pub unsafe extern "C" fn rocksky_agent_reply_shout_with_gif( 562 + agent: *mut Agent, 563 + subject_uri: *const c_char, 564 + subject_cid: *const c_char, 565 + parent_uri: *const c_char, 566 + parent_cid: *const c_char, 567 + message: *const c_char, 568 + gif_json: *const c_char, 569 + ) -> *mut c_char { 570 + let a = with_agent(agent); 571 + let msg = cstr(message); 572 + let message = if msg.is_empty() { None } else { Some(msg) }; 573 + let gif = parse_gif(gif_json); 574 + respond( 575 + RT.block_on(a.reply_shout_with_gif( 576 + &cstr(subject_uri), 577 + &cstr(subject_cid), 578 + &cstr(parent_uri), 579 + &cstr(parent_cid), 580 + message.as_deref(), 581 + gif, 582 + )) 583 + .map_err(|e| e.to_string()), 493 584 ) 494 585 } 495 586
+200
crates/rocksky-uniffi/src/lib.rs
··· 288 288 } 289 289 } 290 290 291 + /// A GIF / sticker / clip to attach to a shout 292 + /// (`app.rocksky.shout.defs#gif`). Only `url` is required. 293 + #[derive(Debug, Clone, Default, uniffi::Record)] 294 + pub struct ShoutGifInput { 295 + /// Direct URL of the animated GIF/MP4. 296 + pub url: String, 297 + /// Smaller still / preview image URL. 298 + #[uniffi(default = None)] 299 + pub preview_url: Option<String>, 300 + /// Alternative text describing the media. 301 + #[uniffi(default = None)] 302 + pub alt: Option<String>, 303 + #[uniffi(default = None)] 304 + pub width: Option<i64>, 305 + #[uniffi(default = None)] 306 + pub height: Option<i64>, 307 + } 308 + 309 + impl From<ShoutGifInput> for rocksky_sdk::ShoutGif { 310 + fn from(g: ShoutGifInput) -> Self { 311 + rocksky_sdk::ShoutGif { 312 + url: g.url, 313 + preview_url: g.preview_url, 314 + alt: g.alt, 315 + width: g.width, 316 + height: g.height, 317 + } 318 + } 319 + } 320 + 291 321 // ---- output records (SDK -> host) ---------------------------------------- 292 322 293 323 /// The four record URIs a scrobble touches. ··· 354 384 avatar: p.avatar, 355 385 created_at: p.created_at, 356 386 updated_at: p.updated_at, 387 + } 388 + } 389 + } 390 + 391 + /// The user who triggered a notification 392 + /// (`app.rocksky.notification.defs#notificationActor`). 393 + #[derive(Debug, Clone, uniffi::Record)] 394 + pub struct NotificationActor { 395 + pub id: Option<String>, 396 + pub did: Option<String>, 397 + pub handle: Option<String>, 398 + pub display_name: Option<String>, 399 + pub avatar: Option<String>, 400 + } 401 + 402 + impl From<rocksky_sdk::appview::NotificationActor> for NotificationActor { 403 + fn from(a: rocksky_sdk::appview::NotificationActor) -> Self { 404 + NotificationActor { 405 + id: a.id, 406 + did: a.did, 407 + handle: a.handle, 408 + display_name: a.display_name, 409 + avatar: a.avatar, 410 + } 411 + } 412 + } 413 + 414 + /// A single notification (`app.rocksky.notification.defs#notificationView`). 415 + #[derive(Debug, Clone, uniffi::Record)] 416 + pub struct NotificationView { 417 + pub id: String, 418 + /// One of `like_scrobble`, `follow`, `comment_scrobble`, `comment_profile`, 419 + /// `reply`, `react_comment`. 420 + pub notification_type: String, 421 + /// Whether the notification has been viewed. 422 + pub read: bool, 423 + pub created_at: String, 424 + pub subject_uri: Option<String>, 425 + pub shout_id: Option<String>, 426 + pub shout_content: Option<String>, 427 + pub actor: Option<NotificationActor>, 428 + } 429 + 430 + impl From<rocksky_sdk::appview::NotificationView> for NotificationView { 431 + fn from(n: rocksky_sdk::appview::NotificationView) -> Self { 432 + NotificationView { 433 + id: n.id, 434 + notification_type: n.r#type, 435 + read: n.read, 436 + created_at: n.created_at, 437 + subject_uri: n.subject_uri, 438 + shout_id: n.shout_id, 439 + shout_content: n.shout_content, 440 + actor: n.actor.map(Into::into), 441 + } 442 + } 443 + } 444 + 445 + /// A page of notifications (`app.rocksky.notification.listNotifications`). 446 + #[derive(Debug, Clone, uniffi::Record)] 447 + pub struct NotificationList { 448 + pub notifications: Vec<NotificationView>, 449 + /// The number of unread notifications. 450 + pub unread_count: i64, 451 + /// Cursor to pass to the next call for the following page. 452 + pub cursor: Option<String>, 453 + } 454 + 455 + impl From<rocksky_sdk::appview::NotificationList> for NotificationList { 456 + fn from(l: rocksky_sdk::appview::NotificationList) -> Self { 457 + NotificationList { 458 + notifications: l.notifications.into_iter().map(Into::into).collect(), 459 + unread_count: l.unread_count, 460 + cursor: l.cursor, 461 + } 462 + } 463 + } 464 + 465 + /// The unread-notification count (`app.rocksky.notification.getUnreadCount`). 466 + #[derive(Debug, Clone, uniffi::Record)] 467 + pub struct UnreadCount { 468 + pub count: i64, 469 + } 470 + 471 + impl From<rocksky_sdk::appview::UnreadCount> for UnreadCount { 472 + fn from(c: rocksky_sdk::appview::UnreadCount) -> Self { 473 + UnreadCount { count: c.count } 474 + } 475 + } 476 + 477 + /// The result of marking notifications seen 478 + /// (`app.rocksky.notification.updateSeen`). 479 + #[derive(Debug, Clone, uniffi::Record)] 480 + pub struct UpdateSeenResult { 481 + /// The number of unread notifications remaining. 482 + pub unread_count: i64, 483 + } 484 + 485 + impl From<rocksky_sdk::appview::UpdateSeenResult> for UpdateSeenResult { 486 + fn from(r: rocksky_sdk::appview::UpdateSeenResult) -> Self { 487 + UpdateSeenResult { 488 + unread_count: r.unread_count, 357 489 } 358 490 } 359 491 } ··· 1081 1213 pub fn apikeys(&self, limit: u32, offset: u32) -> Result<String, RockskyError> { 1082 1214 json(RT.block_on(self.inner.apikeys(limit, offset))) 1083 1215 } 1216 + 1217 + /// The authenticated viewer's unread-notification count 1218 + /// (`app.rocksky.notification.getUnreadCount`). 1219 + pub fn unread_count(&self) -> Result<UnreadCount, RockskyError> { 1220 + Ok(RT.block_on(self.inner.unread_count()).map_err(err)?.into()) 1221 + } 1222 + 1223 + /// The authenticated viewer's notifications, most recent first 1224 + /// (`app.rocksky.notification.listNotifications`). `limit` defaults to 30. 1225 + pub fn notifications( 1226 + &self, 1227 + limit: Option<u32>, 1228 + cursor: Option<String>, 1229 + ) -> Result<NotificationList, RockskyError> { 1230 + Ok(RT 1231 + .block_on(self.inner.notifications(limit, cursor.as_deref())) 1232 + .map_err(err)? 1233 + .into()) 1234 + } 1235 + 1236 + /// Mark notifications as viewed (`app.rocksky.notification.updateSeen`). Pass 1237 + /// the ids to mark, or an empty list to mark **all** as viewed. 1238 + pub fn update_seen(&self, ids: Vec<String>) -> Result<UpdateSeenResult, RockskyError> { 1239 + Ok(RT 1240 + .block_on(self.inner.update_seen(&ids)) 1241 + .map_err(err)? 1242 + .into()) 1243 + } 1084 1244 } 1085 1245 1086 1246 /// Serialize a raw-JSON core read result to a string for the FFI boundary. ··· 1202 1362 .map_err(err) 1203 1363 } 1204 1364 1365 + /// Post a shout with an optional GIF/sticker/clip attachment. Pass at least 1366 + /// one of `message` / `gif`. Returns the shout URI. 1367 + pub fn shout_with_gif( 1368 + &self, 1369 + subject_uri: String, 1370 + subject_cid: String, 1371 + message: Option<String>, 1372 + gif: Option<ShoutGifInput>, 1373 + ) -> Result<String, RockskyError> { 1374 + RT.block_on(self.inner.shout_with_gif( 1375 + &subject_uri, 1376 + &subject_cid, 1377 + message.as_deref(), 1378 + gif.map(Into::into), 1379 + )) 1380 + .map_err(err) 1381 + } 1382 + 1205 1383 /// Reply to a shout. Returns the shout URI. 1206 1384 pub fn reply_shout( 1207 1385 &self, ··· 1217 1395 &parent_uri, 1218 1396 &parent_cid, 1219 1397 &message, 1398 + )) 1399 + .map_err(err) 1400 + } 1401 + 1402 + /// Reply to a shout with an optional GIF/sticker/clip attachment. Pass at 1403 + /// least one of `message` / `gif`. Returns the shout URI. 1404 + pub fn reply_shout_with_gif( 1405 + &self, 1406 + subject_uri: String, 1407 + subject_cid: String, 1408 + parent_uri: String, 1409 + parent_cid: String, 1410 + message: Option<String>, 1411 + gif: Option<ShoutGifInput>, 1412 + ) -> Result<String, RockskyError> { 1413 + RT.block_on(self.inner.reply_shout_with_gif( 1414 + &subject_uri, 1415 + &subject_cid, 1416 + &parent_uri, 1417 + &parent_cid, 1418 + message.as_deref(), 1419 + gif.map(Into::into), 1220 1420 )) 1221 1421 .map_err(err) 1222 1422 }
+1 -1
sdk/clojure/build.clj
··· 13 13 [deps-deploy.deps-deploy :as dd])) 14 14 15 15 (def lib 'app.rocksky/sdk) 16 - (def version "0.7.0-SNAPSHOT") 16 + (def version "0.8.0-SNAPSHOT") 17 17 (def class-dir "target/classes") 18 18 (def basis (delay (b/create-basis {:project "deps.edn"}))) 19 19 (def jar-file (format "target/%s-%s.jar" (name lib) version))
+46
sdk/clojure/src/rocksky/core.clj
··· 38 38 (def ^:private h-toptracks (delay (downcall "rocksky_top_tracks" ADDR [ADDR I32 I32]))) 39 39 (def ^:private h-stats (delay (downcall "rocksky_global_stats" ADDR [ADDR]))) 40 40 (def ^:private h-get (delay (downcall "rocksky_get" ADDR [ADDR ADDR ADDR ADDR]))) 41 + (def ^:private h-update-seen (delay (downcall "rocksky_update_seen" ADDR [ADDR ADDR ADDR]))) 41 42 (def ^:private h-lib-get (delay (downcall "rocksky_library_get" ADDR [ADDR ADDR ADDR ADDR]))) 42 43 (def ^:private h-lib-post (delay (downcall "rocksky_library_post" ADDR [ADDR ADDR ADDR ADDR]))) 43 44 (def ^:private h-match (delay (downcall "rocksky_match_song" ADDR [ADDR ADDR ADDR ADDR ADDR]))) ··· 55 56 (def ^:private h-like (delay (downcall "rocksky_agent_like" ADDR [ADDR ADDR ADDR]))) 56 57 (def ^:private h-follow (delay (downcall "rocksky_agent_follow" ADDR [ADDR ADDR]))) 57 58 (def ^:private h-shout (delay (downcall "rocksky_agent_shout" ADDR [ADDR ADDR ADDR ADDR]))) 59 + (def ^:private h-shout-gif (delay (downcall "rocksky_agent_shout_with_gif" ADDR [ADDR ADDR ADDR ADDR ADDR]))) 60 + (def ^:private h-reply-shout-gif (delay (downcall "rocksky_agent_reply_shout_with_gif" ADDR [ADDR ADDR ADDR ADDR ADDR ADDR ADDR]))) 58 61 (def ^:private h-refresh (delay (downcall "rocksky_agent_refresh_session" ADDR [ADDR]))) 59 62 60 63 (defn- read-free ··· 152 155 (.allocateFrom a (str nsid)) 153 156 (.allocateFrom a (json/generate-string body))])))))) 154 157 158 + ;; ---- notifications (auth-gated; `token` required) ----------------------- 159 + 160 + (defn unread-count 161 + "The authenticated viewer's unread-notification count. Returns 162 + {\"count\" n}. `token` is required." 163 + ([token] (unread-count token nil)) 164 + ([token base] 165 + (query "app.rocksky.notification.getUnreadCount" {} base token))) 166 + 167 + (defn notifications 168 + "The authenticated viewer's notifications, most recent first. `token` is 169 + required; `opts` may contain :limit (default 30) and :cursor. Returns 170 + {\"notifications\" [...] \"unreadCount\" n \"cursor\" c?}." 171 + ([token] (notifications token {} nil)) 172 + ([token opts] (notifications token opts nil)) 173 + ([token opts base] 174 + (query "app.rocksky.notification.listNotifications" 175 + (into {} (filter (comp some? val) {:limit (:limit opts) :cursor (:cursor opts)})) 176 + base token))) 177 + 178 + (defn update-seen 179 + "Mark notifications as viewed. `ids` is a vector of notification ids, or [] to 180 + mark all. `token` is required. Returns {\"unreadCount\" n}." 181 + ([token ids] (update-seen token ids nil)) 182 + ([token ids base] 183 + (with-open [^Arena a (Arena/ofConfined)] 184 + (unwrap (.invokeWithArguments ^MethodHandle @h-update-seen 185 + (object-array [(.allocateFrom a (str (or base ""))) 186 + (.allocateFrom a (str token)) 187 + (.allocateFrom a (json/generate-string (or ids [])))])))))) 188 + 155 189 (defn match-song 156 190 "Resolve full canonical metadata for a bare title + artist (matchSong)." 157 191 ([title artist] (match-song title artist nil nil nil)) ··· 266 300 (defn follow [agent did] (agent-call @h-follow agent did)) 267 301 (defn shout [agent subject-uri subject-cid message] 268 302 (agent-call @h-shout agent subject-uri subject-cid message)) 303 + (defn shout-with-gif 304 + "Post a shout with an optional GIF/sticker/clip. Pass at least one of `message` 305 + / `gif` (a map: :url required, plus :previewUrl :alt :width :height)." 306 + [agent subject-uri subject-cid message gif] 307 + (agent-call @h-shout-gif agent subject-uri subject-cid 308 + (or message "") (if gif (json/generate-string gif) ""))) 309 + (defn reply-shout-with-gif 310 + "Reply to a shout with an optional GIF/sticker/clip (see shout-with-gif), plus 311 + a parent strong-ref (`parent-uri`/`parent-cid`)." 312 + [agent subject-uri subject-cid parent-uri parent-cid message gif] 313 + (agent-call @h-reply-shout-gif agent subject-uri subject-cid parent-uri parent-cid 314 + (or message "") (if gif (json/generate-string gif) ""))) 269 315 (defn refresh-session [agent] (agent-call @h-refresh agent)) 270 316 271 317 (defn agent-close
+52
sdk/elixir/lib/rocksky.ex
··· 43 43 def get(nsid, params \\ %{}, base \\ "", token \\ ""), 44 44 do: :rocksky.get(to_bin(nsid), params, to_bin(base), to_bin(token)) 45 45 46 + @doc """ 47 + The authenticated viewer's unread-notification count (`token` required). 48 + Returns `%{"count" => n}`. 49 + """ 50 + def unread_count(token, base \\ ""), 51 + do: :rocksky.unread_count(to_bin(token), to_bin(base)) 52 + 53 + @doc """ 54 + The authenticated viewer's notifications, most recent first (`token` required). 55 + `params` may include `"limit"` (default 30) and `"cursor"`. 56 + """ 57 + def notifications(token, params \\ %{}, base \\ ""), 58 + do: :rocksky.notifications(to_bin(token), params, to_bin(base)) 59 + 60 + @doc """ 61 + Mark notifications as viewed (`token` required). `ids` is a list of notification 62 + ids, or `[]` to mark all. Returns `%{"unreadCount" => n}`. 63 + """ 64 + def update_seen(token, ids \\ [], base \\ ""), 65 + do: :rocksky.update_seen(to_bin(token), ids, to_bin(base)) 66 + 46 67 @doc "Resolve full canonical metadata for a bare title + artist (matchSong)." 47 68 def match_song(title, artist, mb_id \\ "", isrc \\ "", base \\ ""), 48 69 do: :rocksky.match_song(to_bin(base), to_bin(title), to_bin(artist), to_bin(mb_id), to_bin(isrc)) ··· 112 133 def shout(agent, subject_uri, subject_cid, message), 113 134 do: :rocksky.agent_shout(agent, to_bin(subject_uri), to_bin(subject_cid), to_bin(message)) 114 135 136 + @doc """ 137 + Post a shout with an optional GIF/sticker/clip. Pass at least one of `message` 138 + / `gif`. `gif` is a map (`"url"` required, plus `"previewUrl"`, `"alt"`, 139 + `"width"`, `"height"`) or `nil`. 140 + """ 141 + def shout_with_gif(agent, subject_uri, subject_cid, message, gif \\ nil), 142 + do: 143 + :rocksky.agent_shout_with_gif( 144 + agent, 145 + to_bin(subject_uri), 146 + to_bin(subject_cid), 147 + to_bin(message), 148 + gif_arg(gif) 149 + ) 150 + 151 + @doc "Reply to a shout with an optional GIF/sticker/clip (see `shout_with_gif/5`)." 152 + def reply_shout_with_gif(agent, subject_uri, subject_cid, parent_uri, parent_cid, message, gif \\ nil), 153 + do: 154 + :rocksky.agent_reply_shout_with_gif( 155 + agent, 156 + to_bin(subject_uri), 157 + to_bin(subject_cid), 158 + to_bin(parent_uri), 159 + to_bin(parent_cid), 160 + to_bin(message), 161 + gif_arg(gif) 162 + ) 163 + 115 164 @doc "Proactively refresh the session (keep-alive)." 116 165 def refresh_session(agent), do: :rocksky.agent_refresh_session(agent) 166 + 167 + defp gif_arg(nil), do: :undefined 168 + defp gif_arg(gif), do: gif 117 169 118 170 defp to_bin(s) when is_binary(s), do: s 119 171 defp to_bin(s), do: to_string(s)
+1 -1
sdk/elixir/mix.exs
··· 1 1 defmodule Rocksky.MixProject do 2 2 use Mix.Project 3 3 4 - @version "0.7.0" 4 + @version "0.8.0" 5 5 @source_url "https://github.com/tsirysndr/rocksky" 6 6 7 7 def project do
+61 -1
sdk/erlang/src/rocksky.erl
··· 19 19 agent_login/3, agent_login/4, agent_login/5, agent_scrobble/2, 20 20 agent_scrobble_match/2, agent_scrobble_match/7, agent_sync_repo/1, 21 21 agent_hydrate_from_jetstream/1, agent_like/3, 22 - agent_follow/2, agent_shout/4, agent_refresh_session/1]). 22 + agent_follow/2, agent_shout/4, agent_shout_with_gif/5, 23 + agent_reply_shout_with_gif/7, agent_refresh_session/1, 24 + unread_count/1, unread_count/2, notifications/1, notifications/2, 25 + notifications/3, update_seen/2, update_seen/3, update_seen_raw/3, 26 + agent_shout_with_gif_raw/5, agent_reply_shout_with_gif_raw/7]). 23 27 24 28 %% Decode a NIF JSON-envelope binary into {ok, Value} | {error, Message}. 25 29 unwrap(Bin) -> ··· 62 66 %% Flat form for cross-language callers passing a pre-encoded JSON params object. 63 67 get_raw(Base, Nsid, ParamsJson, Token) -> 64 68 unwrap(rocksky_nif:get(b(Base), b(Nsid), b(ParamsJson), b(Token))). 69 + 70 + %% ---- notifications (auth-gated; `Token` required) ---- 71 + 72 + %% The authenticated viewer's unread-notification count. Returns 73 + %% {ok, #{<<"count">> => N}}. 74 + unread_count(Token) -> unread_count(Token, <<>>). 75 + unread_count(Token, Base) -> 76 + get(<<"app.rocksky.notification.getUnreadCount">>, #{}, Base, Token). 77 + 78 + %% The authenticated viewer's notifications, most recent first. `Params` is a map 79 + %% that may contain <<"limit">> (default 30) and <<"cursor">>. Returns 80 + %% {ok, #{<<"notifications">> => [...], <<"unreadCount">> => N, <<"cursor">> => C}}. 81 + notifications(Token) -> notifications(Token, #{}, <<>>). 82 + notifications(Token, Params) -> notifications(Token, Params, <<>>). 83 + notifications(Token, Params, Base) -> 84 + get(<<"app.rocksky.notification.listNotifications">>, Params, Base, Token). 85 + 86 + %% Mark notifications as viewed. `Ids` is a list of notification id binaries, or 87 + %% [] to mark all. Returns {ok, #{<<"unreadCount">> => N}}. 88 + update_seen(Token, Ids) -> update_seen(Token, Ids, <<>>). 89 + update_seen(Token, Ids, Base) -> 90 + unwrap(rocksky_nif:update_seen(b(Base), b(Token), iolist_to_binary(json:encode(Ids)))). 91 + 92 + %% Flat form for cross-language callers passing a pre-encoded JSON ids array. 93 + update_seen_raw(Token, IdsJson, Base) -> 94 + unwrap(rocksky_nif:update_seen(b(Base), b(Token), b(IdsJson))). 65 95 66 96 %% ---- authenticated library.* (uploaded-music) escape hatches ---- 67 97 %% Every app.rocksky.library.* call requires auth — `Token` must be non-empty. ··· 173 203 agent_follow(Agent, Did) -> unwrap(rocksky_nif:agent_follow(Agent, b(Did))). 174 204 agent_shout(Agent, SubjectUri, SubjectCid, Message) -> 175 205 unwrap(rocksky_nif:agent_shout(Agent, b(SubjectUri), b(SubjectCid), b(Message))). 206 + 207 + %% Post a shout with an optional GIF/sticker/clip. Pass at least one of `Message` 208 + %% / `Gif`. `Gif` is a map (<<"url">> required, plus <<"previewUrl">>, <<"alt">>, 209 + %% <<"width">>, <<"height">>) or `undefined`. 210 + agent_shout_with_gif(Agent, SubjectUri, SubjectCid, Message, Gif) -> 211 + unwrap(rocksky_nif:agent_shout_with_gif( 212 + Agent, b(SubjectUri), b(SubjectCid), b(Message), gif_json(Gif))). 213 + 214 + %% Reply to a shout with an optional GIF/sticker/clip (see agent_shout_with_gif), 215 + %% plus a parent strong-ref (`ParentUri`/`ParentCid`). 216 + agent_reply_shout_with_gif(Agent, SubjectUri, SubjectCid, ParentUri, ParentCid, Message, Gif) -> 217 + unwrap(rocksky_nif:agent_reply_shout_with_gif( 218 + Agent, b(SubjectUri), b(SubjectCid), b(ParentUri), b(ParentCid), 219 + b(Message), gif_json(Gif))). 220 + 176 221 agent_refresh_session(Agent) -> unwrap(rocksky_nif:agent_refresh_session(Agent)). 222 + 223 + %% Encode a GIF embed map to a JSON binary; `undefined` yields an empty binary. 224 + gif_json(undefined) -> <<>>; 225 + gif_json(Gif) -> iolist_to_binary(json:encode(Gif)). 226 + 227 + %% Flat forms for cross-language callers passing a pre-encoded JSON gif embed 228 + %% (empty binary for none) and a plain message binary. 229 + agent_shout_with_gif_raw(Agent, SubjectUri, SubjectCid, Message, GifJson) -> 230 + unwrap(rocksky_nif:agent_shout_with_gif( 231 + Agent, b(SubjectUri), b(SubjectCid), b(Message), b(GifJson))). 232 + 233 + agent_reply_shout_with_gif_raw(Agent, SubjectUri, SubjectCid, ParentUri, ParentCid, Message, GifJson) -> 234 + unwrap(rocksky_nif:agent_reply_shout_with_gif( 235 + Agent, b(SubjectUri), b(SubjectCid), b(ParentUri), b(ParentCid), 236 + b(Message), b(GifJson))).
+1 -1
sdk/erlang/src/rocksky_erl.app.src
··· 3 3 "Official Erlang SDK for Rocksky — a Rustler NIF over the shared Rust core " 4 4 "(rocksky-sdk): AppView reads, record writes (scrobble fan-out, like, " 5 5 "follow, shout), and the identity hashes shared across every Rocksky SDK."}, 6 - {vsn, "0.4.0"}, 6 + {vsn, "0.5.0"}, 7 7 {registered, []}, 8 8 %% crypto/inets/ssl/public_key back the first-load NIF download + checksum 9 9 %% verify in rocksky_nif. kernel/stdlib are mandatory.
+5 -1
sdk/erlang/src/rocksky_nif.erl
··· 26 26 agent_scrobble_match/2, agent_sync_repo/1, agent_hydrate_from_jetstream/1, 27 27 agent_create_song/2, agent_create_album/2, agent_create_artist/2, 28 28 agent_like/3, agent_unlike/2, agent_follow/2, agent_unfollow/2, 29 - agent_shout/4, agent_reply_shout/6, agent_set_now_playing/2, 29 + agent_shout/4, agent_reply_shout/6, agent_shout_with_gif/5, 30 + agent_reply_shout_with_gif/7, update_seen/3, agent_set_now_playing/2, 30 31 agent_clear_now_playing/1]). 31 32 32 33 -on_load(init/0). ··· 211 212 top_tracks(_Base, _Limit, _Offset) -> ?NOT_LOADED. 212 213 global_stats(_Base) -> ?NOT_LOADED. 213 214 get(_Base, _Nsid, _ParamsJson, _Token) -> ?NOT_LOADED. 215 + update_seen(_Base, _Token, _IdsJson) -> ?NOT_LOADED. 214 216 library_get(_Base, _Token, _Nsid, _ParamsJson) -> ?NOT_LOADED. 215 217 library_post(_Base, _Token, _Nsid, _BodyJson) -> ?NOT_LOADED. 216 218 match_song(_Base, _Title, _Artist, _MbId, _Isrc) -> ?NOT_LOADED. ··· 278 280 agent_unfollow(_Agent, _Did) -> ?NOT_LOADED. 279 281 agent_shout(_Agent, _SubjectUri, _SubjectCid, _Message) -> ?NOT_LOADED. 280 282 agent_reply_shout(_Agent, _SubjectUri, _SubjectCid, _ParentUri, _ParentCid, _Message) -> ?NOT_LOADED. 283 + agent_shout_with_gif(_Agent, _SubjectUri, _SubjectCid, _Message, _GifJson) -> ?NOT_LOADED. 284 + agent_reply_shout_with_gif(_Agent, _SubjectUri, _SubjectCid, _ParentUri, _ParentCid, _Message, _GifJson) -> ?NOT_LOADED. 281 285 agent_set_now_playing(_Agent, _Json) -> ?NOT_LOADED. 282 286 agent_clear_now_playing(_Agent) -> ?NOT_LOADED.
+1 -1
sdk/gleam/gleam.toml
··· 1 1 name = "rocksky" 2 - version = "1.7.0" 2 + version = "1.8.0" 3 3 4 4 description = "Gleam SDK for Rocksky — native bindings to the shared Rust core: AppView reads, AT Protocol PDS writes, and identity hashes" 5 5 licences = ["MIT"]
+2 -2
sdk/gleam/manifest.toml
··· 9 9 packages = [ 10 10 { name = "gleam_stdlib", version = "1.0.3", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1F543AFBA5D33DA493E6087F4E4C4F20D899411343512686C98A8ABB2963CF22" }, 11 11 { name = "gleeunit", version = "1.10.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "254B697FE72EEAD7BF82E941723918E421317813AC49923EE76A18C788C61E72" }, 12 - { name = "rocksky_erl", version = "0.2.1", build_tools = ["rebar3"], requirements = [], otp_app = "rocksky_erl", source = "hex", outer_checksum = "C9EC000E84AC855B917F716FD984339F6E70D5C2FDFA5F3AD23BBD0D31ADCC81" }, 12 + { name = "rocksky_erl", version = "0.4.0", build_tools = ["rebar3"], requirements = [], otp_app = "rocksky_erl", source = "hex", outer_checksum = "FF2D849469D57E8A6126ABA44FB1723FB9581E4206B0FEB7195C77BBB29D4F95" }, 13 13 ] 14 14 15 15 [requirements] 16 16 gleam_stdlib = { version = ">= 0.71.0 and < 2.0.0" } 17 17 gleeunit = { version = ">= 1.2.0 and < 2.0.0" } 18 - rocksky_erl = { version = ">= 0.2.0 and < 1.0.0" } 18 + rocksky_erl = { version = ">= 0.3.0 and < 1.0.0" }
+78
sdk/gleam/src/rocksky/client.gleam
··· 98 98 get_ffi(endpoint, nsid, params_json, "") 99 99 } 100 100 101 + // ---- notifications (auth-gated; `token` required) ------------------------ 102 + 103 + /// The authenticated viewer's unread-notification count. Returns 104 + /// `{"count": n}`. 105 + pub fn unread_count(token: String) -> Dynamic { 106 + get_ffi("", "app.rocksky.notification.getUnreadCount", "{}", token) 107 + } 108 + 109 + /// The authenticated viewer's notifications, most recent first. `params_json` is 110 + /// a JSON object that may contain `"limit"` (default 30) and `"cursor"`. 111 + pub fn notifications(token: String, params_json: String) -> Dynamic { 112 + get_ffi("", "app.rocksky.notification.listNotifications", params_json, token) 113 + } 114 + 115 + @external(erlang, "rocksky", "update_seen_raw") 116 + fn update_seen_ffi(token: String, ids_json: String, base: String) -> Dynamic 117 + 118 + /// Mark notifications as viewed. `ids_json` is a JSON array of notification ids 119 + /// (`"[\"id1\",\"id2\"]"`), or `"[]"` to mark all. Returns `{"unreadCount": n}`. 120 + pub fn update_seen(token: String, ids_json: String) -> Dynamic { 121 + update_seen_ffi(token, ids_json, "") 122 + } 123 + 101 124 @external(erlang, "rocksky", "match_song") 102 125 fn match_song_ffi(title: String, artist: String) -> Dynamic 103 126 ··· 248 271 message: String, 249 272 ) -> Dynamic { 250 273 agent_shout_ffi(agent, subject_uri, subject_cid, message) 274 + } 275 + 276 + @external(erlang, "rocksky", "agent_shout_with_gif_raw") 277 + fn agent_shout_with_gif_ffi( 278 + agent: Agent, 279 + subject_uri: String, 280 + subject_cid: String, 281 + message: String, 282 + gif_json: String, 283 + ) -> Dynamic 284 + 285 + /// Post a shout with an optional GIF/sticker/clip. Pass at least one of 286 + /// `message` / `gif_json` (a JSON gif embed with `"url"` required, plus 287 + /// `"previewUrl"`, `"alt"`, `"width"`, `"height"`; `""` for none). 288 + pub fn shout_with_gif( 289 + agent: Agent, 290 + subject_uri: String, 291 + subject_cid: String, 292 + message: String, 293 + gif_json: String, 294 + ) -> Dynamic { 295 + agent_shout_with_gif_ffi(agent, subject_uri, subject_cid, message, gif_json) 296 + } 297 + 298 + @external(erlang, "rocksky", "agent_reply_shout_with_gif_raw") 299 + fn agent_reply_shout_with_gif_ffi( 300 + agent: Agent, 301 + subject_uri: String, 302 + subject_cid: String, 303 + parent_uri: String, 304 + parent_cid: String, 305 + message: String, 306 + gif_json: String, 307 + ) -> Dynamic 308 + 309 + /// Reply to a shout with an optional GIF/sticker/clip (see 310 + /// [shout_with_gif](#shout_with_gif)), plus a parent strong-ref. 311 + pub fn reply_shout_with_gif( 312 + agent: Agent, 313 + subject_uri: String, 314 + subject_cid: String, 315 + parent_uri: String, 316 + parent_cid: String, 317 + message: String, 318 + gif_json: String, 319 + ) -> Dynamic { 320 + agent_reply_shout_with_gif_ffi( 321 + agent, 322 + subject_uri, 323 + subject_cid, 324 + parent_uri, 325 + parent_cid, 326 + message, 327 + gif_json, 328 + ) 251 329 } 252 330 253 331 @external(erlang, "rocksky", "agent_refresh_session")
+24
sdk/go/rocksky/agent.go
··· 408 408 }) 409 409 } 410 410 411 + // ShoutWithGif posts a shout with an optional GIF/sticker/clip attachment 412 + // (app.rocksky.shout). Pass at least one of message / gif — message may be empty 413 + // when a gif is attached. Returns the URI. 414 + func (a *Agent) ShoutWithGif(ctx context.Context, subjectURI, subjectCID, message string, gif *gen.ShoutGif) (string, error) { 415 + return a.create(ctx, colShout, gen.ShoutRecord{ 416 + Subject: &gen.StrongRef{URI: subjectURI, CID: subjectCID}, 417 + Message: message, 418 + Gif: gif, 419 + CreatedAt: nowRFC3339(), 420 + }) 421 + } 422 + 423 + // ReplyShoutWithGif replies to a shout with an optional GIF/sticker/clip 424 + // attachment, with a parent strong-ref. Pass at least one of message / gif. 425 + func (a *Agent) ReplyShoutWithGif(ctx context.Context, subjectURI, subjectCID, parentURI, parentCID, message string, gif *gen.ShoutGif) (string, error) { 426 + return a.create(ctx, colShout, gen.ShoutRecord{ 427 + Subject: &gen.StrongRef{URI: subjectURI, CID: subjectCID}, 428 + Parent: &gen.StrongRef{URI: parentURI, CID: parentCID}, 429 + Message: message, 430 + Gif: gif, 431 + CreatedAt: nowRFC3339(), 432 + }) 433 + } 434 + 411 435 // SetNowPlaying upserts the actor's now-playing status singleton (rkey "self"). 412 436 func (a *Agent) SetNowPlaying(ctx context.Context, track gen.ActorTrackView) (string, error) { 413 437 return a.put(ctx, colStatus, "self", gen.StatusRecord{
+31
sdk/go/rocksky/client.go
··· 123 123 return &out, err 124 124 } 125 125 126 + // UnreadCount returns the authenticated viewer's unread-notification count 127 + // (app.rocksky.notification.getUnreadCount, auth-gated). 128 + func (c *Client) UnreadCount(ctx context.Context) (*gen.GetUnreadCountOutput, error) { 129 + var out gen.GetUnreadCountOutput 130 + err := c.query(ctx, "app.rocksky.notification.getUnreadCount", nil, &out) 131 + return &out, err 132 + } 133 + 134 + // Notifications returns the authenticated viewer's notifications, most recent 135 + // first (app.rocksky.notification.listNotifications, auth-gated). limit defaults 136 + // to 30 server-side when <= 0; paginate via cursor. 137 + func (c *Client) Notifications(ctx context.Context, limit int, cursor string) (*gen.ListNotificationsOutput, error) { 138 + var out gen.ListNotificationsOutput 139 + params := map[string]any{"cursor": cursor} 140 + if limit > 0 { 141 + params["limit"] = limit 142 + } 143 + err := c.query(ctx, "app.rocksky.notification.listNotifications", params, &out) 144 + return &out, err 145 + } 146 + 147 + // UpdateSeen marks notifications as viewed (app.rocksky.notification.updateSeen, 148 + // auth-gated). Pass the notification ids to mark, or nil/empty to mark all of 149 + // the viewer's notifications. Returns the number remaining unread. 150 + func (c *Client) UpdateSeen(ctx context.Context, ids []string) (*gen.UpdateSeenOutput, error) { 151 + var out gen.UpdateSeenOutput 152 + err := c.xrpc.Do(ctx, xrpc.Procedure, "application/json", 153 + "app.rocksky.notification.updateSeen", nil, gen.UpdateSeenInput{Ids: ids}, &out) 154 + return &out, err 155 + } 156 + 126 157 // Local response envelopes keyed on the production JSON (some generated Output 127 158 // types drift from what the AppView actually returns, e.g. getActorSongs -> tracks). 128 159 type (
+93 -4
sdk/go/rocksky/gen/types.go
··· 491 491 Feeds []FeedUriView `json:"feeds,omitempty"` 492 492 } 493 493 494 - type DescribeFeedGeneratorParams struct { 495 - } 496 - 497 494 type DislikeShoutInput struct { 498 495 // The unique identifier of the shout to dislike 499 496 URI string `json:"uri,omitempty"` ··· 1376 1373 URI string `json:"uri,omitempty"` 1377 1374 } 1378 1375 1376 + type GetUnreadCountOutput struct { 1377 + // The number of unread notifications. 1378 + Count int `json:"count,omitempty"` 1379 + } 1380 + 1379 1381 type GetUserOutput struct { 1380 1382 } 1381 1383 ··· 1527 1529 URI string `json:"uri,omitempty"` 1528 1530 } 1529 1531 1532 + type ListNotificationsOutput struct { 1533 + Notifications []NotificationView `json:"notifications,omitempty"` 1534 + // The number of unread notifications. 1535 + UnreadCount int `json:"unreadCount,omitempty"` 1536 + // A cursor value to pass to subsequent calls to get the next page of results. 1537 + Cursor string `json:"cursor,omitempty"` 1538 + } 1539 + 1540 + type ListNotificationsParams struct { 1541 + Limit int `json:"limit,omitempty"` 1542 + Cursor string `json:"cursor,omitempty"` 1543 + } 1544 + 1530 1545 type MatchSongParams struct { 1531 1546 // The title of the song to retrieve 1532 1547 Title string `json:"title,omitempty"` ··· 1553 1568 LastScrobbleSeenAt string `json:"lastScrobbleSeenAt,omitempty"` 1554 1569 } 1555 1570 1571 + // NotificationActor The user who triggered a notification. 1572 + type NotificationActor struct { 1573 + // The unique identifier of the actor. 1574 + ID string `json:"id,omitempty"` 1575 + // The decentralized identifier of the actor. 1576 + DID string `json:"did,omitempty"` 1577 + // The handle of the actor. 1578 + Handle string `json:"handle,omitempty"` 1579 + // The display name of the actor. 1580 + DisplayName string `json:"displayName,omitempty"` 1581 + // The URL of the actor's avatar image. 1582 + Avatar string `json:"avatar,omitempty"` 1583 + } 1584 + 1585 + type NotificationView struct { 1586 + // The unique identifier of the notification. 1587 + ID string `json:"id,omitempty"` 1588 + // The notification type: like_scrobble, follow, comment_scrobble, comment_profile, reply, or react_comment. 1589 + Type string `json:"type,omitempty"` 1590 + // Whether the notification has been viewed. 1591 + Read bool `json:"read,omitempty"` 1592 + // When the notification was created. 1593 + CreatedAt string `json:"createdAt,omitempty"` 1594 + // The at-uri of the subject the notification relates to. 1595 + SubjectURI string `json:"subjectUri,omitempty"` 1596 + // The id of the related shout, if any. 1597 + ShoutID string `json:"shoutId,omitempty"` 1598 + // The content of the related shout, if any. 1599 + ShoutContent string `json:"shoutContent,omitempty"` 1600 + Actor *NotificationActor `json:"actor,omitempty"` 1601 + } 1602 + 1556 1603 type PingOutput struct { 1557 1604 } 1558 1605 ··· 2088 2135 Avatar string `json:"avatar,omitempty"` 2089 2136 } 2090 2137 2138 + // ShoutGif A GIF, sticker, or clip embedded in a shout. `url` may point at an image (GIF/WebP) or a video (MP4); the client decides how to render it from the file extension. 2139 + type ShoutGif struct { 2140 + // Direct URL of the animated GIF/MP4. 2141 + URL string `json:"url,omitempty"` 2142 + // Smaller still/preview image URL. 2143 + PreviewURL string `json:"previewUrl,omitempty"` 2144 + // Alternative text describing the media. 2145 + Alt string `json:"alt,omitempty"` 2146 + // The intrinsic width of the media in pixels. 2147 + Width int `json:"width,omitempty"` 2148 + // The intrinsic height of the media in pixels. 2149 + Height int `json:"height,omitempty"` 2150 + } 2151 + 2152 + // ShoutMention A mention of another actor within the shout message, anchored to a UTF-8 byte range in the message. 2153 + type ShoutMention struct { 2154 + // The DID of the mentioned actor. 2155 + DID string `json:"did,omitempty"` 2156 + // Inclusive UTF-8 byte offset of the mention start. 2157 + ByteStart int `json:"byteStart,omitempty"` 2158 + // Exclusive UTF-8 byte offset of the mention end. 2159 + ByteEnd int `json:"byteEnd,omitempty"` 2160 + } 2161 + 2091 2162 type ShoutRecord struct { 2092 - // The message of the shout. 2163 + // The message of the shout. Optional when a gif/sticker/clip is attached. 2093 2164 Message string `json:"message,omitempty"` 2094 2165 // The date when the shout was created. 2095 2166 CreatedAt string `json:"createdAt,omitempty"` 2096 2167 Parent *StrongRef `json:"parent,omitempty"` 2097 2168 Subject *StrongRef `json:"subject,omitempty"` 2169 + // An attached GIF, sticker, or clip (e.g. from KLIPY). 2170 + Gif *ShoutGif `json:"gif,omitempty"` 2171 + // Mentions of other actors within the message, anchored to UTF-8 byte ranges. 2172 + Facets []ShoutMention `json:"facets,omitempty"` 2098 2173 } 2099 2174 2100 2175 type ShoutView struct { ··· 2108 2183 CreatedAt string `json:"createdAt,omitempty"` 2109 2184 // The author of the shout. 2110 2185 Author *ShoutAuthor `json:"author,omitempty"` 2186 + // An attached GIF, sticker, or clip. 2187 + Gif *ShoutGif `json:"gif,omitempty"` 2188 + // Mentions of other actors within the message, anchored to UTF-8 byte ranges. 2189 + Facets []ShoutMention `json:"facets,omitempty"` 2111 2190 } 2112 2191 2113 2192 type SongFirstScrobbleView struct { ··· 2542 2621 2543 2622 type UpdatePlaylistOutput struct { 2544 2623 } 2624 + 2625 + type UpdateSeenInput struct { 2626 + // The ids of the notifications to mark as viewed. Omit to mark all. 2627 + Ids []string `json:"ids,omitempty"` 2628 + } 2629 + 2630 + type UpdateSeenOutput struct { 2631 + // The number of unread notifications remaining. 2632 + UnreadCount int `json:"unreadCount,omitempty"` 2633 + }
+1 -1
sdk/kotlin/rocksky/build.gradle.kts
··· 18 18 } 19 19 20 20 group = "app.rocksky" 21 - version = "0.8.0" 21 + version = "0.9.0" 22 22 23 23 kotlin { 24 24 jvmToolchain(17)
+2021
sdk/kotlin/rocksky/src/main/kotlin/uniffi/rocksky_uniffi/rocksky_uniffi.kt
··· 876 876 877 877 878 878 879 + 880 + 881 + 882 + 883 + 884 + 885 + 886 + 887 + 888 + 889 + 890 + 891 + 892 + 893 + 894 + 895 + 896 + 897 + 898 + 899 + 900 + 901 + 902 + 903 + 904 + 905 + 906 + 907 + 908 + 909 + 910 + 911 + 912 + 913 + 914 + 915 + 916 + 917 + 918 + 919 + 920 + 921 + 922 + 923 + 924 + 925 + 926 + 927 + 928 + 929 + 930 + 931 + 932 + 933 + 934 + 935 + 936 + 937 + 938 + 939 + 940 + 941 + 942 + 943 + 944 + 945 + 946 + 947 + 948 + 949 + 950 + 951 + 952 + 953 + 954 + 955 + 956 + 957 + 958 + 959 + 960 + 961 + 962 + 963 + 964 + 965 + 966 + 967 + 968 + 969 + 970 + 971 + 972 + 973 + 974 + 879 975 // A JNA Library to expose the extern-C FFI definitions. 880 976 // This is an implementation detail which will be called internally by the public API. 881 977 ··· 923 1019 ): Unit 924 1020 fun uniffi_rocksky_uniffi_fn_method_agent_reply_shout(`ptr`: Pointer,`subjectUri`: RustBuffer.ByValue,`subjectCid`: RustBuffer.ByValue,`parentUri`: RustBuffer.ByValue,`parentCid`: RustBuffer.ByValue,`message`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 925 1021 ): RustBuffer.ByValue 1022 + fun uniffi_rocksky_uniffi_fn_method_agent_reply_shout_with_gif(`ptr`: Pointer,`subjectUri`: RustBuffer.ByValue,`subjectCid`: RustBuffer.ByValue,`parentUri`: RustBuffer.ByValue,`parentCid`: RustBuffer.ByValue,`message`: RustBuffer.ByValue,`gif`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1023 + ): RustBuffer.ByValue 926 1024 fun uniffi_rocksky_uniffi_fn_method_agent_scrobble(`ptr`: Pointer,`input`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 927 1025 ): RustBuffer.ByValue 928 1026 fun uniffi_rocksky_uniffi_fn_method_agent_scrobble_match(`ptr`: Pointer,`input`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, ··· 930 1028 fun uniffi_rocksky_uniffi_fn_method_agent_set_now_playing(`ptr`: Pointer,`track`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 931 1029 ): Unit 932 1030 fun uniffi_rocksky_uniffi_fn_method_agent_shout(`ptr`: Pointer,`subjectUri`: RustBuffer.ByValue,`subjectCid`: RustBuffer.ByValue,`message`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1031 + ): RustBuffer.ByValue 1032 + fun uniffi_rocksky_uniffi_fn_method_agent_shout_with_gif(`ptr`: Pointer,`subjectUri`: RustBuffer.ByValue,`subjectCid`: RustBuffer.ByValue,`message`: RustBuffer.ByValue,`gif`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 933 1033 ): RustBuffer.ByValue 934 1034 fun uniffi_rocksky_uniffi_fn_method_agent_sync_repo(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 935 1035 ): RustBuffer.ByValue ··· 1009 1109 ): RustBuffer.ByValue 1010 1110 fun uniffi_rocksky_uniffi_fn_method_appview_neighbours(`ptr`: Pointer,`actor`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1011 1111 ): RustBuffer.ByValue 1112 + fun uniffi_rocksky_uniffi_fn_method_appview_notifications(`ptr`: Pointer,`limit`: RustBuffer.ByValue,`cursor`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1113 + ): RustBuffer.ByValue 1012 1114 fun uniffi_rocksky_uniffi_fn_method_appview_playback_queue(`ptr`: Pointer,`playerId`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1013 1115 ): RustBuffer.ByValue 1014 1116 fun uniffi_rocksky_uniffi_fn_method_appview_playlist(`ptr`: Pointer,`uri`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, ··· 1055 1157 ): RustBuffer.ByValue 1056 1158 fun uniffi_rocksky_uniffi_fn_method_appview_track_shouts(`ptr`: Pointer,`uri`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1057 1159 ): RustBuffer.ByValue 1160 + fun uniffi_rocksky_uniffi_fn_method_appview_unread_count(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1161 + ): RustBuffer.ByValue 1162 + fun uniffi_rocksky_uniffi_fn_method_appview_update_seen(`ptr`: Pointer,`ids`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1163 + ): RustBuffer.ByValue 1058 1164 fun uniffi_rocksky_uniffi_fn_method_appview_wrapped(`ptr`: Pointer,`actor`: RustBuffer.ByValue,`year`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1059 1165 ): RustBuffer.ByValue 1166 + fun uniffi_rocksky_uniffi_fn_clone_library(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1167 + ): Pointer 1168 + fun uniffi_rocksky_uniffi_fn_free_library(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1169 + ): Unit 1170 + fun uniffi_rocksky_uniffi_fn_constructor_library_new(`base`: RustBuffer.ByValue,`token`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1171 + ): Pointer 1172 + fun uniffi_rocksky_uniffi_fn_method_library_create_playlist(`ptr`: Pointer,`name`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1173 + ): RustBuffer.ByValue 1174 + fun uniffi_rocksky_uniffi_fn_method_library_delete_album(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1175 + ): RustBuffer.ByValue 1176 + fun uniffi_rocksky_uniffi_fn_method_library_delete_playlist(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1177 + ): RustBuffer.ByValue 1178 + fun uniffi_rocksky_uniffi_fn_method_library_delete_song(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1179 + ): RustBuffer.ByValue 1180 + fun uniffi_rocksky_uniffi_fn_method_library_get_album(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1181 + ): RustBuffer.ByValue 1182 + fun uniffi_rocksky_uniffi_fn_method_library_get_album_info(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1183 + ): RustBuffer.ByValue 1184 + fun uniffi_rocksky_uniffi_fn_method_library_get_album_list(`ptr`: Pointer,`type`: RustBuffer.ByValue,`size`: RustBuffer.ByValue,`offset`: RustBuffer.ByValue,`fromYear`: RustBuffer.ByValue,`toYear`: RustBuffer.ByValue,`genre`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1185 + ): RustBuffer.ByValue 1186 + fun uniffi_rocksky_uniffi_fn_method_library_get_artist(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1187 + ): RustBuffer.ByValue 1188 + fun uniffi_rocksky_uniffi_fn_method_library_get_artist_info(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1189 + ): RustBuffer.ByValue 1190 + fun uniffi_rocksky_uniffi_fn_method_library_get_artists(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1191 + ): RustBuffer.ByValue 1192 + fun uniffi_rocksky_uniffi_fn_method_library_get_cover_art_url(`ptr`: Pointer,`id`: RustBuffer.ByValue,`size`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1193 + ): RustBuffer.ByValue 1194 + fun uniffi_rocksky_uniffi_fn_method_library_get_download_url(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1195 + ): RustBuffer.ByValue 1196 + fun uniffi_rocksky_uniffi_fn_method_library_get_genres(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1197 + ): RustBuffer.ByValue 1198 + fun uniffi_rocksky_uniffi_fn_method_library_get_indexes(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1199 + ): RustBuffer.ByValue 1200 + fun uniffi_rocksky_uniffi_fn_method_library_get_internet_radio_stations(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1201 + ): RustBuffer.ByValue 1202 + fun uniffi_rocksky_uniffi_fn_method_library_get_license(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1203 + ): RustBuffer.ByValue 1204 + fun uniffi_rocksky_uniffi_fn_method_library_get_lyrics(`ptr`: Pointer,`artist`: RustBuffer.ByValue,`title`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1205 + ): RustBuffer.ByValue 1206 + fun uniffi_rocksky_uniffi_fn_method_library_get_music_directory(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1207 + ): RustBuffer.ByValue 1208 + fun uniffi_rocksky_uniffi_fn_method_library_get_music_folders(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1209 + ): RustBuffer.ByValue 1210 + fun uniffi_rocksky_uniffi_fn_method_library_get_now_playing(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1211 + ): RustBuffer.ByValue 1212 + fun uniffi_rocksky_uniffi_fn_method_library_get_play_queue(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1213 + ): RustBuffer.ByValue 1214 + fun uniffi_rocksky_uniffi_fn_method_library_get_playlist(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1215 + ): RustBuffer.ByValue 1216 + fun uniffi_rocksky_uniffi_fn_method_library_get_playlists(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1217 + ): RustBuffer.ByValue 1218 + fun uniffi_rocksky_uniffi_fn_method_library_get_random_songs(`ptr`: Pointer,`size`: RustBuffer.ByValue,`genre`: RustBuffer.ByValue,`fromYear`: RustBuffer.ByValue,`toYear`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1219 + ): RustBuffer.ByValue 1220 + fun uniffi_rocksky_uniffi_fn_method_library_get_scan_status(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1221 + ): RustBuffer.ByValue 1222 + fun uniffi_rocksky_uniffi_fn_method_library_get_similar_songs(`ptr`: Pointer,`id`: RustBuffer.ByValue,`count`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1223 + ): RustBuffer.ByValue 1224 + fun uniffi_rocksky_uniffi_fn_method_library_get_song(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1225 + ): RustBuffer.ByValue 1226 + fun uniffi_rocksky_uniffi_fn_method_library_get_songs_by_genre(`ptr`: Pointer,`genre`: RustBuffer.ByValue,`count`: RustBuffer.ByValue,`offset`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1227 + ): RustBuffer.ByValue 1228 + fun uniffi_rocksky_uniffi_fn_method_library_get_starred(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1229 + ): RustBuffer.ByValue 1230 + fun uniffi_rocksky_uniffi_fn_method_library_get_stream_url(`ptr`: Pointer,`id`: RustBuffer.ByValue,`maxBitRate`: RustBuffer.ByValue,`format`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1231 + ): RustBuffer.ByValue 1232 + fun uniffi_rocksky_uniffi_fn_method_library_get_top_songs(`ptr`: Pointer,`artist`: RustBuffer.ByValue,`count`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1233 + ): RustBuffer.ByValue 1234 + fun uniffi_rocksky_uniffi_fn_method_library_get_user(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1235 + ): RustBuffer.ByValue 1236 + fun uniffi_rocksky_uniffi_fn_method_library_ping(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1237 + ): RustBuffer.ByValue 1238 + fun uniffi_rocksky_uniffi_fn_method_library_save_play_queue(`ptr`: Pointer,`id`: RustBuffer.ByValue,`current`: RustBuffer.ByValue,`position`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1239 + ): RustBuffer.ByValue 1240 + fun uniffi_rocksky_uniffi_fn_method_library_scrobble(`ptr`: Pointer,`id`: RustBuffer.ByValue,`time`: RustBuffer.ByValue,`submission`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1241 + ): RustBuffer.ByValue 1242 + fun uniffi_rocksky_uniffi_fn_method_library_search(`ptr`: Pointer,`query`: RustBuffer.ByValue,`artistCount`: RustBuffer.ByValue,`artistOffset`: RustBuffer.ByValue,`albumCount`: RustBuffer.ByValue,`albumOffset`: RustBuffer.ByValue,`songCount`: RustBuffer.ByValue,`songOffset`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1243 + ): RustBuffer.ByValue 1244 + fun uniffi_rocksky_uniffi_fn_method_library_star(`ptr`: Pointer,`id`: RustBuffer.ByValue,`albumId`: RustBuffer.ByValue,`artistId`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1245 + ): RustBuffer.ByValue 1246 + fun uniffi_rocksky_uniffi_fn_method_library_start_scan(`ptr`: Pointer,uniffi_out_err: UniffiRustCallStatus, 1247 + ): RustBuffer.ByValue 1248 + fun uniffi_rocksky_uniffi_fn_method_library_unstar(`ptr`: Pointer,`id`: RustBuffer.ByValue,`albumId`: RustBuffer.ByValue,`artistId`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1249 + ): RustBuffer.ByValue 1250 + fun uniffi_rocksky_uniffi_fn_method_library_update_now_playing(`ptr`: Pointer,`id`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1251 + ): RustBuffer.ByValue 1252 + fun uniffi_rocksky_uniffi_fn_method_library_update_playlist(`ptr`: Pointer,`playlistId`: RustBuffer.ByValue,`name`: RustBuffer.ByValue,`comment`: RustBuffer.ByValue,`songIdToAdd`: RustBuffer.ByValue,`songIndexToRemove`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1253 + ): RustBuffer.ByValue 1060 1254 fun uniffi_rocksky_uniffi_fn_func_album_hash(`album`: RustBuffer.ByValue,`albumArtist`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, 1061 1255 ): RustBuffer.ByValue 1062 1256 fun uniffi_rocksky_uniffi_fn_func_artist_hash(`albumArtist`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, ··· 1203 1397 ): Short 1204 1398 fun uniffi_rocksky_uniffi_checksum_method_agent_reply_shout( 1205 1399 ): Short 1400 + fun uniffi_rocksky_uniffi_checksum_method_agent_reply_shout_with_gif( 1401 + ): Short 1206 1402 fun uniffi_rocksky_uniffi_checksum_method_agent_scrobble( 1207 1403 ): Short 1208 1404 fun uniffi_rocksky_uniffi_checksum_method_agent_scrobble_match( ··· 1210 1406 fun uniffi_rocksky_uniffi_checksum_method_agent_set_now_playing( 1211 1407 ): Short 1212 1408 fun uniffi_rocksky_uniffi_checksum_method_agent_shout( 1409 + ): Short 1410 + fun uniffi_rocksky_uniffi_checksum_method_agent_shout_with_gif( 1213 1411 ): Short 1214 1412 fun uniffi_rocksky_uniffi_checksum_method_agent_sync_repo( 1215 1413 ): Short ··· 1283 1481 ): Short 1284 1482 fun uniffi_rocksky_uniffi_checksum_method_appview_neighbours( 1285 1483 ): Short 1484 + fun uniffi_rocksky_uniffi_checksum_method_appview_notifications( 1485 + ): Short 1286 1486 fun uniffi_rocksky_uniffi_checksum_method_appview_playback_queue( 1287 1487 ): Short 1288 1488 fun uniffi_rocksky_uniffi_checksum_method_appview_playlist( ··· 1329 1529 ): Short 1330 1530 fun uniffi_rocksky_uniffi_checksum_method_appview_track_shouts( 1331 1531 ): Short 1532 + fun uniffi_rocksky_uniffi_checksum_method_appview_unread_count( 1533 + ): Short 1534 + fun uniffi_rocksky_uniffi_checksum_method_appview_update_seen( 1535 + ): Short 1332 1536 fun uniffi_rocksky_uniffi_checksum_method_appview_wrapped( 1333 1537 ): Short 1538 + fun uniffi_rocksky_uniffi_checksum_method_library_create_playlist( 1539 + ): Short 1540 + fun uniffi_rocksky_uniffi_checksum_method_library_delete_album( 1541 + ): Short 1542 + fun uniffi_rocksky_uniffi_checksum_method_library_delete_playlist( 1543 + ): Short 1544 + fun uniffi_rocksky_uniffi_checksum_method_library_delete_song( 1545 + ): Short 1546 + fun uniffi_rocksky_uniffi_checksum_method_library_get_album( 1547 + ): Short 1548 + fun uniffi_rocksky_uniffi_checksum_method_library_get_album_info( 1549 + ): Short 1550 + fun uniffi_rocksky_uniffi_checksum_method_library_get_album_list( 1551 + ): Short 1552 + fun uniffi_rocksky_uniffi_checksum_method_library_get_artist( 1553 + ): Short 1554 + fun uniffi_rocksky_uniffi_checksum_method_library_get_artist_info( 1555 + ): Short 1556 + fun uniffi_rocksky_uniffi_checksum_method_library_get_artists( 1557 + ): Short 1558 + fun uniffi_rocksky_uniffi_checksum_method_library_get_cover_art_url( 1559 + ): Short 1560 + fun uniffi_rocksky_uniffi_checksum_method_library_get_download_url( 1561 + ): Short 1562 + fun uniffi_rocksky_uniffi_checksum_method_library_get_genres( 1563 + ): Short 1564 + fun uniffi_rocksky_uniffi_checksum_method_library_get_indexes( 1565 + ): Short 1566 + fun uniffi_rocksky_uniffi_checksum_method_library_get_internet_radio_stations( 1567 + ): Short 1568 + fun uniffi_rocksky_uniffi_checksum_method_library_get_license( 1569 + ): Short 1570 + fun uniffi_rocksky_uniffi_checksum_method_library_get_lyrics( 1571 + ): Short 1572 + fun uniffi_rocksky_uniffi_checksum_method_library_get_music_directory( 1573 + ): Short 1574 + fun uniffi_rocksky_uniffi_checksum_method_library_get_music_folders( 1575 + ): Short 1576 + fun uniffi_rocksky_uniffi_checksum_method_library_get_now_playing( 1577 + ): Short 1578 + fun uniffi_rocksky_uniffi_checksum_method_library_get_play_queue( 1579 + ): Short 1580 + fun uniffi_rocksky_uniffi_checksum_method_library_get_playlist( 1581 + ): Short 1582 + fun uniffi_rocksky_uniffi_checksum_method_library_get_playlists( 1583 + ): Short 1584 + fun uniffi_rocksky_uniffi_checksum_method_library_get_random_songs( 1585 + ): Short 1586 + fun uniffi_rocksky_uniffi_checksum_method_library_get_scan_status( 1587 + ): Short 1588 + fun uniffi_rocksky_uniffi_checksum_method_library_get_similar_songs( 1589 + ): Short 1590 + fun uniffi_rocksky_uniffi_checksum_method_library_get_song( 1591 + ): Short 1592 + fun uniffi_rocksky_uniffi_checksum_method_library_get_songs_by_genre( 1593 + ): Short 1594 + fun uniffi_rocksky_uniffi_checksum_method_library_get_starred( 1595 + ): Short 1596 + fun uniffi_rocksky_uniffi_checksum_method_library_get_stream_url( 1597 + ): Short 1598 + fun uniffi_rocksky_uniffi_checksum_method_library_get_top_songs( 1599 + ): Short 1600 + fun uniffi_rocksky_uniffi_checksum_method_library_get_user( 1601 + ): Short 1602 + fun uniffi_rocksky_uniffi_checksum_method_library_ping( 1603 + ): Short 1604 + fun uniffi_rocksky_uniffi_checksum_method_library_save_play_queue( 1605 + ): Short 1606 + fun uniffi_rocksky_uniffi_checksum_method_library_scrobble( 1607 + ): Short 1608 + fun uniffi_rocksky_uniffi_checksum_method_library_search( 1609 + ): Short 1610 + fun uniffi_rocksky_uniffi_checksum_method_library_star( 1611 + ): Short 1612 + fun uniffi_rocksky_uniffi_checksum_method_library_start_scan( 1613 + ): Short 1614 + fun uniffi_rocksky_uniffi_checksum_method_library_unstar( 1615 + ): Short 1616 + fun uniffi_rocksky_uniffi_checksum_method_library_update_now_playing( 1617 + ): Short 1618 + fun uniffi_rocksky_uniffi_checksum_method_library_update_playlist( 1619 + ): Short 1334 1620 fun uniffi_rocksky_uniffi_checksum_constructor_agent_login_password( 1335 1621 ): Short 1336 1622 fun uniffi_rocksky_uniffi_checksum_constructor_appview_new( 1623 + ): Short 1624 + fun uniffi_rocksky_uniffi_checksum_constructor_library_new( 1337 1625 ): Short 1338 1626 fun ffi_rocksky_uniffi_uniffi_contract_version( 1339 1627 ): Int ··· 1394 1682 if (lib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout() != 29470.toShort()) { 1395 1683 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1396 1684 } 1685 + if (lib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout_with_gif() != 30347.toShort()) { 1686 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1687 + } 1397 1688 if (lib.uniffi_rocksky_uniffi_checksum_method_agent_scrobble() != 17314.toShort()) { 1398 1689 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1399 1690 } ··· 1406 1697 if (lib.uniffi_rocksky_uniffi_checksum_method_agent_shout() != 41382.toShort()) { 1407 1698 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1408 1699 } 1700 + if (lib.uniffi_rocksky_uniffi_checksum_method_agent_shout_with_gif() != 51807.toShort()) { 1701 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1702 + } 1409 1703 if (lib.uniffi_rocksky_uniffi_checksum_method_agent_sync_repo() != 33910.toShort()) { 1410 1704 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1411 1705 } ··· 1514 1808 if (lib.uniffi_rocksky_uniffi_checksum_method_appview_neighbours() != 57546.toShort()) { 1515 1809 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1516 1810 } 1811 + if (lib.uniffi_rocksky_uniffi_checksum_method_appview_notifications() != 60047.toShort()) { 1812 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1813 + } 1517 1814 if (lib.uniffi_rocksky_uniffi_checksum_method_appview_playback_queue() != 32322.toShort()) { 1518 1815 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1519 1816 } ··· 1583 1880 if (lib.uniffi_rocksky_uniffi_checksum_method_appview_track_shouts() != 8713.toShort()) { 1584 1881 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1585 1882 } 1883 + if (lib.uniffi_rocksky_uniffi_checksum_method_appview_unread_count() != 41669.toShort()) { 1884 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1885 + } 1886 + if (lib.uniffi_rocksky_uniffi_checksum_method_appview_update_seen() != 15297.toShort()) { 1887 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1888 + } 1586 1889 if (lib.uniffi_rocksky_uniffi_checksum_method_appview_wrapped() != 63835.toShort()) { 1587 1890 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1588 1891 } 1892 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_create_playlist() != 1198.toShort()) { 1893 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1894 + } 1895 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_delete_album() != 61199.toShort()) { 1896 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1897 + } 1898 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_delete_playlist() != 22674.toShort()) { 1899 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1900 + } 1901 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_delete_song() != 65357.toShort()) { 1902 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1903 + } 1904 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_album() != 29404.toShort()) { 1905 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1906 + } 1907 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_album_info() != 52466.toShort()) { 1908 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1909 + } 1910 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_album_list() != 40173.toShort()) { 1911 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1912 + } 1913 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_artist() != 29339.toShort()) { 1914 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1915 + } 1916 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_artist_info() != 16237.toShort()) { 1917 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1918 + } 1919 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_artists() != 28277.toShort()) { 1920 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1921 + } 1922 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_cover_art_url() != 4983.toShort()) { 1923 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1924 + } 1925 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_download_url() != 28146.toShort()) { 1926 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1927 + } 1928 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_genres() != 59896.toShort()) { 1929 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1930 + } 1931 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_indexes() != 12238.toShort()) { 1932 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1933 + } 1934 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_internet_radio_stations() != 55752.toShort()) { 1935 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1936 + } 1937 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_license() != 5838.toShort()) { 1938 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1939 + } 1940 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_lyrics() != 38380.toShort()) { 1941 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1942 + } 1943 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_music_directory() != 52674.toShort()) { 1944 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1945 + } 1946 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_music_folders() != 17682.toShort()) { 1947 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1948 + } 1949 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_now_playing() != 36367.toShort()) { 1950 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1951 + } 1952 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_play_queue() != 65057.toShort()) { 1953 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1954 + } 1955 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_playlist() != 64635.toShort()) { 1956 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1957 + } 1958 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_playlists() != 42853.toShort()) { 1959 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1960 + } 1961 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_random_songs() != 50256.toShort()) { 1962 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1963 + } 1964 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_scan_status() != 65363.toShort()) { 1965 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1966 + } 1967 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_similar_songs() != 43677.toShort()) { 1968 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1969 + } 1970 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_song() != 35370.toShort()) { 1971 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1972 + } 1973 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_songs_by_genre() != 55810.toShort()) { 1974 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1975 + } 1976 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_starred() != 42756.toShort()) { 1977 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1978 + } 1979 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_stream_url() != 25069.toShort()) { 1980 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1981 + } 1982 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_top_songs() != 31996.toShort()) { 1983 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1984 + } 1985 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_get_user() != 22213.toShort()) { 1986 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1987 + } 1988 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_ping() != 50138.toShort()) { 1989 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1990 + } 1991 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_save_play_queue() != 48102.toShort()) { 1992 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1993 + } 1994 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_scrobble() != 2804.toShort()) { 1995 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1996 + } 1997 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_search() != 53170.toShort()) { 1998 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1999 + } 2000 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_star() != 19540.toShort()) { 2001 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 2002 + } 2003 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_start_scan() != 3950.toShort()) { 2004 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 2005 + } 2006 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_unstar() != 50111.toShort()) { 2007 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 2008 + } 2009 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_update_now_playing() != 58737.toShort()) { 2010 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 2011 + } 2012 + if (lib.uniffi_rocksky_uniffi_checksum_method_library_update_playlist() != 33660.toShort()) { 2013 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 2014 + } 1589 2015 if (lib.uniffi_rocksky_uniffi_checksum_constructor_agent_login_password() != 59184.toShort()) { 1590 2016 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1591 2017 } 1592 2018 if (lib.uniffi_rocksky_uniffi_checksum_constructor_appview_new() != 526.toShort()) { 2019 + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 2020 + } 2021 + if (lib.uniffi_rocksky_uniffi_checksum_constructor_library_new() != 16490.toShort()) { 1593 2022 throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 1594 2023 } 1595 2024 } ··· 1997 2426 fun `replyShout`(`subjectUri`: kotlin.String, `subjectCid`: kotlin.String, `parentUri`: kotlin.String, `parentCid`: kotlin.String, `message`: kotlin.String): kotlin.String 1998 2427 1999 2428 /** 2429 + * Reply to a shout with an optional GIF/sticker/clip attachment. Pass at 2430 + * least one of `message` / `gif`. Returns the shout URI. 2431 + */ 2432 + fun `replyShoutWithGif`(`subjectUri`: kotlin.String, `subjectCid`: kotlin.String, `parentUri`: kotlin.String, `parentCid`: kotlin.String, `message`: kotlin.String?, `gif`: ShoutGifInput?): kotlin.String 2433 + 2434 + /** 2000 2435 * Scrobble a play — fans out to artist/album/song then the scrobble. 2001 2436 */ 2002 2437 fun `scrobble`(`input`: ScrobbleInput): ScrobbleResult ··· 2016 2451 * Post a shout on a subject. Returns the shout URI. 2017 2452 */ 2018 2453 fun `shout`(`subjectUri`: kotlin.String, `subjectCid`: kotlin.String, `message`: kotlin.String): kotlin.String 2454 + 2455 + /** 2456 + * Post a shout with an optional GIF/sticker/clip attachment. Pass at least 2457 + * one of `message` / `gif`. Returns the shout URI. 2458 + */ 2459 + fun `shoutWithGif`(`subjectUri`: kotlin.String, `subjectCid`: kotlin.String, `message`: kotlin.String?, `gif`: ShoutGifInput?): kotlin.String 2019 2460 2020 2461 /** 2021 2462 * Download the caller's repo (CAR) and (re)build the local dedup index, ··· 2273 2714 2274 2715 2275 2716 /** 2717 + * Reply to a shout with an optional GIF/sticker/clip attachment. Pass at 2718 + * least one of `message` / `gif`. Returns the shout URI. 2719 + */ 2720 + @Throws(RockskyException::class)override fun `replyShoutWithGif`(`subjectUri`: kotlin.String, `subjectCid`: kotlin.String, `parentUri`: kotlin.String, `parentCid`: kotlin.String, `message`: kotlin.String?, `gif`: ShoutGifInput?): kotlin.String { 2721 + return FfiConverterString.lift( 2722 + callWithPointer { 2723 + uniffiRustCallWithError(RockskyException) { _status -> 2724 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_agent_reply_shout_with_gif( 2725 + it, FfiConverterString.lower(`subjectUri`),FfiConverterString.lower(`subjectCid`),FfiConverterString.lower(`parentUri`),FfiConverterString.lower(`parentCid`),FfiConverterOptionalString.lower(`message`),FfiConverterOptionalTypeShoutGifInput.lower(`gif`),_status) 2726 + } 2727 + } 2728 + ) 2729 + } 2730 + 2731 + 2732 + 2733 + /** 2276 2734 * Scrobble a play — fans out to artist/album/song then the scrobble. 2277 2735 */ 2278 2736 @Throws(RockskyException::class)override fun `scrobble`(`input`: ScrobbleInput): ScrobbleResult { ··· 2329 2787 uniffiRustCallWithError(RockskyException) { _status -> 2330 2788 UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_agent_shout( 2331 2789 it, FfiConverterString.lower(`subjectUri`),FfiConverterString.lower(`subjectCid`),FfiConverterString.lower(`message`),_status) 2790 + } 2791 + } 2792 + ) 2793 + } 2794 + 2795 + 2796 + 2797 + /** 2798 + * Post a shout with an optional GIF/sticker/clip attachment. Pass at least 2799 + * one of `message` / `gif`. Returns the shout URI. 2800 + */ 2801 + @Throws(RockskyException::class)override fun `shoutWithGif`(`subjectUri`: kotlin.String, `subjectCid`: kotlin.String, `message`: kotlin.String?, `gif`: ShoutGifInput?): kotlin.String { 2802 + return FfiConverterString.lift( 2803 + callWithPointer { 2804 + uniffiRustCallWithError(RockskyException) { _status -> 2805 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_agent_shout_with_gif( 2806 + it, FfiConverterString.lower(`subjectUri`),FfiConverterString.lower(`subjectCid`),FfiConverterOptionalString.lower(`message`),FfiConverterOptionalTypeShoutGifInput.lower(`gif`),_status) 2332 2807 } 2333 2808 } 2334 2809 ) ··· 2607 3082 2608 3083 fun `neighbours`(`actor`: kotlin.String): kotlin.String 2609 3084 3085 + /** 3086 + * The authenticated viewer's notifications, most recent first 3087 + * (`app.rocksky.notification.listNotifications`). `limit` defaults to 30. 3088 + */ 3089 + fun `notifications`(`limit`: kotlin.UInt?, `cursor`: kotlin.String?): NotificationList 3090 + 2610 3091 fun `playbackQueue`(`playerId`: kotlin.String): kotlin.String 2611 3092 2612 3093 fun `playlist`(`uri`: kotlin.String): kotlin.String ··· 2658 3139 fun `topTracksInterval`(`limit`: kotlin.UInt, `offset`: kotlin.UInt, `interval`: DateInterval): List<SongView> 2659 3140 2660 3141 fun `trackShouts`(`uri`: kotlin.String): kotlin.String 3142 + 3143 + /** 3144 + * The authenticated viewer's unread-notification count 3145 + * (`app.rocksky.notification.getUnreadCount`). 3146 + */ 3147 + fun `unreadCount`(): UnreadCount 3148 + 3149 + /** 3150 + * Mark notifications as viewed (`app.rocksky.notification.updateSeen`). Pass 3151 + * the ids to mark, or an empty list to mark **all** as viewed. 3152 + */ 3153 + fun `updateSeen`(`ids`: List<kotlin.String>): UpdateSeenResult 2661 3154 2662 3155 fun `wrapped`(`actor`: kotlin.String, `year`: kotlin.UInt?): kotlin.String 2663 3156 ··· 3196 3689 3197 3690 3198 3691 3692 + /** 3693 + * The authenticated viewer's notifications, most recent first 3694 + * (`app.rocksky.notification.listNotifications`). `limit` defaults to 30. 3695 + */ 3696 + @Throws(RockskyException::class)override fun `notifications`(`limit`: kotlin.UInt?, `cursor`: kotlin.String?): NotificationList { 3697 + return FfiConverterTypeNotificationList.lift( 3698 + callWithPointer { 3699 + uniffiRustCallWithError(RockskyException) { _status -> 3700 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_appview_notifications( 3701 + it, FfiConverterOptionalUInt.lower(`limit`),FfiConverterOptionalString.lower(`cursor`),_status) 3702 + } 3703 + } 3704 + ) 3705 + } 3706 + 3707 + 3708 + 3199 3709 @Throws(RockskyException::class)override fun `playbackQueue`(`playerId`: kotlin.String): kotlin.String { 3200 3710 return FfiConverterString.lift( 3201 3711 callWithPointer { ··· 3501 4011 3502 4012 3503 4013 4014 + /** 4015 + * The authenticated viewer's unread-notification count 4016 + * (`app.rocksky.notification.getUnreadCount`). 4017 + */ 4018 + @Throws(RockskyException::class)override fun `unreadCount`(): UnreadCount { 4019 + return FfiConverterTypeUnreadCount.lift( 4020 + callWithPointer { 4021 + uniffiRustCallWithError(RockskyException) { _status -> 4022 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_appview_unread_count( 4023 + it, _status) 4024 + } 4025 + } 4026 + ) 4027 + } 4028 + 4029 + 4030 + 4031 + /** 4032 + * Mark notifications as viewed (`app.rocksky.notification.updateSeen`). Pass 4033 + * the ids to mark, or an empty list to mark **all** as viewed. 4034 + */ 4035 + @Throws(RockskyException::class)override fun `updateSeen`(`ids`: List<kotlin.String>): UpdateSeenResult { 4036 + return FfiConverterTypeUpdateSeenResult.lift( 4037 + callWithPointer { 4038 + uniffiRustCallWithError(RockskyException) { _status -> 4039 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_appview_update_seen( 4040 + it, FfiConverterSequenceString.lower(`ids`),_status) 4041 + } 4042 + } 4043 + ) 4044 + } 4045 + 4046 + 4047 + 3504 4048 @Throws(RockskyException::class)override fun `wrapped`(`actor`: kotlin.String, `year`: kotlin.UInt?): kotlin.String { 3505 4049 return FfiConverterString.lift( 3506 4050 callWithPointer { ··· 3550 4094 } 3551 4095 3552 4096 4097 + // This template implements a class for working with a Rust struct via a Pointer/Arc<T> 4098 + // to the live Rust struct on the other side of the FFI. 4099 + // 4100 + // Each instance implements core operations for working with the Rust `Arc<T>` and the 4101 + // Kotlin Pointer to work with the live Rust struct on the other side of the FFI. 4102 + // 4103 + // There's some subtlety here, because we have to be careful not to operate on a Rust 4104 + // struct after it has been dropped, and because we must expose a public API for freeing 4105 + // theq Kotlin wrapper object in lieu of reliable finalizers. The core requirements are: 4106 + // 4107 + // * Each instance holds an opaque pointer to the underlying Rust struct. 4108 + // Method calls need to read this pointer from the object's state and pass it in to 4109 + // the Rust FFI. 4110 + // 4111 + // * When an instance is no longer needed, its pointer should be passed to a 4112 + // special destructor function provided by the Rust FFI, which will drop the 4113 + // underlying Rust struct. 4114 + // 4115 + // * Given an instance, calling code is expected to call the special 4116 + // `destroy` method in order to free it after use, either by calling it explicitly 4117 + // or by using a higher-level helper like the `use` method. Failing to do so risks 4118 + // leaking the underlying Rust struct. 4119 + // 4120 + // * We can't assume that calling code will do the right thing, and must be prepared 4121 + // to handle Kotlin method calls executing concurrently with or even after a call to 4122 + // `destroy`, and to handle multiple (possibly concurrent!) calls to `destroy`. 4123 + // 4124 + // * We must never allow Rust code to operate on the underlying Rust struct after 4125 + // the destructor has been called, and must never call the destructor more than once. 4126 + // Doing so may trigger memory unsafety. 4127 + // 4128 + // * To mitigate many of the risks of leaking memory and use-after-free unsafety, a `Cleaner` 4129 + // is implemented to call the destructor when the Kotlin object becomes unreachable. 4130 + // This is done in a background thread. This is not a panacea, and client code should be aware that 4131 + // 1. the thread may starve if some there are objects that have poorly performing 4132 + // `drop` methods or do significant work in their `drop` methods. 4133 + // 2. the thread is shared across the whole library. This can be tuned by using `android_cleaner = true`, 4134 + // or `android = true` in the [`kotlin` section of the `uniffi.toml` file](https://mozilla.github.io/uniffi-rs/kotlin/configuration.html). 4135 + // 4136 + // If we try to implement this with mutual exclusion on access to the pointer, there is the 4137 + // possibility of a race between a method call and a concurrent call to `destroy`: 4138 + // 4139 + // * Thread A starts a method call, reads the value of the pointer, but is interrupted 4140 + // before it can pass the pointer over the FFI to Rust. 4141 + // * Thread B calls `destroy` and frees the underlying Rust struct. 4142 + // * Thread A resumes, passing the already-read pointer value to Rust and triggering 4143 + // a use-after-free. 4144 + // 4145 + // One possible solution would be to use a `ReadWriteLock`, with each method call taking 4146 + // a read lock (and thus allowed to run concurrently) and the special `destroy` method 4147 + // taking a write lock (and thus blocking on live method calls). However, we aim not to 4148 + // generate methods with any hidden blocking semantics, and a `destroy` method that might 4149 + // block if called incorrectly seems to meet that bar. 4150 + // 4151 + // So, we achieve our goals by giving each instance an associated `AtomicLong` counter to track 4152 + // the number of in-flight method calls, and an `AtomicBoolean` flag to indicate whether `destroy` 4153 + // has been called. These are updated according to the following rules: 4154 + // 4155 + // * The initial value of the counter is 1, indicating a live object with no in-flight calls. 4156 + // The initial value for the flag is false. 4157 + // 4158 + // * At the start of each method call, we atomically check the counter. 4159 + // If it is 0 then the underlying Rust struct has already been destroyed and the call is aborted. 4160 + // If it is nonzero them we atomically increment it by 1 and proceed with the method call. 4161 + // 4162 + // * At the end of each method call, we atomically decrement and check the counter. 4163 + // If it has reached zero then we destroy the underlying Rust struct. 4164 + // 4165 + // * When `destroy` is called, we atomically flip the flag from false to true. 4166 + // If the flag was already true we silently fail. 4167 + // Otherwise we atomically decrement and check the counter. 4168 + // If it has reached zero then we destroy the underlying Rust struct. 4169 + // 4170 + // Astute readers may observe that this all sounds very similar to the way that Rust's `Arc<T>` works, 4171 + // and indeed it is, with the addition of a flag to guard against multiple calls to `destroy`. 4172 + // 4173 + // The overall effect is that the underlying Rust struct is destroyed only when `destroy` has been 4174 + // called *and* all in-flight method calls have completed, avoiding violating any of the expectations 4175 + // of the underlying Rust code. 4176 + // 4177 + // This makes a cleaner a better alternative to _not_ calling `destroy()` as 4178 + // and when the object is finished with, but the abstraction is not perfect: if the Rust object's `drop` 4179 + // method is slow, and/or there are many objects to cleanup, and it's on a low end Android device, then the cleaner 4180 + // thread may be starved, and the app will leak memory. 4181 + // 4182 + // In this case, `destroy`ing manually may be a better solution. 4183 + // 4184 + // The cleaner can live side by side with the manual calling of `destroy`. In the order of responsiveness, uniffi objects 4185 + // with Rust peers are reclaimed: 4186 + // 4187 + // 1. By calling the `destroy` method of the object, which calls `rustObject.free()`. If that doesn't happen: 4188 + // 2. When the object becomes unreachable, AND the Cleaner thread gets to call `rustObject.free()`. If the thread is starved then: 4189 + // 3. The memory is reclaimed when the process terminates. 4190 + // 4191 + // [1] https://stackoverflow.com/questions/24376768/can-java-finalize-an-object-when-it-is-still-in-scope/24380219 4192 + // 4193 + 4194 + 4195 + /** 4196 + * Authenticated `app.rocksky.library.*` client. A non-empty access token is 4197 + * mandatory — [`Library::new`] errors without one, so no library call can be 4198 + * made unauthenticated. Methods return the raw JSON payload as a string. 4199 + */ 4200 + public interface LibraryInterface { 4201 + 4202 + /** 4203 + * `app.rocksky.library.createPlaylist` — returns the raw JSON payload. 4204 + */ 4205 + fun `createPlaylist`(`name`: kotlin.String): kotlin.String 4206 + 4207 + /** 4208 + * `app.rocksky.library.deleteAlbum` — returns the raw JSON payload. 4209 + */ 4210 + fun `deleteAlbum`(`id`: kotlin.String): kotlin.String 4211 + 4212 + /** 4213 + * `app.rocksky.library.deletePlaylist` — returns the raw JSON payload. 4214 + */ 4215 + fun `deletePlaylist`(`id`: kotlin.String): kotlin.String 4216 + 4217 + /** 4218 + * `app.rocksky.library.deleteSong` — returns the raw JSON payload. 4219 + */ 4220 + fun `deleteSong`(`id`: kotlin.String): kotlin.String 4221 + 4222 + /** 4223 + * `app.rocksky.library.getAlbum` — returns the raw JSON payload. 4224 + */ 4225 + fun `getAlbum`(`id`: kotlin.String): kotlin.String 4226 + 4227 + /** 4228 + * `app.rocksky.library.getAlbumInfo` — returns the raw JSON payload. 4229 + */ 4230 + fun `getAlbumInfo`(`id`: kotlin.String): kotlin.String 4231 + 4232 + /** 4233 + * `app.rocksky.library.getAlbumList` — returns the raw JSON payload. 4234 + */ 4235 + fun `getAlbumList`(`type`: kotlin.String, `size`: kotlin.Long?, `offset`: kotlin.Long?, `fromYear`: kotlin.Long?, `toYear`: kotlin.Long?, `genre`: kotlin.String?): kotlin.String 4236 + 4237 + /** 4238 + * `app.rocksky.library.getArtist` — returns the raw JSON payload. 4239 + */ 4240 + fun `getArtist`(`id`: kotlin.String): kotlin.String 4241 + 4242 + /** 4243 + * `app.rocksky.library.getArtistInfo` — returns the raw JSON payload. 4244 + */ 4245 + fun `getArtistInfo`(`id`: kotlin.String): kotlin.String 4246 + 4247 + /** 4248 + * `app.rocksky.library.getArtists` — returns the raw JSON payload. 4249 + */ 4250 + fun `getArtists`(): kotlin.String 4251 + 4252 + /** 4253 + * `app.rocksky.library.getCoverArtUrl` — returns the raw JSON payload. 4254 + */ 4255 + fun `getCoverArtUrl`(`id`: kotlin.String, `size`: kotlin.Long?): kotlin.String 4256 + 4257 + /** 4258 + * `app.rocksky.library.getDownloadUrl` — returns the raw JSON payload. 4259 + */ 4260 + fun `getDownloadUrl`(`id`: kotlin.String): kotlin.String 4261 + 4262 + /** 4263 + * `app.rocksky.library.getGenres` — returns the raw JSON payload. 4264 + */ 4265 + fun `getGenres`(): kotlin.String 4266 + 4267 + /** 4268 + * `app.rocksky.library.getIndexes` — returns the raw JSON payload. 4269 + */ 4270 + fun `getIndexes`(): kotlin.String 4271 + 4272 + /** 4273 + * `app.rocksky.library.getInternetRadioStations` — returns the raw JSON payload. 4274 + */ 4275 + fun `getInternetRadioStations`(): kotlin.String 4276 + 4277 + /** 4278 + * `app.rocksky.library.getLicense` — returns the raw JSON payload. 4279 + */ 4280 + fun `getLicense`(): kotlin.String 4281 + 4282 + /** 4283 + * `app.rocksky.library.getLyrics` — returns the raw JSON payload. 4284 + */ 4285 + fun `getLyrics`(`artist`: kotlin.String?, `title`: kotlin.String?): kotlin.String 4286 + 4287 + /** 4288 + * `app.rocksky.library.getMusicDirectory` — returns the raw JSON payload. 4289 + */ 4290 + fun `getMusicDirectory`(`id`: kotlin.String): kotlin.String 4291 + 4292 + /** 4293 + * `app.rocksky.library.getMusicFolders` — returns the raw JSON payload. 4294 + */ 4295 + fun `getMusicFolders`(): kotlin.String 4296 + 4297 + /** 4298 + * `app.rocksky.library.getNowPlaying` — returns the raw JSON payload. 4299 + */ 4300 + fun `getNowPlaying`(): kotlin.String 4301 + 4302 + /** 4303 + * `app.rocksky.library.getPlayQueue` — returns the raw JSON payload. 4304 + */ 4305 + fun `getPlayQueue`(): kotlin.String 4306 + 4307 + /** 4308 + * `app.rocksky.library.getPlaylist` — returns the raw JSON payload. 4309 + */ 4310 + fun `getPlaylist`(`id`: kotlin.String): kotlin.String 4311 + 4312 + /** 4313 + * `app.rocksky.library.getPlaylists` — returns the raw JSON payload. 4314 + */ 4315 + fun `getPlaylists`(): kotlin.String 4316 + 4317 + /** 4318 + * `app.rocksky.library.getRandomSongs` — returns the raw JSON payload. 4319 + */ 4320 + fun `getRandomSongs`(`size`: kotlin.Long?, `genre`: kotlin.String?, `fromYear`: kotlin.Long?, `toYear`: kotlin.Long?): kotlin.String 4321 + 4322 + /** 4323 + * `app.rocksky.library.getScanStatus` — returns the raw JSON payload. 4324 + */ 4325 + fun `getScanStatus`(): kotlin.String 4326 + 4327 + /** 4328 + * `app.rocksky.library.getSimilarSongs` — returns the raw JSON payload. 4329 + */ 4330 + fun `getSimilarSongs`(`id`: kotlin.String, `count`: kotlin.Long?): kotlin.String 4331 + 4332 + /** 4333 + * `app.rocksky.library.getSong` — returns the raw JSON payload. 4334 + */ 4335 + fun `getSong`(`id`: kotlin.String): kotlin.String 4336 + 4337 + /** 4338 + * `app.rocksky.library.getSongsByGenre` — returns the raw JSON payload. 4339 + */ 4340 + fun `getSongsByGenre`(`genre`: kotlin.String, `count`: kotlin.Long?, `offset`: kotlin.Long?): kotlin.String 4341 + 4342 + /** 4343 + * `app.rocksky.library.getStarred` — returns the raw JSON payload. 4344 + */ 4345 + fun `getStarred`(): kotlin.String 4346 + 4347 + /** 4348 + * `app.rocksky.library.getStreamUrl` — returns the raw JSON payload. 4349 + */ 4350 + fun `getStreamUrl`(`id`: kotlin.String, `maxBitRate`: kotlin.Long?, `format`: kotlin.String?): kotlin.String 4351 + 4352 + /** 4353 + * `app.rocksky.library.getTopSongs` — returns the raw JSON payload. 4354 + */ 4355 + fun `getTopSongs`(`artist`: kotlin.String, `count`: kotlin.Long?): kotlin.String 4356 + 4357 + /** 4358 + * `app.rocksky.library.getUser` — returns the raw JSON payload. 4359 + */ 4360 + fun `getUser`(): kotlin.String 4361 + 4362 + /** 4363 + * `app.rocksky.library.ping` — returns the raw JSON payload. 4364 + */ 4365 + fun `ping`(): kotlin.String 4366 + 4367 + /** 4368 + * `app.rocksky.library.savePlayQueue` — returns the raw JSON payload. 4369 + */ 4370 + fun `savePlayQueue`(`id`: kotlin.String?, `current`: kotlin.String?, `position`: kotlin.Long?): kotlin.String 4371 + 4372 + /** 4373 + * `app.rocksky.library.scrobble` — returns the raw JSON payload. 4374 + */ 4375 + fun `scrobble`(`id`: kotlin.String, `time`: kotlin.Long?, `submission`: kotlin.Boolean?): kotlin.String 4376 + 4377 + /** 4378 + * `app.rocksky.library.search` — returns the raw JSON payload. 4379 + */ 4380 + fun `search`(`query`: kotlin.String, `artistCount`: kotlin.Long?, `artistOffset`: kotlin.Long?, `albumCount`: kotlin.Long?, `albumOffset`: kotlin.Long?, `songCount`: kotlin.Long?, `songOffset`: kotlin.Long?): kotlin.String 4381 + 4382 + /** 4383 + * `app.rocksky.library.star` — returns the raw JSON payload. 4384 + */ 4385 + fun `star`(`id`: kotlin.String, `albumId`: kotlin.String?, `artistId`: kotlin.String?): kotlin.String 4386 + 4387 + /** 4388 + * `app.rocksky.library.startScan` — returns the raw JSON payload. 4389 + */ 4390 + fun `startScan`(): kotlin.String 4391 + 4392 + /** 4393 + * `app.rocksky.library.unstar` — returns the raw JSON payload. 4394 + */ 4395 + fun `unstar`(`id`: kotlin.String, `albumId`: kotlin.String?, `artistId`: kotlin.String?): kotlin.String 4396 + 4397 + /** 4398 + * `app.rocksky.library.updateNowPlaying` — returns the raw JSON payload. 4399 + */ 4400 + fun `updateNowPlaying`(`id`: kotlin.String): kotlin.String 4401 + 4402 + /** 4403 + * `app.rocksky.library.updatePlaylist` — returns the raw JSON payload. 4404 + */ 4405 + fun `updatePlaylist`(`playlistId`: kotlin.String, `name`: kotlin.String?, `comment`: kotlin.String?, `songIdToAdd`: kotlin.String?, `songIndexToRemove`: kotlin.Long?): kotlin.String 4406 + 4407 + companion object 4408 + } 4409 + 4410 + /** 4411 + * Authenticated `app.rocksky.library.*` client. A non-empty access token is 4412 + * mandatory — [`Library::new`] errors without one, so no library call can be 4413 + * made unauthenticated. Methods return the raw JSON payload as a string. 4414 + */ 4415 + open class Library: Disposable, AutoCloseable, LibraryInterface { 4416 + 4417 + constructor(pointer: Pointer) { 4418 + this.pointer = pointer 4419 + this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) 4420 + } 4421 + 4422 + /** 4423 + * This constructor can be used to instantiate a fake object. Only used for tests. Any 4424 + * attempt to actually use an object constructed this way will fail as there is no 4425 + * connected Rust object. 4426 + */ 4427 + @Suppress("UNUSED_PARAMETER") 4428 + constructor(noPointer: NoPointer) { 4429 + this.pointer = null 4430 + this.cleanable = UniffiLib.CLEANER.register(this, UniffiCleanAction(pointer)) 4431 + } 4432 + /** 4433 + * Build against an AppView base (default when `None`) with the required 4434 + * bearer token. Errors if `token` is empty. 4435 + */ 4436 + constructor(`base`: kotlin.String?, `token`: kotlin.String) : 4437 + this( 4438 + uniffiRustCallWithError(RockskyException) { _status -> 4439 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_constructor_library_new( 4440 + FfiConverterOptionalString.lower(`base`),FfiConverterString.lower(`token`),_status) 4441 + } 4442 + ) 4443 + 4444 + protected val pointer: Pointer? 4445 + protected val cleanable: UniffiCleaner.Cleanable 4446 + 4447 + private val wasDestroyed = AtomicBoolean(false) 4448 + private val callCounter = AtomicLong(1) 4449 + 4450 + override fun destroy() { 4451 + // Only allow a single call to this method. 4452 + // TODO: maybe we should log a warning if called more than once? 4453 + if (this.wasDestroyed.compareAndSet(false, true)) { 4454 + // This decrement always matches the initial count of 1 given at creation time. 4455 + if (this.callCounter.decrementAndGet() == 0L) { 4456 + cleanable.clean() 4457 + } 4458 + } 4459 + } 4460 + 4461 + @Synchronized 4462 + override fun close() { 4463 + this.destroy() 4464 + } 4465 + 4466 + internal inline fun <R> callWithPointer(block: (ptr: Pointer) -> R): R { 4467 + // Check and increment the call counter, to keep the object alive. 4468 + // This needs a compare-and-set retry loop in case of concurrent updates. 4469 + do { 4470 + val c = this.callCounter.get() 4471 + if (c == 0L) { 4472 + throw IllegalStateException("${this.javaClass.simpleName} object has already been destroyed") 4473 + } 4474 + if (c == Long.MAX_VALUE) { 4475 + throw IllegalStateException("${this.javaClass.simpleName} call counter would overflow") 4476 + } 4477 + } while (! this.callCounter.compareAndSet(c, c + 1L)) 4478 + // Now we can safely do the method call without the pointer being freed concurrently. 4479 + try { 4480 + return block(this.uniffiClonePointer()) 4481 + } finally { 4482 + // This decrement always matches the increment we performed above. 4483 + if (this.callCounter.decrementAndGet() == 0L) { 4484 + cleanable.clean() 4485 + } 4486 + } 4487 + } 4488 + 4489 + // Use a static inner class instead of a closure so as not to accidentally 4490 + // capture `this` as part of the cleanable's action. 4491 + private class UniffiCleanAction(private val pointer: Pointer?) : Runnable { 4492 + override fun run() { 4493 + pointer?.let { ptr -> 4494 + uniffiRustCall { status -> 4495 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_free_library(ptr, status) 4496 + } 4497 + } 4498 + } 4499 + } 4500 + 4501 + fun uniffiClonePointer(): Pointer { 4502 + return uniffiRustCall() { status -> 4503 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_clone_library(pointer!!, status) 4504 + } 4505 + } 4506 + 4507 + 4508 + /** 4509 + * `app.rocksky.library.createPlaylist` — returns the raw JSON payload. 4510 + */ 4511 + @Throws(RockskyException::class)override fun `createPlaylist`(`name`: kotlin.String): kotlin.String { 4512 + return FfiConverterString.lift( 4513 + callWithPointer { 4514 + uniffiRustCallWithError(RockskyException) { _status -> 4515 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_create_playlist( 4516 + it, FfiConverterString.lower(`name`),_status) 4517 + } 4518 + } 4519 + ) 4520 + } 4521 + 4522 + 4523 + 4524 + /** 4525 + * `app.rocksky.library.deleteAlbum` — returns the raw JSON payload. 4526 + */ 4527 + @Throws(RockskyException::class)override fun `deleteAlbum`(`id`: kotlin.String): kotlin.String { 4528 + return FfiConverterString.lift( 4529 + callWithPointer { 4530 + uniffiRustCallWithError(RockskyException) { _status -> 4531 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_delete_album( 4532 + it, FfiConverterString.lower(`id`),_status) 4533 + } 4534 + } 4535 + ) 4536 + } 4537 + 4538 + 4539 + 4540 + /** 4541 + * `app.rocksky.library.deletePlaylist` — returns the raw JSON payload. 4542 + */ 4543 + @Throws(RockskyException::class)override fun `deletePlaylist`(`id`: kotlin.String): kotlin.String { 4544 + return FfiConverterString.lift( 4545 + callWithPointer { 4546 + uniffiRustCallWithError(RockskyException) { _status -> 4547 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_delete_playlist( 4548 + it, FfiConverterString.lower(`id`),_status) 4549 + } 4550 + } 4551 + ) 4552 + } 4553 + 4554 + 4555 + 4556 + /** 4557 + * `app.rocksky.library.deleteSong` — returns the raw JSON payload. 4558 + */ 4559 + @Throws(RockskyException::class)override fun `deleteSong`(`id`: kotlin.String): kotlin.String { 4560 + return FfiConverterString.lift( 4561 + callWithPointer { 4562 + uniffiRustCallWithError(RockskyException) { _status -> 4563 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_delete_song( 4564 + it, FfiConverterString.lower(`id`),_status) 4565 + } 4566 + } 4567 + ) 4568 + } 4569 + 4570 + 4571 + 4572 + /** 4573 + * `app.rocksky.library.getAlbum` — returns the raw JSON payload. 4574 + */ 4575 + @Throws(RockskyException::class)override fun `getAlbum`(`id`: kotlin.String): kotlin.String { 4576 + return FfiConverterString.lift( 4577 + callWithPointer { 4578 + uniffiRustCallWithError(RockskyException) { _status -> 4579 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_album( 4580 + it, FfiConverterString.lower(`id`),_status) 4581 + } 4582 + } 4583 + ) 4584 + } 4585 + 4586 + 4587 + 4588 + /** 4589 + * `app.rocksky.library.getAlbumInfo` — returns the raw JSON payload. 4590 + */ 4591 + @Throws(RockskyException::class)override fun `getAlbumInfo`(`id`: kotlin.String): kotlin.String { 4592 + return FfiConverterString.lift( 4593 + callWithPointer { 4594 + uniffiRustCallWithError(RockskyException) { _status -> 4595 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_album_info( 4596 + it, FfiConverterString.lower(`id`),_status) 4597 + } 4598 + } 4599 + ) 4600 + } 4601 + 4602 + 4603 + 4604 + /** 4605 + * `app.rocksky.library.getAlbumList` — returns the raw JSON payload. 4606 + */ 4607 + @Throws(RockskyException::class)override fun `getAlbumList`(`type`: kotlin.String, `size`: kotlin.Long?, `offset`: kotlin.Long?, `fromYear`: kotlin.Long?, `toYear`: kotlin.Long?, `genre`: kotlin.String?): kotlin.String { 4608 + return FfiConverterString.lift( 4609 + callWithPointer { 4610 + uniffiRustCallWithError(RockskyException) { _status -> 4611 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_album_list( 4612 + it, FfiConverterString.lower(`type`),FfiConverterOptionalLong.lower(`size`),FfiConverterOptionalLong.lower(`offset`),FfiConverterOptionalLong.lower(`fromYear`),FfiConverterOptionalLong.lower(`toYear`),FfiConverterOptionalString.lower(`genre`),_status) 4613 + } 4614 + } 4615 + ) 4616 + } 4617 + 4618 + 4619 + 4620 + /** 4621 + * `app.rocksky.library.getArtist` — returns the raw JSON payload. 4622 + */ 4623 + @Throws(RockskyException::class)override fun `getArtist`(`id`: kotlin.String): kotlin.String { 4624 + return FfiConverterString.lift( 4625 + callWithPointer { 4626 + uniffiRustCallWithError(RockskyException) { _status -> 4627 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_artist( 4628 + it, FfiConverterString.lower(`id`),_status) 4629 + } 4630 + } 4631 + ) 4632 + } 4633 + 4634 + 4635 + 4636 + /** 4637 + * `app.rocksky.library.getArtistInfo` — returns the raw JSON payload. 4638 + */ 4639 + @Throws(RockskyException::class)override fun `getArtistInfo`(`id`: kotlin.String): kotlin.String { 4640 + return FfiConverterString.lift( 4641 + callWithPointer { 4642 + uniffiRustCallWithError(RockskyException) { _status -> 4643 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_artist_info( 4644 + it, FfiConverterString.lower(`id`),_status) 4645 + } 4646 + } 4647 + ) 4648 + } 4649 + 4650 + 4651 + 4652 + /** 4653 + * `app.rocksky.library.getArtists` — returns the raw JSON payload. 4654 + */ 4655 + @Throws(RockskyException::class)override fun `getArtists`(): kotlin.String { 4656 + return FfiConverterString.lift( 4657 + callWithPointer { 4658 + uniffiRustCallWithError(RockskyException) { _status -> 4659 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_artists( 4660 + it, _status) 4661 + } 4662 + } 4663 + ) 4664 + } 4665 + 4666 + 4667 + 4668 + /** 4669 + * `app.rocksky.library.getCoverArtUrl` — returns the raw JSON payload. 4670 + */ 4671 + @Throws(RockskyException::class)override fun `getCoverArtUrl`(`id`: kotlin.String, `size`: kotlin.Long?): kotlin.String { 4672 + return FfiConverterString.lift( 4673 + callWithPointer { 4674 + uniffiRustCallWithError(RockskyException) { _status -> 4675 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_cover_art_url( 4676 + it, FfiConverterString.lower(`id`),FfiConverterOptionalLong.lower(`size`),_status) 4677 + } 4678 + } 4679 + ) 4680 + } 4681 + 4682 + 4683 + 4684 + /** 4685 + * `app.rocksky.library.getDownloadUrl` — returns the raw JSON payload. 4686 + */ 4687 + @Throws(RockskyException::class)override fun `getDownloadUrl`(`id`: kotlin.String): kotlin.String { 4688 + return FfiConverterString.lift( 4689 + callWithPointer { 4690 + uniffiRustCallWithError(RockskyException) { _status -> 4691 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_download_url( 4692 + it, FfiConverterString.lower(`id`),_status) 4693 + } 4694 + } 4695 + ) 4696 + } 4697 + 4698 + 4699 + 4700 + /** 4701 + * `app.rocksky.library.getGenres` — returns the raw JSON payload. 4702 + */ 4703 + @Throws(RockskyException::class)override fun `getGenres`(): kotlin.String { 4704 + return FfiConverterString.lift( 4705 + callWithPointer { 4706 + uniffiRustCallWithError(RockskyException) { _status -> 4707 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_genres( 4708 + it, _status) 4709 + } 4710 + } 4711 + ) 4712 + } 4713 + 4714 + 4715 + 4716 + /** 4717 + * `app.rocksky.library.getIndexes` — returns the raw JSON payload. 4718 + */ 4719 + @Throws(RockskyException::class)override fun `getIndexes`(): kotlin.String { 4720 + return FfiConverterString.lift( 4721 + callWithPointer { 4722 + uniffiRustCallWithError(RockskyException) { _status -> 4723 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_indexes( 4724 + it, _status) 4725 + } 4726 + } 4727 + ) 4728 + } 4729 + 4730 + 4731 + 4732 + /** 4733 + * `app.rocksky.library.getInternetRadioStations` — returns the raw JSON payload. 4734 + */ 4735 + @Throws(RockskyException::class)override fun `getInternetRadioStations`(): kotlin.String { 4736 + return FfiConverterString.lift( 4737 + callWithPointer { 4738 + uniffiRustCallWithError(RockskyException) { _status -> 4739 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_internet_radio_stations( 4740 + it, _status) 4741 + } 4742 + } 4743 + ) 4744 + } 4745 + 4746 + 4747 + 4748 + /** 4749 + * `app.rocksky.library.getLicense` — returns the raw JSON payload. 4750 + */ 4751 + @Throws(RockskyException::class)override fun `getLicense`(): kotlin.String { 4752 + return FfiConverterString.lift( 4753 + callWithPointer { 4754 + uniffiRustCallWithError(RockskyException) { _status -> 4755 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_license( 4756 + it, _status) 4757 + } 4758 + } 4759 + ) 4760 + } 4761 + 4762 + 4763 + 4764 + /** 4765 + * `app.rocksky.library.getLyrics` — returns the raw JSON payload. 4766 + */ 4767 + @Throws(RockskyException::class)override fun `getLyrics`(`artist`: kotlin.String?, `title`: kotlin.String?): kotlin.String { 4768 + return FfiConverterString.lift( 4769 + callWithPointer { 4770 + uniffiRustCallWithError(RockskyException) { _status -> 4771 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_lyrics( 4772 + it, FfiConverterOptionalString.lower(`artist`),FfiConverterOptionalString.lower(`title`),_status) 4773 + } 4774 + } 4775 + ) 4776 + } 4777 + 4778 + 4779 + 4780 + /** 4781 + * `app.rocksky.library.getMusicDirectory` — returns the raw JSON payload. 4782 + */ 4783 + @Throws(RockskyException::class)override fun `getMusicDirectory`(`id`: kotlin.String): kotlin.String { 4784 + return FfiConverterString.lift( 4785 + callWithPointer { 4786 + uniffiRustCallWithError(RockskyException) { _status -> 4787 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_music_directory( 4788 + it, FfiConverterString.lower(`id`),_status) 4789 + } 4790 + } 4791 + ) 4792 + } 4793 + 4794 + 4795 + 4796 + /** 4797 + * `app.rocksky.library.getMusicFolders` — returns the raw JSON payload. 4798 + */ 4799 + @Throws(RockskyException::class)override fun `getMusicFolders`(): kotlin.String { 4800 + return FfiConverterString.lift( 4801 + callWithPointer { 4802 + uniffiRustCallWithError(RockskyException) { _status -> 4803 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_music_folders( 4804 + it, _status) 4805 + } 4806 + } 4807 + ) 4808 + } 4809 + 4810 + 4811 + 4812 + /** 4813 + * `app.rocksky.library.getNowPlaying` — returns the raw JSON payload. 4814 + */ 4815 + @Throws(RockskyException::class)override fun `getNowPlaying`(): kotlin.String { 4816 + return FfiConverterString.lift( 4817 + callWithPointer { 4818 + uniffiRustCallWithError(RockskyException) { _status -> 4819 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_now_playing( 4820 + it, _status) 4821 + } 4822 + } 4823 + ) 4824 + } 4825 + 4826 + 4827 + 4828 + /** 4829 + * `app.rocksky.library.getPlayQueue` — returns the raw JSON payload. 4830 + */ 4831 + @Throws(RockskyException::class)override fun `getPlayQueue`(): kotlin.String { 4832 + return FfiConverterString.lift( 4833 + callWithPointer { 4834 + uniffiRustCallWithError(RockskyException) { _status -> 4835 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_play_queue( 4836 + it, _status) 4837 + } 4838 + } 4839 + ) 4840 + } 4841 + 4842 + 4843 + 4844 + /** 4845 + * `app.rocksky.library.getPlaylist` — returns the raw JSON payload. 4846 + */ 4847 + @Throws(RockskyException::class)override fun `getPlaylist`(`id`: kotlin.String): kotlin.String { 4848 + return FfiConverterString.lift( 4849 + callWithPointer { 4850 + uniffiRustCallWithError(RockskyException) { _status -> 4851 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_playlist( 4852 + it, FfiConverterString.lower(`id`),_status) 4853 + } 4854 + } 4855 + ) 4856 + } 4857 + 4858 + 4859 + 4860 + /** 4861 + * `app.rocksky.library.getPlaylists` — returns the raw JSON payload. 4862 + */ 4863 + @Throws(RockskyException::class)override fun `getPlaylists`(): kotlin.String { 4864 + return FfiConverterString.lift( 4865 + callWithPointer { 4866 + uniffiRustCallWithError(RockskyException) { _status -> 4867 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_playlists( 4868 + it, _status) 4869 + } 4870 + } 4871 + ) 4872 + } 4873 + 4874 + 4875 + 4876 + /** 4877 + * `app.rocksky.library.getRandomSongs` — returns the raw JSON payload. 4878 + */ 4879 + @Throws(RockskyException::class)override fun `getRandomSongs`(`size`: kotlin.Long?, `genre`: kotlin.String?, `fromYear`: kotlin.Long?, `toYear`: kotlin.Long?): kotlin.String { 4880 + return FfiConverterString.lift( 4881 + callWithPointer { 4882 + uniffiRustCallWithError(RockskyException) { _status -> 4883 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_random_songs( 4884 + it, FfiConverterOptionalLong.lower(`size`),FfiConverterOptionalString.lower(`genre`),FfiConverterOptionalLong.lower(`fromYear`),FfiConverterOptionalLong.lower(`toYear`),_status) 4885 + } 4886 + } 4887 + ) 4888 + } 4889 + 4890 + 4891 + 4892 + /** 4893 + * `app.rocksky.library.getScanStatus` — returns the raw JSON payload. 4894 + */ 4895 + @Throws(RockskyException::class)override fun `getScanStatus`(): kotlin.String { 4896 + return FfiConverterString.lift( 4897 + callWithPointer { 4898 + uniffiRustCallWithError(RockskyException) { _status -> 4899 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_scan_status( 4900 + it, _status) 4901 + } 4902 + } 4903 + ) 4904 + } 4905 + 4906 + 4907 + 4908 + /** 4909 + * `app.rocksky.library.getSimilarSongs` — returns the raw JSON payload. 4910 + */ 4911 + @Throws(RockskyException::class)override fun `getSimilarSongs`(`id`: kotlin.String, `count`: kotlin.Long?): kotlin.String { 4912 + return FfiConverterString.lift( 4913 + callWithPointer { 4914 + uniffiRustCallWithError(RockskyException) { _status -> 4915 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_similar_songs( 4916 + it, FfiConverterString.lower(`id`),FfiConverterOptionalLong.lower(`count`),_status) 4917 + } 4918 + } 4919 + ) 4920 + } 4921 + 4922 + 4923 + 4924 + /** 4925 + * `app.rocksky.library.getSong` — returns the raw JSON payload. 4926 + */ 4927 + @Throws(RockskyException::class)override fun `getSong`(`id`: kotlin.String): kotlin.String { 4928 + return FfiConverterString.lift( 4929 + callWithPointer { 4930 + uniffiRustCallWithError(RockskyException) { _status -> 4931 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_song( 4932 + it, FfiConverterString.lower(`id`),_status) 4933 + } 4934 + } 4935 + ) 4936 + } 4937 + 4938 + 4939 + 4940 + /** 4941 + * `app.rocksky.library.getSongsByGenre` — returns the raw JSON payload. 4942 + */ 4943 + @Throws(RockskyException::class)override fun `getSongsByGenre`(`genre`: kotlin.String, `count`: kotlin.Long?, `offset`: kotlin.Long?): kotlin.String { 4944 + return FfiConverterString.lift( 4945 + callWithPointer { 4946 + uniffiRustCallWithError(RockskyException) { _status -> 4947 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_songs_by_genre( 4948 + it, FfiConverterString.lower(`genre`),FfiConverterOptionalLong.lower(`count`),FfiConverterOptionalLong.lower(`offset`),_status) 4949 + } 4950 + } 4951 + ) 4952 + } 4953 + 4954 + 4955 + 4956 + /** 4957 + * `app.rocksky.library.getStarred` — returns the raw JSON payload. 4958 + */ 4959 + @Throws(RockskyException::class)override fun `getStarred`(): kotlin.String { 4960 + return FfiConverterString.lift( 4961 + callWithPointer { 4962 + uniffiRustCallWithError(RockskyException) { _status -> 4963 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_starred( 4964 + it, _status) 4965 + } 4966 + } 4967 + ) 4968 + } 4969 + 4970 + 4971 + 4972 + /** 4973 + * `app.rocksky.library.getStreamUrl` — returns the raw JSON payload. 4974 + */ 4975 + @Throws(RockskyException::class)override fun `getStreamUrl`(`id`: kotlin.String, `maxBitRate`: kotlin.Long?, `format`: kotlin.String?): kotlin.String { 4976 + return FfiConverterString.lift( 4977 + callWithPointer { 4978 + uniffiRustCallWithError(RockskyException) { _status -> 4979 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_stream_url( 4980 + it, FfiConverterString.lower(`id`),FfiConverterOptionalLong.lower(`maxBitRate`),FfiConverterOptionalString.lower(`format`),_status) 4981 + } 4982 + } 4983 + ) 4984 + } 4985 + 4986 + 4987 + 4988 + /** 4989 + * `app.rocksky.library.getTopSongs` — returns the raw JSON payload. 4990 + */ 4991 + @Throws(RockskyException::class)override fun `getTopSongs`(`artist`: kotlin.String, `count`: kotlin.Long?): kotlin.String { 4992 + return FfiConverterString.lift( 4993 + callWithPointer { 4994 + uniffiRustCallWithError(RockskyException) { _status -> 4995 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_top_songs( 4996 + it, FfiConverterString.lower(`artist`),FfiConverterOptionalLong.lower(`count`),_status) 4997 + } 4998 + } 4999 + ) 5000 + } 5001 + 5002 + 5003 + 5004 + /** 5005 + * `app.rocksky.library.getUser` — returns the raw JSON payload. 5006 + */ 5007 + @Throws(RockskyException::class)override fun `getUser`(): kotlin.String { 5008 + return FfiConverterString.lift( 5009 + callWithPointer { 5010 + uniffiRustCallWithError(RockskyException) { _status -> 5011 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_get_user( 5012 + it, _status) 5013 + } 5014 + } 5015 + ) 5016 + } 5017 + 5018 + 5019 + 5020 + /** 5021 + * `app.rocksky.library.ping` — returns the raw JSON payload. 5022 + */ 5023 + @Throws(RockskyException::class)override fun `ping`(): kotlin.String { 5024 + return FfiConverterString.lift( 5025 + callWithPointer { 5026 + uniffiRustCallWithError(RockskyException) { _status -> 5027 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_ping( 5028 + it, _status) 5029 + } 5030 + } 5031 + ) 5032 + } 5033 + 5034 + 5035 + 5036 + /** 5037 + * `app.rocksky.library.savePlayQueue` — returns the raw JSON payload. 5038 + */ 5039 + @Throws(RockskyException::class)override fun `savePlayQueue`(`id`: kotlin.String?, `current`: kotlin.String?, `position`: kotlin.Long?): kotlin.String { 5040 + return FfiConverterString.lift( 5041 + callWithPointer { 5042 + uniffiRustCallWithError(RockskyException) { _status -> 5043 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_save_play_queue( 5044 + it, FfiConverterOptionalString.lower(`id`),FfiConverterOptionalString.lower(`current`),FfiConverterOptionalLong.lower(`position`),_status) 5045 + } 5046 + } 5047 + ) 5048 + } 5049 + 5050 + 5051 + 5052 + /** 5053 + * `app.rocksky.library.scrobble` — returns the raw JSON payload. 5054 + */ 5055 + @Throws(RockskyException::class)override fun `scrobble`(`id`: kotlin.String, `time`: kotlin.Long?, `submission`: kotlin.Boolean?): kotlin.String { 5056 + return FfiConverterString.lift( 5057 + callWithPointer { 5058 + uniffiRustCallWithError(RockskyException) { _status -> 5059 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_scrobble( 5060 + it, FfiConverterString.lower(`id`),FfiConverterOptionalLong.lower(`time`),FfiConverterOptionalBoolean.lower(`submission`),_status) 5061 + } 5062 + } 5063 + ) 5064 + } 5065 + 5066 + 5067 + 5068 + /** 5069 + * `app.rocksky.library.search` — returns the raw JSON payload. 5070 + */ 5071 + @Throws(RockskyException::class)override fun `search`(`query`: kotlin.String, `artistCount`: kotlin.Long?, `artistOffset`: kotlin.Long?, `albumCount`: kotlin.Long?, `albumOffset`: kotlin.Long?, `songCount`: kotlin.Long?, `songOffset`: kotlin.Long?): kotlin.String { 5072 + return FfiConverterString.lift( 5073 + callWithPointer { 5074 + uniffiRustCallWithError(RockskyException) { _status -> 5075 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_search( 5076 + it, FfiConverterString.lower(`query`),FfiConverterOptionalLong.lower(`artistCount`),FfiConverterOptionalLong.lower(`artistOffset`),FfiConverterOptionalLong.lower(`albumCount`),FfiConverterOptionalLong.lower(`albumOffset`),FfiConverterOptionalLong.lower(`songCount`),FfiConverterOptionalLong.lower(`songOffset`),_status) 5077 + } 5078 + } 5079 + ) 5080 + } 5081 + 5082 + 5083 + 5084 + /** 5085 + * `app.rocksky.library.star` — returns the raw JSON payload. 5086 + */ 5087 + @Throws(RockskyException::class)override fun `star`(`id`: kotlin.String, `albumId`: kotlin.String?, `artistId`: kotlin.String?): kotlin.String { 5088 + return FfiConverterString.lift( 5089 + callWithPointer { 5090 + uniffiRustCallWithError(RockskyException) { _status -> 5091 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_star( 5092 + it, FfiConverterString.lower(`id`),FfiConverterOptionalString.lower(`albumId`),FfiConverterOptionalString.lower(`artistId`),_status) 5093 + } 5094 + } 5095 + ) 5096 + } 5097 + 5098 + 5099 + 5100 + /** 5101 + * `app.rocksky.library.startScan` — returns the raw JSON payload. 5102 + */ 5103 + @Throws(RockskyException::class)override fun `startScan`(): kotlin.String { 5104 + return FfiConverterString.lift( 5105 + callWithPointer { 5106 + uniffiRustCallWithError(RockskyException) { _status -> 5107 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_start_scan( 5108 + it, _status) 5109 + } 5110 + } 5111 + ) 5112 + } 5113 + 5114 + 5115 + 5116 + /** 5117 + * `app.rocksky.library.unstar` — returns the raw JSON payload. 5118 + */ 5119 + @Throws(RockskyException::class)override fun `unstar`(`id`: kotlin.String, `albumId`: kotlin.String?, `artistId`: kotlin.String?): kotlin.String { 5120 + return FfiConverterString.lift( 5121 + callWithPointer { 5122 + uniffiRustCallWithError(RockskyException) { _status -> 5123 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_unstar( 5124 + it, FfiConverterString.lower(`id`),FfiConverterOptionalString.lower(`albumId`),FfiConverterOptionalString.lower(`artistId`),_status) 5125 + } 5126 + } 5127 + ) 5128 + } 5129 + 5130 + 5131 + 5132 + /** 5133 + * `app.rocksky.library.updateNowPlaying` — returns the raw JSON payload. 5134 + */ 5135 + @Throws(RockskyException::class)override fun `updateNowPlaying`(`id`: kotlin.String): kotlin.String { 5136 + return FfiConverterString.lift( 5137 + callWithPointer { 5138 + uniffiRustCallWithError(RockskyException) { _status -> 5139 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_update_now_playing( 5140 + it, FfiConverterString.lower(`id`),_status) 5141 + } 5142 + } 5143 + ) 5144 + } 5145 + 5146 + 5147 + 5148 + /** 5149 + * `app.rocksky.library.updatePlaylist` — returns the raw JSON payload. 5150 + */ 5151 + @Throws(RockskyException::class)override fun `updatePlaylist`(`playlistId`: kotlin.String, `name`: kotlin.String?, `comment`: kotlin.String?, `songIdToAdd`: kotlin.String?, `songIndexToRemove`: kotlin.Long?): kotlin.String { 5152 + return FfiConverterString.lift( 5153 + callWithPointer { 5154 + uniffiRustCallWithError(RockskyException) { _status -> 5155 + UniffiLib.INSTANCE.uniffi_rocksky_uniffi_fn_method_library_update_playlist( 5156 + it, FfiConverterString.lower(`playlistId`),FfiConverterOptionalString.lower(`name`),FfiConverterOptionalString.lower(`comment`),FfiConverterOptionalString.lower(`songIdToAdd`),FfiConverterOptionalLong.lower(`songIndexToRemove`),_status) 5157 + } 5158 + } 5159 + ) 5160 + } 5161 + 5162 + 5163 + 5164 + 5165 + 5166 + 5167 + companion object 5168 + 5169 + } 5170 + 5171 + /** 5172 + * @suppress 5173 + */ 5174 + public object FfiConverterTypeLibrary: FfiConverter<Library, Pointer> { 5175 + 5176 + override fun lower(value: Library): Pointer { 5177 + return value.uniffiClonePointer() 5178 + } 5179 + 5180 + override fun lift(value: Pointer): Library { 5181 + return Library(value) 5182 + } 5183 + 5184 + override fun read(buf: ByteBuffer): Library { 5185 + // The Rust code always writes pointers as 8 bytes, and will 5186 + // fail to compile if they don't fit. 5187 + return lift(Pointer(buf.getLong())) 5188 + } 5189 + 5190 + override fun allocationSize(value: Library) = 8UL 5191 + 5192 + override fun write(value: Library, buf: ByteBuffer) { 5193 + // The Rust code always expects pointers written as 8 bytes, 5194 + // and will fail to compile if they don't fit. 5195 + buf.putLong(Pointer.nativeValue(lower(value))) 5196 + } 5197 + } 5198 + 5199 + 3553 5200 3554 5201 /** 3555 5202 * An album record (`app.rocksky.album`); `artist` is the album artist. ··· 3831 5478 3832 5479 3833 5480 /** 5481 + * The user who triggered a notification 5482 + * (`app.rocksky.notification.defs#notificationActor`). 5483 + */ 5484 + data class NotificationActor ( 5485 + var `id`: kotlin.String?, 5486 + var `did`: kotlin.String?, 5487 + var `handle`: kotlin.String?, 5488 + var `displayName`: kotlin.String?, 5489 + var `avatar`: kotlin.String? 5490 + ) { 5491 + 5492 + companion object 5493 + } 5494 + 5495 + /** 5496 + * @suppress 5497 + */ 5498 + public object FfiConverterTypeNotificationActor: FfiConverterRustBuffer<NotificationActor> { 5499 + override fun read(buf: ByteBuffer): NotificationActor { 5500 + return NotificationActor( 5501 + FfiConverterOptionalString.read(buf), 5502 + FfiConverterOptionalString.read(buf), 5503 + FfiConverterOptionalString.read(buf), 5504 + FfiConverterOptionalString.read(buf), 5505 + FfiConverterOptionalString.read(buf), 5506 + ) 5507 + } 5508 + 5509 + override fun allocationSize(value: NotificationActor) = ( 5510 + FfiConverterOptionalString.allocationSize(value.`id`) + 5511 + FfiConverterOptionalString.allocationSize(value.`did`) + 5512 + FfiConverterOptionalString.allocationSize(value.`handle`) + 5513 + FfiConverterOptionalString.allocationSize(value.`displayName`) + 5514 + FfiConverterOptionalString.allocationSize(value.`avatar`) 5515 + ) 5516 + 5517 + override fun write(value: NotificationActor, buf: ByteBuffer) { 5518 + FfiConverterOptionalString.write(value.`id`, buf) 5519 + FfiConverterOptionalString.write(value.`did`, buf) 5520 + FfiConverterOptionalString.write(value.`handle`, buf) 5521 + FfiConverterOptionalString.write(value.`displayName`, buf) 5522 + FfiConverterOptionalString.write(value.`avatar`, buf) 5523 + } 5524 + } 5525 + 5526 + 5527 + 5528 + /** 5529 + * A page of notifications (`app.rocksky.notification.listNotifications`). 5530 + */ 5531 + data class NotificationList ( 5532 + var `notifications`: List<NotificationView>, 5533 + /** 5534 + * The number of unread notifications. 5535 + */ 5536 + var `unreadCount`: kotlin.Long, 5537 + /** 5538 + * Cursor to pass to the next call for the following page. 5539 + */ 5540 + var `cursor`: kotlin.String? 5541 + ) { 5542 + 5543 + companion object 5544 + } 5545 + 5546 + /** 5547 + * @suppress 5548 + */ 5549 + public object FfiConverterTypeNotificationList: FfiConverterRustBuffer<NotificationList> { 5550 + override fun read(buf: ByteBuffer): NotificationList { 5551 + return NotificationList( 5552 + FfiConverterSequenceTypeNotificationView.read(buf), 5553 + FfiConverterLong.read(buf), 5554 + FfiConverterOptionalString.read(buf), 5555 + ) 5556 + } 5557 + 5558 + override fun allocationSize(value: NotificationList) = ( 5559 + FfiConverterSequenceTypeNotificationView.allocationSize(value.`notifications`) + 5560 + FfiConverterLong.allocationSize(value.`unreadCount`) + 5561 + FfiConverterOptionalString.allocationSize(value.`cursor`) 5562 + ) 5563 + 5564 + override fun write(value: NotificationList, buf: ByteBuffer) { 5565 + FfiConverterSequenceTypeNotificationView.write(value.`notifications`, buf) 5566 + FfiConverterLong.write(value.`unreadCount`, buf) 5567 + FfiConverterOptionalString.write(value.`cursor`, buf) 5568 + } 5569 + } 5570 + 5571 + 5572 + 5573 + /** 5574 + * A single notification (`app.rocksky.notification.defs#notificationView`). 5575 + */ 5576 + data class NotificationView ( 5577 + var `id`: kotlin.String, 5578 + /** 5579 + * One of `like_scrobble`, `follow`, `comment_scrobble`, `comment_profile`, 5580 + * `reply`, `react_comment`. 5581 + */ 5582 + var `notificationType`: kotlin.String, 5583 + /** 5584 + * Whether the notification has been viewed. 5585 + */ 5586 + var `read`: kotlin.Boolean, 5587 + var `createdAt`: kotlin.String, 5588 + var `subjectUri`: kotlin.String?, 5589 + var `shoutId`: kotlin.String?, 5590 + var `shoutContent`: kotlin.String?, 5591 + var `actor`: NotificationActor? 5592 + ) { 5593 + 5594 + companion object 5595 + } 5596 + 5597 + /** 5598 + * @suppress 5599 + */ 5600 + public object FfiConverterTypeNotificationView: FfiConverterRustBuffer<NotificationView> { 5601 + override fun read(buf: ByteBuffer): NotificationView { 5602 + return NotificationView( 5603 + FfiConverterString.read(buf), 5604 + FfiConverterString.read(buf), 5605 + FfiConverterBoolean.read(buf), 5606 + FfiConverterString.read(buf), 5607 + FfiConverterOptionalString.read(buf), 5608 + FfiConverterOptionalString.read(buf), 5609 + FfiConverterOptionalString.read(buf), 5610 + FfiConverterOptionalTypeNotificationActor.read(buf), 5611 + ) 5612 + } 5613 + 5614 + override fun allocationSize(value: NotificationView) = ( 5615 + FfiConverterString.allocationSize(value.`id`) + 5616 + FfiConverterString.allocationSize(value.`notificationType`) + 5617 + FfiConverterBoolean.allocationSize(value.`read`) + 5618 + FfiConverterString.allocationSize(value.`createdAt`) + 5619 + FfiConverterOptionalString.allocationSize(value.`subjectUri`) + 5620 + FfiConverterOptionalString.allocationSize(value.`shoutId`) + 5621 + FfiConverterOptionalString.allocationSize(value.`shoutContent`) + 5622 + FfiConverterOptionalTypeNotificationActor.allocationSize(value.`actor`) 5623 + ) 5624 + 5625 + override fun write(value: NotificationView, buf: ByteBuffer) { 5626 + FfiConverterString.write(value.`id`, buf) 5627 + FfiConverterString.write(value.`notificationType`, buf) 5628 + FfiConverterBoolean.write(value.`read`, buf) 5629 + FfiConverterString.write(value.`createdAt`, buf) 5630 + FfiConverterOptionalString.write(value.`subjectUri`, buf) 5631 + FfiConverterOptionalString.write(value.`shoutId`, buf) 5632 + FfiConverterOptionalString.write(value.`shoutContent`, buf) 5633 + FfiConverterOptionalTypeNotificationActor.write(value.`actor`, buf) 5634 + } 5635 + } 5636 + 5637 + 5638 + 5639 + /** 3834 5640 * The now-playing track (`app.rocksky.actor.status`). 3835 5641 */ 3836 5642 data class NowPlayingInput ( ··· 4291 6097 4292 6098 4293 6099 /** 6100 + * A GIF / sticker / clip to attach to a shout 6101 + * (`app.rocksky.shout.defs#gif`). Only `url` is required. 6102 + */ 6103 + data class ShoutGifInput ( 6104 + /** 6105 + * Direct URL of the animated GIF/MP4. 6106 + */ 6107 + var `url`: kotlin.String, 6108 + /** 6109 + * Smaller still / preview image URL. 6110 + */ 6111 + var `previewUrl`: kotlin.String? = null, 6112 + /** 6113 + * Alternative text describing the media. 6114 + */ 6115 + var `alt`: kotlin.String? = null, 6116 + var `width`: kotlin.Long? = null, 6117 + var `height`: kotlin.Long? = null 6118 + ) { 6119 + 6120 + companion object 6121 + } 6122 + 6123 + /** 6124 + * @suppress 6125 + */ 6126 + public object FfiConverterTypeShoutGifInput: FfiConverterRustBuffer<ShoutGifInput> { 6127 + override fun read(buf: ByteBuffer): ShoutGifInput { 6128 + return ShoutGifInput( 6129 + FfiConverterString.read(buf), 6130 + FfiConverterOptionalString.read(buf), 6131 + FfiConverterOptionalString.read(buf), 6132 + FfiConverterOptionalLong.read(buf), 6133 + FfiConverterOptionalLong.read(buf), 6134 + ) 6135 + } 6136 + 6137 + override fun allocationSize(value: ShoutGifInput) = ( 6138 + FfiConverterString.allocationSize(value.`url`) + 6139 + FfiConverterOptionalString.allocationSize(value.`previewUrl`) + 6140 + FfiConverterOptionalString.allocationSize(value.`alt`) + 6141 + FfiConverterOptionalLong.allocationSize(value.`width`) + 6142 + FfiConverterOptionalLong.allocationSize(value.`height`) 6143 + ) 6144 + 6145 + override fun write(value: ShoutGifInput, buf: ByteBuffer) { 6146 + FfiConverterString.write(value.`url`, buf) 6147 + FfiConverterOptionalString.write(value.`previewUrl`, buf) 6148 + FfiConverterOptionalString.write(value.`alt`, buf) 6149 + FfiConverterOptionalLong.write(value.`width`, buf) 6150 + FfiConverterOptionalLong.write(value.`height`, buf) 6151 + } 6152 + } 6153 + 6154 + 6155 + 6156 + /** 4294 6157 * A canonical track record (`app.rocksky.song`). 4295 6158 */ 4296 6159 data class SongInput ( ··· 4477 6340 4478 6341 4479 6342 /** 6343 + * The unread-notification count (`app.rocksky.notification.getUnreadCount`). 6344 + */ 6345 + data class UnreadCount ( 6346 + var `count`: kotlin.Long 6347 + ) { 6348 + 6349 + companion object 6350 + } 6351 + 6352 + /** 6353 + * @suppress 6354 + */ 6355 + public object FfiConverterTypeUnreadCount: FfiConverterRustBuffer<UnreadCount> { 6356 + override fun read(buf: ByteBuffer): UnreadCount { 6357 + return UnreadCount( 6358 + FfiConverterLong.read(buf), 6359 + ) 6360 + } 6361 + 6362 + override fun allocationSize(value: UnreadCount) = ( 6363 + FfiConverterLong.allocationSize(value.`count`) 6364 + ) 6365 + 6366 + override fun write(value: UnreadCount, buf: ByteBuffer) { 6367 + FfiConverterLong.write(value.`count`, buf) 6368 + } 6369 + } 6370 + 6371 + 6372 + 6373 + /** 6374 + * The result of marking notifications seen 6375 + * (`app.rocksky.notification.updateSeen`). 6376 + */ 6377 + data class UpdateSeenResult ( 6378 + /** 6379 + * The number of unread notifications remaining. 6380 + */ 6381 + var `unreadCount`: kotlin.Long 6382 + ) { 6383 + 6384 + companion object 6385 + } 6386 + 6387 + /** 6388 + * @suppress 6389 + */ 6390 + public object FfiConverterTypeUpdateSeenResult: FfiConverterRustBuffer<UpdateSeenResult> { 6391 + override fun read(buf: ByteBuffer): UpdateSeenResult { 6392 + return UpdateSeenResult( 6393 + FfiConverterLong.read(buf), 6394 + ) 6395 + } 6396 + 6397 + override fun allocationSize(value: UpdateSeenResult) = ( 6398 + FfiConverterLong.allocationSize(value.`unreadCount`) 6399 + ) 6400 + 6401 + override fun write(value: UpdateSeenResult, buf: ByteBuffer) { 6402 + FfiConverterLong.write(value.`unreadCount`, buf) 6403 + } 6404 + } 6405 + 6406 + 6407 + 6408 + /** 4480 6409 * A typed date window for the `top_*` charts. `Range` bounds are RFC-3339 4481 6410 * datetimes (e.g. `2026-01-01T00:00:00Z`). 4482 6411 */ ··· 4855 6784 /** 4856 6785 * @suppress 4857 6786 */ 6787 + public object FfiConverterOptionalTypeNotificationActor: FfiConverterRustBuffer<NotificationActor?> { 6788 + override fun read(buf: ByteBuffer): NotificationActor? { 6789 + if (buf.get().toInt() == 0) { 6790 + return null 6791 + } 6792 + return FfiConverterTypeNotificationActor.read(buf) 6793 + } 6794 + 6795 + override fun allocationSize(value: NotificationActor?): ULong { 6796 + if (value == null) { 6797 + return 1UL 6798 + } else { 6799 + return 1UL + FfiConverterTypeNotificationActor.allocationSize(value) 6800 + } 6801 + } 6802 + 6803 + override fun write(value: NotificationActor?, buf: ByteBuffer) { 6804 + if (value == null) { 6805 + buf.put(0) 6806 + } else { 6807 + buf.put(1) 6808 + FfiConverterTypeNotificationActor.write(value, buf) 6809 + } 6810 + } 6811 + } 6812 + 6813 + 6814 + 6815 + 6816 + /** 6817 + * @suppress 6818 + */ 4858 6819 public object FfiConverterOptionalTypeProfile: FfiConverterRustBuffer<Profile?> { 4859 6820 override fun read(buf: ByteBuffer): Profile? { 4860 6821 if (buf.get().toInt() == 0) { ··· 4887 6848 /** 4888 6849 * @suppress 4889 6850 */ 6851 + public object FfiConverterOptionalTypeShoutGifInput: FfiConverterRustBuffer<ShoutGifInput?> { 6852 + override fun read(buf: ByteBuffer): ShoutGifInput? { 6853 + if (buf.get().toInt() == 0) { 6854 + return null 6855 + } 6856 + return FfiConverterTypeShoutGifInput.read(buf) 6857 + } 6858 + 6859 + override fun allocationSize(value: ShoutGifInput?): ULong { 6860 + if (value == null) { 6861 + return 1UL 6862 + } else { 6863 + return 1UL + FfiConverterTypeShoutGifInput.allocationSize(value) 6864 + } 6865 + } 6866 + 6867 + override fun write(value: ShoutGifInput?, buf: ByteBuffer) { 6868 + if (value == null) { 6869 + buf.put(0) 6870 + } else { 6871 + buf.put(1) 6872 + FfiConverterTypeShoutGifInput.write(value, buf) 6873 + } 6874 + } 6875 + } 6876 + 6877 + 6878 + 6879 + 6880 + /** 6881 + * @suppress 6882 + */ 4890 6883 public object FfiConverterSequenceString: FfiConverterRustBuffer<List<kotlin.String>> { 4891 6884 override fun read(buf: ByteBuffer): List<kotlin.String> { 4892 6885 val len = buf.getInt() ··· 4961 6954 buf.putInt(value.size) 4962 6955 value.iterator().forEach { 4963 6956 FfiConverterTypeArtistView.write(it, buf) 6957 + } 6958 + } 6959 + } 6960 + 6961 + 6962 + 6963 + 6964 + /** 6965 + * @suppress 6966 + */ 6967 + public object FfiConverterSequenceTypeNotificationView: FfiConverterRustBuffer<List<NotificationView>> { 6968 + override fun read(buf: ByteBuffer): List<NotificationView> { 6969 + val len = buf.getInt() 6970 + return List<NotificationView>(len) { 6971 + FfiConverterTypeNotificationView.read(buf) 6972 + } 6973 + } 6974 + 6975 + override fun allocationSize(value: List<NotificationView>): ULong { 6976 + val sizeForLength = 4UL 6977 + val sizeForItems = value.map { FfiConverterTypeNotificationView.allocationSize(it) }.sum() 6978 + return sizeForLength + sizeForItems 6979 + } 6980 + 6981 + override fun write(value: List<NotificationView>, buf: ByteBuffer) { 6982 + buf.putInt(value.size) 6983 + value.iterator().forEach { 6984 + FfiConverterTypeNotificationView.write(it, buf) 4964 6985 } 4965 6986 } 4966 6987 }
+1 -1
sdk/python/pyproject.toml
··· 1 1 [project] 2 2 name = "rocksky" 3 - version = "0.7.0" 3 + version = "0.8.0" 4 4 description = "Python SDK for Rocksky — native bindings to the shared Rust core" 5 5 readme = "README.md" 6 6 license = { text = "MIT" }
+2193
sdk/python/src/rocksky/rocksky_uniffi.py
··· 489 489 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 490 490 if lib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout() != 29470: 491 491 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 492 + if lib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout_with_gif() != 30347: 493 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 492 494 if lib.uniffi_rocksky_uniffi_checksum_method_agent_scrobble() != 17314: 493 495 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 494 496 if lib.uniffi_rocksky_uniffi_checksum_method_agent_scrobble_match() != 139: ··· 496 498 if lib.uniffi_rocksky_uniffi_checksum_method_agent_set_now_playing() != 46985: 497 499 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 498 500 if lib.uniffi_rocksky_uniffi_checksum_method_agent_shout() != 41382: 501 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 502 + if lib.uniffi_rocksky_uniffi_checksum_method_agent_shout_with_gif() != 51807: 499 503 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 500 504 if lib.uniffi_rocksky_uniffi_checksum_method_agent_sync_repo() != 33910: 501 505 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") ··· 569 573 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 570 574 if lib.uniffi_rocksky_uniffi_checksum_method_appview_neighbours() != 57546: 571 575 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 576 + if lib.uniffi_rocksky_uniffi_checksum_method_appview_notifications() != 60047: 577 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 572 578 if lib.uniffi_rocksky_uniffi_checksum_method_appview_playback_queue() != 32322: 573 579 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 574 580 if lib.uniffi_rocksky_uniffi_checksum_method_appview_playlist() != 2389: ··· 615 621 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 616 622 if lib.uniffi_rocksky_uniffi_checksum_method_appview_track_shouts() != 8713: 617 623 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 624 + if lib.uniffi_rocksky_uniffi_checksum_method_appview_unread_count() != 41669: 625 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 626 + if lib.uniffi_rocksky_uniffi_checksum_method_appview_update_seen() != 15297: 627 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 618 628 if lib.uniffi_rocksky_uniffi_checksum_method_appview_wrapped() != 63835: 619 629 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 630 + if lib.uniffi_rocksky_uniffi_checksum_method_library_create_playlist() != 1198: 631 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 632 + if lib.uniffi_rocksky_uniffi_checksum_method_library_delete_album() != 61199: 633 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 634 + if lib.uniffi_rocksky_uniffi_checksum_method_library_delete_playlist() != 22674: 635 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 636 + if lib.uniffi_rocksky_uniffi_checksum_method_library_delete_song() != 65357: 637 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 638 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_album() != 29404: 639 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 640 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_album_info() != 52466: 641 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 642 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_album_list() != 40173: 643 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 644 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_artist() != 29339: 645 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 646 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_artist_info() != 16237: 647 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 648 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_artists() != 28277: 649 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 650 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_cover_art_url() != 4983: 651 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 652 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_download_url() != 28146: 653 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 654 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_genres() != 59896: 655 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 656 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_indexes() != 12238: 657 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 658 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_internet_radio_stations() != 55752: 659 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 660 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_license() != 5838: 661 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 662 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_lyrics() != 38380: 663 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 664 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_music_directory() != 52674: 665 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 666 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_music_folders() != 17682: 667 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 668 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_now_playing() != 36367: 669 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 670 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_play_queue() != 65057: 671 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 672 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_playlist() != 64635: 673 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 674 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_playlists() != 42853: 675 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 676 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_random_songs() != 50256: 677 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 678 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_scan_status() != 65363: 679 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 680 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_similar_songs() != 43677: 681 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 682 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_song() != 35370: 683 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 684 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_songs_by_genre() != 55810: 685 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 686 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_starred() != 42756: 687 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 688 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_stream_url() != 25069: 689 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 690 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_top_songs() != 31996: 691 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 692 + if lib.uniffi_rocksky_uniffi_checksum_method_library_get_user() != 22213: 693 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 694 + if lib.uniffi_rocksky_uniffi_checksum_method_library_ping() != 50138: 695 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 696 + if lib.uniffi_rocksky_uniffi_checksum_method_library_save_play_queue() != 48102: 697 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 698 + if lib.uniffi_rocksky_uniffi_checksum_method_library_scrobble() != 2804: 699 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 700 + if lib.uniffi_rocksky_uniffi_checksum_method_library_search() != 53170: 701 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 702 + if lib.uniffi_rocksky_uniffi_checksum_method_library_star() != 19540: 703 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 704 + if lib.uniffi_rocksky_uniffi_checksum_method_library_start_scan() != 3950: 705 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 706 + if lib.uniffi_rocksky_uniffi_checksum_method_library_unstar() != 50111: 707 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 708 + if lib.uniffi_rocksky_uniffi_checksum_method_library_update_now_playing() != 58737: 709 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 710 + if lib.uniffi_rocksky_uniffi_checksum_method_library_update_playlist() != 33660: 711 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 620 712 if lib.uniffi_rocksky_uniffi_checksum_constructor_agent_login_password() != 59184: 621 713 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 622 714 if lib.uniffi_rocksky_uniffi_checksum_constructor_appview_new() != 526: 715 + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 716 + if lib.uniffi_rocksky_uniffi_checksum_constructor_library_new() != 16490: 623 717 raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") 624 718 625 719 # A ctypes library to expose the extern-C FFI definitions. ··· 812 906 ctypes.POINTER(_UniffiRustCallStatus), 813 907 ) 814 908 _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_reply_shout.restype = _UniffiRustBuffer 909 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_reply_shout_with_gif.argtypes = ( 910 + ctypes.c_void_p, 911 + _UniffiRustBuffer, 912 + _UniffiRustBuffer, 913 + _UniffiRustBuffer, 914 + _UniffiRustBuffer, 915 + _UniffiRustBuffer, 916 + _UniffiRustBuffer, 917 + ctypes.POINTER(_UniffiRustCallStatus), 918 + ) 919 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_reply_shout_with_gif.restype = _UniffiRustBuffer 815 920 _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_scrobble.argtypes = ( 816 921 ctypes.c_void_p, 817 922 _UniffiRustBuffer, ··· 838 943 ctypes.POINTER(_UniffiRustCallStatus), 839 944 ) 840 945 _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_shout.restype = _UniffiRustBuffer 946 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_shout_with_gif.argtypes = ( 947 + ctypes.c_void_p, 948 + _UniffiRustBuffer, 949 + _UniffiRustBuffer, 950 + _UniffiRustBuffer, 951 + _UniffiRustBuffer, 952 + ctypes.POINTER(_UniffiRustCallStatus), 953 + ) 954 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_shout_with_gif.restype = _UniffiRustBuffer 841 955 _UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_sync_repo.argtypes = ( 842 956 ctypes.c_void_p, 843 957 ctypes.POINTER(_UniffiRustCallStatus), ··· 1107 1221 ctypes.POINTER(_UniffiRustCallStatus), 1108 1222 ) 1109 1223 _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_neighbours.restype = _UniffiRustBuffer 1224 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_notifications.argtypes = ( 1225 + ctypes.c_void_p, 1226 + _UniffiRustBuffer, 1227 + _UniffiRustBuffer, 1228 + ctypes.POINTER(_UniffiRustCallStatus), 1229 + ) 1230 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_notifications.restype = _UniffiRustBuffer 1110 1231 _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_playback_queue.argtypes = ( 1111 1232 ctypes.c_void_p, 1112 1233 _UniffiRustBuffer, ··· 1277 1398 ctypes.POINTER(_UniffiRustCallStatus), 1278 1399 ) 1279 1400 _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_track_shouts.restype = _UniffiRustBuffer 1401 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_unread_count.argtypes = ( 1402 + ctypes.c_void_p, 1403 + ctypes.POINTER(_UniffiRustCallStatus), 1404 + ) 1405 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_unread_count.restype = _UniffiRustBuffer 1406 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_update_seen.argtypes = ( 1407 + ctypes.c_void_p, 1408 + _UniffiRustBuffer, 1409 + ctypes.POINTER(_UniffiRustCallStatus), 1410 + ) 1411 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_update_seen.restype = _UniffiRustBuffer 1280 1412 _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_wrapped.argtypes = ( 1281 1413 ctypes.c_void_p, 1282 1414 _UniffiRustBuffer, ··· 1284 1416 ctypes.POINTER(_UniffiRustCallStatus), 1285 1417 ) 1286 1418 _UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_wrapped.restype = _UniffiRustBuffer 1419 + _UniffiLib.uniffi_rocksky_uniffi_fn_clone_library.argtypes = ( 1420 + ctypes.c_void_p, 1421 + ctypes.POINTER(_UniffiRustCallStatus), 1422 + ) 1423 + _UniffiLib.uniffi_rocksky_uniffi_fn_clone_library.restype = ctypes.c_void_p 1424 + _UniffiLib.uniffi_rocksky_uniffi_fn_free_library.argtypes = ( 1425 + ctypes.c_void_p, 1426 + ctypes.POINTER(_UniffiRustCallStatus), 1427 + ) 1428 + _UniffiLib.uniffi_rocksky_uniffi_fn_free_library.restype = None 1429 + _UniffiLib.uniffi_rocksky_uniffi_fn_constructor_library_new.argtypes = ( 1430 + _UniffiRustBuffer, 1431 + _UniffiRustBuffer, 1432 + ctypes.POINTER(_UniffiRustCallStatus), 1433 + ) 1434 + _UniffiLib.uniffi_rocksky_uniffi_fn_constructor_library_new.restype = ctypes.c_void_p 1435 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_create_playlist.argtypes = ( 1436 + ctypes.c_void_p, 1437 + _UniffiRustBuffer, 1438 + ctypes.POINTER(_UniffiRustCallStatus), 1439 + ) 1440 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_create_playlist.restype = _UniffiRustBuffer 1441 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_album.argtypes = ( 1442 + ctypes.c_void_p, 1443 + _UniffiRustBuffer, 1444 + ctypes.POINTER(_UniffiRustCallStatus), 1445 + ) 1446 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_album.restype = _UniffiRustBuffer 1447 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_playlist.argtypes = ( 1448 + ctypes.c_void_p, 1449 + _UniffiRustBuffer, 1450 + ctypes.POINTER(_UniffiRustCallStatus), 1451 + ) 1452 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_playlist.restype = _UniffiRustBuffer 1453 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_song.argtypes = ( 1454 + ctypes.c_void_p, 1455 + _UniffiRustBuffer, 1456 + ctypes.POINTER(_UniffiRustCallStatus), 1457 + ) 1458 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_song.restype = _UniffiRustBuffer 1459 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album.argtypes = ( 1460 + ctypes.c_void_p, 1461 + _UniffiRustBuffer, 1462 + ctypes.POINTER(_UniffiRustCallStatus), 1463 + ) 1464 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album.restype = _UniffiRustBuffer 1465 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album_info.argtypes = ( 1466 + ctypes.c_void_p, 1467 + _UniffiRustBuffer, 1468 + ctypes.POINTER(_UniffiRustCallStatus), 1469 + ) 1470 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album_info.restype = _UniffiRustBuffer 1471 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album_list.argtypes = ( 1472 + ctypes.c_void_p, 1473 + _UniffiRustBuffer, 1474 + _UniffiRustBuffer, 1475 + _UniffiRustBuffer, 1476 + _UniffiRustBuffer, 1477 + _UniffiRustBuffer, 1478 + _UniffiRustBuffer, 1479 + ctypes.POINTER(_UniffiRustCallStatus), 1480 + ) 1481 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album_list.restype = _UniffiRustBuffer 1482 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artist.argtypes = ( 1483 + ctypes.c_void_p, 1484 + _UniffiRustBuffer, 1485 + ctypes.POINTER(_UniffiRustCallStatus), 1486 + ) 1487 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artist.restype = _UniffiRustBuffer 1488 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artist_info.argtypes = ( 1489 + ctypes.c_void_p, 1490 + _UniffiRustBuffer, 1491 + ctypes.POINTER(_UniffiRustCallStatus), 1492 + ) 1493 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artist_info.restype = _UniffiRustBuffer 1494 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artists.argtypes = ( 1495 + ctypes.c_void_p, 1496 + ctypes.POINTER(_UniffiRustCallStatus), 1497 + ) 1498 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artists.restype = _UniffiRustBuffer 1499 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_cover_art_url.argtypes = ( 1500 + ctypes.c_void_p, 1501 + _UniffiRustBuffer, 1502 + _UniffiRustBuffer, 1503 + ctypes.POINTER(_UniffiRustCallStatus), 1504 + ) 1505 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_cover_art_url.restype = _UniffiRustBuffer 1506 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_download_url.argtypes = ( 1507 + ctypes.c_void_p, 1508 + _UniffiRustBuffer, 1509 + ctypes.POINTER(_UniffiRustCallStatus), 1510 + ) 1511 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_download_url.restype = _UniffiRustBuffer 1512 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_genres.argtypes = ( 1513 + ctypes.c_void_p, 1514 + ctypes.POINTER(_UniffiRustCallStatus), 1515 + ) 1516 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_genres.restype = _UniffiRustBuffer 1517 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_indexes.argtypes = ( 1518 + ctypes.c_void_p, 1519 + ctypes.POINTER(_UniffiRustCallStatus), 1520 + ) 1521 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_indexes.restype = _UniffiRustBuffer 1522 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_internet_radio_stations.argtypes = ( 1523 + ctypes.c_void_p, 1524 + ctypes.POINTER(_UniffiRustCallStatus), 1525 + ) 1526 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_internet_radio_stations.restype = _UniffiRustBuffer 1527 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_license.argtypes = ( 1528 + ctypes.c_void_p, 1529 + ctypes.POINTER(_UniffiRustCallStatus), 1530 + ) 1531 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_license.restype = _UniffiRustBuffer 1532 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_lyrics.argtypes = ( 1533 + ctypes.c_void_p, 1534 + _UniffiRustBuffer, 1535 + _UniffiRustBuffer, 1536 + ctypes.POINTER(_UniffiRustCallStatus), 1537 + ) 1538 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_lyrics.restype = _UniffiRustBuffer 1539 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_music_directory.argtypes = ( 1540 + ctypes.c_void_p, 1541 + _UniffiRustBuffer, 1542 + ctypes.POINTER(_UniffiRustCallStatus), 1543 + ) 1544 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_music_directory.restype = _UniffiRustBuffer 1545 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_music_folders.argtypes = ( 1546 + ctypes.c_void_p, 1547 + ctypes.POINTER(_UniffiRustCallStatus), 1548 + ) 1549 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_music_folders.restype = _UniffiRustBuffer 1550 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_now_playing.argtypes = ( 1551 + ctypes.c_void_p, 1552 + ctypes.POINTER(_UniffiRustCallStatus), 1553 + ) 1554 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_now_playing.restype = _UniffiRustBuffer 1555 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_play_queue.argtypes = ( 1556 + ctypes.c_void_p, 1557 + ctypes.POINTER(_UniffiRustCallStatus), 1558 + ) 1559 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_play_queue.restype = _UniffiRustBuffer 1560 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_playlist.argtypes = ( 1561 + ctypes.c_void_p, 1562 + _UniffiRustBuffer, 1563 + ctypes.POINTER(_UniffiRustCallStatus), 1564 + ) 1565 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_playlist.restype = _UniffiRustBuffer 1566 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_playlists.argtypes = ( 1567 + ctypes.c_void_p, 1568 + ctypes.POINTER(_UniffiRustCallStatus), 1569 + ) 1570 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_playlists.restype = _UniffiRustBuffer 1571 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_random_songs.argtypes = ( 1572 + ctypes.c_void_p, 1573 + _UniffiRustBuffer, 1574 + _UniffiRustBuffer, 1575 + _UniffiRustBuffer, 1576 + _UniffiRustBuffer, 1577 + ctypes.POINTER(_UniffiRustCallStatus), 1578 + ) 1579 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_random_songs.restype = _UniffiRustBuffer 1580 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_scan_status.argtypes = ( 1581 + ctypes.c_void_p, 1582 + ctypes.POINTER(_UniffiRustCallStatus), 1583 + ) 1584 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_scan_status.restype = _UniffiRustBuffer 1585 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_similar_songs.argtypes = ( 1586 + ctypes.c_void_p, 1587 + _UniffiRustBuffer, 1588 + _UniffiRustBuffer, 1589 + ctypes.POINTER(_UniffiRustCallStatus), 1590 + ) 1591 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_similar_songs.restype = _UniffiRustBuffer 1592 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_song.argtypes = ( 1593 + ctypes.c_void_p, 1594 + _UniffiRustBuffer, 1595 + ctypes.POINTER(_UniffiRustCallStatus), 1596 + ) 1597 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_song.restype = _UniffiRustBuffer 1598 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_songs_by_genre.argtypes = ( 1599 + ctypes.c_void_p, 1600 + _UniffiRustBuffer, 1601 + _UniffiRustBuffer, 1602 + _UniffiRustBuffer, 1603 + ctypes.POINTER(_UniffiRustCallStatus), 1604 + ) 1605 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_songs_by_genre.restype = _UniffiRustBuffer 1606 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_starred.argtypes = ( 1607 + ctypes.c_void_p, 1608 + ctypes.POINTER(_UniffiRustCallStatus), 1609 + ) 1610 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_starred.restype = _UniffiRustBuffer 1611 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_stream_url.argtypes = ( 1612 + ctypes.c_void_p, 1613 + _UniffiRustBuffer, 1614 + _UniffiRustBuffer, 1615 + _UniffiRustBuffer, 1616 + ctypes.POINTER(_UniffiRustCallStatus), 1617 + ) 1618 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_stream_url.restype = _UniffiRustBuffer 1619 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_top_songs.argtypes = ( 1620 + ctypes.c_void_p, 1621 + _UniffiRustBuffer, 1622 + _UniffiRustBuffer, 1623 + ctypes.POINTER(_UniffiRustCallStatus), 1624 + ) 1625 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_top_songs.restype = _UniffiRustBuffer 1626 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_user.argtypes = ( 1627 + ctypes.c_void_p, 1628 + ctypes.POINTER(_UniffiRustCallStatus), 1629 + ) 1630 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_user.restype = _UniffiRustBuffer 1631 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_ping.argtypes = ( 1632 + ctypes.c_void_p, 1633 + ctypes.POINTER(_UniffiRustCallStatus), 1634 + ) 1635 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_ping.restype = _UniffiRustBuffer 1636 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_save_play_queue.argtypes = ( 1637 + ctypes.c_void_p, 1638 + _UniffiRustBuffer, 1639 + _UniffiRustBuffer, 1640 + _UniffiRustBuffer, 1641 + ctypes.POINTER(_UniffiRustCallStatus), 1642 + ) 1643 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_save_play_queue.restype = _UniffiRustBuffer 1644 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_scrobble.argtypes = ( 1645 + ctypes.c_void_p, 1646 + _UniffiRustBuffer, 1647 + _UniffiRustBuffer, 1648 + _UniffiRustBuffer, 1649 + ctypes.POINTER(_UniffiRustCallStatus), 1650 + ) 1651 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_scrobble.restype = _UniffiRustBuffer 1652 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_search.argtypes = ( 1653 + ctypes.c_void_p, 1654 + _UniffiRustBuffer, 1655 + _UniffiRustBuffer, 1656 + _UniffiRustBuffer, 1657 + _UniffiRustBuffer, 1658 + _UniffiRustBuffer, 1659 + _UniffiRustBuffer, 1660 + _UniffiRustBuffer, 1661 + ctypes.POINTER(_UniffiRustCallStatus), 1662 + ) 1663 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_search.restype = _UniffiRustBuffer 1664 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_star.argtypes = ( 1665 + ctypes.c_void_p, 1666 + _UniffiRustBuffer, 1667 + _UniffiRustBuffer, 1668 + _UniffiRustBuffer, 1669 + ctypes.POINTER(_UniffiRustCallStatus), 1670 + ) 1671 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_star.restype = _UniffiRustBuffer 1672 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_start_scan.argtypes = ( 1673 + ctypes.c_void_p, 1674 + ctypes.POINTER(_UniffiRustCallStatus), 1675 + ) 1676 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_start_scan.restype = _UniffiRustBuffer 1677 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_unstar.argtypes = ( 1678 + ctypes.c_void_p, 1679 + _UniffiRustBuffer, 1680 + _UniffiRustBuffer, 1681 + _UniffiRustBuffer, 1682 + ctypes.POINTER(_UniffiRustCallStatus), 1683 + ) 1684 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_unstar.restype = _UniffiRustBuffer 1685 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_update_now_playing.argtypes = ( 1686 + ctypes.c_void_p, 1687 + _UniffiRustBuffer, 1688 + ctypes.POINTER(_UniffiRustCallStatus), 1689 + ) 1690 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_update_now_playing.restype = _UniffiRustBuffer 1691 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_update_playlist.argtypes = ( 1692 + ctypes.c_void_p, 1693 + _UniffiRustBuffer, 1694 + _UniffiRustBuffer, 1695 + _UniffiRustBuffer, 1696 + _UniffiRustBuffer, 1697 + _UniffiRustBuffer, 1698 + ctypes.POINTER(_UniffiRustCallStatus), 1699 + ) 1700 + _UniffiLib.uniffi_rocksky_uniffi_fn_method_library_update_playlist.restype = _UniffiRustBuffer 1287 1701 _UniffiLib.uniffi_rocksky_uniffi_fn_func_album_hash.argtypes = ( 1288 1702 _UniffiRustBuffer, 1289 1703 _UniffiRustBuffer, ··· 1612 2026 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout.argtypes = ( 1613 2027 ) 1614 2028 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout.restype = ctypes.c_uint16 2029 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout_with_gif.argtypes = ( 2030 + ) 2031 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_reply_shout_with_gif.restype = ctypes.c_uint16 1615 2032 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_scrobble.argtypes = ( 1616 2033 ) 1617 2034 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_scrobble.restype = ctypes.c_uint16 ··· 1624 2041 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_shout.argtypes = ( 1625 2042 ) 1626 2043 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_shout.restype = ctypes.c_uint16 2044 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_shout_with_gif.argtypes = ( 2045 + ) 2046 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_shout_with_gif.restype = ctypes.c_uint16 1627 2047 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_sync_repo.argtypes = ( 1628 2048 ) 1629 2049 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_agent_sync_repo.restype = ctypes.c_uint16 ··· 1732 2152 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_neighbours.argtypes = ( 1733 2153 ) 1734 2154 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_neighbours.restype = ctypes.c_uint16 2155 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_notifications.argtypes = ( 2156 + ) 2157 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_notifications.restype = ctypes.c_uint16 1735 2158 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_playback_queue.argtypes = ( 1736 2159 ) 1737 2160 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_playback_queue.restype = ctypes.c_uint16 ··· 1801 2224 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_track_shouts.argtypes = ( 1802 2225 ) 1803 2226 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_track_shouts.restype = ctypes.c_uint16 2227 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_unread_count.argtypes = ( 2228 + ) 2229 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_unread_count.restype = ctypes.c_uint16 2230 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_update_seen.argtypes = ( 2231 + ) 2232 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_update_seen.restype = ctypes.c_uint16 1804 2233 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_wrapped.argtypes = ( 1805 2234 ) 1806 2235 _UniffiLib.uniffi_rocksky_uniffi_checksum_method_appview_wrapped.restype = ctypes.c_uint16 2236 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_create_playlist.argtypes = ( 2237 + ) 2238 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_create_playlist.restype = ctypes.c_uint16 2239 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_delete_album.argtypes = ( 2240 + ) 2241 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_delete_album.restype = ctypes.c_uint16 2242 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_delete_playlist.argtypes = ( 2243 + ) 2244 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_delete_playlist.restype = ctypes.c_uint16 2245 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_delete_song.argtypes = ( 2246 + ) 2247 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_delete_song.restype = ctypes.c_uint16 2248 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_album.argtypes = ( 2249 + ) 2250 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_album.restype = ctypes.c_uint16 2251 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_album_info.argtypes = ( 2252 + ) 2253 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_album_info.restype = ctypes.c_uint16 2254 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_album_list.argtypes = ( 2255 + ) 2256 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_album_list.restype = ctypes.c_uint16 2257 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_artist.argtypes = ( 2258 + ) 2259 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_artist.restype = ctypes.c_uint16 2260 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_artist_info.argtypes = ( 2261 + ) 2262 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_artist_info.restype = ctypes.c_uint16 2263 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_artists.argtypes = ( 2264 + ) 2265 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_artists.restype = ctypes.c_uint16 2266 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_cover_art_url.argtypes = ( 2267 + ) 2268 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_cover_art_url.restype = ctypes.c_uint16 2269 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_download_url.argtypes = ( 2270 + ) 2271 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_download_url.restype = ctypes.c_uint16 2272 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_genres.argtypes = ( 2273 + ) 2274 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_genres.restype = ctypes.c_uint16 2275 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_indexes.argtypes = ( 2276 + ) 2277 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_indexes.restype = ctypes.c_uint16 2278 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_internet_radio_stations.argtypes = ( 2279 + ) 2280 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_internet_radio_stations.restype = ctypes.c_uint16 2281 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_license.argtypes = ( 2282 + ) 2283 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_license.restype = ctypes.c_uint16 2284 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_lyrics.argtypes = ( 2285 + ) 2286 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_lyrics.restype = ctypes.c_uint16 2287 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_music_directory.argtypes = ( 2288 + ) 2289 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_music_directory.restype = ctypes.c_uint16 2290 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_music_folders.argtypes = ( 2291 + ) 2292 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_music_folders.restype = ctypes.c_uint16 2293 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_now_playing.argtypes = ( 2294 + ) 2295 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_now_playing.restype = ctypes.c_uint16 2296 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_play_queue.argtypes = ( 2297 + ) 2298 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_play_queue.restype = ctypes.c_uint16 2299 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_playlist.argtypes = ( 2300 + ) 2301 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_playlist.restype = ctypes.c_uint16 2302 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_playlists.argtypes = ( 2303 + ) 2304 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_playlists.restype = ctypes.c_uint16 2305 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_random_songs.argtypes = ( 2306 + ) 2307 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_random_songs.restype = ctypes.c_uint16 2308 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_scan_status.argtypes = ( 2309 + ) 2310 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_scan_status.restype = ctypes.c_uint16 2311 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_similar_songs.argtypes = ( 2312 + ) 2313 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_similar_songs.restype = ctypes.c_uint16 2314 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_song.argtypes = ( 2315 + ) 2316 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_song.restype = ctypes.c_uint16 2317 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_songs_by_genre.argtypes = ( 2318 + ) 2319 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_songs_by_genre.restype = ctypes.c_uint16 2320 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_starred.argtypes = ( 2321 + ) 2322 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_starred.restype = ctypes.c_uint16 2323 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_stream_url.argtypes = ( 2324 + ) 2325 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_stream_url.restype = ctypes.c_uint16 2326 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_top_songs.argtypes = ( 2327 + ) 2328 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_top_songs.restype = ctypes.c_uint16 2329 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_user.argtypes = ( 2330 + ) 2331 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_get_user.restype = ctypes.c_uint16 2332 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_ping.argtypes = ( 2333 + ) 2334 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_ping.restype = ctypes.c_uint16 2335 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_save_play_queue.argtypes = ( 2336 + ) 2337 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_save_play_queue.restype = ctypes.c_uint16 2338 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_scrobble.argtypes = ( 2339 + ) 2340 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_scrobble.restype = ctypes.c_uint16 2341 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_search.argtypes = ( 2342 + ) 2343 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_search.restype = ctypes.c_uint16 2344 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_star.argtypes = ( 2345 + ) 2346 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_star.restype = ctypes.c_uint16 2347 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_start_scan.argtypes = ( 2348 + ) 2349 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_start_scan.restype = ctypes.c_uint16 2350 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_unstar.argtypes = ( 2351 + ) 2352 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_unstar.restype = ctypes.c_uint16 2353 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_update_now_playing.argtypes = ( 2354 + ) 2355 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_update_now_playing.restype = ctypes.c_uint16 2356 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_update_playlist.argtypes = ( 2357 + ) 2358 + _UniffiLib.uniffi_rocksky_uniffi_checksum_method_library_update_playlist.restype = ctypes.c_uint16 1807 2359 _UniffiLib.uniffi_rocksky_uniffi_checksum_constructor_agent_login_password.argtypes = ( 1808 2360 ) 1809 2361 _UniffiLib.uniffi_rocksky_uniffi_checksum_constructor_agent_login_password.restype = ctypes.c_uint16 1810 2362 _UniffiLib.uniffi_rocksky_uniffi_checksum_constructor_appview_new.argtypes = ( 1811 2363 ) 1812 2364 _UniffiLib.uniffi_rocksky_uniffi_checksum_constructor_appview_new.restype = ctypes.c_uint16 2365 + _UniffiLib.uniffi_rocksky_uniffi_checksum_constructor_library_new.argtypes = ( 2366 + ) 2367 + _UniffiLib.uniffi_rocksky_uniffi_checksum_constructor_library_new.restype = ctypes.c_uint16 1813 2368 _UniffiLib.ffi_rocksky_uniffi_uniffi_contract_version.argtypes = ( 1814 2369 ) 1815 2370 _UniffiLib.ffi_rocksky_uniffi_uniffi_contract_version.restype = ctypes.c_uint32 ··· 1966 2521 """ 1967 2522 1968 2523 raise NotImplementedError 2524 + def reply_shout_with_gif(self, subject_uri: "str",subject_cid: "str",parent_uri: "str",parent_cid: "str",message: "typing.Optional[str]",gif: "typing.Optional[ShoutGifInput]"): 2525 + """ 2526 + Reply to a shout with an optional GIF/sticker/clip attachment. Pass at 2527 + least one of `message` / `gif`. Returns the shout URI. 2528 + """ 2529 + 2530 + raise NotImplementedError 1969 2531 def scrobble(self, input: "ScrobbleInput"): 1970 2532 """ 1971 2533 Scrobble a play — fans out to artist/album/song then the scrobble. ··· 1988 2550 def shout(self, subject_uri: "str",subject_cid: "str",message: "str"): 1989 2551 """ 1990 2552 Post a shout on a subject. Returns the shout URI. 2553 + """ 2554 + 2555 + raise NotImplementedError 2556 + def shout_with_gif(self, subject_uri: "str",subject_cid: "str",message: "typing.Optional[str]",gif: "typing.Optional[ShoutGifInput]"): 2557 + """ 2558 + Post a shout with an optional GIF/sticker/clip attachment. Pass at least 2559 + one of `message` / `gif`. Returns the shout URI. 1991 2560 """ 1992 2561 1993 2562 raise NotImplementedError ··· 2215 2784 2216 2785 2217 2786 2787 + def reply_shout_with_gif(self, subject_uri: "str",subject_cid: "str",parent_uri: "str",parent_cid: "str",message: "typing.Optional[str]",gif: "typing.Optional[ShoutGifInput]") -> "str": 2788 + """ 2789 + Reply to a shout with an optional GIF/sticker/clip attachment. Pass at 2790 + least one of `message` / `gif`. Returns the shout URI. 2791 + """ 2792 + 2793 + _UniffiConverterString.check_lower(subject_uri) 2794 + 2795 + _UniffiConverterString.check_lower(subject_cid) 2796 + 2797 + _UniffiConverterString.check_lower(parent_uri) 2798 + 2799 + _UniffiConverterString.check_lower(parent_cid) 2800 + 2801 + _UniffiConverterOptionalString.check_lower(message) 2802 + 2803 + _UniffiConverterOptionalTypeShoutGifInput.check_lower(gif) 2804 + 2805 + return _UniffiConverterString.lift( 2806 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_reply_shout_with_gif,self._uniffi_clone_pointer(), 2807 + _UniffiConverterString.lower(subject_uri), 2808 + _UniffiConverterString.lower(subject_cid), 2809 + _UniffiConverterString.lower(parent_uri), 2810 + _UniffiConverterString.lower(parent_cid), 2811 + _UniffiConverterOptionalString.lower(message), 2812 + _UniffiConverterOptionalTypeShoutGifInput.lower(gif)) 2813 + ) 2814 + 2815 + 2816 + 2817 + 2818 + 2218 2819 def scrobble(self, input: "ScrobbleInput") -> "ScrobbleResult": 2219 2820 """ 2220 2821 Scrobble a play — fans out to artist/album/song then the scrobble. ··· 2285 2886 2286 2887 2287 2888 2889 + def shout_with_gif(self, subject_uri: "str",subject_cid: "str",message: "typing.Optional[str]",gif: "typing.Optional[ShoutGifInput]") -> "str": 2890 + """ 2891 + Post a shout with an optional GIF/sticker/clip attachment. Pass at least 2892 + one of `message` / `gif`. Returns the shout URI. 2893 + """ 2894 + 2895 + _UniffiConverterString.check_lower(subject_uri) 2896 + 2897 + _UniffiConverterString.check_lower(subject_cid) 2898 + 2899 + _UniffiConverterOptionalString.check_lower(message) 2900 + 2901 + _UniffiConverterOptionalTypeShoutGifInput.check_lower(gif) 2902 + 2903 + return _UniffiConverterString.lift( 2904 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_agent_shout_with_gif,self._uniffi_clone_pointer(), 2905 + _UniffiConverterString.lower(subject_uri), 2906 + _UniffiConverterString.lower(subject_cid), 2907 + _UniffiConverterOptionalString.lower(message), 2908 + _UniffiConverterOptionalTypeShoutGifInput.lower(gif)) 2909 + ) 2910 + 2911 + 2912 + 2913 + 2914 + 2288 2915 def sync_repo(self, ) -> "str": 2289 2916 """ 2290 2917 Download the caller's repo (CAR) and (re)build the local dedup index, ··· 2433 3060 raise NotImplementedError 2434 3061 def neighbours(self, actor: "str"): 2435 3062 raise NotImplementedError 3063 + def notifications(self, limit: "typing.Optional[int]",cursor: "typing.Optional[str]"): 3064 + """ 3065 + The authenticated viewer's notifications, most recent first 3066 + (`app.rocksky.notification.listNotifications`). `limit` defaults to 30. 3067 + """ 3068 + 3069 + raise NotImplementedError 2436 3070 def playback_queue(self, player_id: "str"): 2437 3071 raise NotImplementedError 2438 3072 def playlist(self, uri: "str"): ··· 2486 3120 2487 3121 raise NotImplementedError 2488 3122 def track_shouts(self, uri: "str"): 3123 + raise NotImplementedError 3124 + def unread_count(self, ): 3125 + """ 3126 + The authenticated viewer's unread-notification count 3127 + (`app.rocksky.notification.getUnreadCount`). 3128 + """ 3129 + 3130 + raise NotImplementedError 3131 + def update_seen(self, ids: "typing.List[str]"): 3132 + """ 3133 + Mark notifications as viewed (`app.rocksky.notification.updateSeen`). Pass 3134 + the ids to mark, or an empty list to mark **all** as viewed. 3135 + """ 3136 + 2489 3137 raise NotImplementedError 2490 3138 def wrapped(self, actor: "str",year: "typing.Optional[int]"): 2491 3139 raise NotImplementedError ··· 3049 3697 3050 3698 3051 3699 3700 + def notifications(self, limit: "typing.Optional[int]",cursor: "typing.Optional[str]") -> "NotificationList": 3701 + """ 3702 + The authenticated viewer's notifications, most recent first 3703 + (`app.rocksky.notification.listNotifications`). `limit` defaults to 30. 3704 + """ 3705 + 3706 + _UniffiConverterOptionalUInt32.check_lower(limit) 3707 + 3708 + _UniffiConverterOptionalString.check_lower(cursor) 3709 + 3710 + return _UniffiConverterTypeNotificationList.lift( 3711 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_notifications,self._uniffi_clone_pointer(), 3712 + _UniffiConverterOptionalUInt32.lower(limit), 3713 + _UniffiConverterOptionalString.lower(cursor)) 3714 + ) 3715 + 3716 + 3717 + 3718 + 3719 + 3052 3720 def playback_queue(self, player_id: "str") -> "str": 3053 3721 _UniffiConverterString.check_lower(player_id) 3054 3722 ··· 3429 4097 3430 4098 3431 4099 4100 + def unread_count(self, ) -> "UnreadCount": 4101 + """ 4102 + The authenticated viewer's unread-notification count 4103 + (`app.rocksky.notification.getUnreadCount`). 4104 + """ 4105 + 4106 + return _UniffiConverterTypeUnreadCount.lift( 4107 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_unread_count,self._uniffi_clone_pointer(),) 4108 + ) 4109 + 4110 + 4111 + 4112 + 4113 + 4114 + def update_seen(self, ids: "typing.List[str]") -> "UpdateSeenResult": 4115 + """ 4116 + Mark notifications as viewed (`app.rocksky.notification.updateSeen`). Pass 4117 + the ids to mark, or an empty list to mark **all** as viewed. 4118 + """ 4119 + 4120 + _UniffiConverterSequenceString.check_lower(ids) 4121 + 4122 + return _UniffiConverterTypeUpdateSeenResult.lift( 4123 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_appview_update_seen,self._uniffi_clone_pointer(), 4124 + _UniffiConverterSequenceString.lower(ids)) 4125 + ) 4126 + 4127 + 4128 + 4129 + 4130 + 3432 4131 def wrapped(self, actor: "str",year: "typing.Optional[int]") -> "str": 3433 4132 _UniffiConverterString.check_lower(actor) 3434 4133 ··· 3474 4173 buf.write_u64(cls.lower(value)) 3475 4174 3476 4175 4176 + 4177 + class LibraryProtocol(typing.Protocol): 4178 + """ 4179 + Authenticated `app.rocksky.library.*` client. A non-empty access token is 4180 + mandatory — [`Library::new`] errors without one, so no library call can be 4181 + made unauthenticated. Methods return the raw JSON payload as a string. 4182 + """ 4183 + 4184 + def create_playlist(self, name: "str"): 4185 + """ 4186 + `app.rocksky.library.createPlaylist` — returns the raw JSON payload. 4187 + """ 4188 + 4189 + raise NotImplementedError 4190 + def delete_album(self, id: "str"): 4191 + """ 4192 + `app.rocksky.library.deleteAlbum` — returns the raw JSON payload. 4193 + """ 4194 + 4195 + raise NotImplementedError 4196 + def delete_playlist(self, id: "str"): 4197 + """ 4198 + `app.rocksky.library.deletePlaylist` — returns the raw JSON payload. 4199 + """ 4200 + 4201 + raise NotImplementedError 4202 + def delete_song(self, id: "str"): 4203 + """ 4204 + `app.rocksky.library.deleteSong` — returns the raw JSON payload. 4205 + """ 4206 + 4207 + raise NotImplementedError 4208 + def get_album(self, id: "str"): 4209 + """ 4210 + `app.rocksky.library.getAlbum` — returns the raw JSON payload. 4211 + """ 4212 + 4213 + raise NotImplementedError 4214 + def get_album_info(self, id: "str"): 4215 + """ 4216 + `app.rocksky.library.getAlbumInfo` — returns the raw JSON payload. 4217 + """ 4218 + 4219 + raise NotImplementedError 4220 + def get_album_list(self, type: "str",size: "typing.Optional[int]",offset: "typing.Optional[int]",from_year: "typing.Optional[int]",to_year: "typing.Optional[int]",genre: "typing.Optional[str]"): 4221 + """ 4222 + `app.rocksky.library.getAlbumList` — returns the raw JSON payload. 4223 + """ 4224 + 4225 + raise NotImplementedError 4226 + def get_artist(self, id: "str"): 4227 + """ 4228 + `app.rocksky.library.getArtist` — returns the raw JSON payload. 4229 + """ 4230 + 4231 + raise NotImplementedError 4232 + def get_artist_info(self, id: "str"): 4233 + """ 4234 + `app.rocksky.library.getArtistInfo` — returns the raw JSON payload. 4235 + """ 4236 + 4237 + raise NotImplementedError 4238 + def get_artists(self, ): 4239 + """ 4240 + `app.rocksky.library.getArtists` — returns the raw JSON payload. 4241 + """ 4242 + 4243 + raise NotImplementedError 4244 + def get_cover_art_url(self, id: "str",size: "typing.Optional[int]"): 4245 + """ 4246 + `app.rocksky.library.getCoverArtUrl` — returns the raw JSON payload. 4247 + """ 4248 + 4249 + raise NotImplementedError 4250 + def get_download_url(self, id: "str"): 4251 + """ 4252 + `app.rocksky.library.getDownloadUrl` — returns the raw JSON payload. 4253 + """ 4254 + 4255 + raise NotImplementedError 4256 + def get_genres(self, ): 4257 + """ 4258 + `app.rocksky.library.getGenres` — returns the raw JSON payload. 4259 + """ 4260 + 4261 + raise NotImplementedError 4262 + def get_indexes(self, ): 4263 + """ 4264 + `app.rocksky.library.getIndexes` — returns the raw JSON payload. 4265 + """ 4266 + 4267 + raise NotImplementedError 4268 + def get_internet_radio_stations(self, ): 4269 + """ 4270 + `app.rocksky.library.getInternetRadioStations` — returns the raw JSON payload. 4271 + """ 4272 + 4273 + raise NotImplementedError 4274 + def get_license(self, ): 4275 + """ 4276 + `app.rocksky.library.getLicense` — returns the raw JSON payload. 4277 + """ 4278 + 4279 + raise NotImplementedError 4280 + def get_lyrics(self, artist: "typing.Optional[str]",title: "typing.Optional[str]"): 4281 + """ 4282 + `app.rocksky.library.getLyrics` — returns the raw JSON payload. 4283 + """ 4284 + 4285 + raise NotImplementedError 4286 + def get_music_directory(self, id: "str"): 4287 + """ 4288 + `app.rocksky.library.getMusicDirectory` — returns the raw JSON payload. 4289 + """ 4290 + 4291 + raise NotImplementedError 4292 + def get_music_folders(self, ): 4293 + """ 4294 + `app.rocksky.library.getMusicFolders` — returns the raw JSON payload. 4295 + """ 4296 + 4297 + raise NotImplementedError 4298 + def get_now_playing(self, ): 4299 + """ 4300 + `app.rocksky.library.getNowPlaying` — returns the raw JSON payload. 4301 + """ 4302 + 4303 + raise NotImplementedError 4304 + def get_play_queue(self, ): 4305 + """ 4306 + `app.rocksky.library.getPlayQueue` — returns the raw JSON payload. 4307 + """ 4308 + 4309 + raise NotImplementedError 4310 + def get_playlist(self, id: "str"): 4311 + """ 4312 + `app.rocksky.library.getPlaylist` — returns the raw JSON payload. 4313 + """ 4314 + 4315 + raise NotImplementedError 4316 + def get_playlists(self, ): 4317 + """ 4318 + `app.rocksky.library.getPlaylists` — returns the raw JSON payload. 4319 + """ 4320 + 4321 + raise NotImplementedError 4322 + def get_random_songs(self, size: "typing.Optional[int]",genre: "typing.Optional[str]",from_year: "typing.Optional[int]",to_year: "typing.Optional[int]"): 4323 + """ 4324 + `app.rocksky.library.getRandomSongs` — returns the raw JSON payload. 4325 + """ 4326 + 4327 + raise NotImplementedError 4328 + def get_scan_status(self, ): 4329 + """ 4330 + `app.rocksky.library.getScanStatus` — returns the raw JSON payload. 4331 + """ 4332 + 4333 + raise NotImplementedError 4334 + def get_similar_songs(self, id: "str",count: "typing.Optional[int]"): 4335 + """ 4336 + `app.rocksky.library.getSimilarSongs` — returns the raw JSON payload. 4337 + """ 4338 + 4339 + raise NotImplementedError 4340 + def get_song(self, id: "str"): 4341 + """ 4342 + `app.rocksky.library.getSong` — returns the raw JSON payload. 4343 + """ 4344 + 4345 + raise NotImplementedError 4346 + def get_songs_by_genre(self, genre: "str",count: "typing.Optional[int]",offset: "typing.Optional[int]"): 4347 + """ 4348 + `app.rocksky.library.getSongsByGenre` — returns the raw JSON payload. 4349 + """ 4350 + 4351 + raise NotImplementedError 4352 + def get_starred(self, ): 4353 + """ 4354 + `app.rocksky.library.getStarred` — returns the raw JSON payload. 4355 + """ 4356 + 4357 + raise NotImplementedError 4358 + def get_stream_url(self, id: "str",max_bit_rate: "typing.Optional[int]",format: "typing.Optional[str]"): 4359 + """ 4360 + `app.rocksky.library.getStreamUrl` — returns the raw JSON payload. 4361 + """ 4362 + 4363 + raise NotImplementedError 4364 + def get_top_songs(self, artist: "str",count: "typing.Optional[int]"): 4365 + """ 4366 + `app.rocksky.library.getTopSongs` — returns the raw JSON payload. 4367 + """ 4368 + 4369 + raise NotImplementedError 4370 + def get_user(self, ): 4371 + """ 4372 + `app.rocksky.library.getUser` — returns the raw JSON payload. 4373 + """ 4374 + 4375 + raise NotImplementedError 4376 + def ping(self, ): 4377 + """ 4378 + `app.rocksky.library.ping` — returns the raw JSON payload. 4379 + """ 4380 + 4381 + raise NotImplementedError 4382 + def save_play_queue(self, id: "typing.Optional[str]",current: "typing.Optional[str]",position: "typing.Optional[int]"): 4383 + """ 4384 + `app.rocksky.library.savePlayQueue` — returns the raw JSON payload. 4385 + """ 4386 + 4387 + raise NotImplementedError 4388 + def scrobble(self, id: "str",time: "typing.Optional[int]",submission: "typing.Optional[bool]"): 4389 + """ 4390 + `app.rocksky.library.scrobble` — returns the raw JSON payload. 4391 + """ 4392 + 4393 + raise NotImplementedError 4394 + def search(self, query: "str",artist_count: "typing.Optional[int]",artist_offset: "typing.Optional[int]",album_count: "typing.Optional[int]",album_offset: "typing.Optional[int]",song_count: "typing.Optional[int]",song_offset: "typing.Optional[int]"): 4395 + """ 4396 + `app.rocksky.library.search` — returns the raw JSON payload. 4397 + """ 4398 + 4399 + raise NotImplementedError 4400 + def star(self, id: "str",album_id: "typing.Optional[str]",artist_id: "typing.Optional[str]"): 4401 + """ 4402 + `app.rocksky.library.star` — returns the raw JSON payload. 4403 + """ 4404 + 4405 + raise NotImplementedError 4406 + def start_scan(self, ): 4407 + """ 4408 + `app.rocksky.library.startScan` — returns the raw JSON payload. 4409 + """ 4410 + 4411 + raise NotImplementedError 4412 + def unstar(self, id: "str",album_id: "typing.Optional[str]",artist_id: "typing.Optional[str]"): 4413 + """ 4414 + `app.rocksky.library.unstar` — returns the raw JSON payload. 4415 + """ 4416 + 4417 + raise NotImplementedError 4418 + def update_now_playing(self, id: "str"): 4419 + """ 4420 + `app.rocksky.library.updateNowPlaying` — returns the raw JSON payload. 4421 + """ 4422 + 4423 + raise NotImplementedError 4424 + def update_playlist(self, playlist_id: "str",name: "typing.Optional[str]",comment: "typing.Optional[str]",song_id_to_add: "typing.Optional[str]",song_index_to_remove: "typing.Optional[int]"): 4425 + """ 4426 + `app.rocksky.library.updatePlaylist` — returns the raw JSON payload. 4427 + """ 4428 + 4429 + raise NotImplementedError 4430 + 4431 + 4432 + class Library: 4433 + """ 4434 + Authenticated `app.rocksky.library.*` client. A non-empty access token is 4435 + mandatory — [`Library::new`] errors without one, so no library call can be 4436 + made unauthenticated. Methods return the raw JSON payload as a string. 4437 + """ 4438 + 4439 + _pointer: ctypes.c_void_p 4440 + def __init__(self, base: "typing.Optional[str]",token: "str"): 4441 + """ 4442 + Build against an AppView base (default when `None`) with the required 4443 + bearer token. Errors if `token` is empty. 4444 + """ 4445 + 4446 + _UniffiConverterOptionalString.check_lower(base) 4447 + 4448 + _UniffiConverterString.check_lower(token) 4449 + 4450 + self._pointer = _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_constructor_library_new, 4451 + _UniffiConverterOptionalString.lower(base), 4452 + _UniffiConverterString.lower(token)) 4453 + 4454 + def __del__(self): 4455 + # In case of partial initialization of instances. 4456 + pointer = getattr(self, "_pointer", None) 4457 + if pointer is not None: 4458 + _uniffi_rust_call(_UniffiLib.uniffi_rocksky_uniffi_fn_free_library, pointer) 4459 + 4460 + def _uniffi_clone_pointer(self): 4461 + return _uniffi_rust_call(_UniffiLib.uniffi_rocksky_uniffi_fn_clone_library, self._pointer) 4462 + 4463 + # Used by alternative constructors or any methods which return this type. 4464 + @classmethod 4465 + def _make_instance_(cls, pointer): 4466 + # Lightly yucky way to bypass the usual __init__ logic 4467 + # and just create a new instance with the required pointer. 4468 + inst = cls.__new__(cls) 4469 + inst._pointer = pointer 4470 + return inst 4471 + 4472 + 4473 + def create_playlist(self, name: "str") -> "str": 4474 + """ 4475 + `app.rocksky.library.createPlaylist` — returns the raw JSON payload. 4476 + """ 4477 + 4478 + _UniffiConverterString.check_lower(name) 4479 + 4480 + return _UniffiConverterString.lift( 4481 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_create_playlist,self._uniffi_clone_pointer(), 4482 + _UniffiConverterString.lower(name)) 4483 + ) 4484 + 4485 + 4486 + 4487 + 4488 + 4489 + def delete_album(self, id: "str") -> "str": 4490 + """ 4491 + `app.rocksky.library.deleteAlbum` — returns the raw JSON payload. 4492 + """ 4493 + 4494 + _UniffiConverterString.check_lower(id) 4495 + 4496 + return _UniffiConverterString.lift( 4497 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_album,self._uniffi_clone_pointer(), 4498 + _UniffiConverterString.lower(id)) 4499 + ) 4500 + 4501 + 4502 + 4503 + 4504 + 4505 + def delete_playlist(self, id: "str") -> "str": 4506 + """ 4507 + `app.rocksky.library.deletePlaylist` — returns the raw JSON payload. 4508 + """ 4509 + 4510 + _UniffiConverterString.check_lower(id) 4511 + 4512 + return _UniffiConverterString.lift( 4513 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_playlist,self._uniffi_clone_pointer(), 4514 + _UniffiConverterString.lower(id)) 4515 + ) 4516 + 4517 + 4518 + 4519 + 4520 + 4521 + def delete_song(self, id: "str") -> "str": 4522 + """ 4523 + `app.rocksky.library.deleteSong` — returns the raw JSON payload. 4524 + """ 4525 + 4526 + _UniffiConverterString.check_lower(id) 4527 + 4528 + return _UniffiConverterString.lift( 4529 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_delete_song,self._uniffi_clone_pointer(), 4530 + _UniffiConverterString.lower(id)) 4531 + ) 4532 + 4533 + 4534 + 4535 + 4536 + 4537 + def get_album(self, id: "str") -> "str": 4538 + """ 4539 + `app.rocksky.library.getAlbum` — returns the raw JSON payload. 4540 + """ 4541 + 4542 + _UniffiConverterString.check_lower(id) 4543 + 4544 + return _UniffiConverterString.lift( 4545 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album,self._uniffi_clone_pointer(), 4546 + _UniffiConverterString.lower(id)) 4547 + ) 4548 + 4549 + 4550 + 4551 + 4552 + 4553 + def get_album_info(self, id: "str") -> "str": 4554 + """ 4555 + `app.rocksky.library.getAlbumInfo` — returns the raw JSON payload. 4556 + """ 4557 + 4558 + _UniffiConverterString.check_lower(id) 4559 + 4560 + return _UniffiConverterString.lift( 4561 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album_info,self._uniffi_clone_pointer(), 4562 + _UniffiConverterString.lower(id)) 4563 + ) 4564 + 4565 + 4566 + 4567 + 4568 + 4569 + def get_album_list(self, type: "str",size: "typing.Optional[int]",offset: "typing.Optional[int]",from_year: "typing.Optional[int]",to_year: "typing.Optional[int]",genre: "typing.Optional[str]") -> "str": 4570 + """ 4571 + `app.rocksky.library.getAlbumList` — returns the raw JSON payload. 4572 + """ 4573 + 4574 + _UniffiConverterString.check_lower(type) 4575 + 4576 + _UniffiConverterOptionalInt64.check_lower(size) 4577 + 4578 + _UniffiConverterOptionalInt64.check_lower(offset) 4579 + 4580 + _UniffiConverterOptionalInt64.check_lower(from_year) 4581 + 4582 + _UniffiConverterOptionalInt64.check_lower(to_year) 4583 + 4584 + _UniffiConverterOptionalString.check_lower(genre) 4585 + 4586 + return _UniffiConverterString.lift( 4587 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_album_list,self._uniffi_clone_pointer(), 4588 + _UniffiConverterString.lower(type), 4589 + _UniffiConverterOptionalInt64.lower(size), 4590 + _UniffiConverterOptionalInt64.lower(offset), 4591 + _UniffiConverterOptionalInt64.lower(from_year), 4592 + _UniffiConverterOptionalInt64.lower(to_year), 4593 + _UniffiConverterOptionalString.lower(genre)) 4594 + ) 4595 + 4596 + 4597 + 4598 + 4599 + 4600 + def get_artist(self, id: "str") -> "str": 4601 + """ 4602 + `app.rocksky.library.getArtist` — returns the raw JSON payload. 4603 + """ 4604 + 4605 + _UniffiConverterString.check_lower(id) 4606 + 4607 + return _UniffiConverterString.lift( 4608 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artist,self._uniffi_clone_pointer(), 4609 + _UniffiConverterString.lower(id)) 4610 + ) 4611 + 4612 + 4613 + 4614 + 4615 + 4616 + def get_artist_info(self, id: "str") -> "str": 4617 + """ 4618 + `app.rocksky.library.getArtistInfo` — returns the raw JSON payload. 4619 + """ 4620 + 4621 + _UniffiConverterString.check_lower(id) 4622 + 4623 + return _UniffiConverterString.lift( 4624 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artist_info,self._uniffi_clone_pointer(), 4625 + _UniffiConverterString.lower(id)) 4626 + ) 4627 + 4628 + 4629 + 4630 + 4631 + 4632 + def get_artists(self, ) -> "str": 4633 + """ 4634 + `app.rocksky.library.getArtists` — returns the raw JSON payload. 4635 + """ 4636 + 4637 + return _UniffiConverterString.lift( 4638 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_artists,self._uniffi_clone_pointer(),) 4639 + ) 4640 + 4641 + 4642 + 4643 + 4644 + 4645 + def get_cover_art_url(self, id: "str",size: "typing.Optional[int]") -> "str": 4646 + """ 4647 + `app.rocksky.library.getCoverArtUrl` — returns the raw JSON payload. 4648 + """ 4649 + 4650 + _UniffiConverterString.check_lower(id) 4651 + 4652 + _UniffiConverterOptionalInt64.check_lower(size) 4653 + 4654 + return _UniffiConverterString.lift( 4655 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_cover_art_url,self._uniffi_clone_pointer(), 4656 + _UniffiConverterString.lower(id), 4657 + _UniffiConverterOptionalInt64.lower(size)) 4658 + ) 4659 + 4660 + 4661 + 4662 + 4663 + 4664 + def get_download_url(self, id: "str") -> "str": 4665 + """ 4666 + `app.rocksky.library.getDownloadUrl` — returns the raw JSON payload. 4667 + """ 4668 + 4669 + _UniffiConverterString.check_lower(id) 4670 + 4671 + return _UniffiConverterString.lift( 4672 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_download_url,self._uniffi_clone_pointer(), 4673 + _UniffiConverterString.lower(id)) 4674 + ) 4675 + 4676 + 4677 + 4678 + 4679 + 4680 + def get_genres(self, ) -> "str": 4681 + """ 4682 + `app.rocksky.library.getGenres` — returns the raw JSON payload. 4683 + """ 4684 + 4685 + return _UniffiConverterString.lift( 4686 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_genres,self._uniffi_clone_pointer(),) 4687 + ) 4688 + 4689 + 4690 + 4691 + 4692 + 4693 + def get_indexes(self, ) -> "str": 4694 + """ 4695 + `app.rocksky.library.getIndexes` — returns the raw JSON payload. 4696 + """ 4697 + 4698 + return _UniffiConverterString.lift( 4699 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_indexes,self._uniffi_clone_pointer(),) 4700 + ) 4701 + 4702 + 4703 + 4704 + 4705 + 4706 + def get_internet_radio_stations(self, ) -> "str": 4707 + """ 4708 + `app.rocksky.library.getInternetRadioStations` — returns the raw JSON payload. 4709 + """ 4710 + 4711 + return _UniffiConverterString.lift( 4712 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_internet_radio_stations,self._uniffi_clone_pointer(),) 4713 + ) 4714 + 4715 + 4716 + 4717 + 4718 + 4719 + def get_license(self, ) -> "str": 4720 + """ 4721 + `app.rocksky.library.getLicense` — returns the raw JSON payload. 4722 + """ 4723 + 4724 + return _UniffiConverterString.lift( 4725 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_license,self._uniffi_clone_pointer(),) 4726 + ) 4727 + 4728 + 4729 + 4730 + 4731 + 4732 + def get_lyrics(self, artist: "typing.Optional[str]",title: "typing.Optional[str]") -> "str": 4733 + """ 4734 + `app.rocksky.library.getLyrics` — returns the raw JSON payload. 4735 + """ 4736 + 4737 + _UniffiConverterOptionalString.check_lower(artist) 4738 + 4739 + _UniffiConverterOptionalString.check_lower(title) 4740 + 4741 + return _UniffiConverterString.lift( 4742 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_lyrics,self._uniffi_clone_pointer(), 4743 + _UniffiConverterOptionalString.lower(artist), 4744 + _UniffiConverterOptionalString.lower(title)) 4745 + ) 4746 + 4747 + 4748 + 4749 + 4750 + 4751 + def get_music_directory(self, id: "str") -> "str": 4752 + """ 4753 + `app.rocksky.library.getMusicDirectory` — returns the raw JSON payload. 4754 + """ 4755 + 4756 + _UniffiConverterString.check_lower(id) 4757 + 4758 + return _UniffiConverterString.lift( 4759 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_music_directory,self._uniffi_clone_pointer(), 4760 + _UniffiConverterString.lower(id)) 4761 + ) 4762 + 4763 + 4764 + 4765 + 4766 + 4767 + def get_music_folders(self, ) -> "str": 4768 + """ 4769 + `app.rocksky.library.getMusicFolders` — returns the raw JSON payload. 4770 + """ 4771 + 4772 + return _UniffiConverterString.lift( 4773 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_music_folders,self._uniffi_clone_pointer(),) 4774 + ) 4775 + 4776 + 4777 + 4778 + 4779 + 4780 + def get_now_playing(self, ) -> "str": 4781 + """ 4782 + `app.rocksky.library.getNowPlaying` — returns the raw JSON payload. 4783 + """ 4784 + 4785 + return _UniffiConverterString.lift( 4786 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_now_playing,self._uniffi_clone_pointer(),) 4787 + ) 4788 + 4789 + 4790 + 4791 + 4792 + 4793 + def get_play_queue(self, ) -> "str": 4794 + """ 4795 + `app.rocksky.library.getPlayQueue` — returns the raw JSON payload. 4796 + """ 4797 + 4798 + return _UniffiConverterString.lift( 4799 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_play_queue,self._uniffi_clone_pointer(),) 4800 + ) 4801 + 4802 + 4803 + 4804 + 4805 + 4806 + def get_playlist(self, id: "str") -> "str": 4807 + """ 4808 + `app.rocksky.library.getPlaylist` — returns the raw JSON payload. 4809 + """ 4810 + 4811 + _UniffiConverterString.check_lower(id) 4812 + 4813 + return _UniffiConverterString.lift( 4814 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_playlist,self._uniffi_clone_pointer(), 4815 + _UniffiConverterString.lower(id)) 4816 + ) 4817 + 4818 + 4819 + 4820 + 4821 + 4822 + def get_playlists(self, ) -> "str": 4823 + """ 4824 + `app.rocksky.library.getPlaylists` — returns the raw JSON payload. 4825 + """ 4826 + 4827 + return _UniffiConverterString.lift( 4828 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_playlists,self._uniffi_clone_pointer(),) 4829 + ) 4830 + 4831 + 4832 + 4833 + 4834 + 4835 + def get_random_songs(self, size: "typing.Optional[int]",genre: "typing.Optional[str]",from_year: "typing.Optional[int]",to_year: "typing.Optional[int]") -> "str": 4836 + """ 4837 + `app.rocksky.library.getRandomSongs` — returns the raw JSON payload. 4838 + """ 4839 + 4840 + _UniffiConverterOptionalInt64.check_lower(size) 4841 + 4842 + _UniffiConverterOptionalString.check_lower(genre) 4843 + 4844 + _UniffiConverterOptionalInt64.check_lower(from_year) 4845 + 4846 + _UniffiConverterOptionalInt64.check_lower(to_year) 4847 + 4848 + return _UniffiConverterString.lift( 4849 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_random_songs,self._uniffi_clone_pointer(), 4850 + _UniffiConverterOptionalInt64.lower(size), 4851 + _UniffiConverterOptionalString.lower(genre), 4852 + _UniffiConverterOptionalInt64.lower(from_year), 4853 + _UniffiConverterOptionalInt64.lower(to_year)) 4854 + ) 4855 + 4856 + 4857 + 4858 + 4859 + 4860 + def get_scan_status(self, ) -> "str": 4861 + """ 4862 + `app.rocksky.library.getScanStatus` — returns the raw JSON payload. 4863 + """ 4864 + 4865 + return _UniffiConverterString.lift( 4866 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_scan_status,self._uniffi_clone_pointer(),) 4867 + ) 4868 + 4869 + 4870 + 4871 + 4872 + 4873 + def get_similar_songs(self, id: "str",count: "typing.Optional[int]") -> "str": 4874 + """ 4875 + `app.rocksky.library.getSimilarSongs` — returns the raw JSON payload. 4876 + """ 4877 + 4878 + _UniffiConverterString.check_lower(id) 4879 + 4880 + _UniffiConverterOptionalInt64.check_lower(count) 4881 + 4882 + return _UniffiConverterString.lift( 4883 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_similar_songs,self._uniffi_clone_pointer(), 4884 + _UniffiConverterString.lower(id), 4885 + _UniffiConverterOptionalInt64.lower(count)) 4886 + ) 4887 + 4888 + 4889 + 4890 + 4891 + 4892 + def get_song(self, id: "str") -> "str": 4893 + """ 4894 + `app.rocksky.library.getSong` — returns the raw JSON payload. 4895 + """ 4896 + 4897 + _UniffiConverterString.check_lower(id) 4898 + 4899 + return _UniffiConverterString.lift( 4900 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_song,self._uniffi_clone_pointer(), 4901 + _UniffiConverterString.lower(id)) 4902 + ) 4903 + 4904 + 4905 + 4906 + 4907 + 4908 + def get_songs_by_genre(self, genre: "str",count: "typing.Optional[int]",offset: "typing.Optional[int]") -> "str": 4909 + """ 4910 + `app.rocksky.library.getSongsByGenre` — returns the raw JSON payload. 4911 + """ 4912 + 4913 + _UniffiConverterString.check_lower(genre) 4914 + 4915 + _UniffiConverterOptionalInt64.check_lower(count) 4916 + 4917 + _UniffiConverterOptionalInt64.check_lower(offset) 4918 + 4919 + return _UniffiConverterString.lift( 4920 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_songs_by_genre,self._uniffi_clone_pointer(), 4921 + _UniffiConverterString.lower(genre), 4922 + _UniffiConverterOptionalInt64.lower(count), 4923 + _UniffiConverterOptionalInt64.lower(offset)) 4924 + ) 4925 + 4926 + 4927 + 4928 + 4929 + 4930 + def get_starred(self, ) -> "str": 4931 + """ 4932 + `app.rocksky.library.getStarred` — returns the raw JSON payload. 4933 + """ 4934 + 4935 + return _UniffiConverterString.lift( 4936 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_starred,self._uniffi_clone_pointer(),) 4937 + ) 4938 + 4939 + 4940 + 4941 + 4942 + 4943 + def get_stream_url(self, id: "str",max_bit_rate: "typing.Optional[int]",format: "typing.Optional[str]") -> "str": 4944 + """ 4945 + `app.rocksky.library.getStreamUrl` — returns the raw JSON payload. 4946 + """ 4947 + 4948 + _UniffiConverterString.check_lower(id) 4949 + 4950 + _UniffiConverterOptionalInt64.check_lower(max_bit_rate) 4951 + 4952 + _UniffiConverterOptionalString.check_lower(format) 4953 + 4954 + return _UniffiConverterString.lift( 4955 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_stream_url,self._uniffi_clone_pointer(), 4956 + _UniffiConverterString.lower(id), 4957 + _UniffiConverterOptionalInt64.lower(max_bit_rate), 4958 + _UniffiConverterOptionalString.lower(format)) 4959 + ) 4960 + 4961 + 4962 + 4963 + 4964 + 4965 + def get_top_songs(self, artist: "str",count: "typing.Optional[int]") -> "str": 4966 + """ 4967 + `app.rocksky.library.getTopSongs` — returns the raw JSON payload. 4968 + """ 4969 + 4970 + _UniffiConverterString.check_lower(artist) 4971 + 4972 + _UniffiConverterOptionalInt64.check_lower(count) 4973 + 4974 + return _UniffiConverterString.lift( 4975 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_top_songs,self._uniffi_clone_pointer(), 4976 + _UniffiConverterString.lower(artist), 4977 + _UniffiConverterOptionalInt64.lower(count)) 4978 + ) 4979 + 4980 + 4981 + 4982 + 4983 + 4984 + def get_user(self, ) -> "str": 4985 + """ 4986 + `app.rocksky.library.getUser` — returns the raw JSON payload. 4987 + """ 4988 + 4989 + return _UniffiConverterString.lift( 4990 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_get_user,self._uniffi_clone_pointer(),) 4991 + ) 4992 + 4993 + 4994 + 4995 + 4996 + 4997 + def ping(self, ) -> "str": 4998 + """ 4999 + `app.rocksky.library.ping` — returns the raw JSON payload. 5000 + """ 5001 + 5002 + return _UniffiConverterString.lift( 5003 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_ping,self._uniffi_clone_pointer(),) 5004 + ) 5005 + 5006 + 5007 + 5008 + 5009 + 5010 + def save_play_queue(self, id: "typing.Optional[str]",current: "typing.Optional[str]",position: "typing.Optional[int]") -> "str": 5011 + """ 5012 + `app.rocksky.library.savePlayQueue` — returns the raw JSON payload. 5013 + """ 5014 + 5015 + _UniffiConverterOptionalString.check_lower(id) 5016 + 5017 + _UniffiConverterOptionalString.check_lower(current) 5018 + 5019 + _UniffiConverterOptionalInt64.check_lower(position) 5020 + 5021 + return _UniffiConverterString.lift( 5022 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_save_play_queue,self._uniffi_clone_pointer(), 5023 + _UniffiConverterOptionalString.lower(id), 5024 + _UniffiConverterOptionalString.lower(current), 5025 + _UniffiConverterOptionalInt64.lower(position)) 5026 + ) 5027 + 5028 + 5029 + 5030 + 5031 + 5032 + def scrobble(self, id: "str",time: "typing.Optional[int]",submission: "typing.Optional[bool]") -> "str": 5033 + """ 5034 + `app.rocksky.library.scrobble` — returns the raw JSON payload. 5035 + """ 5036 + 5037 + _UniffiConverterString.check_lower(id) 5038 + 5039 + _UniffiConverterOptionalInt64.check_lower(time) 5040 + 5041 + _UniffiConverterOptionalBool.check_lower(submission) 5042 + 5043 + return _UniffiConverterString.lift( 5044 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_scrobble,self._uniffi_clone_pointer(), 5045 + _UniffiConverterString.lower(id), 5046 + _UniffiConverterOptionalInt64.lower(time), 5047 + _UniffiConverterOptionalBool.lower(submission)) 5048 + ) 5049 + 5050 + 5051 + 5052 + 5053 + 5054 + def search(self, query: "str",artist_count: "typing.Optional[int]",artist_offset: "typing.Optional[int]",album_count: "typing.Optional[int]",album_offset: "typing.Optional[int]",song_count: "typing.Optional[int]",song_offset: "typing.Optional[int]") -> "str": 5055 + """ 5056 + `app.rocksky.library.search` — returns the raw JSON payload. 5057 + """ 5058 + 5059 + _UniffiConverterString.check_lower(query) 5060 + 5061 + _UniffiConverterOptionalInt64.check_lower(artist_count) 5062 + 5063 + _UniffiConverterOptionalInt64.check_lower(artist_offset) 5064 + 5065 + _UniffiConverterOptionalInt64.check_lower(album_count) 5066 + 5067 + _UniffiConverterOptionalInt64.check_lower(album_offset) 5068 + 5069 + _UniffiConverterOptionalInt64.check_lower(song_count) 5070 + 5071 + _UniffiConverterOptionalInt64.check_lower(song_offset) 5072 + 5073 + return _UniffiConverterString.lift( 5074 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_search,self._uniffi_clone_pointer(), 5075 + _UniffiConverterString.lower(query), 5076 + _UniffiConverterOptionalInt64.lower(artist_count), 5077 + _UniffiConverterOptionalInt64.lower(artist_offset), 5078 + _UniffiConverterOptionalInt64.lower(album_count), 5079 + _UniffiConverterOptionalInt64.lower(album_offset), 5080 + _UniffiConverterOptionalInt64.lower(song_count), 5081 + _UniffiConverterOptionalInt64.lower(song_offset)) 5082 + ) 5083 + 5084 + 5085 + 5086 + 5087 + 5088 + def star(self, id: "str",album_id: "typing.Optional[str]",artist_id: "typing.Optional[str]") -> "str": 5089 + """ 5090 + `app.rocksky.library.star` — returns the raw JSON payload. 5091 + """ 5092 + 5093 + _UniffiConverterString.check_lower(id) 5094 + 5095 + _UniffiConverterOptionalString.check_lower(album_id) 5096 + 5097 + _UniffiConverterOptionalString.check_lower(artist_id) 5098 + 5099 + return _UniffiConverterString.lift( 5100 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_star,self._uniffi_clone_pointer(), 5101 + _UniffiConverterString.lower(id), 5102 + _UniffiConverterOptionalString.lower(album_id), 5103 + _UniffiConverterOptionalString.lower(artist_id)) 5104 + ) 5105 + 5106 + 5107 + 5108 + 5109 + 5110 + def start_scan(self, ) -> "str": 5111 + """ 5112 + `app.rocksky.library.startScan` — returns the raw JSON payload. 5113 + """ 5114 + 5115 + return _UniffiConverterString.lift( 5116 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_start_scan,self._uniffi_clone_pointer(),) 5117 + ) 5118 + 5119 + 5120 + 5121 + 5122 + 5123 + def unstar(self, id: "str",album_id: "typing.Optional[str]",artist_id: "typing.Optional[str]") -> "str": 5124 + """ 5125 + `app.rocksky.library.unstar` — returns the raw JSON payload. 5126 + """ 5127 + 5128 + _UniffiConverterString.check_lower(id) 5129 + 5130 + _UniffiConverterOptionalString.check_lower(album_id) 5131 + 5132 + _UniffiConverterOptionalString.check_lower(artist_id) 5133 + 5134 + return _UniffiConverterString.lift( 5135 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_unstar,self._uniffi_clone_pointer(), 5136 + _UniffiConverterString.lower(id), 5137 + _UniffiConverterOptionalString.lower(album_id), 5138 + _UniffiConverterOptionalString.lower(artist_id)) 5139 + ) 5140 + 5141 + 5142 + 5143 + 5144 + 5145 + def update_now_playing(self, id: "str") -> "str": 5146 + """ 5147 + `app.rocksky.library.updateNowPlaying` — returns the raw JSON payload. 5148 + """ 5149 + 5150 + _UniffiConverterString.check_lower(id) 5151 + 5152 + return _UniffiConverterString.lift( 5153 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_update_now_playing,self._uniffi_clone_pointer(), 5154 + _UniffiConverterString.lower(id)) 5155 + ) 5156 + 5157 + 5158 + 5159 + 5160 + 5161 + def update_playlist(self, playlist_id: "str",name: "typing.Optional[str]",comment: "typing.Optional[str]",song_id_to_add: "typing.Optional[str]",song_index_to_remove: "typing.Optional[int]") -> "str": 5162 + """ 5163 + `app.rocksky.library.updatePlaylist` — returns the raw JSON payload. 5164 + """ 5165 + 5166 + _UniffiConverterString.check_lower(playlist_id) 5167 + 5168 + _UniffiConverterOptionalString.check_lower(name) 5169 + 5170 + _UniffiConverterOptionalString.check_lower(comment) 5171 + 5172 + _UniffiConverterOptionalString.check_lower(song_id_to_add) 5173 + 5174 + _UniffiConverterOptionalInt64.check_lower(song_index_to_remove) 5175 + 5176 + return _UniffiConverterString.lift( 5177 + _uniffi_rust_call_with_error(_UniffiConverterTypeRockskyError,_UniffiLib.uniffi_rocksky_uniffi_fn_method_library_update_playlist,self._uniffi_clone_pointer(), 5178 + _UniffiConverterString.lower(playlist_id), 5179 + _UniffiConverterOptionalString.lower(name), 5180 + _UniffiConverterOptionalString.lower(comment), 5181 + _UniffiConverterOptionalString.lower(song_id_to_add), 5182 + _UniffiConverterOptionalInt64.lower(song_index_to_remove)) 5183 + ) 5184 + 5185 + 5186 + 5187 + 5188 + 5189 + 5190 + class _UniffiConverterTypeLibrary: 5191 + 5192 + @staticmethod 5193 + def lift(value: int): 5194 + return Library._make_instance_(value) 5195 + 5196 + @staticmethod 5197 + def check_lower(value: Library): 5198 + if not isinstance(value, Library): 5199 + raise TypeError("Expected Library instance, {} found".format(type(value).__name__)) 5200 + 5201 + @staticmethod 5202 + def lower(value: LibraryProtocol): 5203 + if not isinstance(value, Library): 5204 + raise TypeError("Expected Library instance, {} found".format(type(value).__name__)) 5205 + return value._uniffi_clone_pointer() 5206 + 5207 + @classmethod 5208 + def read(cls, buf: _UniffiRustBuffer): 5209 + ptr = buf.read_u64() 5210 + if ptr == 0: 5211 + raise InternalError("Raw pointer value was null") 5212 + return cls.lift(ptr) 5213 + 5214 + @classmethod 5215 + def write(cls, value: LibraryProtocol, buf: _UniffiRustBuffer): 5216 + buf.write_u64(cls.lower(value)) 5217 + 5218 + 3477 5219 class AlbumInput: 3478 5220 """ 3479 5221 An album record (`app.rocksky.album`); `artist` is the album artist. ··· 3883 5625 _UniffiConverterUInt64.write(value.tracks, buf) 3884 5626 3885 5627 5628 + class NotificationActor: 5629 + """ 5630 + The user who triggered a notification 5631 + (`app.rocksky.notification.defs#notificationActor`). 5632 + """ 5633 + 5634 + id: "typing.Optional[str]" 5635 + did: "typing.Optional[str]" 5636 + handle: "typing.Optional[str]" 5637 + display_name: "typing.Optional[str]" 5638 + avatar: "typing.Optional[str]" 5639 + def __init__(self, *, id: "typing.Optional[str]", did: "typing.Optional[str]", handle: "typing.Optional[str]", display_name: "typing.Optional[str]", avatar: "typing.Optional[str]"): 5640 + self.id = id 5641 + self.did = did 5642 + self.handle = handle 5643 + self.display_name = display_name 5644 + self.avatar = avatar 5645 + 5646 + def __str__(self): 5647 + return "NotificationActor(id={}, did={}, handle={}, display_name={}, avatar={})".format(self.id, self.did, self.handle, self.display_name, self.avatar) 5648 + 5649 + def __eq__(self, other): 5650 + if self.id != other.id: 5651 + return False 5652 + if self.did != other.did: 5653 + return False 5654 + if self.handle != other.handle: 5655 + return False 5656 + if self.display_name != other.display_name: 5657 + return False 5658 + if self.avatar != other.avatar: 5659 + return False 5660 + return True 5661 + 5662 + class _UniffiConverterTypeNotificationActor(_UniffiConverterRustBuffer): 5663 + @staticmethod 5664 + def read(buf): 5665 + return NotificationActor( 5666 + id=_UniffiConverterOptionalString.read(buf), 5667 + did=_UniffiConverterOptionalString.read(buf), 5668 + handle=_UniffiConverterOptionalString.read(buf), 5669 + display_name=_UniffiConverterOptionalString.read(buf), 5670 + avatar=_UniffiConverterOptionalString.read(buf), 5671 + ) 5672 + 5673 + @staticmethod 5674 + def check_lower(value): 5675 + _UniffiConverterOptionalString.check_lower(value.id) 5676 + _UniffiConverterOptionalString.check_lower(value.did) 5677 + _UniffiConverterOptionalString.check_lower(value.handle) 5678 + _UniffiConverterOptionalString.check_lower(value.display_name) 5679 + _UniffiConverterOptionalString.check_lower(value.avatar) 5680 + 5681 + @staticmethod 5682 + def write(value, buf): 5683 + _UniffiConverterOptionalString.write(value.id, buf) 5684 + _UniffiConverterOptionalString.write(value.did, buf) 5685 + _UniffiConverterOptionalString.write(value.handle, buf) 5686 + _UniffiConverterOptionalString.write(value.display_name, buf) 5687 + _UniffiConverterOptionalString.write(value.avatar, buf) 5688 + 5689 + 5690 + class NotificationList: 5691 + """ 5692 + A page of notifications (`app.rocksky.notification.listNotifications`). 5693 + """ 5694 + 5695 + notifications: "typing.List[NotificationView]" 5696 + unread_count: "int" 5697 + """ 5698 + The number of unread notifications. 5699 + """ 5700 + 5701 + cursor: "typing.Optional[str]" 5702 + """ 5703 + Cursor to pass to the next call for the following page. 5704 + """ 5705 + 5706 + def __init__(self, *, notifications: "typing.List[NotificationView]", unread_count: "int", cursor: "typing.Optional[str]"): 5707 + self.notifications = notifications 5708 + self.unread_count = unread_count 5709 + self.cursor = cursor 5710 + 5711 + def __str__(self): 5712 + return "NotificationList(notifications={}, unread_count={}, cursor={})".format(self.notifications, self.unread_count, self.cursor) 5713 + 5714 + def __eq__(self, other): 5715 + if self.notifications != other.notifications: 5716 + return False 5717 + if self.unread_count != other.unread_count: 5718 + return False 5719 + if self.cursor != other.cursor: 5720 + return False 5721 + return True 5722 + 5723 + class _UniffiConverterTypeNotificationList(_UniffiConverterRustBuffer): 5724 + @staticmethod 5725 + def read(buf): 5726 + return NotificationList( 5727 + notifications=_UniffiConverterSequenceTypeNotificationView.read(buf), 5728 + unread_count=_UniffiConverterInt64.read(buf), 5729 + cursor=_UniffiConverterOptionalString.read(buf), 5730 + ) 5731 + 5732 + @staticmethod 5733 + def check_lower(value): 5734 + _UniffiConverterSequenceTypeNotificationView.check_lower(value.notifications) 5735 + _UniffiConverterInt64.check_lower(value.unread_count) 5736 + _UniffiConverterOptionalString.check_lower(value.cursor) 5737 + 5738 + @staticmethod 5739 + def write(value, buf): 5740 + _UniffiConverterSequenceTypeNotificationView.write(value.notifications, buf) 5741 + _UniffiConverterInt64.write(value.unread_count, buf) 5742 + _UniffiConverterOptionalString.write(value.cursor, buf) 5743 + 5744 + 5745 + class NotificationView: 5746 + """ 5747 + A single notification (`app.rocksky.notification.defs#notificationView`). 5748 + """ 5749 + 5750 + id: "str" 5751 + notification_type: "str" 5752 + """ 5753 + One of `like_scrobble`, `follow`, `comment_scrobble`, `comment_profile`, 5754 + `reply`, `react_comment`. 5755 + """ 5756 + 5757 + read: "bool" 5758 + """ 5759 + Whether the notification has been viewed. 5760 + """ 5761 + 5762 + created_at: "str" 5763 + subject_uri: "typing.Optional[str]" 5764 + shout_id: "typing.Optional[str]" 5765 + shout_content: "typing.Optional[str]" 5766 + actor: "typing.Optional[NotificationActor]" 5767 + def __init__(self, *, id: "str", notification_type: "str", read: "bool", created_at: "str", subject_uri: "typing.Optional[str]", shout_id: "typing.Optional[str]", shout_content: "typing.Optional[str]", actor: "typing.Optional[NotificationActor]"): 5768 + self.id = id 5769 + self.notification_type = notification_type 5770 + self.read = read 5771 + self.created_at = created_at 5772 + self.subject_uri = subject_uri 5773 + self.shout_id = shout_id 5774 + self.shout_content = shout_content 5775 + self.actor = actor 5776 + 5777 + def __str__(self): 5778 + return "NotificationView(id={}, notification_type={}, read={}, created_at={}, subject_uri={}, shout_id={}, shout_content={}, actor={})".format(self.id, self.notification_type, self.read, self.created_at, self.subject_uri, self.shout_id, self.shout_content, self.actor) 5779 + 5780 + def __eq__(self, other): 5781 + if self.id != other.id: 5782 + return False 5783 + if self.notification_type != other.notification_type: 5784 + return False 5785 + if self.read != other.read: 5786 + return False 5787 + if self.created_at != other.created_at: 5788 + return False 5789 + if self.subject_uri != other.subject_uri: 5790 + return False 5791 + if self.shout_id != other.shout_id: 5792 + return False 5793 + if self.shout_content != other.shout_content: 5794 + return False 5795 + if self.actor != other.actor: 5796 + return False 5797 + return True 5798 + 5799 + class _UniffiConverterTypeNotificationView(_UniffiConverterRustBuffer): 5800 + @staticmethod 5801 + def read(buf): 5802 + return NotificationView( 5803 + id=_UniffiConverterString.read(buf), 5804 + notification_type=_UniffiConverterString.read(buf), 5805 + read=_UniffiConverterBool.read(buf), 5806 + created_at=_UniffiConverterString.read(buf), 5807 + subject_uri=_UniffiConverterOptionalString.read(buf), 5808 + shout_id=_UniffiConverterOptionalString.read(buf), 5809 + shout_content=_UniffiConverterOptionalString.read(buf), 5810 + actor=_UniffiConverterOptionalTypeNotificationActor.read(buf), 5811 + ) 5812 + 5813 + @staticmethod 5814 + def check_lower(value): 5815 + _UniffiConverterString.check_lower(value.id) 5816 + _UniffiConverterString.check_lower(value.notification_type) 5817 + _UniffiConverterBool.check_lower(value.read) 5818 + _UniffiConverterString.check_lower(value.created_at) 5819 + _UniffiConverterOptionalString.check_lower(value.subject_uri) 5820 + _UniffiConverterOptionalString.check_lower(value.shout_id) 5821 + _UniffiConverterOptionalString.check_lower(value.shout_content) 5822 + _UniffiConverterOptionalTypeNotificationActor.check_lower(value.actor) 5823 + 5824 + @staticmethod 5825 + def write(value, buf): 5826 + _UniffiConverterString.write(value.id, buf) 5827 + _UniffiConverterString.write(value.notification_type, buf) 5828 + _UniffiConverterBool.write(value.read, buf) 5829 + _UniffiConverterString.write(value.created_at, buf) 5830 + _UniffiConverterOptionalString.write(value.subject_uri, buf) 5831 + _UniffiConverterOptionalString.write(value.shout_id, buf) 5832 + _UniffiConverterOptionalString.write(value.shout_content, buf) 5833 + _UniffiConverterOptionalTypeNotificationActor.write(value.actor, buf) 5834 + 5835 + 3886 5836 class NowPlayingInput: 3887 5837 """ 3888 5838 The now-playing track (`app.rocksky.actor.status`). ··· 4611 6561 _UniffiConverterOptionalUInt32.write(value.likes_count, buf) 4612 6562 4613 6563 6564 + class ShoutGifInput: 6565 + """ 6566 + A GIF / sticker / clip to attach to a shout 6567 + (`app.rocksky.shout.defs#gif`). Only `url` is required. 6568 + """ 6569 + 6570 + url: "str" 6571 + """ 6572 + Direct URL of the animated GIF/MP4. 6573 + """ 6574 + 6575 + preview_url: "typing.Optional[str]" 6576 + """ 6577 + Smaller still / preview image URL. 6578 + """ 6579 + 6580 + alt: "typing.Optional[str]" 6581 + """ 6582 + Alternative text describing the media. 6583 + """ 6584 + 6585 + width: "typing.Optional[int]" 6586 + height: "typing.Optional[int]" 6587 + def __init__(self, *, url: "str", preview_url: "typing.Optional[str]" = _DEFAULT, alt: "typing.Optional[str]" = _DEFAULT, width: "typing.Optional[int]" = _DEFAULT, height: "typing.Optional[int]" = _DEFAULT): 6588 + self.url = url 6589 + if preview_url is _DEFAULT: 6590 + self.preview_url = None 6591 + else: 6592 + self.preview_url = preview_url 6593 + if alt is _DEFAULT: 6594 + self.alt = None 6595 + else: 6596 + self.alt = alt 6597 + if width is _DEFAULT: 6598 + self.width = None 6599 + else: 6600 + self.width = width 6601 + if height is _DEFAULT: 6602 + self.height = None 6603 + else: 6604 + self.height = height 6605 + 6606 + def __str__(self): 6607 + return "ShoutGifInput(url={}, preview_url={}, alt={}, width={}, height={})".format(self.url, self.preview_url, self.alt, self.width, self.height) 6608 + 6609 + def __eq__(self, other): 6610 + if self.url != other.url: 6611 + return False 6612 + if self.preview_url != other.preview_url: 6613 + return False 6614 + if self.alt != other.alt: 6615 + return False 6616 + if self.width != other.width: 6617 + return False 6618 + if self.height != other.height: 6619 + return False 6620 + return True 6621 + 6622 + class _UniffiConverterTypeShoutGifInput(_UniffiConverterRustBuffer): 6623 + @staticmethod 6624 + def read(buf): 6625 + return ShoutGifInput( 6626 + url=_UniffiConverterString.read(buf), 6627 + preview_url=_UniffiConverterOptionalString.read(buf), 6628 + alt=_UniffiConverterOptionalString.read(buf), 6629 + width=_UniffiConverterOptionalInt64.read(buf), 6630 + height=_UniffiConverterOptionalInt64.read(buf), 6631 + ) 6632 + 6633 + @staticmethod 6634 + def check_lower(value): 6635 + _UniffiConverterString.check_lower(value.url) 6636 + _UniffiConverterOptionalString.check_lower(value.preview_url) 6637 + _UniffiConverterOptionalString.check_lower(value.alt) 6638 + _UniffiConverterOptionalInt64.check_lower(value.width) 6639 + _UniffiConverterOptionalInt64.check_lower(value.height) 6640 + 6641 + @staticmethod 6642 + def write(value, buf): 6643 + _UniffiConverterString.write(value.url, buf) 6644 + _UniffiConverterOptionalString.write(value.preview_url, buf) 6645 + _UniffiConverterOptionalString.write(value.alt, buf) 6646 + _UniffiConverterOptionalInt64.write(value.width, buf) 6647 + _UniffiConverterOptionalInt64.write(value.height, buf) 6648 + 6649 + 4614 6650 class SongInput: 4615 6651 """ 4616 6652 A canonical track record (`app.rocksky.song`). ··· 4924 6960 _UniffiConverterOptionalString.write(value.created_at, buf) 4925 6961 4926 6962 6963 + class UnreadCount: 6964 + """ 6965 + The unread-notification count (`app.rocksky.notification.getUnreadCount`). 6966 + """ 6967 + 6968 + count: "int" 6969 + def __init__(self, *, count: "int"): 6970 + self.count = count 6971 + 6972 + def __str__(self): 6973 + return "UnreadCount(count={})".format(self.count) 6974 + 6975 + def __eq__(self, other): 6976 + if self.count != other.count: 6977 + return False 6978 + return True 6979 + 6980 + class _UniffiConverterTypeUnreadCount(_UniffiConverterRustBuffer): 6981 + @staticmethod 6982 + def read(buf): 6983 + return UnreadCount( 6984 + count=_UniffiConverterInt64.read(buf), 6985 + ) 6986 + 6987 + @staticmethod 6988 + def check_lower(value): 6989 + _UniffiConverterInt64.check_lower(value.count) 6990 + 6991 + @staticmethod 6992 + def write(value, buf): 6993 + _UniffiConverterInt64.write(value.count, buf) 6994 + 6995 + 6996 + class UpdateSeenResult: 6997 + """ 6998 + The result of marking notifications seen 6999 + (`app.rocksky.notification.updateSeen`). 7000 + """ 7001 + 7002 + unread_count: "int" 7003 + """ 7004 + The number of unread notifications remaining. 7005 + """ 7006 + 7007 + def __init__(self, *, unread_count: "int"): 7008 + self.unread_count = unread_count 7009 + 7010 + def __str__(self): 7011 + return "UpdateSeenResult(unread_count={})".format(self.unread_count) 7012 + 7013 + def __eq__(self, other): 7014 + if self.unread_count != other.unread_count: 7015 + return False 7016 + return True 7017 + 7018 + class _UniffiConverterTypeUpdateSeenResult(_UniffiConverterRustBuffer): 7019 + @staticmethod 7020 + def read(buf): 7021 + return UpdateSeenResult( 7022 + unread_count=_UniffiConverterInt64.read(buf), 7023 + ) 7024 + 7025 + @staticmethod 7026 + def check_lower(value): 7027 + _UniffiConverterInt64.check_lower(value.unread_count) 7028 + 7029 + @staticmethod 7030 + def write(value, buf): 7031 + _UniffiConverterInt64.write(value.unread_count, buf) 7032 + 7033 + 4927 7034 4928 7035 4929 7036 ··· 5337 7444 5338 7445 5339 7446 7447 + class _UniffiConverterOptionalTypeNotificationActor(_UniffiConverterRustBuffer): 7448 + @classmethod 7449 + def check_lower(cls, value): 7450 + if value is not None: 7451 + _UniffiConverterTypeNotificationActor.check_lower(value) 7452 + 7453 + @classmethod 7454 + def write(cls, value, buf): 7455 + if value is None: 7456 + buf.write_u8(0) 7457 + return 7458 + 7459 + buf.write_u8(1) 7460 + _UniffiConverterTypeNotificationActor.write(value, buf) 7461 + 7462 + @classmethod 7463 + def read(cls, buf): 7464 + flag = buf.read_u8() 7465 + if flag == 0: 7466 + return None 7467 + elif flag == 1: 7468 + return _UniffiConverterTypeNotificationActor.read(buf) 7469 + else: 7470 + raise InternalError("Unexpected flag byte for optional type") 7471 + 7472 + 7473 + 5340 7474 class _UniffiConverterOptionalTypeProfile(_UniffiConverterRustBuffer): 5341 7475 @classmethod 5342 7476 def check_lower(cls, value): ··· 5364 7498 5365 7499 5366 7500 7501 + class _UniffiConverterOptionalTypeShoutGifInput(_UniffiConverterRustBuffer): 7502 + @classmethod 7503 + def check_lower(cls, value): 7504 + if value is not None: 7505 + _UniffiConverterTypeShoutGifInput.check_lower(value) 7506 + 7507 + @classmethod 7508 + def write(cls, value, buf): 7509 + if value is None: 7510 + buf.write_u8(0) 7511 + return 7512 + 7513 + buf.write_u8(1) 7514 + _UniffiConverterTypeShoutGifInput.write(value, buf) 7515 + 7516 + @classmethod 7517 + def read(cls, buf): 7518 + flag = buf.read_u8() 7519 + if flag == 0: 7520 + return None 7521 + elif flag == 1: 7522 + return _UniffiConverterTypeShoutGifInput.read(buf) 7523 + else: 7524 + raise InternalError("Unexpected flag byte for optional type") 7525 + 7526 + 7527 + 5367 7528 class _UniffiConverterSequenceString(_UniffiConverterRustBuffer): 5368 7529 @classmethod 5369 7530 def check_lower(cls, value): ··· 5435 7596 5436 7597 return [ 5437 7598 _UniffiConverterTypeArtistView.read(buf) for i in range(count) 7599 + ] 7600 + 7601 + 7602 + 7603 + class _UniffiConverterSequenceTypeNotificationView(_UniffiConverterRustBuffer): 7604 + @classmethod 7605 + def check_lower(cls, value): 7606 + for item in value: 7607 + _UniffiConverterTypeNotificationView.check_lower(item) 7608 + 7609 + @classmethod 7610 + def write(cls, value, buf): 7611 + items = len(value) 7612 + buf.write_i32(items) 7613 + for item in value: 7614 + _UniffiConverterTypeNotificationView.write(item, buf) 7615 + 7616 + @classmethod 7617 + def read(cls, buf): 7618 + count = buf.read_i32() 7619 + if count < 0: 7620 + raise InternalError("Unexpected negative sequence length") 7621 + 7622 + return [ 7623 + _UniffiConverterTypeNotificationView.read(buf) for i in range(count) 5438 7624 ] 5439 7625 5440 7626 ··· 5586 7772 "ArtistInput", 5587 7773 "ArtistView", 5588 7774 "GlobalStats", 7775 + "NotificationActor", 7776 + "NotificationList", 7777 + "NotificationView", 5589 7778 "NowPlayingInput", 5590 7779 "Profile", 5591 7780 "ProfileView", ··· 5593 7782 "ScrobbleMatchInput", 5594 7783 "ScrobbleResult", 5595 7784 "ScrobbleView", 7785 + "ShoutGifInput", 5596 7786 "SongInput", 5597 7787 "SongView", 7788 + "UnreadCount", 7789 + "UpdateSeenResult", 5598 7790 "album_hash", 5599 7791 "artist_hash", 5600 7792 "song_hash", 5601 7793 "Agent", 5602 7794 "AppView", 7795 + "Library", 5603 7796 ] 5604 7797
+45
sdk/ruby/lib/rocksky.rb
··· 27 27 "char* rocksky_top_tracks(const char*, unsigned int, unsigned int)", 28 28 "char* rocksky_global_stats(const char*)", 29 29 "char* rocksky_get(const char*, const char*, const char*, const char*)", 30 + "char* rocksky_update_seen(const char*, const char*, const char*)", 30 31 "char* rocksky_library_get(const char*, const char*, const char*, const char*)", 31 32 "char* rocksky_library_post(const char*, const char*, const char*, const char*)", 32 33 "char* rocksky_match_song(const char*, const char*, const char*, const char*, const char*)", ··· 44 45 "char* rocksky_agent_like(void*, const char*, const char*)", 45 46 "char* rocksky_agent_follow(void*, const char*)", 46 47 "char* rocksky_agent_shout(void*, const char*, const char*, const char*)", 48 + "char* rocksky_agent_shout_with_gif(void*, const char*, const char*, const char*, const char*)", 49 + "char* rocksky_agent_reply_shout_with_gif(void*, const char*, const char*, const char*, const char*, const char*, const char*)", 47 50 "char* rocksky_agent_refresh_session(void*)" 48 51 ].each { |sig| extern sig } 49 52 end ··· 102 105 unwrap(C.rocksky_get(base.to_s, nsid, JSON.generate(params), token.to_s)) 103 106 end 104 107 108 + # ---- notifications (auth-gated; +token+ required) ---- 109 + 110 + # The authenticated viewer's unread-notification count. Returns 111 + # { "count" => Integer }. 112 + def self.unread_count(token:, base: nil) 113 + get("app.rocksky.notification.getUnreadCount", {}, base: base, token: token) 114 + end 115 + 116 + # The authenticated viewer's notifications, most recent first. +limit+ defaults 117 + # to 30 server-side; +cursor+ paginates. Returns 118 + # { "notifications" => [...], "unreadCount" => Integer, "cursor" => String? }. 119 + def self.notifications(token:, limit: nil, cursor: nil, base: nil) 120 + params = {} 121 + params[:limit] = limit unless limit.nil? 122 + params[:cursor] = cursor unless cursor.nil? 123 + get("app.rocksky.notification.listNotifications", params, base: base, token: token) 124 + end 125 + 126 + # Mark notifications as viewed. +ids+ is an array of notification ids, or an 127 + # empty array to mark *all* as viewed. Returns { "unreadCount" => Integer }. 128 + def self.update_seen(token:, ids: [], base: nil) 129 + unwrap(C.rocksky_update_seen(base.to_s, token.to_s, JSON.generate(ids))) 130 + end 131 + 105 132 # Resolve full canonical metadata for a bare title + artist (matchSong). 106 133 def self.match_song(title, artist, mb_id: nil, isrc: nil, base: nil) 107 134 unwrap(C.rocksky_match_song(base.to_s, title, artist, mb_id.to_s, isrc.to_s)) ··· 198 225 199 226 def shout(subject_uri, subject_cid, message) 200 227 Rocksky.unwrap(C.rocksky_agent_shout(@ptr, subject_uri, subject_cid, message)) 228 + end 229 + 230 + # Post a shout with an optional GIF/sticker/clip attachment. Pass at least 231 + # one of +message+ / +gif+. +gif+ is a Hash with camelCase keys ("url" 232 + # required, plus "previewUrl", "alt", "width", "height"). 233 + def shout_with_gif(subject_uri, subject_cid, message: nil, gif: nil) 234 + Rocksky.unwrap(C.rocksky_agent_shout_with_gif( 235 + @ptr, subject_uri, subject_cid, message.to_s, gif ? JSON.generate(gif) : "" 236 + )) 237 + end 238 + 239 + # Reply to a shout with an optional GIF/sticker/clip attachment. Semantics 240 + # match #shout_with_gif, plus a parent strong-ref (+parent_uri+/+parent_cid+). 241 + def reply_shout_with_gif(subject_uri, subject_cid, parent_uri, parent_cid, message: nil, gif: nil) 242 + Rocksky.unwrap(C.rocksky_agent_reply_shout_with_gif( 243 + @ptr, subject_uri, subject_cid, parent_uri, parent_cid, 244 + message.to_s, gif ? JSON.generate(gif) : "" 245 + )) 201 246 end 202 247 203 248 def refresh_session
+1 -1
sdk/ruby/lib/rocksky/version.rb
··· 1 1 # frozen_string_literal: true 2 2 3 3 module Rocksky 4 - VERSION = "0.7.0" 4 + VERSION = "0.8.0" 5 5 end
+1 -1
sdk/typescript/package.json
··· 1 1 { 2 2 "name": "@rocksky/sdk", 3 - "version": "0.7.3", 3 + "version": "0.8.0", 4 4 "description": "TypeScript SDK for Rocksky \u2014 built on atcute: AppView reads, AT Protocol PDS writes (scrobble, like, follow, shout), a local dedup index, and Jetstream real-time sync.", 5 5 "license": "MIT", 6 6 "repository": {
+17 -6
sdk/typescript/src/agent.ts
··· 16 16 ArtistRecord, 17 17 ActorTrackView, 18 18 ScrobbleRecord, 19 + ShoutGif, 19 20 SongRecord, 20 21 } from "./generated/types.js"; 21 22 import type { IndexStats, RockskyIndex } from "./dedup.js"; ··· 303 304 return this.create(C_FOLLOW, { subject: did, createdAt: nowISO() }); 304 305 } 305 306 306 - /** Post a shout on a subject. Returns the shout URI. */ 307 - shout(subjectUri: string, subjectCid: string, message: string): Promise<string> { 308 - return this.create(C_SHOUT, { subject: { uri: subjectUri, cid: subjectCid }, message, createdAt: nowISO() }); 307 + /** Post a shout on a subject. Returns the shout URI. Pass at least one of 308 + * `message` / `gif` — `message` may be omitted when a GIF/sticker/clip is 309 + * attached. */ 310 + shout(subjectUri: string, subjectCid: string, message?: string, gif?: ShoutGif): Promise<string> { 311 + return this.create(C_SHOUT, { 312 + subject: { uri: subjectUri, cid: subjectCid }, 313 + ...(message !== undefined ? { message } : {}), 314 + ...(gif ? { gif } : {}), 315 + createdAt: nowISO(), 316 + }); 309 317 } 310 318 311 - /** Reply to a shout, with a parent strong-ref. */ 319 + /** Reply to a shout, with a parent strong-ref. Pass at least one of `message` 320 + * / `gif` — `message` may be omitted when a GIF/sticker/clip is attached. */ 312 321 replyShout( 313 322 subjectUri: string, 314 323 subjectCid: string, 315 324 parentUri: string, 316 325 parentCid: string, 317 - message: string, 326 + message?: string, 327 + gif?: ShoutGif, 318 328 ): Promise<string> { 319 329 return this.create(C_SHOUT, { 320 330 subject: { uri: subjectUri, cid: subjectCid }, 321 331 parent: { uri: parentUri, cid: parentCid }, 322 - message, 332 + ...(message !== undefined ? { message } : {}), 333 + ...(gif ? { gif } : {}), 323 334 createdAt: nowISO(), 324 335 }); 325 336 }
+99 -34
sdk/typescript/src/client.ts
··· 6 6 ActorProfileViewBasic, 7 7 ActorProfileViewDetailed, 8 8 AlbumViewBasic, 9 + AlbumViewDetailed, 9 10 ArtistViewBasic, 11 + ArtistViewDetailed, 12 + ChartsView, 13 + FeedGeneratorsView, 14 + FeedRecommendationsView, 15 + FeedRecommendedAlbumsView, 16 + FeedRecommendedArtistsView, 10 17 FeedSearchResultsView, 18 + FeedStoriesView, 19 + FeedView, 11 20 GetActorAlbumsOutput, 12 21 GetActorArtistsOutput, 22 + GetActorCompatibilityOutput, 23 + GetActorNeighboursOutput, 24 + GetActorPlaylistsOutput, 13 25 GetActorScrobblesOutput, 26 + GetAlbumShoutsOutput, 27 + GetApikeysOutput, 28 + GetArtistListenersOutput, 29 + GetArtistRecentListenersOutput, 30 + GetArtistShoutsOutput, 31 + GetFeedGeneratorOutput, 32 + GetMirrorSourcesOutput, 33 + GetProfileShoutsOutput, 34 + GetShoutRepliesOutput, 35 + GetSongRecentListenersOutput, 36 + GetTrackShoutsOutput, 37 + GetUnreadCountOutput, 38 + ListNotificationsOutput, 39 + PlayerCurrentlyPlayingViewDetailed, 40 + PlayerPlaybackQueueViewDetailed, 41 + PlaylistGetPlaylistsOutput, 42 + PlaylistViewDetailed, 43 + RockboxSettingsView, 14 44 ScrobbleViewBasic, 15 45 SongViewBasic, 46 + SongViewDetailed, 16 47 StatsGlobalStatsView, 48 + StatsView, 49 + StatsWrappedView, 50 + UpdateSeenOutput, 17 51 } from "./generated/types.js"; 18 52 19 53 /** ··· 303 337 return this.query("app.rocksky.stats.getGlobalStats", {}); 304 338 } 305 339 306 - // ---- raw-JSON long tail: bespoke shapes returned as `unknown` ---------- 340 + // ---- detail reads (typed against the generated lexicon views) ---------- 307 341 308 342 /** A feed by its at:// URI (paginate via `cursor`). */ 309 - feed(feed: string, limit = 50, cursor?: string): Promise<unknown> { 343 + feed(feed: string, limit = 50, cursor?: string): Promise<FeedView> { 310 344 return this.query("app.rocksky.feed.getFeed", { feed, limit, cursor }); 311 345 } 312 346 /** A single album with its tracklist. */ 313 - album(uri: string): Promise<unknown> { 347 + album(uri: string): Promise<AlbumViewDetailed> { 314 348 return this.query("app.rocksky.album.getAlbum", { uri }); 315 349 } 316 350 /** A single artist with detail. */ 317 - artist(uri: string): Promise<unknown> { 351 + artist(uri: string): Promise<ArtistViewDetailed> { 318 352 return this.query("app.rocksky.artist.getArtist", { uri }); 319 353 } 320 354 /** Resolve full canonical metadata for a bare title + artist 321 355 * (`app.rocksky.song.matchSong`); optionally anchor with `mbId` / `isrc`. */ 322 - matchSong(title: string, artist: string, mbId?: string, isrc?: string): Promise<unknown> { 356 + matchSong(title: string, artist: string, mbId?: string, isrc?: string): Promise<SongViewDetailed> { 323 357 return this.query("app.rocksky.song.matchSong", { title, artist, mbId, isrc }); 324 358 } 325 359 /** A single song by at:// `uri` (or by `mbid` / `isrc` / `spotifyId`). */ 326 - song(opts: { uri?: string; mbid?: string; isrc?: string; spotifyId?: string }): Promise<unknown> { 360 + song(opts: { 361 + uri?: string; 362 + mbid?: string; 363 + isrc?: string; 364 + spotifyId?: string; 365 + }): Promise<SongViewDetailed> { 327 366 return this.query("app.rocksky.song.getSong", opts); 328 367 } 329 368 /** An actor's playlists. */ 330 - actorPlaylists(actor: string, limit = 50, offset = 0): Promise<unknown> { 369 + actorPlaylists(actor: string, limit = 50, offset = 0): Promise<GetActorPlaylistsOutput> { 331 370 return this.query("app.rocksky.actor.getActorPlaylists", { did: actor, limit, offset }); 332 371 } 333 372 /** Actors with similar taste to `actor`. */ 334 - neighbours(actor: string): Promise<unknown> { 373 + neighbours(actor: string): Promise<GetActorNeighboursOutput> { 335 374 return this.query("app.rocksky.actor.getActorNeighbours", { did: actor }); 336 375 } 337 376 /** Music compatibility between the viewer and `actor` (auth). */ 338 - compatibility(actor: string): Promise<unknown> { 377 + compatibility(actor: string): Promise<GetActorCompatibilityOutput> { 339 378 return this.query("app.rocksky.actor.getActorCompatibility", { did: actor }); 340 379 } 341 380 /** An artist's all-time listeners. */ 342 - artistListeners(uri: string, limit = 50, offset = 0): Promise<unknown> { 381 + artistListeners(uri: string, limit = 50, offset = 0): Promise<GetArtistListenersOutput> { 343 382 return this.query("app.rocksky.artist.getArtistListeners", { uri, limit, offset }); 344 383 } 345 384 /** An artist's recent listeners. */ 346 - artistRecentListeners(uri: string, limit = 50, offset = 0): Promise<unknown> { 385 + artistRecentListeners( 386 + uri: string, 387 + limit = 50, 388 + offset = 0, 389 + ): Promise<GetArtistRecentListenersOutput> { 347 390 return this.query("app.rocksky.artist.getArtistRecentListeners", { uri, limit, offset }); 348 391 } 349 392 /** A song's recent listeners. */ 350 - songRecentListeners(uri: string, limit = 50, offset = 0): Promise<unknown> { 393 + songRecentListeners(uri: string, limit = 50, offset = 0): Promise<GetSongRecentListenersOutput> { 351 394 return this.query("app.rocksky.song.getSongRecentListeners", { uri, limit, offset }); 352 395 } 353 396 /** A scrobble time-series chart. Scope with any of `did` / `artisturi` / ··· 360 403 genre?: string; 361 404 from?: string; 362 405 to?: string; 363 - }): Promise<unknown> { 406 + }): Promise<ChartsView> { 364 407 return this.query("app.rocksky.charts.getScrobblesChart", opts); 365 408 } 366 409 /** List the available feed generators. */ 367 - feedGenerators(size?: number): Promise<unknown> { 410 + feedGenerators(size?: number): Promise<FeedGeneratorsView> { 368 411 return this.query("app.rocksky.feed.getFeedGenerators", { size }); 369 412 } 370 413 /** A single feed generator's record. */ 371 - feedGenerator(feed: string): Promise<unknown> { 414 + feedGenerator(feed: string): Promise<GetFeedGeneratorOutput> { 372 415 return this.query("app.rocksky.feed.getFeedGenerator", { feed }); 373 416 } 374 417 /** The stories row. */ 375 - stories(size?: number, feed?: string, following?: boolean): Promise<unknown> { 418 + stories(size?: number, feed?: string, following?: boolean): Promise<FeedStoriesView> { 376 419 return this.query("app.rocksky.feed.getStories", { size, feed, following }); 377 420 } 378 421 /** Track recommendations for `actor`. */ 379 - recommendations(actor: string, limit?: number): Promise<unknown> { 422 + recommendations(actor: string, limit?: number): Promise<FeedRecommendationsView> { 380 423 return this.query("app.rocksky.feed.getRecommendations", { did: actor, limit }); 381 424 } 382 425 /** Artist recommendations for `actor`. */ 383 - artistRecommendations(actor: string, limit?: number): Promise<unknown> { 426 + artistRecommendations(actor: string, limit?: number): Promise<FeedRecommendedArtistsView> { 384 427 return this.query("app.rocksky.feed.getArtistRecommendations", { did: actor, limit }); 385 428 } 386 429 /** Album recommendations for `actor`. */ 387 - albumRecommendations(actor: string, limit?: number): Promise<unknown> { 430 + albumRecommendations(actor: string, limit?: number): Promise<FeedRecommendedAlbumsView> { 388 431 return this.query("app.rocksky.feed.getAlbumRecommendations", { did: actor, limit }); 389 432 } 390 433 /** An actor's aggregate stats. */ 391 - stats(actor: string): Promise<unknown> { 434 + stats(actor: string): Promise<StatsView> { 392 435 return this.query("app.rocksky.stats.getStats", { did: actor }); 393 436 } 394 437 /** An actor's year-in-review. */ 395 - wrapped(actor: string, year?: number): Promise<unknown> { 438 + wrapped(actor: string, year?: number): Promise<StatsWrappedView> { 396 439 return this.query("app.rocksky.stats.getWrapped", { did: actor, year }); 397 440 } 398 441 /** The viewer's configured scrobble mirror sources (auth). */ 399 - mirrorSources(): Promise<unknown> { 442 + mirrorSources(): Promise<GetMirrorSourcesOutput> { 400 443 return this.query("app.rocksky.mirror.getMirrorSources", {}); 401 444 } 402 445 /** What `actor` is playing now. */ 403 - currentlyPlaying(playerId?: string, actor?: string): Promise<unknown> { 446 + currentlyPlaying(playerId?: string, actor?: string): Promise<PlayerCurrentlyPlayingViewDetailed> { 404 447 return this.query("app.rocksky.player.getCurrentlyPlaying", { playerId, actor }); 405 448 } 406 449 /** A player's playback queue. */ 407 - playbackQueue(playerId: string): Promise<unknown> { 450 + playbackQueue(playerId: string): Promise<PlayerPlaybackQueueViewDetailed> { 408 451 return this.query("app.rocksky.player.getPlaybackQueue", { playerId }); 409 452 } 410 453 /** What `actor` is playing now on Spotify. */ 411 - spotifyCurrentlyPlaying(actor: string): Promise<unknown> { 454 + spotifyCurrentlyPlaying(actor: string): Promise<PlayerCurrentlyPlayingViewDetailed> { 412 455 return this.query("app.rocksky.spotify.getCurrentlyPlaying", { actor }); 413 456 } 414 457 /** The playlist catalog. */ 415 - playlists(limit = 50, offset = 0): Promise<unknown> { 458 + playlists(limit = 50, offset = 0): Promise<PlaylistGetPlaylistsOutput> { 416 459 return this.query("app.rocksky.playlist.getPlaylists", { limit, offset }); 417 460 } 418 461 /** A single playlist with its items. */ 419 - playlist(uri: string): Promise<unknown> { 462 + playlist(uri: string): Promise<PlaylistViewDetailed> { 420 463 return this.query("app.rocksky.playlist.getPlaylist", { uri }); 421 464 } 422 465 /** Shouts on an album. */ 423 - albumShouts(uri: string, limit = 50, offset = 0): Promise<unknown> { 466 + albumShouts(uri: string, limit = 50, offset = 0): Promise<GetAlbumShoutsOutput> { 424 467 return this.query("app.rocksky.shout.getAlbumShouts", { uri, limit, offset }); 425 468 } 426 469 /** Shouts on an artist. */ 427 - artistShouts(uri: string, limit = 50, offset = 0): Promise<unknown> { 470 + artistShouts(uri: string, limit = 50, offset = 0): Promise<GetArtistShoutsOutput> { 428 471 return this.query("app.rocksky.shout.getArtistShouts", { uri, limit, offset }); 429 472 } 430 473 /** Shouts on a profile. */ 431 - profileShouts(actor: string, limit = 50, offset = 0): Promise<unknown> { 474 + profileShouts(actor: string, limit = 50, offset = 0): Promise<GetProfileShoutsOutput> { 432 475 return this.query("app.rocksky.shout.getProfileShouts", { did: actor, limit, offset }); 433 476 } 434 477 /** Shouts on a track. */ 435 - trackShouts(uri: string): Promise<unknown> { 478 + trackShouts(uri: string): Promise<GetTrackShoutsOutput> { 436 479 return this.query("app.rocksky.shout.getTrackShouts", { uri }); 437 480 } 438 481 /** Replies to a shout. */ 439 - shoutReplies(uri: string, limit = 50, offset = 0): Promise<unknown> { 482 + shoutReplies(uri: string, limit = 50, offset = 0): Promise<GetShoutRepliesOutput> { 440 483 return this.query("app.rocksky.shout.getShoutReplies", { uri, limit, offset }); 441 484 } 442 485 /** An actor's Rockbox EQ / audio settings. */ 443 - audioSettings(actor: string): Promise<unknown> { 486 + audioSettings(actor: string): Promise<RockboxSettingsView> { 444 487 return this.query("app.rocksky.rockbox.getAudioSettings", { did: actor }); 445 488 } 446 489 /** The viewer's API keys (auth). */ 447 - apikeys(limit = 50, offset = 0): Promise<unknown> { 490 + apikeys(limit = 50, offset = 0): Promise<GetApikeysOutput> { 448 491 return this.query("app.rocksky.apikey.getApikeys", { limit, offset }); 492 + } 493 + 494 + // ---- notifications (auth-gated — construct the client with a token) ----- 495 + 496 + /** The authenticated viewer's unread-notification count. */ 497 + unreadCount(): Promise<GetUnreadCountOutput> { 498 + return this.query("app.rocksky.notification.getUnreadCount", {}); 499 + } 500 + /** The authenticated viewer's notifications, most recent first. `limit` 501 + * defaults to 30 server-side; paginate via `cursor`. */ 502 + notifications(limit = 30, cursor?: string): Promise<ListNotificationsOutput> { 503 + return this.query("app.rocksky.notification.listNotifications", { limit, cursor }); 504 + } 505 + /** Mark notifications as viewed. Pass the notification `ids` to mark, or omit 506 + * to mark **all** of the viewer's notifications. Returns the number remaining 507 + * unread. */ 508 + async updateSeen(ids?: string[]): Promise<UpdateSeenOutput> { 509 + const res = await this.rpc.post("app.rocksky.notification.updateSeen" as never, { 510 + input: (ids && ids.length ? { ids } : {}) as never, 511 + } as never); 512 + if (!res.ok) throw new RockskyError(res.data); 513 + return res.data as UpdateSeenOutput; 449 514 } 450 515 }
+97 -6
sdk/typescript/src/generated/types.ts
··· 492 492 feeds?: FeedUriView[]; 493 493 } 494 494 495 - export interface DescribeFeedGeneratorParams { 496 - 497 - } 498 - 499 495 export interface DislikeShoutInput { 500 496 /** The unique identifier of the shout to dislike */ 501 497 uri?: AtUri; ··· 1407 1403 uri: AtUri; 1408 1404 } 1409 1405 1406 + export interface GetUnreadCountOutput { 1407 + /** The number of unread notifications. */ 1408 + count: number; 1409 + } 1410 + 1410 1411 export interface GetUserOutput { 1411 1412 1412 1413 } ··· 1570 1571 uri?: AtUri; 1571 1572 } 1572 1573 1574 + export interface ListNotificationsOutput { 1575 + notifications: NotificationView[]; 1576 + /** The number of unread notifications. */ 1577 + unreadCount: number; 1578 + /** A cursor value to pass to subsequent calls to get the next page of results. */ 1579 + cursor?: string; 1580 + } 1581 + 1582 + export interface ListNotificationsParams { 1583 + limit?: number; 1584 + cursor?: string; 1585 + } 1586 + 1573 1587 export interface MatchSongParams { 1574 1588 /** The title of the song to retrieve */ 1575 1589 title: string; ··· 1596 1610 lastScrobbleSeenAt?: DateTime; 1597 1611 } 1598 1612 1613 + /** The user who triggered a notification. */ 1614 + export interface NotificationActor { 1615 + /** The unique identifier of the actor. */ 1616 + id?: string; 1617 + /** The decentralized identifier of the actor. */ 1618 + did?: Did; 1619 + /** The handle of the actor. */ 1620 + handle?: AtIdentifier; 1621 + /** The display name of the actor. */ 1622 + displayName?: string; 1623 + /** The URL of the actor's avatar image. */ 1624 + avatar?: Uri; 1625 + } 1626 + 1627 + export interface NotificationView { 1628 + /** The unique identifier of the notification. */ 1629 + id: string; 1630 + /** The notification type: like_scrobble, follow, comment_scrobble, comment_profile, reply, or react_comment. */ 1631 + type: string; 1632 + /** Whether the notification has been viewed. */ 1633 + read: boolean; 1634 + /** When the notification was created. */ 1635 + createdAt: DateTime; 1636 + /** The at-uri of the subject the notification relates to. */ 1637 + subjectUri?: string; 1638 + /** The id of the related shout, if any. */ 1639 + shoutId?: string; 1640 + /** The content of the related shout, if any. */ 1641 + shoutContent?: string; 1642 + actor?: NotificationActor; 1643 + } 1644 + 1599 1645 export interface PingOutput { 1600 1646 1601 1647 } ··· 2133 2179 displayName?: string; 2134 2180 /** The URL of the author's avatar image. */ 2135 2181 avatar?: Uri; 2182 + } 2183 + 2184 + /** A GIF, sticker, or clip embedded in a shout. `url` may point at an image (GIF/WebP) or a video (MP4); the client decides how to render it from the file extension. */ 2185 + export interface ShoutGif { 2186 + /** Direct URL of the animated GIF/MP4. */ 2187 + url: Uri; 2188 + /** Smaller still/preview image URL. */ 2189 + previewUrl?: Uri; 2190 + /** Alternative text describing the media. */ 2191 + alt?: string; 2192 + /** The intrinsic width of the media in pixels. */ 2193 + width?: number; 2194 + /** The intrinsic height of the media in pixels. */ 2195 + height?: number; 2196 + } 2197 + 2198 + /** A mention of another actor within the shout message, anchored to a UTF-8 byte range in the message. */ 2199 + export interface ShoutMention { 2200 + /** The DID of the mentioned actor. */ 2201 + did: Did; 2202 + /** Inclusive UTF-8 byte offset of the mention start. */ 2203 + byteStart: number; 2204 + /** Exclusive UTF-8 byte offset of the mention end. */ 2205 + byteEnd: number; 2136 2206 } 2137 2207 2138 2208 export interface ShoutRecord { 2139 - /** The message of the shout. */ 2140 - message: string; 2209 + /** The message of the shout. Optional when a gif/sticker/clip is attached. */ 2210 + message?: string; 2141 2211 /** The date when the shout was created. */ 2142 2212 createdAt: DateTime; 2143 2213 parent?: StrongRef; 2144 2214 subject: StrongRef; 2215 + /** An attached GIF, sticker, or clip (e.g. from KLIPY). */ 2216 + gif?: ShoutGif; 2217 + /** Mentions of other actors within the message, anchored to UTF-8 byte ranges. */ 2218 + facets?: ShoutMention[]; 2145 2219 } 2146 2220 2147 2221 export interface ShoutView { ··· 2155 2229 createdAt?: DateTime; 2156 2230 /** The author of the shout. */ 2157 2231 author?: ShoutAuthor; 2232 + /** An attached GIF, sticker, or clip. */ 2233 + gif?: ShoutGif; 2234 + /** Mentions of other actors within the message, anchored to UTF-8 byte ranges. */ 2235 + facets?: ShoutMention[]; 2158 2236 } 2159 2237 2160 2238 export interface SongFirstScrobbleView { ··· 2596 2674 2597 2675 } 2598 2676 2677 + export interface UpdateSeenInput { 2678 + /** The ids of the notifications to mark as viewed. Omit to mark all. */ 2679 + ids?: string[]; 2680 + } 2681 + 2682 + export interface UpdateSeenOutput { 2683 + /** The number of unread notifications remaining. */ 2684 + unreadCount: number; 2685 + } 2686 + 2599 2687 /** 2600 2688 * Map of every XRPC method (NSID) to the type of its response body. 2601 2689 * Endpoints with no output map to `void`. Used by the SDK to type method ··· 2697 2785 "app.rocksky.like.likeSong": SongViewDetailed; 2698 2786 "app.rocksky.mirror.getMirrorSources": GetMirrorSourcesOutput; 2699 2787 "app.rocksky.mirror.putMirrorSource": MirrorSourceView; 2788 + "app.rocksky.notification.getUnreadCount": GetUnreadCountOutput; 2789 + "app.rocksky.notification.listNotifications": ListNotificationsOutput; 2790 + "app.rocksky.notification.updateSeen": UpdateSeenOutput; 2700 2791 "app.rocksky.player.addDirectoryToQueue": void; 2701 2792 "app.rocksky.player.addItemsToQueue": void; 2702 2793 "app.rocksky.player.getCurrentlyPlaying": PlayerCurrentlyPlayingViewDetailed;