Skip to content

Commit

Permalink
Refactoring the Plutus playground client. (#2629)
Browse files Browse the repository at this point in the history
* Moving lots of stuff around.

* Fixing an unused imports warning.

* Setting the plutus logo as a global in entry.js (so webpack is happy with its path in both dev and prod).

Co-authored-by: Kris Jenkins <kris.jenkins@tweag.io>
  • Loading branch information
merivale and Kris Jenkins committed Jan 21, 2021
1 parent 84f537f commit 72197eb
Show file tree
Hide file tree
Showing 23 changed files with 619 additions and 136 deletions.
2 changes: 2 additions & 0 deletions plutus-playground-client/entry.js
Expand Up @@ -16,5 +16,7 @@ import { initVimMode, VimMode } from 'monaco-vim';
global.VimMode = VimMode;
global.initVimMode = initVimMode;
global.monacoExtraTypeScriptLibs = [];
import plutusLogo from 'static/images/plutus-logo.svg';
global.plutusLogo = plutusLogo

import './src/Main.purs';
26 changes: 26 additions & 0 deletions plutus-playground-client/src/Action/Lenses.purs
@@ -0,0 +1,26 @@
module Action.Lenses
( _caller
, _blocks
, _InSlot
, _slot
) where

import Data.BigInteger (BigInteger)
import Data.Lens (Iso', Lens', iso)
import Data.Lens.Record (prop)
import Data.Newtype (unwrap, wrap)
import Data.Symbol (SProxy(..))
import Plutus.V1.Ledger.Slot (Slot)
import Prelude ((<<<))

_caller :: forall r a. Lens' { caller :: a | r } a
_caller = prop (SProxy :: SProxy "caller")

_blocks :: forall r a. Lens' { blocks :: a | r } a
_blocks = prop (SProxy :: SProxy "blocks")

_InSlot :: Iso' Slot BigInteger
_InSlot = iso (_.getSlot <<< unwrap) (wrap <<< { getSlot: _ })

_slot :: forall r a. Lens' { slot :: a | r } a
_slot = prop (SProxy :: SProxy "slot")
2 changes: 1 addition & 1 deletion plutus-playground-client/src/Action/Validation.purs
Expand Up @@ -5,9 +5,9 @@ import Data.Lens (view)
import Playground.Types (ContractCall(..), SimulatorWallet)
import Prelude ((==), (&&), (<<<))
import Schema.Types (FormArgument)
import Types (_simulatorWalletWallet, _walletId)
import Validation (isValid)
import Wallet.Emulator.Wallet (Wallet)
import Wallet.Lenses (_simulatorWalletWallet, _walletId)

actionIsValid :: Array SimulatorWallet -> ContractCall FormArgument -> Boolean
actionIsValid simulatorWallets simulatorAction = actionWalletsExist simulatorAction && isValid simulatorAction
Expand Down
6 changes: 4 additions & 2 deletions plutus-playground-client/src/Action/View.purs
@@ -1,6 +1,7 @@
module Action.View (actionsPane) where

import Action.Validation (actionIsValid)
import Action.Lenses (_InSlot)
import Bootstrap (btn, card, cardBody_, col, colFormLabel, col_, formCheck, formCheckInline, formCheckInput, formCheckLabel, formControl, formGroup_, formRow_, floatRight)
import Data.Array (mapWithIndex)
import Data.Array as Array
Expand All @@ -15,15 +16,16 @@ import Halogen.HTML.Elements.Keyed as Keyed
import Halogen.HTML.Events (onChange, onClick, onDragEnd, onDragEnter, onDragLeave, onDragOver, onDragStart, onDrop, onValueInput)
import Halogen.HTML.Properties (InputType(..), checked, class_, classes, draggable, for, id_, name, placeholder, required, type_, value)
import Icons (Icon(..), icon)
import Plutus.V1.Ledger.Slot (Slot)
import MainFrame.Types (DragAndDropEventType(..), HAction(..), SimulatorAction)
import Playground.Lenses (_endpointDescription, _getEndpointDescription)
import Playground.Types (ContractCall(..), SimulatorWallet, _FunctionSchema)
import Plutus.V1.Ledger.Slot (Slot)
import Prelude (const, map, show, ($), (+), (<$>), (<<<), (<>), (==))
import Schema.Types (ActionEvent(..), FormArgument, SimulationAction(..))
import Schema.View (actionArgumentForm)
import Types (DragAndDropEventType(..), HAction(..), SimulatorAction, _InSlot, _walletId)
import Validation (_argument)
import ValueEditor (valueForm)
import Wallet.Lenses (_walletId)
import Wallet.View (walletIdPane)
import Web.Event.Event (Event)
import Web.HTML.Event.DragEvent (DragEvent)
Expand Down
44 changes: 44 additions & 0 deletions plutus-playground-client/src/Editor/Lenses.purs
@@ -0,0 +1,44 @@
module Editor.Lenses
( _warnings
, _keyBindings
, _feedbackPaneMinimised
, _lastCompiledCode
, _currentCodeIsCompiled
, _feedbackPaneDragStart
, _feedbackPaneExtend
, _feedbackPanePreviousExtend
) where

import Data.Lens (Lens')
import Data.Lens.Iso.Newtype (_Newtype)
import Data.Lens.Record (prop)
import Data.Maybe (Maybe)
import Data.Symbol (SProxy(..))
import Editor.Types (State)
import Halogen.Monaco (KeyBindings)
import Language.Haskell.Interpreter (SourceCode)
import Prelude ((<<<))

_warnings :: forall s a. Lens' { warnings :: a | s } a
_warnings = prop (SProxy :: SProxy "warnings")

_keyBindings :: Lens' State KeyBindings
_keyBindings = _Newtype <<< prop (SProxy :: SProxy "keyBindings")

_feedbackPaneMinimised :: Lens' State Boolean
_feedbackPaneMinimised = _Newtype <<< prop (SProxy :: SProxy "feedbackPaneMinimised")

_lastCompiledCode :: Lens' State (Maybe SourceCode)
_lastCompiledCode = _Newtype <<< prop (SProxy :: SProxy "lastCompiledCode")

_currentCodeIsCompiled :: Lens' State Boolean
_currentCodeIsCompiled = _Newtype <<< prop (SProxy :: SProxy "currentCodeIsCompiled")

_feedbackPaneDragStart :: Lens' State (Maybe Int)
_feedbackPaneDragStart = _Newtype <<< prop (SProxy :: SProxy "feedbackPaneDragStart")

_feedbackPaneExtend :: Lens' State Int
_feedbackPaneExtend = _Newtype <<< prop (SProxy :: SProxy "feedbackPaneExtend")

_feedbackPanePreviousExtend :: Lens' State Int
_feedbackPanePreviousExtend = _Newtype <<< prop (SProxy :: SProxy "feedbackPanePreviousExtend")
25 changes: 16 additions & 9 deletions plutus-playground-client/src/Editor/State.purs
@@ -1,22 +1,29 @@
module Editor.State where
module Editor.State
( initialState
, handleAction
, saveBuffer
, initEditor
) where

import Control.Alternative ((<|>))
import Data.Foldable (for_)
import Data.Lens (assign, modifying, use)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Ord (clamp)
import Editor.Types (State(State), Action(..), keybindingsLocalStorageKey, readKeyBindings, _currentCodeIsCompiled, _feedbackPaneDragStart, _feedbackPaneExtend, _feedbackPaneMinimised, _feedbackPanePreviousExtend, _keyBindings, _lastCompiledCode)
import Editor.Lenses (_currentCodeIsCompiled, _feedbackPaneDragStart, _feedbackPaneExtend, _feedbackPaneMinimised, _feedbackPanePreviousExtend, _keyBindings, _lastCompiledCode)
import Editor.Types (State(State), Action(..), readKeyBindings)
import Effect.Aff.Class (class MonadAff, liftAff)
import Effect.Class (class MonadEffect)
import Halogen (HalogenM, liftEffect, query, tell)
import Halogen.Monaco (KeyBindings(..))
import Halogen.Monaco (Message(..), Query(..)) as Monaco
import Language.Haskell.Interpreter (SourceCode(SourceCode))
import LocalStorage (Key)
import LocalStorage as LocalStorage
import LocalStorage (Key, getItem, setItem)
import MainFrame.Lenses (_editorSlot)
import MainFrame.Types (ChildSlots)
import Monaco (Editor, getModel, layout, focus, setPosition, setValue) as Monaco
import Prelude (Unit, bind, discard, not, pure, show, unit, void, (+), (-), ($), (<$>), (==))
import Types (ChildSlots, _editorSlot)
import StaticData (keybindingsLocalStorageKey)
import Web.Event.Extra (preventDefault, readFileFromDragEvent)
import Web.UIEvent.MouseEvent (pageY)

Expand Down Expand Up @@ -59,7 +66,7 @@ handleAction _ (SetKeyBindings binding) = do
void $ query _editorSlot unit $ tell $ Monaco.Focus
void $ query _editorSlot unit $ tell $ Monaco.Resize
assign _keyBindings binding
liftEffect $ LocalStorage.setItem keybindingsLocalStorageKey (show binding)
liftEffect $ setItem keybindingsLocalStorageKey (show binding)

handleAction _ ToggleFeedbackPane = modifying _feedbackPaneMinimised not

Expand Down Expand Up @@ -98,10 +105,10 @@ handleAction _ (FixFeedbackPaneExtend mouseY) = do

------------------------------------------------------------
loadKeyBindings :: forall m. MonadEffect m => m KeyBindings
loadKeyBindings = maybe DefaultBindings readKeyBindings <$> liftEffect (LocalStorage.getItem keybindingsLocalStorageKey)
loadKeyBindings = maybe DefaultBindings readKeyBindings <$> liftEffect (getItem keybindingsLocalStorageKey)

saveBuffer :: forall m. MonadEffect m => Key -> String -> m Unit
saveBuffer bufferLocalStorageKey text = liftEffect $ LocalStorage.setItem bufferLocalStorageKey text
saveBuffer bufferLocalStorageKey text = liftEffect $ setItem bufferLocalStorageKey text

initEditor ::
forall m.
Expand All @@ -113,7 +120,7 @@ initEditor ::
m Unit
initEditor initialContents bufferLocalStorageKey state@(State { keyBindings }) editor =
liftEffect do
savedContents <- LocalStorage.getItem bufferLocalStorageKey
savedContents <- getItem bufferLocalStorageKey
let
contents = fromMaybe "" (savedContents <|> initialContents)
model <- Monaco.getModel editor
Expand Down
75 changes: 22 additions & 53 deletions plutus-playground-client/src/Editor/Types.purs
@@ -1,24 +1,36 @@
module Editor.Types where
module Editor.Types
( State(..)
, Action(..)
, allKeyBindings
, readKeyBindings
) where

import Data.Enum (enumFromTo)
import Data.Lens (Lens')
import Data.Lens.Iso.Newtype (_Newtype)
import Data.Lens.Record (prop)
import Data.Maybe (Maybe)
import Data.Newtype (class Newtype)
import Data.Symbol (SProxy(..))
import Halogen.Monaco (KeyBindings(..))
import Halogen.Monaco (Message) as Monaco
import Halogen.Monaco (KeyBindings(..), Message)
import Language.Haskell.Interpreter (SourceCode)
import LocalStorage (Key(..))
import Monaco (IPosition)
import Prelude (bottom, top, (<<<))
import Prelude (bottom, top)
import Web.HTML.Event.DragEvent (DragEvent)
import Web.UIEvent.MouseEvent (MouseEvent)

newtype State
= State
{ keyBindings :: KeyBindings
, feedbackPaneMinimised :: Boolean
, lastCompiledCode :: Maybe SourceCode
, currentCodeIsCompiled :: Boolean
, feedbackPaneDragStart :: Maybe Int
, feedbackPaneExtend :: Int
, feedbackPanePreviousExtend :: Int
}

derive instance newtypeState :: Newtype State _

data Action
= Init
| HandleEditorMessage Monaco.Message
| HandleEditorMessage Message
| HandleDragEvent DragEvent
| HandleDropEvent DragEvent
| ScrollTo IPosition
Expand All @@ -28,7 +40,6 @@ data Action
| ClearFeedbackPaneDragStart
| FixFeedbackPaneExtend Int

------------------------------------------------------------
allKeyBindings :: Array KeyBindings
allKeyBindings = enumFromTo bottom top

Expand All @@ -38,45 +49,3 @@ readKeyBindings "Emacs" = Emacs
readKeyBindings "Vim" = Vim

readKeyBindings _ = DefaultBindings

------------------------------------------------------------
newtype State
= State
{ keyBindings :: KeyBindings
, feedbackPaneMinimised :: Boolean
, lastCompiledCode :: Maybe SourceCode
, currentCodeIsCompiled :: Boolean
, feedbackPaneDragStart :: Maybe Int
, feedbackPaneExtend :: Int
, feedbackPanePreviousExtend :: Int
}

derive instance newtypeState :: Newtype State _

------------------------------------------------------------
keybindingsLocalStorageKey :: Key
keybindingsLocalStorageKey = Key "EditorPreferences.KeyBindings"

_warnings :: forall s a. Lens' { warnings :: a | s } a
_warnings = prop (SProxy :: SProxy "warnings")

_keyBindings :: Lens' State KeyBindings
_keyBindings = _Newtype <<< prop (SProxy :: SProxy "keyBindings")

_feedbackPaneMinimised :: Lens' State Boolean
_feedbackPaneMinimised = _Newtype <<< prop (SProxy :: SProxy "feedbackPaneMinimised")

_lastCompiledCode :: Lens' State (Maybe SourceCode)
_lastCompiledCode = _Newtype <<< prop (SProxy :: SProxy "lastCompiledCode")

_currentCodeIsCompiled :: Lens' State Boolean
_currentCodeIsCompiled = _Newtype <<< prop (SProxy :: SProxy "currentCodeIsCompiled")

_feedbackPaneDragStart :: Lens' State (Maybe Int)
_feedbackPaneDragStart = _Newtype <<< prop (SProxy :: SProxy "feedbackPaneDragStart")

_feedbackPaneExtend :: Lens' State Int
_feedbackPaneExtend = _Newtype <<< prop (SProxy :: SProxy "feedbackPaneExtend")

_feedbackPanePreviousExtend :: Lens' State Int
_feedbackPanePreviousExtend = _Newtype <<< prop (SProxy :: SProxy "feedbackPanePreviousExtend")
6 changes: 4 additions & 2 deletions plutus-playground-client/src/Editor/View.purs
Expand Up @@ -13,8 +13,9 @@ import Data.Either (Either(..))
import Data.Lens (_Right, preview, to, view)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.String as String
import Editor.Lenses (_warnings)
import Editor.State (initEditor)
import Editor.Types (Action(..), State(..), _warnings, allKeyBindings)
import Editor.Types (Action(..), State(..), allKeyBindings)
import Effect.Aff.Class (class MonadAff)
import Halogen.HTML (ClassName(ClassName), ComponentHTML, HTML, a, button, code_, div, div_, option, p_, pre, pre_, select, slot, text)
import Halogen.HTML.Events (onClick, onDragOver, onDrop, onMouseDown, onMouseMove, onMouseUp, onSelectedIndexChange)
Expand All @@ -24,9 +25,10 @@ import Icons (Icon(..), icon)
import Language.Haskell.Interpreter (CompilationError(CompilationError, RawError), InterpreterError(CompilationErrors, TimeoutError), Warning, _InterpreterResult, _Warning)
import Language.Haskell.Monaco as HM
import LocalStorage (Key)
import MainFrame.Lenses (_editorSlot)
import MainFrame.Types (ChildSlots, HAction(..), View(..), WebCompilationResult)
import Network.RemoteData (RemoteData(..), _Success, isLoading)
import Prelude (const, map, not, pure, show, unit, ($), (<$>), (<<<), (<>), (==))
import Types (ChildSlots, _editorSlot, HAction(..), View(..), WebCompilationResult)
import Web.UIEvent.MouseEvent (MouseEvent, pageY)

editorPreferencesSelect :: forall p. KeyBindings -> HTML p Action
Expand Down
6 changes: 3 additions & 3 deletions plutus-playground-client/src/Main.purs
@@ -1,6 +1,5 @@
module Main where

import Prelude
import Control.Coroutine (Consumer, Process, connect, consumer, runProcess)
import Data.Maybe (Maybe(Nothing))
import Effect (Effect)
Expand All @@ -11,8 +10,9 @@ import Halogen.Aff (awaitBody, runHalogenAff)
import Halogen.VDom.Driver (runUI)
import LocalStorage (RawStorageEvent)
import LocalStorage as LocalStorage
import MainFrame (mkMainFrame)
import Types (HAction(..))
import MainFrame.State (mkMainFrame)
import MainFrame.Types (HAction(..))
import Prelude (Unit, bind, discard, pure, show, ($), (<>))

main :: Effect Unit
main = do
Expand Down

0 comments on commit 72197eb

Please sign in to comment.