Support a FlashCard before showing the notes that comprise a chord

My much anticipated feature: first prompt the user for a name of a chord, then
show the user that chord.

Cascading changes:
I changed the "Tap to practice" overlayButton's opacity from 30% to 100% because
pausing when showFlashCard is True causes the two piece

TIL:
You can batch Elm Subscriptions using the Sub.batch function.

What I haven't learned yet:
How to best handle rotating screens for mobile devices (i.e. portrait
vs. landscape modes). In time...

What's left?
- Support sound
- Support a fine-tune section of the preferences
- Support tablet and web browser variants
- Ask users for the "I chord" instead of asking "C major Root position"
- More styling (of course)
This commit is contained in:
William Carroll 2020-04-19 15:32:20 +01:00
parent f92fe97aff
commit d134db700f
5 changed files with 66 additions and 5 deletions

View file

@ -0,0 +1,42 @@
module FlashCard exposing (render)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Responsive
import State
import Tailwind
import Theory
render :
{ chord : Theory.Chord
, visible : Bool
}
-> Html State.Msg
render { chord, visible } =
let
classes =
[ "bg-white"
, "fixed"
, "top-0"
, "left-0"
, "z-30"
, "w-screen"
, "h-screen"
, Tailwind.if_ visible "opacity-100" "opacity-0"
]
in
button
[ classes |> Tailwind.use |> class ]
[ h1
[ [ "text-center"
, "transform"
, "-rotate-90"
, Responsive.h1
]
|> Tailwind.use
|> class
]
[ text (Theory.viewChord chord) ]
]

View file

@ -16,7 +16,10 @@ subscriptions model =
Sub.none
else
Time.every (model.tempo |> Misc.bpmToMilliseconds |> toFloat) (\_ -> State.NextChord)
Sub.batch
[ Time.every (model.tempo * 2 |> Misc.bpmToMilliseconds |> toFloat) (\_ -> State.ToggleFlashCard)
, Time.every (model.tempo |> Misc.bpmToMilliseconds |> toFloat) (\_ -> State.NextChord)
]
view : State.Model -> Html State.Msg

View file

@ -1,5 +1,6 @@
module Practice exposing (render)
import FlashCard
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
@ -13,7 +14,7 @@ import UI
openPreferences : Html State.Msg
openPreferences =
button
[ class "w-48 h-48 absolute left-0 top-0 z-40"
[ class "w-48 h-48 absolute left-0 top-0 z-50"
, onClick (State.SetView State.Preferences)
]
[ Icon.cog ]
@ -36,6 +37,15 @@ render model =
, handleClick = handleClick
, isVisible = model.isPaused
}
, case model.selectedChord of
Just chord ->
FlashCard.render
{ chord = chord
, visible = model.showFlashCard
}
Nothing ->
span [] []
, Piano.render
{ chord = model.selectedChord
, firstNote = model.firstNote

View file

@ -18,6 +18,7 @@ type Msg
| DoNothing
| SetPracticeMode PracticeMode
| SetView View
| ToggleFlashCard
type View
@ -46,6 +47,7 @@ type alias Model =
, lastNote : Theory.Note
, practiceMode : PracticeMode
, view : View
, showFlashCard : Bool
}
@ -92,10 +94,11 @@ init =
, whitelistedKeys = keys
, selectedChord = Nothing
, isPaused = True
, tempo = 20
, tempo = 10
, firstNote = firstNote
, lastNote = lastNote
, view = Overview
, showFlashCard = True
}
@ -251,3 +254,6 @@ update msg model =
}
, Cmd.none
)
ToggleFlashCard ->
( { model | showFlashCard = not model.showFlashCard }, Cmd.none )

View file

@ -132,7 +132,7 @@ overlayButton { label, handleClick, isVisible } =
, "top-0"
, "left-0"
, "block"
, "z-30"
, "z-40"
, "w-screen"
, "h-screen"
, Tailwind.if_ isVisible "opacity-100" "opacity-0"
@ -140,7 +140,7 @@ overlayButton { label, handleClick, isVisible } =
in
button
[ classes |> Tailwind.use |> class
, style "background-color" "rgba(0,0,0,0.30)"
, style "background-color" "rgba(0,0,0,1.0)"
, onClick handleClick
]
[ h1