All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kubukoz.next.UserMessage.scala Maven / Gradle / Ivy

package com.kubukoz.next

import cats.Show
import cats.effect.std
import cats.implicits._
import cats.~>
import com.kubukoz.next.api.spotify.Item
import com.kubukoz.next.api.spotify.Player
import com.kubukoz.next.api.spotify.PlayerContext
import org.http4s.Uri

import java.nio.file.Path

sealed trait UserMessage extends Product with Serializable

object UserMessage {
  final case class GoToUri(uri: Uri) extends UserMessage
  final case class ConfigFileNotFound(path: Path, validInput: String) extends UserMessage
  final case class SavedConfig(path: Path) extends UserMessage
  case object SavedToken extends UserMessage
  case object RefreshedToken extends UserMessage

  // playback
  case object SwitchingToNext extends UserMessage
  final case class RemovingCurrentTrack(player: Player[PlayerContext.playlist, Item.track]) extends UserMessage
  case object TooCloseToEnd extends UserMessage
  final case class Seeking(desiredProgressPercent: Int) extends UserMessage
}

trait UserOutput[F[_]] {
  def print(msg: UserMessage): F[Unit]
  def mapK[G[_]](fk: F ~> G): UserOutput[G] = msg => fk(print(msg))
}

object UserOutput {
  def apply[F[_]](implicit F: UserOutput[F]): UserOutput[F] = F

  def toConsole[F[_]: std.Console]: UserOutput[F] = {
    implicit val showPath: Show[Path] = Show.fromToString

    import UserMessage._

    val stringify: UserMessage => String = {
      case GoToUri(uri)                         => show"Go to $uri"
      case ConfigFileNotFound(path, validInput) => show"Didn't find config file at $path. Should I create one? ($validInput/n)"
      case SavedConfig(path)                    => show"Saved config to new file at $path"
      case SavedToken                           => "Saved token to file"
      case RefreshedToken                       => "Refreshed token"
      case SwitchingToNext                      => "Switching to next track"
      case RemovingCurrentTrack(player)         =>
        show"""Removing track "${player.item.name}" (${player.item.uri}) from playlist ${player.context.uri.playlist}"""
      case TooCloseToEnd                        => "Too close to song's ending, rewinding to beginning"
      case Seeking(desiredProgressPercent)      => show"Seeking to $desiredProgressPercent%"
    }

    msg => std.Console[F].println(stringify(msg))
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy