···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.player.addItemsToQueue",
44+ "defs": {
55+ "main": {
66+ "type": "procedure",
77+ "description": "Add items to the player's queue",
88+ "parameters": {
99+ "type": "params",
1010+ "required": [
1111+ "items"
1212+ ],
1313+ "properties": {
1414+ "playerId": {
1515+ "type": "string"
1616+ },
1717+ "items": {
1818+ "type": "array",
1919+ "items": {
2020+ "type": "string",
2121+ "description": "List of file identifiers to add to the queue"
2222+ }
2323+ },
2424+ "position": {
2525+ "type": "integer",
2626+ "description": "Position in the queue to insert the items at, defaults to the end if not specified"
2727+ }
2828+ }
2929+ }
3030+ }
3131+ }
3232+}
+12
apps/api/lexicons/player/defs.json
···1010 "description": "The title of the currently playing track"
1111 }
1212 }
1313+ },
1414+ "playbackQueueViewDetailed": {
1515+ "type": "object",
1616+ "properties": {
1717+ "tracks": {
1818+ "type": "array",
1919+ "items": {
2020+ "type": "ref",
2121+ "ref": "app.rocksky.song.defs.songViewBasic"
2222+ }
2323+ }
2424+ }
1325 }
1426 }
1527}
+3
apps/api/lexicons/player/getCurrentlyPlaying.json
···88 "parameters": {
99 "type": "params",
1010 "properties": {
1111+ "playerId": {
1212+ "type": "string"
1313+ },
1114 "actor": {
1215 "type": "string",
1316 "description": "Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user.",
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.player.addItemsToQueue"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Add items to the player's queue"
99+ parameters {
1010+ type = "params"
1111+ required = List("items")
1212+ properties {
1313+ ["playerId"] = new StringType {
1414+ type = "string"
1515+ }
1616+ ["items"] = new Array {
1717+ type = "array"
1818+ items = new StringType {
1919+ type = "string"
2020+ description = "List of file identifiers to add to the queue"
2121+ }
2222+ }
2323+ ["position"] = new IntegerType {
2424+ type = "integer"
2525+ description = "Position in the queue to insert the items at, defaults to the end if not specified"
2626+ }
2727+ }
2828+ }
2929+ }
3030+}
+12
apps/api/pkl/defs/player/defs.pkl
···1212 }
1313 }
1414 }
1515+ ["playbackQueueViewDetailed"] {
1616+ type = "object"
1717+ properties {
1818+ ["tracks"] = new Array {
1919+ type = "array"
2020+ items = new Ref {
2121+ type = "ref"
2222+ ref = "app.rocksky.song.defs.songViewBasic"
2323+ }
2424+ }
2525+ }
2626+ }
1527}
+3
apps/api/pkl/defs/player/getCurrentlyPlaying.pkl
···99 parameters {
1010 type = "params"
1111 properties {
1212+ ["playerId"] = new StringType {
1313+ type = "string"
1414+ }
1215 ["actor"] = new StringType {
1316 type = "string"
1417 format = "at-identifier"
+25
apps/api/pkl/defs/player/getPlaybackQueue.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.player.getPlaybackQueue"
55+defs = new Mapping<String, Query> {
66+ ["main"] {
77+ type = "query"
88+ description = "Retrieve the current playback queue"
99+ parameters {
1010+ type = "params"
1111+ properties {
1212+ ["playerId"] = new StringType {
1313+ type = "string"
1414+ }
1515+ }
1616+ }
1717+ output {
1818+ encoding = "application/json"
1919+ schema = new Ref {
2020+ type = "ref"
2121+ ref = "app.rocksky.player.defs#playbackQueueViewDetailed"
2222+ }
2323+ }
2424+ }
2525+}
+8
apps/api/pkl/defs/player/next.pkl
···66 ["main"] {
77 type = "procedure"
88 description = "Play the next track in the queue"
99+ parameters {
1010+ type = "params"
1111+ properties {
1212+ ["playerId"] = new StringType {
1313+ type = "string"
1414+ }
1515+ }
1616+ }
917 }
1018}
+8
apps/api/pkl/defs/player/pause.pkl
···66 ["main"] {
77 type = "procedure"
88 description = "Pause the currently playing track"
99+ parameters {
1010+ type = "params"
1111+ properties {
1212+ ["playerId"] = new StringType {
1313+ type = "string"
1414+ }
1515+ }
1616+ }
917 }
1018}
+8
apps/api/pkl/defs/player/play.pkl
···66 ["main"] {
77 type = "procedure"
88 description = "Resume playback of the currently paused track"
99+ parameters {
1010+ type = "params"
1111+ properties {
1212+ ["playerId"] = new StringType {
1313+ type = "string"
1414+ }
1515+ }
1616+ }
917 }
1018}
+22
apps/api/pkl/defs/player/playDirectory.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.player.playDirectory"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Play all tracks in a directory"
99+ parameters {
1010+ type = "params"
1111+ required = List("directoryId")
1212+ properties {
1313+ ["playerId"] = new StringType {
1414+ type = "string"
1515+ }
1616+ ["directoryId"] = new StringType {
1717+ type = "string"
1818+ }
1919+ }
2020+ }
2121+ }
2222+}
+22
apps/api/pkl/defs/player/playFile.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.player.playFile"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Play a specific audio file"
99+ parameters {
1010+ type = "params"
1111+ required = List("fileId")
1212+ properties {
1313+ ["playerId"] = new StringType {
1414+ type = "string"
1515+ }
1616+ ["fileId"] = new StringType {
1717+ type = "string"
1818+ }
1919+ }
2020+ }
2121+ }
2222+}
+8
apps/api/pkl/defs/player/previous.pkl
···66 ["main"] {
77 type = "procedure"
88 description = "Play the previous track in the queue"
99+ parameters {
1010+ type = "params"
1111+ properties {
1212+ ["playerId"] = new StringType {
1313+ type = "string"
1414+ }
1515+ }
1616+ }
917 }
1018}
+5-2
apps/api/pkl/defs/player/seek.pkl
···99 parameters {
1010 type = "params"
1111 required = List("position")
1212- properties = new Mapping<String, IntegerType> {
1313- ["position"] {
1212+ properties = new Mapping<String, StringType | IntegerType> {
1313+ ["playerId"] = new StringType {
1414+ type = "string"
1515+ }
1616+ ["position"] = new IntegerType {
1417 type = "integer"
1518 description = "The position in seconds to seek to"
1619 }
+24
apps/api/pkl/defs/playlist/createPlaylist.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.playlist.createPlaylist"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Create a new playlist"
99+ parameters {
1010+ type = "params"
1111+ required = List("name")
1212+ properties {
1313+ ["name"] = new StringType {
1414+ type = "string"
1515+ description = "The name of the playlist"
1616+ }
1717+ ["description"] = new StringType {
1818+ type = "string"
1919+ description = "A brief description of the playlist"
2020+ }
2121+ }
2222+ }
2323+ }
2424+}
+25
apps/api/pkl/defs/playlist/insertDirectory.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.playlist.insertDirectory"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Insert a directory into a playlist"
99+ parameters {
1010+ type = "params"
1111+ required = List("uri")
1212+ properties {
1313+ ["uri"] = new StringType {
1414+ type = "string"
1515+ description = "The URI of the playlist to start"
1616+ format = "at-uri"
1717+ }
1818+ ["directory"] = new StringType {
1919+ type = "string"
2020+ description = "The directory (id) to insert into the playlist"
2121+ }
2222+ }
2323+ }
2424+ }
2525+}
+28
apps/api/pkl/defs/playlist/insertFiles.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.playlist.insertFiles"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Insert files into a playlist"
99+ parameters {
1010+ type = "params"
1111+ required = List("uri")
1212+ properties {
1313+ ["uri"] = new StringType {
1414+ type = "string"
1515+ description = "The URI of the playlist to start"
1616+ format = "at-uri"
1717+ }
1818+ ["files"] = new Array {
1919+ type = "array"
2020+ items = new StringType {
2121+ type = "string"
2222+ description = "List of file (id) to insert into the playlist"
2323+ }
2424+ }
2525+ }
2626+ }
2727+ }
2828+}
+21
apps/api/pkl/defs/playlist/removePlaylist.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.playlist.removePlaylist"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Remove a playlist"
99+ parameters {
1010+ type = "params"
1111+ required = List("uri")
1212+ properties {
1313+ ["uri"] = new StringType {
1414+ type = "string"
1515+ description = "The URI of the playlist to remove"
1616+ format = "at-uri"
1717+ }
1818+ }
1919+ }
2020+ }
2121+}
+25
apps/api/pkl/defs/playlist/removeTrack.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.playlist.removeTrack"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Remove a track from a playlist"
99+ parameters {
1010+ type = "params"
1111+ required = List("uri", "position")
1212+ properties {
1313+ ["uri"] = new StringType {
1414+ type = "string"
1515+ description = "The URI of the playlist to remove the track from"
1616+ format = "at-uri"
1717+ }
1818+ ["position"] = new IntegerType {
1919+ type = "integer"
2020+ description = "The position of the track to remove in the playlist"
2121+ }
2222+ }
2323+ }
2424+ }
2525+}
+21
apps/api/pkl/defs/playlist/startPlaylist.pkl
···11+amends "../../schema/lexicon.pkl"
22+33+lexicon = 1
44+id = "app.rocksky.playlist.startPlaylist"
55+defs = new Mapping<String, Procedure> {
66+ ["main"] {
77+ type = "procedure"
88+ description = "Start a playlist"
99+ parameters {
1010+ type = "params"
1111+ required = List("uri")
1212+ properties {
1313+ ["uri"] = new StringType {
1414+ type = "string"
1515+ description = "The URI of the playlist to start"
1616+ format = "at-uri"
1717+ }
1818+ }
1919+ }
2020+ }
2121+}
-151
apps/api/pkl/defs/song/lovedSong.pkl
···11-amends "../../schema/lexicon.pkl"
22-33-lexicon = 1
44-id = "app.rocksky.lovedSong"
55-defs = new Mapping<String, Record> {
66- ["main"] {
77- type = "record"
88- key = "tid"
99- description = "A declaration of a song."
1010- `record` {
1111- type = "object"
1212- required = List("title", "artist", "album", "duration", "createdAt")
1313- properties {
1414- ["title"] = new StringType {
1515- type = "string"
1616- description = "The title of the song."
1717- minLength = 1
1818- maxLength = 512
1919- }
2020-2121- ["artist"] = new StringType {
2222- type = "string"
2323- description = "The artist of the song."
2424- minLength = 1
2525- maxLength = 256
2626- }
2727-2828- ["albumArtist"] = new StringType {
2929- type = "string"
3030- description = "The album artist of the song."
3131- minLength = 1
3232- maxLength = 256
3333- }
3434-3535- ["album"] = new StringType {
3636- type = "string"
3737- description = "The album of the song."
3838- minLength = 1
3939- maxLength = 256
4040- }
4141-4242- ["duration"] = new IntegerType {
4343- type = "integer"
4444- description = "The duration of the song in seconds."
4545- minimum = 1
4646- }
4747-4848- ["trackNumber"] = new IntegerType {
4949- type = "integer"
5050- description = "The track number of the song in the album."
5151- minimum = 1
5252- }
5353-5454- ["discNumber"] = new IntegerType {
5555- type = "integer"
5656- description = "The disc number of the song in the album."
5757- minimum = 1
5858- }
5959-6060- ["releaseDate"] = new StringType {
6161- type = "string"
6262- description = "The release date of the song."
6363- format = "datetime"
6464- }
6565-6666- ["year"] = new IntegerType {
6767- type = "integer"
6868- description = "The year the song was released."
6969- }
7070-7171- ["genre"] = new StringType {
7272- type = "string"
7373- description = "The genre of the song."
7474- maxLength = 256
7575- }
7676-7777- ["tags"] = new Array {
7878- type = "array"
7979- description = "The tags of the song."
8080- items = new StringType {
8181- type = "string"
8282- minLength = 1
8383- maxLength = 256
8484- }
8585- }
8686-8787- ["composer"] = new StringType {
8888- type = "string"
8989- description = "The composer of the song."
9090- maxLength = 256
9191- }
9292-9393- ["lyrics"] = new StringType {
9494- type = "string"
9595- description = "The lyrics of the song."
9696- maxLength = 10000
9797- }
9898-9999- ["copyrightMessage"] = new StringType {
100100- type = "string"
101101- description = "The copyright message of the song."
102102- minLength = 1
103103- maxLength = 256
104104- }
105105-106106- ["wiki"] = new StringType {
107107- type = "string"
108108- description = "Informations about the song"
109109- maxLength = 10000
110110- }
111111-112112- ["albumArt"] = new Blob {
113113- type = "blob"
114114- description = "The album art of the song."
115115- accept = List("image/png", "image/jpeg")
116116- maxSize = 2000000
117117- }
118118-119119- ["youtubeLink"] = new StringType {
120120- type = "string"
121121- description = "The YouTube link of the song."
122122- format = "uri"
123123- }
124124-125125- ["spotifyLink"] = new StringType {
126126- type = "string"
127127- description = "The Spotify link of the song."
128128- format = "uri"
129129- }
130130-131131- ["tidalLink"] = new StringType {
132132- type = "string"
133133- description = "The Tidal link of the song."
134134- format = "uri"
135135- }
136136-137137- ["appleMusicLink"] = new StringType {
138138- type = "string"
139139- description = "The Apple Music link of the song."
140140- format = "uri"
141141- }
142142-143143- ["createdAt"] = new StringType {
144144- type = "string"
145145- description = "The date when the song was created."
146146- format = "datetime"
147147- }
148148- }
149149- }
150150- }
151151-}
···11-/**
22- * GENERATED CODE - DO NOT MODIFY
33- */
44-import { ValidationResult, BlobRef } from '@atproto/lexicon'
55-import { lexicons } from '../../../lexicons'
66-import { isObj, hasProp } from '../../../util'
77-import { CID } from 'multiformats/cid'
88-99-export interface Record {
1010- /** The title of the song. */
1111- title: string
1212- /** The artist of the song. */
1313- artist: string
1414- /** The album artist of the song. */
1515- albumArtist?: string
1616- /** The album of the song. */
1717- album: string
1818- /** The duration of the song in seconds. */
1919- duration: number
2020- /** The track number of the song in the album. */
2121- trackNumber?: number
2222- /** The disc number of the song in the album. */
2323- discNumber?: number
2424- /** The release date of the song. */
2525- releaseDate?: string
2626- /** The year the song was released. */
2727- year?: number
2828- /** The genre of the song. */
2929- genre?: string
3030- /** The tags of the song. */
3131- tags?: string[]
3232- /** The composer of the song. */
3333- composer?: string
3434- /** The lyrics of the song. */
3535- lyrics?: string
3636- /** The copyright message of the song. */
3737- copyrightMessage?: string
3838- /** Informations about the song */
3939- wiki?: string
4040- /** The album art of the song. */
4141- albumArt?: BlobRef
4242- /** The YouTube link of the song. */
4343- youtubeLink?: string
4444- /** The Spotify link of the song. */
4545- spotifyLink?: string
4646- /** The Tidal link of the song. */
4747- tidalLink?: string
4848- /** The Apple Music link of the song. */
4949- appleMusicLink?: string
5050- /** The date when the song was created. */
5151- createdAt: string
5252- [k: string]: unknown
5353-}
5454-5555-export function isRecord(v: unknown): v is Record {
5656- return (
5757- isObj(v) &&
5858- hasProp(v, '$type') &&
5959- (v.$type === 'app.rocksky.lovedSong#main' ||
6060- v.$type === 'app.rocksky.lovedSong')
6161- )
6262-}
6363-6464-export function validateRecord(v: unknown): ValidationResult {
6565- return lexicons.validate('app.rocksky.lovedSong#main', v)
6666-}
···1010import * as AppRockskyPlayerDefs from './defs'
11111212export interface QueryParams {
1313+ playerId?: string
1314 /** Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user. */
1415 actor?: string
1516}
···99import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
10101111export interface QueryParams {
1212+ playerId?: string
1213 /** The position in seconds to seek to */
1314 position: number
1415}