Skip to content

Commit

Permalink
Use grid as selector
Browse files Browse the repository at this point in the history
  • Loading branch information
abadi199 committed Feb 2, 2020
1 parent 1417d7f commit 1110bba
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 137 deletions.
168 changes: 72 additions & 96 deletions src/Edit.re
Original file line number Diff line number Diff line change
@@ -1,144 +1,120 @@
open Phoneme;

type state = {phonemes: list(phoneme)};
type state = {
phonemes: list(phoneme),
activeIndex: int,
};

let initialState = {phonemes: [firstPhoneme]};
let initialState = {phonemes: [firstPhoneme], activeIndex: 0};

let str = React.string;

type action =
| AddPhoneme
| RemovePhoneme
| PhonemeClicked(int, phoneme);
| PhonemeClicked(int, phoneme)
| SetActive(int)
| SelectionClicked(phoneme);

type accumulator('a) = {
list: list('a),
found: bool,
};

let findAfter = (element: 'a, list: list('a)): list('a) => {
let result: accumulator('a) =
List.fold_right(
(current: 'a, accumulator: accumulator('a)) =>
if (current == element) {
{...accumulator, found: true};
} else if (accumulator.found) {
accumulator;
} else {
{...accumulator, list: [current, ...accumulator.list]};
},
list,
{list: [], found: false},
);

result.list;
};

