···1+{
2+ "lexicon": 1,
3+ "id": "app.rocksky.player.addItemsToQueue",
4+ "defs": {
5+ "main": {
6+ "type": "procedure",
7+ "description": "Add items to the player's queue",
8+ "parameters": {
9+ "type": "params",
10+ "required": [
11+ "items"
12+ ],
13+ "properties": {
14+ "playerId": {
15+ "type": "string"
16+ },
17+ "items": {
18+ "type": "array",
19+ "items": {
20+ "type": "string",
21+ "description": "List of file identifiers to add to the queue"
22+ }
23+ },
24+ "position": {
25+ "type": "integer",
26+ "description": "Position in the queue to insert the items at, defaults to the end if not specified"
27+ }
28+ }
29+ }
30+ }
31+ }
32+}
+12
apps/api/lexicons/player/defs.json
···10 "description": "The title of the currently playing track"
11 }
12 }
00000000000013 }
14 }
15}
···10 "description": "The title of the currently playing track"
11 }
12 }
13+ },
14+ "playbackQueueViewDetailed": {
15+ "type": "object",
16+ "properties": {
17+ "tracks": {
18+ "type": "array",
19+ "items": {
20+ "type": "ref",
21+ "ref": "app.rocksky.song.defs.songViewBasic"
22+ }
23+ }
24+ }
25 }
26 }
27}
+3
apps/api/lexicons/player/getCurrentlyPlaying.json
···8 "parameters": {
9 "type": "params",
10 "properties": {
00011 "actor": {
12 "type": "string",
13 "description": "Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user.",
···8 "parameters": {
9 "type": "params",
10 "properties": {
11+ "playerId": {
12+ "type": "string"
13+ },
14 "actor": {
15 "type": "string",
16 "description": "Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user.",
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.player.addItemsToQueue"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Add items to the player's queue"
9+ parameters {
10+ type = "params"
11+ required = List("items")
12+ properties {
13+ ["playerId"] = new StringType {
14+ type = "string"
15+ }
16+ ["items"] = new Array {
17+ type = "array"
18+ items = new StringType {
19+ type = "string"
20+ description = "List of file identifiers to add to the queue"
21+ }
22+ }
23+ ["position"] = new IntegerType {
24+ type = "integer"
25+ description = "Position in the queue to insert the items at, defaults to the end if not specified"
26+ }
27+ }
28+ }
29+ }
30+}
···12 }
13 }
14 }
15+ ["playbackQueueViewDetailed"] {
16+ type = "object"
17+ properties {
18+ ["tracks"] = new Array {
19+ type = "array"
20+ items = new Ref {
21+ type = "ref"
22+ ref = "app.rocksky.song.defs.songViewBasic"
23+ }
24+ }
25+ }
26+ }
27}
+3
apps/api/pkl/defs/player/getCurrentlyPlaying.pkl
···9 parameters {
10 type = "params"
11 properties {
00012 ["actor"] = new StringType {
13 type = "string"
14 format = "at-identifier"
···9 parameters {
10 type = "params"
11 properties {
12+ ["playerId"] = new StringType {
13+ type = "string"
14+ }
15 ["actor"] = new StringType {
16 type = "string"
17 format = "at-identifier"
+25
apps/api/pkl/defs/player/getPlaybackQueue.pkl
···0000000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.player.getPlaybackQueue"
5+defs = new Mapping<String, Query> {
6+ ["main"] {
7+ type = "query"
8+ description = "Retrieve the current playback queue"
9+ parameters {
10+ type = "params"
11+ properties {
12+ ["playerId"] = new StringType {
13+ type = "string"
14+ }
15+ }
16+ }
17+ output {
18+ encoding = "application/json"
19+ schema = new Ref {
20+ type = "ref"
21+ ref = "app.rocksky.player.defs#playbackQueueViewDetailed"
22+ }
23+ }
24+ }
25+}
+8
apps/api/pkl/defs/player/next.pkl
···6 ["main"] {
7 type = "procedure"
8 description = "Play the next track in the queue"
000000009 }
10}
···6 ["main"] {
7 type = "procedure"
8 description = "Play the next track in the queue"
9+ parameters {
10+ type = "params"
11+ properties {
12+ ["playerId"] = new StringType {
13+ type = "string"
14+ }
15+ }
16+ }
17 }
18}
+8
apps/api/pkl/defs/player/pause.pkl
···6 ["main"] {
7 type = "procedure"
8 description = "Pause the currently playing track"
000000009 }
10}
···6 ["main"] {
7 type = "procedure"
8 description = "Pause the currently playing track"
9+ parameters {
10+ type = "params"
11+ properties {
12+ ["playerId"] = new StringType {
13+ type = "string"
14+ }
15+ }
16+ }
17 }
18}
+8
apps/api/pkl/defs/player/play.pkl
···6 ["main"] {
7 type = "procedure"
8 description = "Resume playback of the currently paused track"
000000009 }
10}
···6 ["main"] {
7 type = "procedure"
8 description = "Resume playback of the currently paused track"
9+ parameters {
10+ type = "params"
11+ properties {
12+ ["playerId"] = new StringType {
13+ type = "string"
14+ }
15+ }
16+ }
17 }
18}
+22
apps/api/pkl/defs/player/playDirectory.pkl
···0000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.player.playDirectory"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Play all tracks in a directory"
9+ parameters {
10+ type = "params"
11+ required = List("directoryId")
12+ properties {
13+ ["playerId"] = new StringType {
14+ type = "string"
15+ }
16+ ["directoryId"] = new StringType {
17+ type = "string"
18+ }
19+ }
20+ }
21+ }
22+}
+22
apps/api/pkl/defs/player/playFile.pkl
···0000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.player.playFile"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Play a specific audio file"
9+ parameters {
10+ type = "params"
11+ required = List("fileId")
12+ properties {
13+ ["playerId"] = new StringType {
14+ type = "string"
15+ }
16+ ["fileId"] = new StringType {
17+ type = "string"
18+ }
19+ }
20+ }
21+ }
22+}
+8
apps/api/pkl/defs/player/previous.pkl
···6 ["main"] {
7 type = "procedure"
8 description = "Play the previous track in the queue"
000000009 }
10}
···6 ["main"] {
7 type = "procedure"
8 description = "Play the previous track in the queue"
9+ parameters {
10+ type = "params"
11+ properties {
12+ ["playerId"] = new StringType {
13+ type = "string"
14+ }
15+ }
16+ }
17 }
18}
+5-2
apps/api/pkl/defs/player/seek.pkl
···9 parameters {
10 type = "params"
11 required = List("position")
12- properties = new Mapping<String, IntegerType> {
13- ["position"] {
00014 type = "integer"
15 description = "The position in seconds to seek to"
16 }
···9 parameters {
10 type = "params"
11 required = List("position")
12+ properties = new Mapping<String, StringType | IntegerType> {
13+ ["playerId"] = new StringType {
14+ type = "string"
15+ }
16+ ["position"] = new IntegerType {
17 type = "integer"
18 description = "The position in seconds to seek to"
19 }
+24
apps/api/pkl/defs/playlist/createPlaylist.pkl
···000000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.playlist.createPlaylist"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Create a new playlist"
9+ parameters {
10+ type = "params"
11+ required = List("name")
12+ properties {
13+ ["name"] = new StringType {
14+ type = "string"
15+ description = "The name of the playlist"
16+ }
17+ ["description"] = new StringType {
18+ type = "string"
19+ description = "A brief description of the playlist"
20+ }
21+ }
22+ }
23+ }
24+}
+25
apps/api/pkl/defs/playlist/insertDirectory.pkl
···0000000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.playlist.insertDirectory"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Insert a directory into a playlist"
9+ parameters {
10+ type = "params"
11+ required = List("uri")
12+ properties {
13+ ["uri"] = new StringType {
14+ type = "string"
15+ description = "The URI of the playlist to start"
16+ format = "at-uri"
17+ }
18+ ["directory"] = new StringType {
19+ type = "string"
20+ description = "The directory (id) to insert into the playlist"
21+ }
22+ }
23+ }
24+ }
25+}
+28
apps/api/pkl/defs/playlist/insertFiles.pkl
···0000000000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.playlist.insertFiles"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Insert files into a playlist"
9+ parameters {
10+ type = "params"
11+ required = List("uri")
12+ properties {
13+ ["uri"] = new StringType {
14+ type = "string"
15+ description = "The URI of the playlist to start"
16+ format = "at-uri"
17+ }
18+ ["files"] = new Array {
19+ type = "array"
20+ items = new StringType {
21+ type = "string"
22+ description = "List of file (id) to insert into the playlist"
23+ }
24+ }
25+ }
26+ }
27+ }
28+}
+21
apps/api/pkl/defs/playlist/removePlaylist.pkl
···000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.playlist.removePlaylist"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Remove a playlist"
9+ parameters {
10+ type = "params"
11+ required = List("uri")
12+ properties {
13+ ["uri"] = new StringType {
14+ type = "string"
15+ description = "The URI of the playlist to remove"
16+ format = "at-uri"
17+ }
18+ }
19+ }
20+ }
21+}
+25
apps/api/pkl/defs/playlist/removeTrack.pkl
···0000000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.playlist.removeTrack"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Remove a track from a playlist"
9+ parameters {
10+ type = "params"
11+ required = List("uri", "position")
12+ properties {
13+ ["uri"] = new StringType {
14+ type = "string"
15+ description = "The URI of the playlist to remove the track from"
16+ format = "at-uri"
17+ }
18+ ["position"] = new IntegerType {
19+ type = "integer"
20+ description = "The position of the track to remove in the playlist"
21+ }
22+ }
23+ }
24+ }
25+}
+21
apps/api/pkl/defs/playlist/startPlaylist.pkl
···000000000000000000000
···1+amends "../../schema/lexicon.pkl"
2+3+lexicon = 1
4+id = "app.rocksky.playlist.startPlaylist"
5+defs = new Mapping<String, Procedure> {
6+ ["main"] {
7+ type = "procedure"
8+ description = "Start a playlist"
9+ parameters {
10+ type = "params"
11+ required = List("uri")
12+ properties {
13+ ["uri"] = new StringType {
14+ type = "string"
15+ description = "The URI of the playlist to start"
16+ format = "at-uri"
17+ }
18+ }
19+ }
20+ }
21+}
-151
apps/api/pkl/defs/song/lovedSong.pkl
···1-amends "../../schema/lexicon.pkl"
2-3-lexicon = 1
4-id = "app.rocksky.lovedSong"
5-defs = new Mapping<String, Record> {
6- ["main"] {
7- type = "record"
8- key = "tid"
9- description = "A declaration of a song."
10- `record` {
11- type = "object"
12- required = List("title", "artist", "album", "duration", "createdAt")
13- properties {
14- ["title"] = new StringType {
15- type = "string"
16- description = "The title of the song."
17- minLength = 1
18- maxLength = 512
19- }
20-21- ["artist"] = new StringType {
22- type = "string"
23- description = "The artist of the song."
24- minLength = 1
25- maxLength = 256
26- }
27-28- ["albumArtist"] = new StringType {
29- type = "string"
30- description = "The album artist of the song."
31- minLength = 1
32- maxLength = 256
33- }
34-35- ["album"] = new StringType {
36- type = "string"
37- description = "The album of the song."
38- minLength = 1
39- maxLength = 256
40- }
41-42- ["duration"] = new IntegerType {
43- type = "integer"
44- description = "The duration of the song in seconds."
45- minimum = 1
46- }
47-48- ["trackNumber"] = new IntegerType {
49- type = "integer"
50- description = "The track number of the song in the album."
51- minimum = 1
52- }
53-54- ["discNumber"] = new IntegerType {
55- type = "integer"
56- description = "The disc number of the song in the album."
57- minimum = 1
58- }
59-60- ["releaseDate"] = new StringType {
61- type = "string"
62- description = "The release date of the song."
63- format = "datetime"
64- }
65-66- ["year"] = new IntegerType {
67- type = "integer"
68- description = "The year the song was released."
69- }
70-71- ["genre"] = new StringType {
72- type = "string"
73- description = "The genre of the song."
74- maxLength = 256
75- }
76-77- ["tags"] = new Array {
78- type = "array"
79- description = "The tags of the song."
80- items = new StringType {
81- type = "string"
82- minLength = 1
83- maxLength = 256
84- }
85- }
86-87- ["composer"] = new StringType {
88- type = "string"
89- description = "The composer of the song."
90- maxLength = 256
91- }
92-93- ["lyrics"] = new StringType {
94- type = "string"
95- description = "The lyrics of the song."
96- maxLength = 10000
97- }
98-99- ["copyrightMessage"] = new StringType {
100- type = "string"
101- description = "The copyright message of the song."
102- minLength = 1
103- maxLength = 256
104- }
105-106- ["wiki"] = new StringType {
107- type = "string"
108- description = "Informations about the song"
109- maxLength = 10000
110- }
111-112- ["albumArt"] = new Blob {
113- type = "blob"
114- description = "The album art of the song."
115- accept = List("image/png", "image/jpeg")
116- maxSize = 2000000
117- }
118-119- ["youtubeLink"] = new StringType {
120- type = "string"
121- description = "The YouTube link of the song."
122- format = "uri"
123- }
124-125- ["spotifyLink"] = new StringType {
126- type = "string"
127- description = "The Spotify link of the song."
128- format = "uri"
129- }
130-131- ["tidalLink"] = new StringType {
132- type = "string"
133- description = "The Tidal link of the song."
134- format = "uri"
135- }
136-137- ["appleMusicLink"] = new StringType {
138- type = "string"
139- description = "The Apple Music link of the song."
140- format = "uri"
141- }
142-143- ["createdAt"] = new StringType {
144- type = "string"
145- description = "The date when the song was created."
146- format = "datetime"
147- }
148- }
149- }
150- }
151-}
···1-/**
2- * GENERATED CODE - DO NOT MODIFY
3- */
4-import { ValidationResult, BlobRef } from '@atproto/lexicon'
5-import { lexicons } from '../../../lexicons'
6-import { isObj, hasProp } from '../../../util'
7-import { CID } from 'multiformats/cid'
8-9-export interface Record {
10- /** The title of the song. */
11- title: string
12- /** The artist of the song. */
13- artist: string
14- /** The album artist of the song. */
15- albumArtist?: string
16- /** The album of the song. */
17- album: string
18- /** The duration of the song in seconds. */
19- duration: number
20- /** The track number of the song in the album. */
21- trackNumber?: number
22- /** The disc number of the song in the album. */
23- discNumber?: number
24- /** The release date of the song. */
25- releaseDate?: string
26- /** The year the song was released. */
27- year?: number
28- /** The genre of the song. */
29- genre?: string
30- /** The tags of the song. */
31- tags?: string[]
32- /** The composer of the song. */
33- composer?: string
34- /** The lyrics of the song. */
35- lyrics?: string
36- /** The copyright message of the song. */
37- copyrightMessage?: string
38- /** Informations about the song */
39- wiki?: string
40- /** The album art of the song. */
41- albumArt?: BlobRef
42- /** The YouTube link of the song. */
43- youtubeLink?: string
44- /** The Spotify link of the song. */
45- spotifyLink?: string
46- /** The Tidal link of the song. */
47- tidalLink?: string
48- /** The Apple Music link of the song. */
49- appleMusicLink?: string
50- /** The date when the song was created. */
51- createdAt: string
52- [k: string]: unknown
53-}
54-55-export function isRecord(v: unknown): v is Record {
56- return (
57- isObj(v) &&
58- hasProp(v, '$type') &&
59- (v.$type === 'app.rocksky.lovedSong#main' ||
60- v.$type === 'app.rocksky.lovedSong')
61- )
62-}
63-64-export function validateRecord(v: unknown): ValidationResult {
65- return lexicons.validate('app.rocksky.lovedSong#main', v)
66-}
···5import { lexicons } from '../../../../lexicons'
6import { isObj, hasProp } from '../../../../util'
7import { CID } from 'multiformats/cid'
089export interface CurrentlyPlayingViewDetailed {
10 /** The title of the currently playing track */
···30 v,
31 )
32}
000000000000000000000000
···5import { lexicons } from '../../../../lexicons'
6import { isObj, hasProp } from '../../../../util'
7import { CID } from 'multiformats/cid'
8+import * as AppRockskySongDefsSongViewBasic from '../song/defs/songViewBasic'
910export interface CurrentlyPlayingViewDetailed {
11 /** The title of the currently playing track */
···31 v,
32 )
33}
34+35+export interface PlaybackQueueViewDetailed {
36+ tracks?: AppRockskySongDefsSongViewBasic.Main[]
37+ [k: string]: unknown
38+}
39+40+export function isPlaybackQueueViewDetailed(
41+ v: unknown,
42+): v is PlaybackQueueViewDetailed {
43+ return (
44+ isObj(v) &&
45+ hasProp(v, '$type') &&
46+ v.$type === 'app.rocksky.player.defs#playbackQueueViewDetailed'
47+ )
48+}
49+50+export function validatePlaybackQueueViewDetailed(
51+ v: unknown,
52+): ValidationResult {
53+ return lexicons.validate(
54+ 'app.rocksky.player.defs#playbackQueueViewDetailed',
55+ v,
56+ )
57+}
···10import * as AppRockskyPlayerDefs from './defs'
1112export interface QueryParams {
013 /** Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user. */
14 actor?: string
15}
···10import * as AppRockskyPlayerDefs from './defs'
1112export interface QueryParams {
13+ playerId?: string
14 /** Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user. */
15 actor?: string
16}
···9import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
1011export interface QueryParams {
012 /** The position in seconds to seek to */
13 position: number
14}
···9import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
1011export interface QueryParams {
12+ playerId?: string
13 /** The position in seconds to seek to */
14 position: number
15}