Skip to content

Commit fc13182

Browse files
author
Ryan Trinkle
authored
Merge pull request #15 from gspia/master
update fileinput example to allow newer reflex
2 parents b7319cb + d7c9f37 commit fc13182

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1806
-425
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
dist
2+
dist-newstyle
3+
dist-ghcjs
24
cabal-dev
35
*.o
46
*.hi

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "reflex-platform"]
2+
path = reflex-platform
3+
url = https://github.com/reflex-frp/reflex-platform

BasicTodo/BasicTodo.cabal

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: BasicTodo
2+
version: 0.1.0.1
3+
build-type: Simple
4+
cabal-version: >=1.10
5+
6+
executable basictodo
7+
main-is: Main.hs
8+
ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
9+
-- other-extensions:
10+
build-depends: base
11+
-- , common -- we don't need common parts here
12+
, containers
13+
, lens
14+
, text
15+
, ghcjs-dom
16+
, reflex
17+
, reflex-dom
18+
-- , reflex-dom-core
19+
, jsaddle
20+
-- , jsaddle-warp
21+
hs-source-dirs: src
22+
default-language: Haskell2010

BasicTodo/BasicTodo.hs

Lines changed: 0 additions & 47 deletions
This file was deleted.

BasicTodo/src/Main.hs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{-# LANGUAGE OverloadedLists #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE RecursiveDo #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
6+
{-
7+
- Stripped version of todo list: just add new todo and delete an old one
8+
-}
9+
10+
import Control.Lens
11+
import qualified Data.Map as M
12+
import qualified Data.Text as T
13+
import Reflex
14+
import Reflex.Dom hiding (mainWidget)
15+
import Reflex.Dom.Core (mainWidget)
16+
17+
18+
type MM a = M.Map Int a
19+
20+
-- add a new value to a map, automatically choosing an unused key
21+
new :: a -> MM a -> MM a
22+
new v m = case M.maxViewWithKey m of
23+
Nothing -> [(0,v)] -- overloadedlists
24+
Just ((k, _), _) -> M.insert (succ k) v m
25+
26+
-- output the ul of the elements of the given map and return the delete
27+
-- event for each key
28+
ulW :: MonadWidget t m => Dynamic t (MM T.Text) -> m (Dynamic t (MM (Event t Int)))
29+
ulW xs = elClass "ul" "list" $ listWithKey xs $ \k x -> elClass "li" "element" $ do
30+
dynText x -- output the text
31+
fmap (const k) <$> elClass "div" "delete" (button "x")
32+
-- tag the event of button press with the key of the text
33+
34+
-- output an input text widget with auto clean on return and return an
35+
-- event firing on return containing the string before clean
36+
inputW :: MonadWidget t m => m (Event t T.Text)
37+
inputW = do
38+
rec let send = ffilter (==13) $ view textInput_keypress input
39+
-- send signal firing on *return* key press
40+
input <- textInput $ def & setValue .~ fmap (const "") send
41+
-- textInput with content reset on send
42+
return $ tag (current $ view textInput_value input) send
43+
-- tag the send signal with the inputText value BEFORE resetting
44+
45+
-- circuit ulW with a MM String kept updated by new strings from the passed
46+
-- event and deletion of single element in the MM
47+
listW :: MonadWidget t m => Event t T.Text -> m ()
48+
listW e = do
49+
rec xs <- foldDyn ($) M.empty $ mergeWith (.)
50+
-- live state, updated by two signals
51+
[ fmap new e -- insert a new text
52+
, switch . current $ zs -- delete text at specific keys
53+
]
54+
bs <- ulW xs -- delete signals from outputted state
55+
let zs = fmap (mergeWith (.) . map (fmap M.delete) . M.elems) bs
56+
-- merge delete events
57+
return ()
58+
59+
app :: forall t m. MonadWidget t m => m ()
60+
app = el "div" $ inputW >>= listW
61+
62+
main :: IO ()
63+
main = run $ mainWidget app
64+

ChangeLog.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Revision history for reflex-examples
2+
3+
## 2018-01-12
4+
5+
* Update README
6+
* Updated all examples to use ghcjs-dom and GHCJS.DOM in the imports.
7+
8+
## 2018-01-11
9+
10+
* Update README
11+
* Update reflex-platform submodule
12+
13+
## 2018-01-10
14+
15+
* Cabal file reorganization
16+
* Use "project" from reflex-platform for all examples.
17+
* Small fixes to nasa-pod -example.
18+
* Small fixes to drag-and-drop -example.
19+
* Added two simple websocket chat examples.
20+
* Changed .gitignore a bit
21+
* Other minor changes.
22+
23+
## 2017 and earlier
24+
25+
* Earlier versions of the examples.

Keyboard/Keyboard.cabal

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Keyboard
2+
version: 0.1.0.1
3+
build-type: Simple
4+
cabal-version: >=1.10
5+
6+
executable keyboard
7+
main-is: Main.hs
8+
ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
9+
-- other-extensions:
10+
build-depends: base
11+
-- , common -- we don't need common parts here
12+
, text
13+
, ghcjs-dom
14+
, reflex
15+
, reflex-dom
16+
, reflex-dom-core
17+
, jsaddle
18+
-- , jsaddle-warp
19+
hs-source-dirs: src
20+
default-language: Haskell2010

Keyboard/Keyboard.hs

Lines changed: 0 additions & 41 deletions
This file was deleted.

Keyboard/README.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
3+
Run with
4+
5+
cabal --project-file=cabal-ghcjs.project --builddir=dist-ghcjs new-build all

Keyboard/src/Main.hs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{-# LANGUAGE OverloadedLists #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE RecursiveDo #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
6+
{-
7+
- buttons + real keyboard both writing to a text box
8+
-}
9+
10+
import Control.Monad (void, forM)
11+
import qualified Data.List.NonEmpty as DL (head)
12+
import Data.Monoid ((<>))
13+
import qualified Data.Text as T
14+
import GHCJS.DOM.HTMLElement (focus)
15+
import GHCJS.DOM.HTMLInputElement hiding (setValue)
16+
import Language.Javascript.JSaddle
17+
import Reflex
18+
import Reflex.Dom hiding (mainWidget)
19+
import Reflex.Dom.Core (mainWidget)
20+
21+
-- import Language.Javascript.JSaddle.Warp
22+
23+
24+
insertAt :: Int -> Char -> T.Text -> T.Text
25+
insertAt n c v = T.take n v <> T.singleton c <> T.drop n v
26+
27+
fromListE :: Reflex t => [Event t a] -> Event t a
28+
fromListE = fmap DL.head . mergeList
29+
30+
performArg :: MonadWidget t m => (b -> JSM a) -> Event t b -> m (Event t a)
31+
performArg f x = performEvent (fmap (liftJSM . f) x)
32+
33+
inputW :: forall m t . MonadWidget t m => Event t Char -> m ()
34+
inputW buttonE = do
35+
rec let newStringE =
36+
attachWith (\v (c,n) -> (n + 1,insertAt n c v)) cur posCharE
37+
cur = current $ value input -- actual string
38+
html = _textInput_element input -- html element
39+
input <- textInput $ def & setValue .~ fmap snd newStringE
40+
posCharE :: Event t (Char,Int)
41+
<- performArg (\c -> (,) c <$> getSelectionStart html) buttonE
42+
_ <- delay 0.1 (fmap snd posCharE)
43+
>>= performArg (\n -> setSelectionStart html (n+ 1)
44+
>> setSelectionEnd html (n + 1))
45+
void $ performArg (const $ focus html) buttonE -- keep the focus right
46+
47+
keys :: MonadWidget t m => m [Event t Char]
48+
keys = forM "qwerty" $ \c -> fmap (const c) <$> button [c] -- OverloadedLists
49+
50+
app :: forall t m. MonadWidget t m => m ()
51+
app = el "div" $ elClass "div" "keys" keys >>= inputW . fromListE
52+
53+
main :: IO ()
54+
main = run $ mainWidget app
55+
56+

0 commit comments

Comments
 (0)