let findBefore = (element: 'a, list: list('a)): list('a) => {
let result: accumulator('a) =
List.fold_left(
(accumulator: accumulator('a), current: 'a) =>
if (current.sound === element.sound) {
{...accumulator, found: true};
} else if (accumulator.found) {
accumulator;
} else {
{...accumulator, list: [current, ...accumulator.list]};
},
{list: [], found: false},
list,
);

result.list |> List.rev;
};

let selectPhoneme = (index, phoneme, list) =>
list |> List.mapi((i, element) => i == index ? phoneme : element);

let reducer = (state, action) => {
switch (action) {
| AddPhoneme => {phonemes: state.phonemes @ [firstPhoneme]}
| RemovePhoneme => {
phonemes: state.phonemes |> List.rev |> List.tl |> List.rev,
| AddPhoneme => {...state, phonemes: state.phonemes @ [firstPhoneme]}
| RemovePhoneme =>
if (List.length(state.phonemes) > 1) {
let newPhonemes = state.phonemes |> List.rev |> List.tl |> List.rev;
let length = List.length(newPhonemes);
{
phonemes: newPhonemes,
activeIndex:
List.length(newPhonemes) > state.activeIndex
? state.activeIndex : length - 1,
};
} else {
state;
}
| PhonemeClicked(index, phoneme) => {
...state,
phonemes: selectPhoneme(index, phoneme, state.phonemes),
}
| SetActive(index) => {...state, activeIndex: index}
| SelectionClicked(clickedPhoneme) => {
...state,
phonemes:
state.phonemes
|> List.mapi((index, phoneme) => {
index == state.activeIndex ? clickedPhoneme : phoneme
}),
}
};
};

[@react.component]
let make = (~state, ~dispatch, ~onViewButtonClicked) => {
module PhonemeSelector = {
module SelectedPhoneme = {
[@react.component]
let make = (~selectedPhoneme as phoneme, ~index) => {
let before: list(phoneme) = phonemes |> findBefore(phoneme);
let after: list(phoneme) = phonemes |> findAfter(phoneme);
<div className="phoneme-selector">
<div className="before">
{before
|> List.mapi((beforeIndex, beforePhoneme) =>
<Phoneme
key={string_of_int(beforeIndex)}
phoneme=beforePhoneme
onClick={() =>
dispatch(PhonemeClicked(index, beforePhoneme))
}
let make = (~selectedPhoneme as phoneme, ~active, ~onClick) => {
<div className={"selected" ++ (active ? " active" : "")}>
<Phoneme phoneme onClick />
</div>;
};
};

module ViewPhonemes = {
[@react.component]
let make = (~phonemes: list(phoneme)) => {
<>
<div className="phonemes">
{phonemes
|> List.mapi((index, selectedPhoneme) =>
<SelectedPhoneme
selectedPhoneme
active={index == state.activeIndex}
key={string_of_int(index)}
onClick={() => dispatch(SetActive(index))}
/>
)
|> Array.of_list
|> React.array}
<button
className="remove-phoneme"
onClick={_evt => dispatch(RemovePhoneme)}>
{str("-")}
</button>
<button
className="add-phoneme" onClick={_evt => dispatch(AddPhoneme)}>
{str("+")}
</button>
</div>
<div className="selected"> <Phoneme phoneme /> </div>
<div className="after">
{after
|> List.mapi((afterIndex, afterPhoneme) =>
<div className="selection">
{Phoneme.phonemes
|> List.mapi((index, phoneme) =>
<Phoneme
key={string_of_int(afterIndex)}
phoneme=afterPhoneme
onClick={() =>
dispatch(PhonemeClicked(index, afterPhoneme))
}
phoneme
key={string_of_int(index)}
onClick={() => dispatch(SelectionClicked(phoneme))}
/>
)
|> Array.of_list
|> React.array}
</div>
</div>;
};
};

module ViewPhonemes = {
[@react.component]
let make = (~phonemes: list(phoneme)) => {
<div className="phonemes">
{phonemes
|> List.mapi((index, selectedPhoneme) =>
<PhonemeSelector
selectedPhoneme
index
key={string_of_int(index)}
/>
)
|> Array.of_list
|> React.array}
<button
className="remove-phoneme"
onClick={_evt => dispatch(RemovePhoneme)}>
{str("-")}
</button>
<button
className="add-phoneme" onClick={_evt => dispatch(AddPhoneme)}>
{str("+")}
</button>
</div>;
</>;
};
};

<div className="edit">
<ViewPhonemes phonemes={state.phonemes} />
<button className="edit-button" onClick={_evt => onViewButtonClicked()}>
{str("Play")}
</button>
<button
className="view-button"
onClick={_evt => onViewButtonClicked()}
title="Play"
/>
</div>;
};
2 changes: 1 addition & 1 deletion src/PhonicsApp.re
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let toView = (state: state) => {

let toEdit = (state: state) => {
switch (state) {
| View(viewState) => Edit({phonemes: viewState.phonemes})
| View(viewState) => Edit({activeIndex: 0, phonemes: viewState.phonemes})
| Edit(_) => state
};
};
Expand Down
8 changes: 5 additions & 3 deletions src/View.re
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ let make = (~dispatch, ~state, ~onEditButtonClicked) => {

<div className="view">
<ViewPhonemes phonemes={state.phonemes} />
<button className="view-button" onClick={_evt => onEditButtonClicked()}>
{str("Edit")}
</button>
<button
className="edit-button"
onClick={_evt => onEditButtonClicked()}
title="Edit"
/>
</div>;
};
1 change: 1 addition & 0 deletions src/icons/play_circle_filled-24px.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/icons/settings-24px.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 53 additions & 37 deletions src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ html {
}
.view-button,
.edit-button {
font-size: 20px;
width: 100px;
// background: rgba(223, 223, 223, 0.5);
font-size: 16px;
width: 50px;
height: 50px;
}

.add-phoneme,
.remove-phoneme {
font-size: 40px;
margin: 10px;
font-size: 20px;
margin-left: 10px;
margin-top: 10px;
width: 50px;
height: 50px;
}
Expand All @@ -37,7 +39,6 @@ html {
.phoneme {
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
background-color: rgba(255, 255, 255, 1);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
Expand All @@ -64,62 +65,77 @@ html {
}
}

.edit,
.view {
display: grid;
height: 100%;
width: 100%;
grid-template-rows: 100vh;
.edit-button,
.view-button {
.edit-button {
background-color: transparent;
position: absolute;
bottom: 20px;
right: 20px;
top: 10px;
right: 10px;
background-image: url("./icons/settings-24px.svg");
background-size: contain;
background-position: center;
background-repeat: no-repeat;
opacity: 0.5;
}
}

.phoneme-selector {
.edit {
display: grid;
position: relative;
.phoneme {
border-top-width: 20px;
border-radius: 15px;
width: 100px;
height: 150px;
margin: 10px 10px;
font-size: 60px;
}
.selected {
background: rgba(0, 0, 0, 0.15);
}
.before,
.after {
height: 100%;
width: 100%;
grid-template-rows: min-content 1fr;
.selection {
padding: 10px;
background: #bcbcbc;
display: flex;
flex-direction: column;
width: 100%;
align-items: center;
flex-wrap: wrap;
overflow-y: auto;
align-items: flex-start;
justify-content: center;
align-content: flex-start;
.phoneme {
border-top-width: 15px;
border-radius: 10px;
margin: 0 40px;
border-top-width: 20px;
border-radius: 15px;
width: 80px;
height: 100px;
margin: 10px;
font-size: 40px;
margin: 10px 10px;
}
}
.before {
.view-button {
background-color: transparent;
position: absolute;
bottom: 100%;
top: 10px;
right: 10px;
background-image: url("./icons/play_circle_filled-24px.svg");
background-size: contain;
background-position: center;
background-repeat: no-repeat;
opacity: 0.5;
}
.after {
position: absolute;
top: 100%;
}

.selected {
&.active {
background: #bcbcbc;
}
.phoneme {
border-top-width: 20px;
border-radius: 15px;
width: 100px;
height: 150px;
margin: 10px 10px;
font-size: 60px;
}
}

.view {
.phoneme {
border-radius: 20px;
border-top-width: 40px;
margin: 0 20px;
width: 250px;
Expand Down

0 comments on commit 1110bba

Please sign in to comment.