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:
		
							parent
							
								
									f92fe97aff
								
							
						
					
					
						commit
						d134db700f
					
				
					 5 changed files with 66 additions and 5 deletions
				
			
		
							
								
								
									
										42
									
								
								website/sandbox/learnpianochords/src/FlashCard.elm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								website/sandbox/learnpianochords/src/FlashCard.elm
									
										
									
									
									
										Normal 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) ] | ||||||
|  |         ] | ||||||
|  | @ -16,7 +16,10 @@ subscriptions model = | ||||||
|         Sub.none |         Sub.none | ||||||
| 
 | 
 | ||||||
|     else |     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 : State.Model -> Html State.Msg | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| module Practice exposing (render) | module Practice exposing (render) | ||||||
| 
 | 
 | ||||||
|  | import FlashCard | ||||||
| import Html exposing (..) | import Html exposing (..) | ||||||
| import Html.Attributes exposing (..) | import Html.Attributes exposing (..) | ||||||
| import Html.Events exposing (..) | import Html.Events exposing (..) | ||||||
|  | @ -13,7 +14,7 @@ import UI | ||||||
| openPreferences : Html State.Msg | openPreferences : Html State.Msg | ||||||
| openPreferences = | openPreferences = | ||||||
|     button |     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) |         , onClick (State.SetView State.Preferences) | ||||||
|         ] |         ] | ||||||
|         [ Icon.cog ] |         [ Icon.cog ] | ||||||
|  | @ -36,6 +37,15 @@ render model = | ||||||
|             , handleClick = handleClick |             , handleClick = handleClick | ||||||
|             , isVisible = model.isPaused |             , isVisible = model.isPaused | ||||||
|             } |             } | ||||||
|  |         , case model.selectedChord of | ||||||
|  |             Just chord -> | ||||||
|  |                 FlashCard.render | ||||||
|  |                     { chord = chord | ||||||
|  |                     , visible = model.showFlashCard | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |             Nothing -> | ||||||
|  |                 span [] [] | ||||||
|         , Piano.render |         , Piano.render | ||||||
|             { chord = model.selectedChord |             { chord = model.selectedChord | ||||||
|             , firstNote = model.firstNote |             , firstNote = model.firstNote | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ type Msg | ||||||
|     | DoNothing |     | DoNothing | ||||||
|     | SetPracticeMode PracticeMode |     | SetPracticeMode PracticeMode | ||||||
|     | SetView View |     | SetView View | ||||||
|  |     | ToggleFlashCard | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| type View | type View | ||||||
|  | @ -46,6 +47,7 @@ type alias Model = | ||||||
|     , lastNote : Theory.Note |     , lastNote : Theory.Note | ||||||
|     , practiceMode : PracticeMode |     , practiceMode : PracticeMode | ||||||
|     , view : View |     , view : View | ||||||
|  |     , showFlashCard : Bool | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -92,10 +94,11 @@ init = | ||||||
|     , whitelistedKeys = keys |     , whitelistedKeys = keys | ||||||
|     , selectedChord = Nothing |     , selectedChord = Nothing | ||||||
|     , isPaused = True |     , isPaused = True | ||||||
|     , tempo = 20 |     , tempo = 10 | ||||||
|     , firstNote = firstNote |     , firstNote = firstNote | ||||||
|     , lastNote = lastNote |     , lastNote = lastNote | ||||||
|     , view = Overview |     , view = Overview | ||||||
|  |     , showFlashCard = True | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -251,3 +254,6 @@ update msg model = | ||||||
|               } |               } | ||||||
|             , Cmd.none |             , Cmd.none | ||||||
|             ) |             ) | ||||||
|  | 
 | ||||||
|  |         ToggleFlashCard -> | ||||||
|  |             ( { model | showFlashCard = not model.showFlashCard }, Cmd.none ) | ||||||
|  |  | ||||||
|  | @ -132,7 +132,7 @@ overlayButton { label, handleClick, isVisible } = | ||||||
|             , "top-0" |             , "top-0" | ||||||
|             , "left-0" |             , "left-0" | ||||||
|             , "block" |             , "block" | ||||||
|             , "z-30" |             , "z-40" | ||||||
|             , "w-screen" |             , "w-screen" | ||||||
|             , "h-screen" |             , "h-screen" | ||||||
|             , Tailwind.if_ isVisible "opacity-100" "opacity-0" |             , Tailwind.if_ isVisible "opacity-100" "opacity-0" | ||||||
|  | @ -140,7 +140,7 @@ overlayButton { label, handleClick, isVisible } = | ||||||
|     in |     in | ||||||
|     button |     button | ||||||
|         [ classes |> Tailwind.use |> class |         [ classes |> Tailwind.use |> class | ||||||
|         , style "background-color" "rgba(0,0,0,0.30)" |         , style "background-color" "rgba(0,0,0,1.0)" | ||||||
|         , onClick handleClick |         , onClick handleClick | ||||||
|         ] |         ] | ||||||
|         [ h1 |         [ h1 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue