Add documentation

This commit is contained in:
Mikko Ahlroth 2023-10-10 19:02:30 +03:00
parent 4e15c49d29
commit ea592fef6d
20 changed files with 54 additions and 1 deletions

View file

@ -1,7 +1,9 @@
/// Information of the logged in user.
pub type User {
User(id: Int, token: String, session_uuid: String)
}
/// Information of the user's device.
pub type Device {
Device(name: String)
}

View file

@ -1,3 +1,6 @@
//// The auth storage stores the user's authentication credentials for future
//// use, i.e. when refreshing the page.
import gleam/dynamic
import gleam/json
import plinth/javascript/storage
@ -6,22 +9,27 @@ import elekf/api/auth/models
const storage_key = "__elektrofoni_auth_storage"
/// Storage format of the authentication data in local storage.
pub type StorageFormat {
StorageFormat(user: models.User, device: models.Device)
}
/// The local storage API used for storing authentication details.
pub type AuthStorage =
varasto.TypedStorage(StorageFormat)
/// Gets the `varasto` instance to use for reading and writing auth storage.
pub fn get() {
let assert Ok(local) = storage.local()
varasto.new(local, reader(), writer())
}
/// Reads the previously stored value, if available.
pub fn read(storage: AuthStorage) {
varasto.get(storage, storage_key)
}
/// Writes new value to the storage.
pub fn write(storage: AuthStorage, data: StorageFormat) {
varasto.set(storage, storage_key, data)
}

View file

@ -3,6 +3,7 @@ import ibroadcast/device_info.{DeviceInfo}
import ibroadcast/request.{RequestConfig}
import elekf/utils/navigator
/// Gets the base request config to use for all requests, authenticated and raw.
pub fn base_request_config(device_name: String) {
RequestConfig(
app_info: elektrofoni.app_info,

View file

@ -1,3 +1,5 @@
//// The library stores the music library retrieved from iBroadcast.
import gleam/map.{Map}
import elekf/library/track.{Track}
import elekf/library/album.{Album}
@ -11,28 +13,34 @@ pub type Library {
)
}
/// Gets an album from the library based on ID.
pub fn get_album(library: Library, id: Int) {
map.get(library.albums, id)
}
/// Gets an artist from the library based on ID.
pub fn get_artist(library: Library, id: Int) {
map.get(library.artists, id)
}
/// Gets a track from the library based on ID.
pub fn get_track(library: Library, id: Int) {
map.get(library.tracks, id)
}
/// Gets an album from the library, asserting that it exists.
pub fn assert_album(library: Library, id: Int) {
let assert Ok(album) = map.get(library.albums, id)
album
}
/// Gets an artist from the library, asserting that it exists.
pub fn assert_artist(library: Library, id: Int) {
let assert Ok(artist) = map.get(library.artists, id)
artist
}
/// Gets a track from the library, asserting that it exists.
pub fn assert_track(library: Library, id: Int) {
let assert Ok(track) = map.get(library.tracks, id)
track

View file

@ -1,3 +1,7 @@
/// A track in the music library.
///
/// The `title_lower` contains the track title in lowercase, which is an
/// optimisation for searching.
pub type Track {
Track(
number: Int,

View file

@ -1,6 +1,7 @@
import ibroadcast/library/library.{Album as APIAlbum}
import elekf/library/album.{Album}
/// Converts API album response to library format.
pub fn from(album: APIAlbum) {
Album(
name: album.name,

View file

@ -1,6 +1,7 @@
import ibroadcast/library/library.{Artist as APIArtist}
import elekf/library/artist.{Artist}
/// Converts API artist response to library format.
pub fn from(artist: APIArtist) {
Artist(
name: artist.name,

View file

@ -6,6 +6,7 @@ import elekf/transfer/album
import elekf/transfer/artist
import elekf/transfer/track
/// Converts API library response to library format.
pub fn from(library: APILibrary) {
let albums = transfer_map(library.albums, album.from)
let artists = transfer_map(library.artists, artist.from)

View file

@ -2,6 +2,7 @@ import gleam/string
import ibroadcast/library/library.{Track as APITrack}
import elekf/library/track.{Track}
/// Converts API track response to library format.
pub fn from(track: APITrack) {
Track(
number: track.number,

View file

@ -28,7 +28,7 @@ pub fn equals(a: Date, b: Date) -> Bool
@external(javascript, "../../date_ffi.mjs", "bigger_than")
pub fn bigger_than(a: Date, b: Date) -> Bool
/// Compare given dates, returning `Gt` if `a` > `b`
/// Compares given dates, returning `Gt` if `a` > `b`
pub fn compare(a: Date, b: Date) -> Order {
case equals(a, b) {
True -> Eq
@ -41,6 +41,7 @@ pub fn compare(a: Date, b: Date) -> Order {
}
}
/// Decodes a dynamic value as an ISO 8601 formatted datetime string.
pub fn decode(value: Dynamic) -> Result(Date, List(DecodeError)) {
use str <- result.try(dynamic.string(value))
use date <- result.try(

View file

@ -4,9 +4,11 @@ import gleam/javascript/promise
import ibroadcast/request as ibroadcast_request
import ibroadcast/http as ibroadcast_http
/// Error returned by an HTTP request.
pub type ResponseError =
ibroadcast_request.ResponseError(fetch.FetchError)
/// Returns an HTTP request function based on `fetch`.
pub fn requestor() -> ibroadcast_http.Requestor(fetch.FetchError) {
fn(req: request.Request(String)) {
use resp <- promise.try_await(fetch.send(req))

View file

@ -1,2 +1,3 @@
/// Returns the current browser's user agent.
@external(javascript, "../../navigator_ffi.mjs", "userAgent")
pub fn user_agent() -> String

View file

@ -1,3 +1,6 @@
//// The authed view manages the user's request config and displays the base
//// view for the app.
import gleam/io
import gleam/int
import gleam/list

View file

@ -1,9 +1,11 @@
import elekf/api/auth/models as auth_models
/// Authentication data for the user.
pub type AuthData {
AuthData(user: auth_models.User, device: auth_models.Device)
}
/// Settings of the iBroadcast API.
pub type Settings {
Settings(artwork_server: String, streaming_server: String)
}

View file

@ -1,3 +1,5 @@
//// The player view renders the media player UI element and its controls.
import gleam/list
import gleam/uri
import lustre/element.{text}

View file

@ -1,3 +1,6 @@
//// The search view renders a search bar, other views must do the searching
//// based on the emitted messages.
import lustre/element.{text}
import lustre/element/html.{button, div, input}
import lustre/attribute

View file

@ -1,3 +1,5 @@
//// The login view displays the login form and starts the login operation.
import gleam/string
import gleam/javascript/promise
import lustre/element.{text}

View file

@ -1,3 +1,5 @@
//// The main view sets up everything and shows the login or authed view.
import gleam/io
import gleam/option
import lustre

View file

@ -1,3 +1,4 @@
/// Views that can be rendered on the main level.
pub type View {
LoginView
AuthedView

View file

@ -1,13 +1,20 @@
import ibroadcast/app_info.{AppInfo}
/// Name of the application.
pub const app_name = "elektrofoni"
/// Version of the application.
pub const app_version = "1.0.0"
/// ID of the application.
pub const app_id = 1098
/// Constant app info to use in application.
pub const app_info = AppInfo(app_name, app_version)
/// The bitrate to use for streaming by default.
pub const bitrate = 256
/// The expiry of the MP3 URLs generated for streaming, from the current moment
/// onwards, in milliseconds.
pub const track_expiry_length = 10_800_000